From 0f2da4b9bf38bd9ee48f6f36ec0c11d1df422918 Mon Sep 17 00:00:00 2001 From: Gregor Best Date: Tue, 5 May 2009 19:55:29 +0200 Subject: [PATCH] widgets: export extents() function This commit adds a function called extents() to widgets. In the case of a systray, it takes the systray's screen as its argument to correctly calculate the width. By default, 1 is assumed. For all other widgets, the argument can be ommitted. The function doesn't return the geometry as drawn, instead it returns the geometry the widget _wants_ to be drawn at, for example an imagebox always has (image width, image height) as the return values even if it's drawn with a smaller width and height on a smaller wibox. Signed-off-by: Gregor Best Signed-off-by: Julien Danjou --- widget.c | 24 ++++++++++++++++++++++++ widget.h | 4 +++- widgets/graph.c | 11 +++++++++++ widgets/imagebox.c | 21 +++++++++++++++++++++ widgets/progressbar.c | 29 +++++++++++++++++++++++++++++ widgets/systray.c | 28 ++++++++++++++++++++++++++++ widgets/textbox.c | 27 +++++++++++++++++++++++++++ 7 files changed, 143 insertions(+), 1 deletion(-) diff --git a/widget.c b/widget.c index a47671350..00b8a95cd 100644 --- a/widget.c +++ b/widget.c @@ -495,6 +495,29 @@ luaA_widget_newindex(lua_State *L) return 0; } +static int +luaA_widget_extents(lua_State *L) +{ + widget_t *widget = luaL_checkudata(L, 1, "widget"); + area_t g = { + .x = 0, + .y = 0, + .width = 0, + .height = 0 + }; + + if(widget->extents) + g = widget->extents(L, widget); + + lua_newtable(L); + lua_pushnumber(L, g.width); + lua_setfield(L, -2, "width"); + lua_pushnumber(L, g.height); + lua_setfield(L, -2, "height"); + + return 1; +} + const struct luaL_reg awesome_widget_methods[] = { { "__call", luaA_widget_new }, @@ -503,6 +526,7 @@ const struct luaL_reg awesome_widget_methods[] = const struct luaL_reg awesome_widget_meta[] = { { "buttons", luaA_widget_buttons }, + { "extents", luaA_widget_extents }, { "__index", luaA_widget_index }, { "__newindex", luaA_widget_newindex }, { "__gc", luaA_widget_gc }, diff --git a/widget.h b/widget.h index 1d8204c42..94add2fbc 100644 --- a/widget.h +++ b/widget.h @@ -37,8 +37,10 @@ struct widget_t widget_constructor_t *type; /** Widget destructor */ widget_destructor_t *destructor; - /** Geometry function */ + /** Geometry function for drawing */ area_t (*geometry)(widget_t *, screen_t *, int, int); + /** Extents function */ + area_t (*extents)(lua_State *, widget_t *); /** Draw function */ void (*draw)(widget_t *, draw_context_t *, area_t, wibox_t *); /** Index function */ diff --git a/widgets/graph.c b/widgets/graph.c index 145ffb6aa..2ff30482f 100644 --- a/widgets/graph.c +++ b/widgets/graph.c @@ -160,6 +160,16 @@ graph_geometry(widget_t *widget, screen_t *screen, int height, int width) return geometry; } +static area_t +graph_extents(lua_State *L, widget_t *widget) +{ + area_t geometry; + graph_data_t *d = widget->data; + geometry.width = geometry.height = d->width; + + return geometry; +} + /** Draw a graph widget. * \param ctx The draw context. * \param w The widget node we are called from. @@ -595,6 +605,7 @@ widget_graph(widget_t *w) w->newindex = luaA_graph_newindex; w->destructor = graph_destructor; w->geometry = graph_geometry; + w->extents = graph_extents; graph_data_t *d = w->data = p_new(graph_data_t, 1); diff --git a/widgets/imagebox.c b/widgets/imagebox.c index f1db63a97..00d65e0a8 100644 --- a/widgets/imagebox.c +++ b/widgets/imagebox.c @@ -76,6 +76,26 @@ imagebox_geometry(widget_t *widget, screen_t *screen, int height, int width) return geometry; } +static area_t +imagebox_extents(lua_State *L, widget_t *widget) +{ + area_t geometry = { + .x = 0, + .y = 0, + .width = 0, + .height = 0 + }; + imagebox_data_t *d = widget->data; + + if(d->image) + { + geometry.width = image_getwidth(d->image); + geometry.height = image_getheight(d->image); + } + + return geometry; +} + /** Draw an image. * \param widget The widget. * \param ctx The draw context. @@ -215,6 +235,7 @@ widget_imagebox(widget_t *w) w->newindex = luaA_imagebox_newindex; w->destructor = imagebox_destructor; w->geometry = imagebox_geometry; + w->extents = imagebox_extents; w->data = d = p_new(imagebox_data_t, 1); d->resize = true; d->valign = AlignTop; diff --git a/widgets/progressbar.c b/widgets/progressbar.c index db55d31a7..8564dc293 100644 --- a/widgets/progressbar.c +++ b/widgets/progressbar.c @@ -163,6 +163,34 @@ progressbar_geometry(widget_t *widget, screen_t *screen, int height, int width) return geometry; } +static area_t +progressbar_extents(lua_State *L, widget_t *widget) +{ + area_t geometry; + progressbar_data_t *d = widget->data; + + if (d->vertical) + { + int pb_width = (int) ((d->width - 2 * (d->border_width + d->border_padding) * d->bars.len + - d->gap * (d->bars.len - 1)) / d->bars.len); + geometry.width = d->bars.len * (pb_width + 2 * (d->border_width + d->border_padding) + + d->gap) - d->gap; + }else + { + int pb_width = d->width - 2 * (d->border_width + d->border_padding); + if(d->ticks_count && d->ticks_gap) + { + int unit = (pb_width + d->ticks_gap) / d->ticks_count; + pb_width = unit * d->ticks_count - d->ticks_gap; /* rounded to match ticks... */ + } + geometry.width = pb_width + 2 * (d->border_width + d->border_padding); + } + + geometry.height = geometry.width; + + return geometry; +} + /** Draw a progressbar. * \param ctx The draw context. * \param w The widget node we're drawing for. @@ -650,6 +678,7 @@ widget_progressbar(widget_t *w) w->newindex = luaA_progressbar_newindex; w->destructor = progressbar_destructor; w->geometry = progressbar_geometry; + w->extents = progressbar_extents; progressbar_data_t *d = w->data = p_new(progressbar_data_t, 1); diff --git a/widgets/systray.c b/widgets/systray.c index 16cb7fd26..16ce9f2b4 100644 --- a/widgets/systray.c +++ b/widgets/systray.c @@ -50,6 +50,33 @@ systray_geometry(widget_t *widget, screen_t *screen, int height, int width) return geometry; } +static area_t +systray_extents(lua_State *L, widget_t *widget) +{ + area_t geometry; + int screen = screen_virttophys(luaL_optnumber(L, -1, 1)), n = 0; + + geometry.height = 0; + int width = 0; + + for(int i = 0; i < globalconf.embedded.len; i++) + if(globalconf.embedded.tab[i].phys_screen == screen) + { + xcb_get_geometry_cookie_t geo = xcb_get_geometry(globalconf.connection, globalconf.embedded.tab[i].win); + xcb_get_geometry_reply_t *g = xcb_get_geometry_reply(globalconf.connection, geo, NULL); + + n++; + if(g->height > geometry.height) + geometry.height = g->height; + if(g->width > width) + width = g->width; + } + + geometry.width = width * n; + + return geometry; +} + static void systray_draw(widget_t *widget, draw_context_t *ctx, area_t geometry, wibox_t *p) @@ -83,6 +110,7 @@ widget_systray(widget_t *w) { w->draw = systray_draw; w->geometry = systray_geometry; + w->extents = systray_extents; return w; } diff --git a/widgets/textbox.c b/widgets/textbox.c index 97107560b..b17285e8f 100644 --- a/widgets/textbox.c +++ b/widgets/textbox.c @@ -79,6 +79,32 @@ textbox_geometry(widget_t *widget, screen_t *screen, int height, int width) return geometry; } +static area_t +textbox_extents(lua_State *L, widget_t *widget) +{ + textbox_data_t *d = widget->data; + area_t geometry = d->extents; + + geometry.width += d->margin.left + d->margin.left; + geometry.height += d->margin.bottom + d->margin.top; + + if(d->bg_image) + { + int bgi_height = image_getheight(d->bg_image); + int bgi_width = image_getwidth(d->bg_image); + double ratio = d->bg_resize ? (double) geometry.height / bgi_height : 1; + geometry.width = MAX(d->extents.width + d->margin.left + d->margin.right, MAX(d->width, bgi_width * ratio)); + } + + if (d->data.len == 0) + { + geometry.width = 0; + geometry.height = 0; + } + + return geometry; +} + /** Draw a textbox widget. * \param widget The widget. * \param ctx The draw context. @@ -376,6 +402,7 @@ widget_textbox(widget_t *w) w->newindex = luaA_textbox_newindex; w->destructor = textbox_destructor; w->geometry = textbox_geometry; + w->extents = textbox_extents; textbox_data_t *d = w->data = p_new(textbox_data_t, 1); d->ellip = PANGO_ELLIPSIZE_END;