diff --git a/src/infobar.c b/src/infobar.c index baf55c0..9f24f22 100644 --- a/src/infobar.c +++ b/src/infobar.c @@ -12,6 +12,8 @@ static void infobar_elem_tag_init(struct element *e); static void infobar_elem_tag_update(struct element *e); +static void infobar_elem_status_init(struct element *e); +static void infobar_elem_status_update(struct element *e); const struct elem_funcs { @@ -21,11 +23,11 @@ const struct elem_funcs } elem_funcs[] = { { 't', infobar_elem_tag_init, infobar_elem_tag_update }, + { 's', infobar_elem_status_init, infobar_elem_status_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 },*/ - + { 'S', infobar_elem_selbar_init, infobar_elem_selbar_update }, + */ { '\0', NULL, NULL } }; @@ -37,6 +39,11 @@ infobar_elem_tag_init(struct element *e) struct geo g = { 0, 0, 0, 0 }; int s, j; + /* Get final size before to use in placement */ + e->geo.w = 0; + TAILQ_FOREACH(t, &e->infobar->screen->tags, next) + e->geo.w += draw_textw(e->infobar->theme, t->name) + PAD; + infobar_elem_placement(e); j = e->geo.x; @@ -75,8 +82,6 @@ infobar_elem_tag_init(struct element *e) } e->infobar->screen->elemupdate |= FLAGINT(ElemTag); - - e->geo.w = j; } static void @@ -110,35 +115,130 @@ infobar_elem_tag_update(struct element *e) } } +static void +infobar_elem_status_init(struct element *e) +{ + struct element *en = TAILQ_NEXT(e, next); + struct barwin *b; + + infobar_elem_placement(e); + + e->geo.w = e->infobar->geo.w - e->geo.x - (en ? e->infobar->geo.w - en->geo.x : 0); + + b = barwin_new(e->infobar->bar->win, e->geo.x, 0, e->geo.w, e->geo.h, 0, 0, false); + + b->fg = e->infobar->theme->bars.fg; + b->bg = e->infobar->theme->bars.bg; + + barwin_map(b); + + SLIST_INSERT_HEAD(&e->bars, b, enext); + + e->infobar->screen->elemupdate |= FLAGINT(ElemStatus); + e->infobar->status = strdup("wmfs2"); +} + +static void +infobar_elem_status_update(struct element *e) +{ + struct barwin *b = SLIST_FIRST(&e->bars); + int l; + + barwin_refresh_color(b); + + /* TODO: status_manage, status.c */ + if(e->infobar->status) + { + l = draw_textw(e->infobar->theme, e->infobar->status); + draw_text(b->dr, e->infobar->theme, e->geo.w - l, + TEXTY(e->infobar->theme, e->geo.h), b->fg, e->infobar->status); + barwin_refresh(b); + } +} + +#define ELEM_INIT(a) \ + do { \ + e = xcalloc(1, sizeof(struct element)); \ + SLIST_INIT(&e->bars); \ + e->infobar = i; \ + e->type = j; \ + e->align = a; \ + e->func_init = elem_funcs[j].func_init; \ + e->func_update = elem_funcs[j].func_update; \ + } while(/* CONSTCOND */ 0); static void infobar_elem_init(struct infobar *i) { - struct element *e; - int n, j; + struct element *e, *es = NULL; + int n, j, k, l = (int)strlen(i->elemorder); + bool s = false; TAILQ_INIT(&i->elements); - for(n = 0; n < (int)strlen(i->elemorder); ++n) + for(n = 0; n < l; ++n) { + /* Element status found, manage other element from the end */ + if(i->elemorder[n] == 's') + { + s = true; + ++n; + break; + } + for(j = 0; j < (int)LEN(elem_funcs); ++j) if(elem_funcs[j].c == i->elemorder[n]) { - e = xcalloc(1, sizeof(struct element)); + ELEM_INIT(Left); - 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); + if(TAILQ_EMPTY(&i->elements)) + TAILQ_INSERT_HEAD(&i->elements, e, next); + else + TAILQ_INSERT_TAIL(&i->elements, e, next); e->func_init(e); + es = e; break; } } + + /* Status make next elements aligning to the right */ + if(s) + { + /* Manage element from the end */ + for(k = l - 1; k >= n; --k) + { + /* Only one status */ + if(i->elemorder[k] == 's') + continue; + + for(j = 0; j < (int)LEN(elem_funcs); ++j) + if(elem_funcs[j].c == i->elemorder[k]) + { + ELEM_INIT(Right); + + if(es) + TAILQ_INSERT_AFTER(&i->elements, es, e, next); + else + TAILQ_INSERT_HEAD(&i->elements, e, next); + + e->func_init(e); + + break; + } + } + + /* Init status at the end */ + j = ElemStatus; + ELEM_INIT(Left); + + if(es) + TAILQ_INSERT_AFTER(&i->elements, es, e, next); + else + TAILQ_INSERT_HEAD(&i->elements, e, next); + + e->func_init(e); + } } void @@ -181,7 +281,7 @@ infobar_new(struct screen *s, char *name, struct theme *theme, enum barpos pos, /* struct barwin create */ i->bar = barwin_new(W->root, i->geo.x, i->geo.y, i->geo.w, i->geo.h, - theme->bars.fg, theme->bars.bg, false); + theme->bars.fg, theme->bars.bg, false); SLIST_INSERT_HEAD(&s->infobars, i, next); diff --git a/src/infobar.h b/src/infobar.h index 229f74b..db9bee7 100644 --- a/src/infobar.h +++ b/src/infobar.h @@ -11,7 +11,7 @@ #include "draw.h" #include "tag.h" -enum { ElemTag = 0, ElemLayout, ElemSelbar, ElemStatus, ElemCustom, ElemLast }; +enum { ElemTag = 0, ElemStatus, ElemCustom, ElemLast }; struct infobar *infobar_new(struct screen *s, char *name, struct theme *theme, enum barpos pos, const char *elem); void infobar_elem_update(struct infobar *i); @@ -25,9 +25,15 @@ infobar_elem_placement(struct element *e) { struct element *p = TAILQ_PREV(e, esub, next); - e->geo.y = e->geo.w = 0; + e->geo.y = 0; e->geo.h = e->infobar->geo.h; - e->geo.x = (p ? p->geo.x + p->geo.w + PAD : 0); + + if(e->align == Left) + e->geo.x = (p ? p->geo.x + p->geo.w: 0); + else + e->geo.x = ((p = TAILQ_NEXT(e, next)) + ? p->geo.x - e->geo.w + : e->infobar->geo.w - e->geo.w); } /* Bars placement management and usable space management */ diff --git a/src/wmfs.h b/src/wmfs.h index fd012b5..8b6b06a 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -97,6 +97,7 @@ struct element struct geo geo; struct infobar *infobar; int type; + enum position align; void (*func_init)(struct element *e); void (*func_update)(struct element *e); SLIST_HEAD(, barwin) bars; @@ -112,6 +113,7 @@ struct infobar enum barpos pos; char *elemorder; char *name; + char *status; TAILQ_HEAD(esub, element) elements; SLIST_ENTRY(infobar) next; };