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 Label Label;
1080ee5cbfSDavid du Colombier
1180ee5cbfSDavid du Colombier struct Label
1280ee5cbfSDavid du Colombier {
1380ee5cbfSDavid du Colombier Control;
1480ee5cbfSDavid du Colombier int border;
1580ee5cbfSDavid du Colombier CFont *font;
1680ee5cbfSDavid du Colombier CImage *image;
1780ee5cbfSDavid du Colombier CImage *textcolor;
1880ee5cbfSDavid du Colombier CImage *bordercolor;
1980ee5cbfSDavid du Colombier char *text;
2080ee5cbfSDavid du Colombier int align;
2180ee5cbfSDavid du Colombier };
2280ee5cbfSDavid du Colombier
2380ee5cbfSDavid du Colombier enum{
2480ee5cbfSDavid du Colombier EAlign,
2580ee5cbfSDavid du Colombier EBorder,
2680ee5cbfSDavid du Colombier EBordercolor,
2780ee5cbfSDavid du Colombier EFocus,
2880ee5cbfSDavid du Colombier EFont,
299a747e4fSDavid du Colombier EHide,
3080ee5cbfSDavid du Colombier EImage,
3180ee5cbfSDavid du Colombier ERect,
329a747e4fSDavid du Colombier EReveal,
3380ee5cbfSDavid du Colombier EShow,
349a747e4fSDavid du Colombier ESize,
3580ee5cbfSDavid du Colombier ETextcolor,
3680ee5cbfSDavid du Colombier EValue,
3780ee5cbfSDavid du Colombier };
3880ee5cbfSDavid du Colombier
3980ee5cbfSDavid du Colombier static char *cmds[] = {
4080ee5cbfSDavid du Colombier [EAlign] = "align",
4180ee5cbfSDavid du Colombier [EBorder] = "border",
4280ee5cbfSDavid du Colombier [EBordercolor] = "bordercolor",
4380ee5cbfSDavid du Colombier [EFocus] = "focus",
4480ee5cbfSDavid du Colombier [EFont] = "font",
459a747e4fSDavid du Colombier [EHide] = "hide",
4680ee5cbfSDavid du Colombier [EImage] = "image",
4780ee5cbfSDavid du Colombier [ERect] = "rect",
489a747e4fSDavid du Colombier [EReveal] = "reveal",
4980ee5cbfSDavid du Colombier [EShow] = "show",
509a747e4fSDavid du Colombier [ESize] = "size",
5180ee5cbfSDavid du Colombier [ETextcolor] = "textcolor",
5280ee5cbfSDavid du Colombier [EValue] = "value",
5380ee5cbfSDavid du Colombier nil
5480ee5cbfSDavid du Colombier };
5580ee5cbfSDavid du Colombier
5680ee5cbfSDavid du Colombier static void labelshow(Label*);
5780ee5cbfSDavid du Colombier
5880ee5cbfSDavid du Colombier static void
labelfree(Control * c)599a747e4fSDavid du Colombier labelfree(Control *c)
6080ee5cbfSDavid du Colombier {
6180ee5cbfSDavid du Colombier Label *l;
6280ee5cbfSDavid du Colombier
639a747e4fSDavid du Colombier l = (Label*)c;
6480ee5cbfSDavid du Colombier _putctlfont(l->font);
6580ee5cbfSDavid du Colombier _putctlimage(l->image);
6680ee5cbfSDavid du Colombier _putctlimage(l->textcolor);
6780ee5cbfSDavid du Colombier _putctlimage(l->bordercolor);
6880ee5cbfSDavid du Colombier }
6980ee5cbfSDavid du Colombier
7080ee5cbfSDavid du Colombier
7180ee5cbfSDavid du Colombier static void
labelshow(Label * l)7280ee5cbfSDavid du Colombier labelshow(Label *l)
7380ee5cbfSDavid du Colombier {
7480ee5cbfSDavid du Colombier Rectangle r;
7580ee5cbfSDavid du Colombier Point p;
7680ee5cbfSDavid du Colombier
779a747e4fSDavid du Colombier if (l->hidden)
789a747e4fSDavid du Colombier return;
7980ee5cbfSDavid du Colombier r = l->rect;
8080ee5cbfSDavid du Colombier draw(l->screen, r, l->image->image, nil, l->image->image->r.min);
8180ee5cbfSDavid du Colombier if(l->border > 0){
8280ee5cbfSDavid du Colombier border(l->screen, r, l->border, l->bordercolor->image, l->bordercolor->image->r.min);
8380ee5cbfSDavid du Colombier r = insetrect(r, l->border);
8480ee5cbfSDavid du Colombier }
8580ee5cbfSDavid du Colombier p = _ctlalignpoint(r,
8680ee5cbfSDavid du Colombier stringwidth(l->font->font, l->text),
8780ee5cbfSDavid du Colombier l->font->font->height, l->align);
8880ee5cbfSDavid du Colombier _string(l->screen, p, l->textcolor->image,
8980ee5cbfSDavid du Colombier ZP, l->font->font, l->text, nil, strlen(l->text),
90ac57dd0bSDavid du Colombier r, nil, ZP, SoverD);
9180ee5cbfSDavid du Colombier flushimage(display, 1);
9280ee5cbfSDavid du Colombier }
9380ee5cbfSDavid du Colombier
9480ee5cbfSDavid du Colombier static void
labelctl(Control * c,CParse * cp)959a747e4fSDavid du Colombier labelctl(Control *c, CParse *cp)
9680ee5cbfSDavid du Colombier {
9780ee5cbfSDavid du Colombier int cmd;
9880ee5cbfSDavid du Colombier Rectangle r;
9980ee5cbfSDavid du Colombier Label *l;
10080ee5cbfSDavid du Colombier
10180ee5cbfSDavid du Colombier l = (Label*)c;
1029a747e4fSDavid du Colombier cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
10380ee5cbfSDavid du Colombier switch(cmd){
10480ee5cbfSDavid du Colombier default:
1059a747e4fSDavid du Colombier ctlerror("%q: unrecognized message '%s'", l->name, cp->str);
10680ee5cbfSDavid du Colombier break;
10780ee5cbfSDavid du Colombier case EAlign:
1089a747e4fSDavid du Colombier _ctlargcount(l, cp, 2);
1099a747e4fSDavid du Colombier l->align = _ctlalignment(cp->args[1]);
11080ee5cbfSDavid du Colombier break;
11180ee5cbfSDavid du Colombier case EBorder:
1129a747e4fSDavid du Colombier _ctlargcount(l, cp, 2);
1139a747e4fSDavid du Colombier if(cp->iargs[1] < 0)
1149a747e4fSDavid du Colombier ctlerror("%q: bad border: %c", l->name, cp->str);
1159a747e4fSDavid du Colombier l->border = cp->iargs[1];
11680ee5cbfSDavid du Colombier break;
11780ee5cbfSDavid du Colombier case EBordercolor:
1189a747e4fSDavid du Colombier _ctlargcount(l, cp, 2);
1199a747e4fSDavid du Colombier _setctlimage(l, &l->bordercolor, cp->args[1]);
12080ee5cbfSDavid du Colombier break;
12180ee5cbfSDavid du Colombier case EFocus:
12280ee5cbfSDavid du Colombier /* ignore focus change */
12380ee5cbfSDavid du Colombier break;
12480ee5cbfSDavid du Colombier case EFont:
1259a747e4fSDavid du Colombier _ctlargcount(l, cp, 2);
1269a747e4fSDavid du Colombier _setctlfont(l, &l->font, cp->args[1]);
1279a747e4fSDavid du Colombier break;
1289a747e4fSDavid du Colombier case EHide:
1299a747e4fSDavid du Colombier _ctlargcount(l, cp, 1);
1309a747e4fSDavid du Colombier l->hidden = 1;
13180ee5cbfSDavid du Colombier break;
13280ee5cbfSDavid du Colombier case EImage:
1339a747e4fSDavid du Colombier _ctlargcount(l, cp, 2);
1349a747e4fSDavid du Colombier _setctlimage(l, &l->image, cp->args[1]);
13580ee5cbfSDavid du Colombier break;
13680ee5cbfSDavid du Colombier case ERect:
1379a747e4fSDavid du Colombier _ctlargcount(l, cp, 5);
1389a747e4fSDavid du Colombier r.min.x = cp->iargs[1];
1399a747e4fSDavid du Colombier r.min.y = cp->iargs[2];
1409a747e4fSDavid du Colombier r.max.x = cp->iargs[3];
1419a747e4fSDavid du Colombier r.max.y = cp->iargs[4];
14280ee5cbfSDavid du Colombier if(Dx(r)<=0 || Dy(r)<=0)
1439a747e4fSDavid du Colombier ctlerror("%q: bad rectangle: %s", l->name, cp->str);
14480ee5cbfSDavid du Colombier l->rect = r;
14580ee5cbfSDavid du Colombier break;
1469a747e4fSDavid du Colombier case EReveal:
1479a747e4fSDavid du Colombier _ctlargcount(l, cp, 1);
1489a747e4fSDavid du Colombier l->hidden = 0;
14980ee5cbfSDavid du Colombier labelshow(l);
15080ee5cbfSDavid du Colombier break;
1519a747e4fSDavid du Colombier case EShow:
1529a747e4fSDavid du Colombier _ctlargcount(l, cp, 1);
1539a747e4fSDavid du Colombier labelshow(l);
154*b85a8364SDavid du Colombier /*
1559a747e4fSDavid du Colombier _ctlargcount(l, cp, 2);
1569a747e4fSDavid du Colombier _setctlimage(l, &l->textcolor, cp->args[1]);
157*b85a8364SDavid du Colombier */
1589a747e4fSDavid du Colombier break;
1599a747e4fSDavid du Colombier case ESize:
1609a747e4fSDavid du Colombier if (cp->nargs == 3)
1619a747e4fSDavid du Colombier r.max = Pt(0x7fffffff, 0x7fffffff);
1629a747e4fSDavid du Colombier else{
1639a747e4fSDavid du Colombier _ctlargcount(l, cp, 5);
1649a747e4fSDavid du Colombier r.max.x = cp->iargs[3];
1659a747e4fSDavid du Colombier r.max.y = cp->iargs[4];
1669a747e4fSDavid du Colombier }
1679a747e4fSDavid du Colombier r.min.x = cp->iargs[1];
1689a747e4fSDavid du Colombier r.min.y = cp->iargs[2];
1699a747e4fSDavid 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)
1709a747e4fSDavid du Colombier ctlerror("%q: bad sizes: %s", l->name, cp->str);
1719a747e4fSDavid du Colombier l->size.min = r.min;
1729a747e4fSDavid du Colombier l->size.max = r.max;
17380ee5cbfSDavid du Colombier break;
17480ee5cbfSDavid du Colombier case ETextcolor:
1759a747e4fSDavid du Colombier _ctlargcount(l, cp, 2);
1769a747e4fSDavid du Colombier _setctlimage(l, &l->textcolor, cp->args[1]);
17780ee5cbfSDavid du Colombier break;
17880ee5cbfSDavid du Colombier case EValue:
1799a747e4fSDavid du Colombier _ctlargcount(l, cp, 2);
1809a747e4fSDavid du Colombier if(strcmp(cp->args[1], l->text) != 0){
18180ee5cbfSDavid du Colombier free(l->text);
1829a747e4fSDavid du Colombier l->text = ctlstrdup(cp->args[1]);
18380ee5cbfSDavid du Colombier labelshow(l);
18480ee5cbfSDavid du Colombier }
18580ee5cbfSDavid du Colombier break;
18680ee5cbfSDavid du Colombier }
18780ee5cbfSDavid du Colombier }
1889a747e4fSDavid du Colombier
1899a747e4fSDavid du Colombier Control*
createlabel(Controlset * cs,char * name)1909a747e4fSDavid du Colombier createlabel(Controlset *cs, char *name)
1919a747e4fSDavid du Colombier {
1929a747e4fSDavid du Colombier Label *l;
1939a747e4fSDavid du Colombier
1949a747e4fSDavid du Colombier l = (Label*)_createctl(cs, "label", sizeof(Label), name);
1959a747e4fSDavid du Colombier l->text = ctlstrdup("");
1969a747e4fSDavid du Colombier l->image = _getctlimage("white");
1979a747e4fSDavid du Colombier l->textcolor = _getctlimage("black");
1989a747e4fSDavid du Colombier l->bordercolor = _getctlimage("black");
1999a747e4fSDavid du Colombier l->font = _getctlfont("font");
2009a747e4fSDavid du Colombier l->border = 0;
2019a747e4fSDavid du Colombier l->ctl = labelctl;
2029a747e4fSDavid du Colombier l->exit = labelfree;
2039a747e4fSDavid du Colombier return (Control *)l;
2049a747e4fSDavid du Colombier }
205