wmfs/wmfs2/src/infobar.c
2011-08-30 15:15:37 +02:00

246 lines
5.0 KiB
C
Executable File

/*
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
* For license, see COPYING.
*/
#include <math.h>
#include "wmfs.h"
#include "draw.h"
#include "infobar.h"
#include "barwin.h"
#include "util.h"
#include "tag.h"
static void infobar_elem_tag_init(Element *e);
static void infobar_elem_tag_update(Element *e);
const struct elem_funcs
{
char c;
void (*func_init)(Element *e);
void (*func_update)(Element *e);
} elem_funcs[] =
{
{ 't', infobar_elem_tag_init, infobar_elem_tag_update },
/* { 'l', infobar_elem_layout_init, infobar_elem_layout_update },
{ 's', infobar_elem_selbar_init, infobar_elem_selbar_update },
{ 'S', infobar_elem_status_init, infobar_elem_status_update },*/
{ '\0', NULL, NULL }
};
static void
infobar_elem_tag_init(Element *e)
{
Tag *t;
Barwin *b, *prev;
Geo g = { 0, 0, 0, 0 };
int s, j;
infobar_elem_placement(e);
j = e->geo.x;
e->geo.h -= (ELEM_TAG_BORDER << 1);
TAILQ_FOREACH(t, &e->infobar->screen->tags, next)
{
s = draw_textw(t->name) + PAD;
/* Init barwin */
b = barwin_new(e->infobar->bar->win, j, 0, s, e->geo.h, 0x009900, 0x777777, false);
/* Set border */
if(ELEM_TAG_BORDER)
{
XSetWindowBorder(W->dpy, b->win, 0x1B3500);
XSetWindowBorderWidth(W->dpy, b->win, ELEM_TAG_BORDER);
}
b->ptr = (void*)t;
barwin_map(b);
/* TODO: refer to tag element configuration */
barwin_mousebind_new(b, Button1, false, g, uicb_tag_set_with_name, (Uicb)t->name);
barwin_mousebind_new(b, Button4, false, g, uicb_tag_next, NULL);
barwin_mousebind_new(b, Button5, false, g, uicb_tag_prev, NULL);
/* insert_tail with SLIST */
if(SLIST_EMPTY(&e->bars))
SLIST_INSERT_HEAD(&e->bars, b, enext);
else
SLIST_INSERT_AFTER(prev, b, enext);
prev = b;
j += s;
}
e->geo.w = j;
}
static void
infobar_elem_tag_update(Element *e)
{
Tag *t, *sel = e->infobar->screen->seltag;
Barwin *b;
SLIST_FOREACH(b, &e->bars, enext)
{
t = (Tag*)b->ptr;
/* Selected */
/* TODO: color from conf */
if(t == sel)
{
b->fg = 0x000000;
b->bg = 0x3D5700;
}
else
{
b->fg = 0x3D5700;
b->bg = 0x000000;
}
barwin_refresh_color(b);
draw_text(b->dr, (PAD >> 1), TEXTY(e->geo.h), b->fg, t->name);
barwin_refresh(b);
}
}
static void
infobar_elem_init(Infobar *i)
{
Element *e;
int n, j;
TAILQ_INIT(&i->elements);
for(n = 0; n < strlen(i->elemorder); ++n)
{
for(j = 0; j < LEN(elem_funcs); ++j)
if(elem_funcs[j].c == i->elemorder[n])
{
e = xcalloc(1, sizeof(Element));
SLIST_INIT(&e->bars);
e->infobar = i;
e->type = j;
e->func_init = elem_funcs[j].func_init;
e->func_update = elem_funcs[j].func_update;
TAILQ_INSERT_TAIL(&i->elements, e, next);
e->func_init(e);
break;
}
}
}
void
infobar_elem_update(Infobar *i)
{
Element *e;
TAILQ_FOREACH(e, &i->elements, next)
if(i->screen->elemupdate & FLAGINT(e->type))
e->func_update(e);
}
void
infobar_elem_remove(Element *e)
{
Barwin *b;
TAILQ_REMOVE(&e->infobar->elements, e, next);
while(!SLIST_EMPTY(&e->bars))
{
b = SLIST_FIRST(&e->bars);
SLIST_REMOVE_HEAD(&e->bars, enext);
barwin_remove(b);
}
}
Infobar*
infobar_new(Scr33n *s, const char *elem)
{
int n;
Infobar *i = (Infobar*)xcalloc(1, sizeof(Infobar));
i->screen = s;
i->elemorder = xstrdup(elem);
/* Active all flags for first refresh */
s->elemupdate |= (1<<0) | (1<<1) /*pow(ElemLast, 2) - 1*/;
/* TODO: Position top/bottom */
infobar_placement(i);
/* Barwin create */
i->bar = barwin_new(W->root, i->geo.x, i->geo.y, i->geo.w, i->geo.h, 0x222222, 0xCCCCCC, false);
/* Render */
barwin_map(i->bar);
barwin_map_subwin(i->bar);
barwin_refresh_color(i->bar);
/* Elements */
infobar_elem_init(i);
infobar_refresh(i);
SLIST_INSERT_HEAD(&s->infobars, i, next);
return i;
}
void
infobar_refresh(Infobar *i)
{
infobar_elem_update(i);
barwin_refresh(i->bar);
}
void
infobar_remove(Infobar *i)
{
Element *e;
free(i->elemorder);
TAILQ_FOREACH(e, &i->elements, next)
infobar_elem_remove(e);
barwin_remove(i->bar);
SLIST_REMOVE(&i->screen->infobars, i, Infobar, next);
free(i);
}
void
infobar_free(Scr33n *s)
{
Infobar *i;
while(!SLIST_EMPTY(&s->infobars))
{
i = SLIST_FIRST(&s->infobars);
infobar_remove(i);
}
}