xref: /plan9/sys/src/libcontrol/label.c (revision b85a83648eec38fe82b6f00adfd7828ceec5ee8d)
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
labelfree(Control * c)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
labelshow(Label * l)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
labelctl(Control * c,CParse * cp)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 		/*
155 		_ctlargcount(l, cp, 2);
156 		_setctlimage(l, &l->textcolor, cp->args[1]);
157 		*/
158 		break;
159 	case ESize:
160 		if (cp->nargs == 3)
161 			r.max = Pt(0x7fffffff, 0x7fffffff);
162 		else{
163 			_ctlargcount(l, cp, 5);
164 			r.max.x = cp->iargs[3];
165 			r.max.y = cp->iargs[4];
166 		}
167 		r.min.x = cp->iargs[1];
168 		r.min.y = cp->iargs[2];
169 		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)
170 			ctlerror("%q: bad sizes: %s", l->name, cp->str);
171 		l->size.min = r.min;
172 		l->size.max = r.max;
173 		break;
174 	case ETextcolor:
175 		_ctlargcount(l, cp, 2);
176 		_setctlimage(l, &l->textcolor, cp->args[1]);
177 		break;
178 	case EValue:
179 		_ctlargcount(l, cp, 2);
180 		if(strcmp(cp->args[1], l->text) != 0){
181 			free(l->text);
182 			l->text = ctlstrdup(cp->args[1]);
183 			labelshow(l);
184 		}
185 		break;
186 	}
187 }
188 
189 Control*
createlabel(Controlset * cs,char * name)190 createlabel(Controlset *cs, char *name)
191 {
192 	Label *l;
193 
194 	l = (Label*)_createctl(cs, "label", sizeof(Label), name);
195 	l->text = ctlstrdup("");
196 	l->image = _getctlimage("white");
197 	l->textcolor = _getctlimage("black");
198 	l->bordercolor = _getctlimage("black");
199 	l->font = _getctlfont("font");
200 	l->border = 0;
201 	l->ctl = labelctl;
202 	l->exit = labelfree;
203 	return (Control *)l;
204 }
205