123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- #include <u.h>
- #include <libc.h>
- #include <thread.h>
- #include <draw.h>
- #include <mouse.h>
- #include <keyboard.h>
- #include <control.h>
- #include "group.h"
- typedef struct Tab Tab;
- struct Tab {
- Control;
- int border;
- int selected;
- int separation;
- char *format;
- CImage *bordercolor;
- CImage *image;
- Control *tabrow;
- Control *tabstack;
- Control *tabcolumn;
- int ntabs;
- int nbuttons;
- Control **buttons;
- };
- enum{
- EAdd,
- EBorder,
- EBordercolor,
- EButton,
- EFocus,
- EFormat,
- EHide,
- EImage,
- ERect,
- EReveal,
- ESeparation,
- ESeparatorcolor,
- EShow,
- ESize,
- EValue,
- };
- static char *cmds[] = {
- [EAdd] = "add",
- [EBorder] = "border",
- [EBordercolor] = "bordercolor",
- [EButton] = "button",
- [EFocus] = "focus",
- [EFormat] = "format",
- [EHide] = "hide",
- [EImage] = "image",
- [ERect] = "rect",
- [EReveal] = "reveal",
- [ESeparation] = "separation",
- [ESeparatorcolor] = "separatorcolor",
- [EShow] = "show",
- [ESize] = "size",
- [EValue] = "value",
- };
- static void
- tabshow(Tab *t)
- {
- int i;
- Rectangle r;
- Group *g;
- if (t->hidden)
- return;
- for(i=0; i<t->nbuttons; i++){
- _ctlprint(t->buttons[i], "value %d", (t->selected==i));
- }
- _ctlprint(t->tabstack, "reveal %d", t->selected);
- _ctlprint(t->tabcolumn, "show");
- if (t->selected < 0)
- return;
- g = (Group*)t->tabcolumn;
- if (g->nseparators == 0){
- return;
- }
- r = g->separators[0];
- r.min.x = t->buttons[t->selected]->rect.min.x;
- r.max.x = t->buttons[t->selected]->rect.max.x;
- draw(t->screen, r, t->image->image, nil, t->image->image->r.min);
- flushimage(display, 1);
- }
- static void
- tabsize(Control *c)
- {
- Tab *t = (Tab*)c;
- if (t->tabcolumn && t->tabcolumn->setsize)
- t->tabcolumn->setsize((Control*)t->tabcolumn);
- }
- static void
- tabctl(Control *c, CParse *cp)
- {
- int cmd, i;
- Control *cbut, *cwin;
- Tab *t;
- Rectangle r;
- t = (Tab*)c;
- cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
- switch(cmd){
- case EAdd:
- if ((cp->nargs & 1) == 0)
- ctlerror("%q: arg count: %s", t->name, cp->args[1]);
- for (i = 1; i < cp->nargs; i += 2){
- cbut = controlcalled(cp->args[i]);
- if (cbut == nil)
- ctlerror("%q: no such control: %s", t->name, cp->args[i]);
- cwin = controlcalled(cp->args[i+1]);
- if (cwin == nil)
- ctlerror("%q: no such control: %s", t->name, cp->args[i+1]);
- _ctladdgroup(t->tabrow, cbut);
- _ctlprint(t->tabstack, "add %q", cp->args[i+1]);
- _ctlprint(cbut, "format '%%s: %q button %%d'", t->name);
- controlwire(cbut, "event", t->controlset->ctl);
- t->buttons = ctlrealloc(t->buttons, (t->nbuttons+1)*sizeof(Control*));
- t->buttons[t->nbuttons] = cbut;
- t->nbuttons++;
- t->selected = -1;
- }
- _ctlprint(t->tabcolumn, "size");
- t->size = t->tabcolumn->size;
- break;
- case EBorder:
- _ctlargcount(t, cp, 2);
- if(cp->iargs[1] < 0)
- ctlerror("%q: bad border: %c", t->name, cp->str);
- t->border = cp->iargs[1];
- break;
- case EBordercolor:
- _ctlargcount(t, cp, 2);
- _setctlimage(t, &t->bordercolor, cp->args[1]);
- break;
- case EButton:
- _ctlargcount(t, cp, 2);
- if (cp->sender == nil)
- ctlerror("%q: senderless buttonevent: %q", t->name, cp->str);
- cbut = controlcalled(cp->sender);
- for(i=0; i<t->nbuttons; i++)
- if (cbut == t->buttons[i])
- break;
- if (i == t->nbuttons)
- ctlerror("%q: not my event: %q", t->name, cp->str);
- if(cp->iargs[1] == 0){
- /* button was turned off; turn it back on */
- _ctlprint(cbut, "value 1");
- }else{
- t->selected = i;
- if (t->format)
- chanprint(t->event, t->format, t->name, i);
- tabshow(t);
- }
- break;
- case EFocus:
- /* ignore focus change */
- break;
- case EFormat:
- _ctlargcount(t, cp, 2);
- t->format = ctlstrdup(cp->args[1]);
- break;
- case EImage:
- _ctlargcount(t, cp, 2);
- _setctlimage(t, &t->image, cp->args[1]);
- break;
- case ESeparation:
- t->tabrow->ctl(t->tabrow, cp);
- t->tabcolumn->ctl(t->tabcolumn, cp);
- break;
- case ERect:
- _ctlargcount(t, cp, 5);
- r.min.x = cp->iargs[1];
- r.min.y = cp->iargs[2];
- r.max.x = cp->iargs[3];
- r.max.y = cp->iargs[4];
- if(Dx(r)<=0 || Dy(r)<=0)
- ctlerror("%q: bad rectangle: %s", t->name, cp->str);
- t->rect = r;
- r = insetrect(r, t->border);
- _ctlprint(t->tabcolumn, "rect %R", r);
- break;
- case EReveal:
- _ctlargcount(t, cp, 1);
- case EHide:
- case ESize:
- t->tabcolumn->ctl(t->tabcolumn, cp);
- break;
- case EShow:
- tabshow(t);
- break;
- case EValue:
- _ctlargcount(t, cp, 2);
- if (cp->iargs[1] < 0 || cp->iargs[1] >= t->nbuttons)
- ctlerror("%q: illegal value '%s'", t->name, cp->str);
- t->selected = cp->iargs[1];
- tabshow(t);
- break;
- default:
- ctlerror("%q: unrecognized message '%s'", t->name, cp->str);
- break;
- }
- }
- static void
- tabfree(Control*c)
- {
- Tab *t = (Tab*)c;
- t->nbuttons = 0;
- free(t->buttons);
- t->buttons = 0;
- }
- static void
- activatetab(Control *c, int act)
- {
- Tab *t;
- t = (Tab*)c;
- if (act)
- activate(t->tabcolumn);
- else
- deactivate(t->tabcolumn);
- }
-
- Control *
- createtab(Controlset *cs, char *name)
- {
- char s[128];
- Tab *t;
- t = (Tab*)_createctl(cs, "tab", sizeof(Tab), name);
- t->selected = -1;
- t->nbuttons = 0;
- t->ctl = tabctl;
- t->mouse = nil;
- t->exit = tabfree;
- snprint(s, sizeof s, "_%s-row", name);
- t->tabrow = createrow(cs, s);
- snprint(s, sizeof s, "_%s-stack", name);
- t->tabstack = createstack(cs, s);
- snprint(s, sizeof s, "_%s-column", name);
- t->tabcolumn = createcolumn(cs, s);
- ctlprint(t->tabcolumn, "add %q %q", t->tabrow->name, t->tabstack->name);
- t->bordercolor = _getctlimage("black");
- t->image = _getctlimage("white");
- t->setsize = tabsize;
- t->activate = activatetab;
- return (Control*)t;
- }
|