summaryrefslogtreecommitdiff
path: root/sys/src/libcontrol/tabs.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libcontrol/tabs.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libcontrol/tabs.c')
-rwxr-xr-xsys/src/libcontrol/tabs.c256
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;
+}