xref: /plan9-contrib/sys/src/libcontrol/label.c (revision b85a83648eec38fe82b6f00adfd7828ceec5ee8d)
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