180ee5cbfSDavid du Colombier #include <u.h>
280ee5cbfSDavid du Colombier #include <libc.h>
380ee5cbfSDavid du Colombier #include <draw.h>
480ee5cbfSDavid du Colombier #include <thread.h>
580ee5cbfSDavid du Colombier #include <mouse.h>
680ee5cbfSDavid du Colombier #include <keyboard.h>
780ee5cbfSDavid du Colombier #include <control.h>
880ee5cbfSDavid du Colombier
980ee5cbfSDavid du Colombier typedef struct Box Box;
1080ee5cbfSDavid du Colombier
1180ee5cbfSDavid du Colombier struct Box
1280ee5cbfSDavid du Colombier {
1380ee5cbfSDavid du Colombier Control;
1480ee5cbfSDavid du Colombier int border;
1580ee5cbfSDavid du Colombier CImage *bordercolor;
1680ee5cbfSDavid du Colombier CImage *image;
1780ee5cbfSDavid du Colombier int align;
1880ee5cbfSDavid du Colombier };
1980ee5cbfSDavid du Colombier
2080ee5cbfSDavid du Colombier enum{
2180ee5cbfSDavid du Colombier EAlign,
2280ee5cbfSDavid du Colombier EBorder,
2380ee5cbfSDavid du Colombier EBordercolor,
2480ee5cbfSDavid du Colombier EFocus,
259a747e4fSDavid du Colombier EHide,
2680ee5cbfSDavid du Colombier EImage,
2780ee5cbfSDavid du Colombier ERect,
289a747e4fSDavid du Colombier EReveal,
2980ee5cbfSDavid du Colombier EShow,
309a747e4fSDavid du Colombier ESize,
3180ee5cbfSDavid du Colombier };
3280ee5cbfSDavid du Colombier
3380ee5cbfSDavid du Colombier static char *cmds[] = {
3480ee5cbfSDavid du Colombier [EAlign] = "align",
3580ee5cbfSDavid du Colombier [EBorder] = "border",
3680ee5cbfSDavid du Colombier [EBordercolor] ="bordercolor",
3780ee5cbfSDavid du Colombier [EFocus] = "focus",
389a747e4fSDavid du Colombier [EHide] = "hide",
3980ee5cbfSDavid du Colombier [EImage] = "image",
4080ee5cbfSDavid du Colombier [ERect] = "rect",
419a747e4fSDavid du Colombier [EReveal] = "reveal",
4280ee5cbfSDavid du Colombier [EShow] = "show",
439a747e4fSDavid du Colombier [ESize] = "size",
4480ee5cbfSDavid du Colombier nil
4580ee5cbfSDavid du Colombier };
4680ee5cbfSDavid du Colombier
4780ee5cbfSDavid du Colombier static void
boxkey(Control * c,Rune * rp)489a747e4fSDavid du Colombier boxkey(Control *c, Rune *rp)
4980ee5cbfSDavid du Colombier {
5080ee5cbfSDavid du Colombier Box *b;
5180ee5cbfSDavid du Colombier
529a747e4fSDavid du Colombier b = (Box*)c;
539a747e4fSDavid du Colombier chanprint(b->event, "%q: key 0x%x", b->name, rp[0]);
5480ee5cbfSDavid du Colombier }
5580ee5cbfSDavid du Colombier
5680ee5cbfSDavid du Colombier static void
boxmouse(Control * c,Mouse * m)579a747e4fSDavid du Colombier boxmouse(Control *c, Mouse *m)
5880ee5cbfSDavid du Colombier {
599a747e4fSDavid du Colombier Box *b;
609a747e4fSDavid du Colombier
619a747e4fSDavid du Colombier b = (Box*)c;
62*da79363fSDavid du Colombier if (ptinrect(m->xy,b->rect))
639a747e4fSDavid du Colombier chanprint(b->event, "%q: mouse %P %d %ld", b->name,
649a747e4fSDavid du Colombier m->xy, m->buttons, m->msec);
659a747e4fSDavid du Colombier }
669a747e4fSDavid du Colombier
679a747e4fSDavid du Colombier static void
boxfree(Control * c)689a747e4fSDavid du Colombier boxfree(Control *c)
699a747e4fSDavid du Colombier {
709a747e4fSDavid du Colombier _putctlimage(((Box*)c)->image);
7180ee5cbfSDavid du Colombier }
7280ee5cbfSDavid du Colombier
7380ee5cbfSDavid du Colombier static void
boxshow(Box * b)7480ee5cbfSDavid du Colombier boxshow(Box *b)
7580ee5cbfSDavid du Colombier {
7680ee5cbfSDavid du Colombier Image *i;
7780ee5cbfSDavid du Colombier Rectangle r;
7880ee5cbfSDavid du Colombier
799a747e4fSDavid du Colombier if(b->hidden)
809a747e4fSDavid du Colombier return;
8180ee5cbfSDavid du Colombier if(b->border > 0){
8280ee5cbfSDavid du Colombier border(b->screen, b->rect, b->border, b->bordercolor->image, ZP);
8380ee5cbfSDavid du Colombier r = insetrect(b->rect, b->border);
8480ee5cbfSDavid du Colombier }else
8580ee5cbfSDavid du Colombier r = b->rect;
8680ee5cbfSDavid du Colombier i = b->image->image;
8780ee5cbfSDavid du Colombier /* BUG: ALIGNMENT AND CLIPPING */
8880ee5cbfSDavid du Colombier draw(b->screen, r, i, nil, ZP);
8980ee5cbfSDavid du Colombier }
9080ee5cbfSDavid du Colombier
9180ee5cbfSDavid du Colombier static void
boxctl(Control * c,CParse * cp)929a747e4fSDavid du Colombier boxctl(Control *c, CParse *cp)
9380ee5cbfSDavid du Colombier {
9480ee5cbfSDavid du Colombier int cmd;
9580ee5cbfSDavid du Colombier Rectangle r;
9680ee5cbfSDavid du Colombier Box *b;
9780ee5cbfSDavid du Colombier
9880ee5cbfSDavid du Colombier b = (Box*)c;
999a747e4fSDavid du Colombier cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
10080ee5cbfSDavid du Colombier switch(cmd){
10180ee5cbfSDavid du Colombier default:
1029a747e4fSDavid du Colombier ctlerror("%q: unrecognized message '%s'", b->name, cp->str);
10380ee5cbfSDavid du Colombier break;
10480ee5cbfSDavid du Colombier case EAlign:
1059a747e4fSDavid du Colombier _ctlargcount(b, cp, 2);
1069a747e4fSDavid du Colombier b->align = _ctlalignment(cp->args[1]);
10780ee5cbfSDavid du Colombier break;
10880ee5cbfSDavid du Colombier case EBorder:
1099a747e4fSDavid du Colombier _ctlargcount(b, cp, 2);
1109a747e4fSDavid du Colombier if(cp->iargs[1] < 0)
1119a747e4fSDavid du Colombier ctlerror("%q: bad border: %c", b->name, cp->str);
1129a747e4fSDavid du Colombier b->border = cp->iargs[1];
11380ee5cbfSDavid du Colombier break;
11480ee5cbfSDavid du Colombier case EBordercolor:
1159a747e4fSDavid du Colombier _ctlargcount(b, cp, 2);
1169a747e4fSDavid du Colombier _setctlimage(b, &b->bordercolor, cp->args[1]);
11780ee5cbfSDavid du Colombier break;
11880ee5cbfSDavid du Colombier case EFocus:
1199a747e4fSDavid du Colombier _ctlargcount(b, cp, 2);
1209a747e4fSDavid du Colombier chanprint(b->event, "%q: focus %s", b->name, cp->args[1]);
1219a747e4fSDavid du Colombier break;
1229a747e4fSDavid du Colombier case EHide:
1239a747e4fSDavid du Colombier _ctlargcount(b, cp, 1);
1249a747e4fSDavid du Colombier b->hidden = 1;
12580ee5cbfSDavid du Colombier break;
12680ee5cbfSDavid du Colombier case EImage:
1279a747e4fSDavid du Colombier _ctlargcount(b, cp, 2);
1289a747e4fSDavid du Colombier _setctlimage(b, &b->image, cp->args[1]);
12980ee5cbfSDavid du Colombier break;
13080ee5cbfSDavid du Colombier case ERect:
1319a747e4fSDavid du Colombier _ctlargcount(b, cp, 5);
1329a747e4fSDavid du Colombier r.min.x = cp->iargs[1];
1339a747e4fSDavid du Colombier r.min.y = cp->iargs[2];
1349a747e4fSDavid du Colombier r.max.x = cp->iargs[3];
1359a747e4fSDavid du Colombier r.max.y = cp->iargs[4];
13680ee5cbfSDavid du Colombier if(Dx(r)<0 || Dy(r)<0)
1379a747e4fSDavid du Colombier ctlerror("%q: bad rectangle: %s", b->name, cp->str);
13880ee5cbfSDavid du Colombier b->rect = r;
13980ee5cbfSDavid du Colombier break;
1409a747e4fSDavid du Colombier case EReveal:
1419a747e4fSDavid du Colombier _ctlargcount(b, cp, 1);
1429a747e4fSDavid du Colombier b->hidden = 0;
14380ee5cbfSDavid du Colombier boxshow(b);
14480ee5cbfSDavid du Colombier break;
1459a747e4fSDavid du Colombier case EShow:
1469a747e4fSDavid du Colombier _ctlargcount(b, cp, 1);
1479a747e4fSDavid du Colombier boxshow(b);
1489a747e4fSDavid du Colombier break;
1499a747e4fSDavid du Colombier case ESize:
1509a747e4fSDavid du Colombier if (cp->nargs == 3)
1519a747e4fSDavid du Colombier r.max = Pt(0x7fffffff, 0x7fffffff);
1529a747e4fSDavid du Colombier else{
1539a747e4fSDavid du Colombier _ctlargcount(b, cp, 5);
1549a747e4fSDavid du Colombier r.max.x = cp->iargs[3];
1559a747e4fSDavid du Colombier r.max.y = cp->iargs[4];
15680ee5cbfSDavid du Colombier }
1579a747e4fSDavid du Colombier r.min.x = cp->iargs[1];
1589a747e4fSDavid du Colombier r.min.y = cp->iargs[2];
1599a747e4fSDavid du Colombier if(r.min.x<=0 || r.min.y<=0 || r.max.x<=0 || r.max.y<=0 || r.max.x < r.min.x || r.max.y < r.min.y)
1609a747e4fSDavid du Colombier ctlerror("%q: bad sizes: %s", b->name, cp->str);
1619a747e4fSDavid du Colombier b->size.min = r.min;
1629a747e4fSDavid du Colombier b->size.max = r.max;
1639a747e4fSDavid du Colombier break;
1649a747e4fSDavid du Colombier }
1659a747e4fSDavid du Colombier }
1669a747e4fSDavid du Colombier
1679a747e4fSDavid du Colombier Control*
createbox(Controlset * cs,char * name)1689a747e4fSDavid du Colombier createbox(Controlset *cs, char *name)
1699a747e4fSDavid du Colombier {
1709a747e4fSDavid du Colombier Box *b;
1719a747e4fSDavid du Colombier
1729a747e4fSDavid du Colombier b = (Box *)_createctl(cs, "box", sizeof(Box), name);
1739a747e4fSDavid du Colombier b->image = _getctlimage("white");
1749a747e4fSDavid du Colombier b->bordercolor = _getctlimage("black");
1759a747e4fSDavid du Colombier b->align = Aupperleft;
1769a747e4fSDavid du Colombier b->key = boxkey;
1779a747e4fSDavid du Colombier b->mouse = boxmouse;
1789a747e4fSDavid du Colombier b->ctl = boxctl;
1799a747e4fSDavid du Colombier b->exit = boxfree;
1809a747e4fSDavid du Colombier return (Control *)b;
18180ee5cbfSDavid du Colombier }
182