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 <farhaven@googlemail.com> Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
45c2ac38a4
commit
0f2da4b9bf
24
widget.c
24
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 },
|
||||
|
|
4
widget.h
4
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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue