titlebar: add support for border, refactorize code

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-06-18 11:22:54 +02:00
parent 8753a54c65
commit 32a73f9ae6
4 changed files with 108 additions and 180 deletions

View File

@ -478,7 +478,7 @@ client_resize(client_t *c, area_t geometry, bool hints)
if(c->titlebar && !c->ismoving && !c->isfloating && layout != layout_floating)
{
titlebar_update_geometry(c, geometry);
titlebar_update_geometry_tiled(c, geometry);
geometry = titlebar_geometry_remove(c->titlebar, geometry);
}

View File

@ -185,6 +185,12 @@ struct titlebar_t
{
xcolor_t fg, bg;
} colors;
/** Border */
struct
{
xcolor_t color;
int width;
} border;
};
/** Delete a titlebar structure.

View File

@ -137,223 +137,100 @@ titlebar_draw(client_t *c)
draw_context_delete(&ctx);
}
/** Update the titlebar geometry for a floating client.
* \param c the client
*/
void
titlebar_update_geometry_floating(client_t *c)
titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
{
int width, x_offset = 0, y_offset = 0;
if(!c->titlebar || !c->titlebar->sw)
return;
switch(c->titlebar->position)
{
default:
return;
case Top:
if(c->titlebar->width)
width = MIN(c->titlebar->width, c->geometry.width);
width = MAX(1, MIN(c->titlebar->width, geometry.width - 2 * c->titlebar->border.width));
else
width = c->geometry.width + 2 * c->border;
width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->border.width);
switch(c->titlebar->align)
{
default:
break;
case AlignRight:
x_offset = 2 * c->border + c->geometry.width - width;
break;
case AlignCenter:
x_offset = (c->geometry.width - width) / 2;
break;
}
simplewindow_moveresize(c->titlebar->sw,
c->geometry.x + x_offset,
c->geometry.y - c->titlebar->sw->geometry.height,
width,
c->titlebar->sw->geometry.height);
break;
case Bottom:
if(c->titlebar->width)
width = MIN(c->titlebar->width, c->geometry.width);
else
width = c->geometry.width + 2 * c->border;
switch(c->titlebar->align)
{
default:
break;
case AlignRight:
x_offset = 2 * c->border + c->geometry.width - width;
break;
case AlignCenter:
x_offset = (c->geometry.width - width) / 2;
break;
}
simplewindow_moveresize(c->titlebar->sw,
c->geometry.x + x_offset,
c->geometry.y + c->geometry.height + 2 * c->border,
width,
c->titlebar->sw->geometry.height);
break;
case Left:
if(c->titlebar->width)
width = MIN(c->titlebar->width, c->geometry.height);
else
width = c->geometry.height + 2 * c->border;
switch(c->titlebar->align)
{
default:
break;
case AlignRight:
y_offset = 2 * c->border + c->geometry.height - width;
break;
case AlignCenter:
y_offset = (c->geometry.height - width) / 2;
break;
}
simplewindow_moveresize(c->titlebar->sw,
c->geometry.x - c->titlebar->sw->geometry.width,
c->geometry.y + y_offset,
c->titlebar->sw->geometry.width,
width);
break;
case Right:
if(c->titlebar->width)
width = MIN(c->titlebar->width, c->geometry.height);
else
width = c->geometry.height + 2 * c->border;
switch(c->titlebar->align)
{
default:
break;
case AlignRight:
y_offset = 2 * c->border + c->geometry.height - width;
break;
case AlignCenter:
y_offset = (c->geometry.height - width) / 2;
break;
}
simplewindow_moveresize(c->titlebar->sw,
c->geometry.x + c->geometry.width + 2 * c->border,
c->geometry.y + y_offset,
c->titlebar->sw->geometry.width,
width);
break;
}
titlebar_draw(c);
}
/** Update the titlebar geometry for a tiled client.
* \param c The client.
* \param geometry The geometry the client will receive.
*/
void
titlebar_update_geometry(client_t *c, area_t geometry)
{
int width, x_offset = 0 , y_offset = 0;
if(!c->titlebar || !c->titlebar->sw)
return;
switch(c->titlebar->position)
{
default:
return;
case Top:
if(!c->titlebar->width)
width = geometry.width + 2 * c->border;
else
width = MIN(c->titlebar->width, geometry.width);
switch(c->titlebar->align)
{
default:
break;
case AlignRight:
x_offset = 2 * c->border + geometry.width - width;
x_offset = 2 * c->border + geometry.width - width - 2 * c->titlebar->border.width;
break;
case AlignCenter:
x_offset = (geometry.width - width) / 2;
break;
}
simplewindow_moveresize(c->titlebar->sw,
geometry.x + x_offset,
geometry.y,
width,
c->titlebar->sw->geometry.height);
res->x = geometry.x + x_offset;
res->y = geometry.y - c->titlebar->height - 2 * c->titlebar->border.width;
res->width = width;
res->height = c->titlebar->height;
break;
case Bottom:
if(c->titlebar->width)
width = geometry.width + 2 * c->border;
width = MAX(1, MIN(c->titlebar->width, geometry.width - 2 * c->titlebar->border.width));
else
width = MIN(c->titlebar->width, geometry.width);
width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->border.width);
switch(c->titlebar->align)
{
default:
break;
case AlignRight:
x_offset = 2 * c->border + geometry.width - width;
x_offset = 2 * c->border + geometry.width - width - 2 * c->titlebar->border.width;
break;
case AlignCenter:
x_offset = (geometry.width - width) / 2;
break;
}
simplewindow_moveresize(c->titlebar->sw,
geometry.x + x_offset,
geometry.y + geometry.height
- c->titlebar->sw->geometry.height + 2 * c->border,
width,
c->titlebar->sw->geometry.height);
res->x = geometry.x + x_offset;
res->y = geometry.y + geometry.height + 2 * c->border;
res->width = width;
res->height = c->titlebar->height;
break;
case Left:
if(!c->titlebar->width)
width = geometry.height + 2 * c->border;
if(c->titlebar->width)
width = MAX(1, MIN(c->titlebar->width, geometry.height - 2 * c->titlebar->border.width));
else
width = MIN(c->titlebar->width, geometry.height);
width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->border.width);
switch(c->titlebar->align)
{
default:
break;
case AlignRight:
y_offset = 2 * c->border + geometry.height - width;
y_offset = 2 * c->border + geometry.height - width - 2 * c->titlebar->border.width;
break;
case AlignCenter:
y_offset = (geometry.height - width) / 2;
break;
}
simplewindow_moveresize(c->titlebar->sw,
geometry.x,
geometry.y + y_offset,
c->titlebar->sw->geometry.width,
width);
res->x = geometry.x - c->titlebar->height;
res->y = geometry.y + y_offset;
res->width = c->titlebar->height;
res->height = width;
break;
case Right:
if(c->titlebar->width)
width = geometry.height + 2 * c->border;
width = MAX(1, MIN(c->titlebar->width, geometry.height - 2 * c->titlebar->border.width));
else
width = MIN(c->titlebar->width, geometry.height);
width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->border.width);
switch(c->titlebar->align)
{
default:
break;
case AlignRight:
y_offset = 2 * c->border + geometry.height - width;
y_offset = 2 * c->border + geometry.height - width - 2 * c->titlebar->border.width;
break;
case AlignCenter:
y_offset = (geometry.height - width) / 2;
break;
}
simplewindow_moveresize(c->titlebar->sw,
geometry.x + geometry.width
- c->titlebar->sw->geometry.width + 2 * c->border,
geometry.y + y_offset,
c->titlebar->sw->geometry.width,
width);
res->x = geometry.x + geometry.width + 2 * c->border;
res->y = geometry.y + y_offset;
res->width = c->titlebar->height;
res->height = width;
break;
}
titlebar_draw(c);
}
/** Set client titlebar position.
@ -363,6 +240,7 @@ void
titlebar_init(client_t *c)
{
int width = 0, height = 0;
area_t geom;
switch(c->titlebar->position)
{
@ -372,26 +250,33 @@ titlebar_init(client_t *c)
case Top:
case Bottom:
if(c->titlebar->width)
width = MIN(c->titlebar->width, c->geometry.width);
width = MIN(c->titlebar->width, c->geometry.width - 2 * c->titlebar->border.width);
else
width = c->geometry.width + 2 * c->border;
width = c->geometry.width + 2 * c->border - 2 * c->titlebar->border.width;
height = c->titlebar->height;
break;
case Left:
case Right:
if(c->titlebar->width)
height = MIN(c->titlebar->width, c->geometry.height);
height = MIN(c->titlebar->width, c->geometry.height - 2 * c->titlebar->border.width);
else
height = c->geometry.height + 2 * c->border;
height = c->geometry.height + 2 * c->border - 2 * c->titlebar->border.width;
width = c->titlebar->height;
break;
}
c->titlebar->sw = simplewindow_new(globalconf.connection,
c->phys_screen, 0, 0,
width, height, 0);
titlebar_geometry_compute(c, c->geometry, &geom);
c->titlebar->sw = simplewindow_new(globalconf.connection, c->phys_screen, geom.x, geom.y,
geom.width, geom.height, c->titlebar->border.width);
if(c->titlebar->border.width)
xcb_change_window_attributes(globalconf.connection, c->titlebar->sw->window,
XCB_CW_BORDER_PIXEL, &c->titlebar->border.color.pixel);
titlebar_draw(c);
xcb_map_window(globalconf.connection, c->titlebar->sw->window);
if(client_isvisible(c, c->screen))
xcb_map_window(globalconf.connection, c->titlebar->sw->window);
}
/** Create a new titlebar.
@ -422,20 +307,24 @@ luaA_titlebar_new(lua_State *L)
tb->position = position_get_from_str(luaA_getopt_string(L, 1, "position", "top"));
lua_getfield(L, 1, "fg");
if((color = luaL_optstring(L, -1, NULL)))
if((color = luaA_getopt_string(L, -1, "fg", NULL)))
xcolor_new(globalconf.connection, globalconf.default_screen,
color, &tb->colors.fg);
else
tb->colors.fg = globalconf.colors.fg;
lua_getfield(L, 1, "bg");
if((color = luaL_optstring(L, -1, NULL)))
if((color = luaA_getopt_string(L, 1, "bg", NULL)))
xcolor_new(globalconf.connection, globalconf.default_screen,
color, &tb->colors.bg);
else
tb->colors.bg = globalconf.colors.bg;
if((color = luaA_getopt_string(L, 1, "border_color", NULL)))
xcolor_new(globalconf.connection, globalconf.default_screen,
color, &tb->border.color);
tb->border.width = luaA_getopt_number(L, 1, "border_width", 0);
return luaA_titlebar_userdata_new(tb);
}

View File

@ -26,9 +26,8 @@
client_t * client_getbytitlebar(titlebar_t *);
client_t * client_getbytitlebarwin(xcb_window_t);
void titlebar_geometry_compute(client_t *, area_t, area_t *);
void titlebar_draw(client_t *);
void titlebar_update_geometry_floating(client_t *);
void titlebar_update_geometry(client_t *, area_t);
void titlebar_init(client_t *);
int luaA_titlebar_userdata_new(titlebar_t *);
@ -45,18 +44,18 @@ titlebar_geometry_add(titlebar_t *t, area_t geometry)
switch(t->position)
{
case Top:
geometry.y -= t->sw->geometry.height;
geometry.height += t->sw->geometry.height;
geometry.y -= t->sw->geometry.height + 2 * t->border.width;
geometry.height += t->sw->geometry.height + 2 * t->border.width;
break;
case Bottom:
geometry.height += t->sw->geometry.height;
geometry.height += t->sw->geometry.height + 2 * t->border.width;
break;
case Left:
geometry.x -= t->sw->geometry.width;
geometry.width += t->sw->geometry.width;
geometry.x -= t->sw->geometry.width + 2 * t->border.width;
geometry.width += t->sw->geometry.width + 2 * t->border.width;
break;
case Right:
geometry.width += t->sw->geometry.width;
geometry.width += t->sw->geometry.width + 2 * t->border.width;
break;
default:
break;
@ -77,18 +76,18 @@ titlebar_geometry_remove(titlebar_t *t, area_t geometry)
switch(t->position)
{
case Top:
geometry.y += t->sw->geometry.height;
geometry.height -= t->sw->geometry.height;
geometry.y += t->sw->geometry.height + 2 * t->border.width;
geometry.height -= t->sw->geometry.height + 2 * t->border.width;
break;
case Bottom:
geometry.height -= t->sw->geometry.height;
geometry.height -= t->sw->geometry.height + 2 * t->border.width;
break;
case Left:
geometry.x += t->sw->geometry.width;
geometry.width -= t->sw->geometry.width;
geometry.x += t->sw->geometry.width + 2 * t->border.width;
geometry.width -= t->sw->geometry.width + 2 * t->border.width;
break;
case Right:
geometry.width -= t->sw->geometry.width;
geometry.width -= t->sw->geometry.width + 2 * t->border.width;
break;
default:
break;
@ -97,5 +96,39 @@ titlebar_geometry_remove(titlebar_t *t, area_t geometry)
return geometry;
}
/** Update the titlebar geometry for a floating client.
* \param c the client
*/
static inline void
titlebar_update_geometry_floating(client_t *c)
{
area_t geom;
if(!c->titlebar || !c->titlebar->sw)
return;
titlebar_geometry_compute(c, c->geometry, &geom);
simplewindow_moveresize(c->titlebar->sw, geom.x, geom.y, geom.width, geom.height);
titlebar_draw(c);
}
/** Update the titlebar geometry for a tiled client.
* \param c The client.
* \param geometry The geometry the client will receive.
*/
static inline void
titlebar_update_geometry_tiled(client_t *c, area_t geometry)
{
area_t geom;
if(!c->titlebar || !c->titlebar->sw)
return;
titlebar_geometry_compute(c, geometry, &geom);
simplewindow_moveresize(c->titlebar->sw, geom.x, geom.y, geom.width, geom.height);
titlebar_draw(c);
}
#endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80