xref: /plan9-contrib/sys/src/libcontrol/label.c (revision d46c239f8612929b7dbade67d0d071633df3a15d)
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <thread.h>
5 #include <mouse.h>
6 #include <keyboard.h>
7 #include <control.h>
8 
9 typedef struct Label Label;
10 
11 struct Label
12 {
13 	Control;
14 	int		border;
15 	CFont	*font;
16 	CImage	*image;
17 	CImage	*textcolor;
18 	CImage	*bordercolor;
19 	char		*text;
20 	int		align;
21 };
22 
23 enum{
24 	EAlign,
25 	EBorder,
26 	EBordercolor,
27 	EFocus,
28 	EFont,
29 	EHide,
30 	EImage,
31 	ERect,
32 	EReveal,
33 	EShow,
34 	ESize,
35 	ETextcolor,
36 	EValue,
37 };
38 
39 static char *cmds[] = {
40 	[EAlign] =			"align",
41 	[EBorder] =		"border",
42 	[EBordercolor] =	"bordercolor",
43 	[EFocus] = 		"focus",
44 	[EFont] =			"font",
45 	[EHide] =			"hide",
46 	[EImage] =		"image",
47 	[ERect] =			"rect",
48 	[EReveal] =		"reveal",
49 	[EShow] =			"show",
50 	[ESize] =			"size",
51 	[ETextcolor] =		"textcolor",
52 	[EValue] =			"value",
53 	nil
54 };
55 
56 static void	labelshow(Label*);
57 
58 static void
59 labelfree(Control *c)
60 {
61 	Label *l;
62 
63 	l = (Label*)c;
64 	_putctlfont(l->font);
65 	_putctlimage(l->image);
66 	_putctlimage(l->textcolor);
67 	_putctlimage(l->bordercolor);
68 }
69 
70 
71 static void
72 labelshow(Label *l)
73 {
74 	Rectangle r;
75 	Point p;
76 
77 	if (l->hidden)
78 		return;
79 	r = l->rect;
80 	draw(l->screen, r, l->image->image, nil, l->image->image->r.min);
81 	if(l->border > 0){
82 		border(l->screen, r, l->border, l->bordercolor->image, l->bordercolor->image->r.min);
83 		r = insetrect(r, l->border);
84 	}
85 	p = _ctlalignpoint(r,
86 		stringwidth(l->font->font, l->text),
87 		l->font->font->height, l->align);
88 	_string(l->screen, p, l->textcolor->image,
89 		ZP, l->font->font, l->text, nil, strlen(l->text),
90 		r, nil, ZP, SoverD);
91 	flushimage(display, 1);
92 }
93 
94 static void
95 labelctl(Control *c, CParse *cp)
96 {
97 	int cmd;
98 	Rectangle r;
99 	Label *l;
100 
101 	l = (Label*)c;
102 	cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
103 	switch(cmd){
104 	default:
105 		ctlerror("%q: unrecognized message '%s'", l->name, cp->str);
106 		break;
107 	case EAlign:
108 		_ctlargcount(l, cp, 2);
109 		l->align = _ctlalignment(cp->args[1]);
110 		break;
111 	case EBorder:
112 		_ctlargcount(l, cp, 2);
113 		if(cp->iargs[1] < 0)
114 			ctlerror("%q: bad border: %c", l->name, cp->str);
115 		l->border = cp->iargs[1];
116 		break;
117 	case EBordercolor:
118 		_ctlargcount(l, cp, 2);
119 		_setctlimage(l, &l->bordercolor, cp->args[1]);
120 		break;
121 	case EFocus:
122 		/* ignore focus change */
123 		break;
124 	case EFont:
125 		_ctlargcount(l, cp, 2);
126 		_setctlfont(l, &l->font, cp->args[1]);
127 		break;
128 	case EHide:
129 		_ctlargcount(l, cp, 1);
130 		l->hidden = 1;
131 		break;
132 	case EImage:
133 		_ctlargcount(l, cp, 2);
134 		_setctlimage(l, &l->image, cp->args[1]);
135 		break;
136 	case ERect:
137 		_ctlargcount(l, cp, 5);
138 		r.min.x = cp->iargs[1];
139 		r.min.y = cp->iargs[2];
140 		r.max.x = cp->iargs[3];
141 		r.max.y = cp->iargs[4];
142 		if(Dx(r)<=0 || Dy(r)<=0)
143 			ctlerror("%q: bad rectangle: %s", l->name, cp->str);
144 		l->rect = r;
145 		break;
146 	case EReveal:
147 		_ctlargcount(l, cp, 1);
148 		l->hidden = 0;
149 		labelshow(l);
150 		break;
151 	case EShow:
152 		_ctlargcount(l, cp, 1);
153 		labelshow(l);
154 		break;
155 		_ctlargcount(l, cp, 2);
156 		_setctlimage(l, &l->textcolor, cp->args[1]);
157 		break;
158 	case ESize:
159 		if (cp->nargs == 3)
160 			r.max = Pt(0x7fffffff, 0x7fffffff);
161 		else{
162 			_ctlargcount(l, cp, 5);
163 			r.max.x = cp->iargs[3];
164 			r.max.y = cp->iargs[4];
165 		}
166 		r.min.x = cp->iargs[1];
167 		r.min.y = cp->iargs[2];
168 		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)
169 			ctlerror("%q: bad sizes: %s", l->name, cp->str);
170 		l->size.min = r.min;
171 		l->size.max = r.max;
172 		break;
173 	case ETextcolor:
174 		_ctlargcount(l, cp, 2);
175 		_setctlimage(l, &l->textcolor, cp->args[1]);
176 		break;
177 	case EValue:
178 		_ctlargcount(l, cp, 2);
179 		if(strcmp(cp->args[1], l->text) != 0){
180 			free(l->text);
181 			l->text = ctlstrdup(cp->args[1]);
182 			labelshow(l);
183 		}
184 		break;
185 	}
186 }
187 
188 Control*
189 createlabel(Controlset *cs, char *name)
190 {
191 	Label *l;
192 
193 	l = (Label*)_createctl(cs, "label", sizeof(Label), name);
194 	l->text = ctlstrdup("");
195 	l->image = _getctlimage("white");
196 	l->textcolor = _getctlimage("black");
197 	l->bordercolor = _getctlimage("black");
198 	l->font = _getctlfont("font");
199 	l->border = 0;
200 	l->ctl = labelctl;
201 	l->exit = labelfree;
202 	return (Control *)l;
203 }
204