diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libcontrol/tabs.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libcontrol/tabs.c')
-rwxr-xr-x | sys/src/libcontrol/tabs.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/sys/src/libcontrol/tabs.c b/sys/src/libcontrol/tabs.c new file mode 100755 index 000000000..41737c2f4 --- /dev/null +++ b/sys/src/libcontrol/tabs.c @@ -0,0 +1,256 @@ +#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; +} |