Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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 Textbutton Textbutton;
10
 
11
struct Textbutton
12
{
13
	Control;
14
	CFont	*font;
15
	CImage	*image;
16
	CImage	*mask;
17
	CImage	*light;
18
	CImage	*bordercolor;
19
	CImage	*textcolor;
20
	CImage	*pressedtextcolor;
21
	CImage	*paletextcolor;
22
	int		pressed;
23
	int		lastbut;
24
	int		lastshow;
25
	char		**line;
26
	int		nline;
27
	int		align;
28
	int		border;
29
	int		off;
30
	int		showoff;
31
	int		prepress;
32
};
33
 
34
enum{
35
	EAlign,
36
	EBorder,
37
	EBordercolor,
38
	EFocus,
39
	EFont,
40
	EFormat,
41
	EHide,
42
	EImage,
43
	ELight,
44
	EMask,
45
	EPaletextcolor,
46
	EPressedtextcolor,
47
	ERect,
48
	EReveal,
49
	EShow,
50
	ESize,
51
	EText,
52
	ETextcolor,
53
	EValue,
54
};
55
 
56
static char *cmds[] = {
57
	[EAlign] =			"align",
58
	[EBorder] =		"border",
59
	[EBordercolor] = 	"bordercolor",
60
	[EFocus] = 		"focus",
61
	[EFont] =			"font",
62
	[EFormat] = 		"format",
63
	[EHide] =			"hide",
64
	[EImage] =		"image",
65
	[ELight] =			"light",
66
	[EMask] =			"mask",
67
	[EPaletextcolor] ="paletextcolor",
68
	[EPressedtextcolor] ="pressedtextcolor",
69
	[ERect] =			"rect",
70
	[EReveal] =		"reveal",
71
	[EShow] =			"show",
72
	[ESize] =			"size",
73
	[EText] =			"text",
74
	[ETextcolor] =		"textcolor",
75
	[EValue] =			"value",
76
	nil
77
};
78
 
79
static void	textbuttonshow(Textbutton*);
80
 
81
static void
82
textbuttonmouse(Control *c, Mouse *m)
83
{
84
	Textbutton *t;
85
 
86
	t = (Textbutton *)c;
87
	if(m->buttons&7) {
88
		if (ptinrect(m->xy,t->rect)) {
89
			if (t->off) {
90
				t->off = 0;
91
				textbuttonshow(t);
92
			}
93
		} else {
94
			if (!t->off) {
95
				t->off = 1;
96
				textbuttonshow(t);
97
			}
98
		}
99
	}
100
	if((m->buttons&7) != t->lastbut){
101
		if(m->buttons & 7){
102
			t->prepress = t->pressed;
103
			if (t->pressed)
104
				t->pressed = 0;
105
			else
106
				t->pressed = 1;
107
			textbuttonshow(t);
108
		}else{	/* generate event on button up */
109
			if (ptinrect(m->xy,t->rect))
110
				chanprint(t->event, t->format, t->name, t->pressed);
111
			else {
112
				t->off = 0;
113
				t->pressed = t->prepress;
114
				textbuttonshow(t);
115
			}
116
		}
117
	}
118
	t->lastbut = m->buttons & 7;
119
}
120
 
121
static void
122
textbuttonfree(Control *c)
123
{
124
	int i;
125
	Textbutton *t;
126
 
127
	t = (Textbutton*)c;
128
	_putctlfont(t->font);
129
	_putctlimage(t->image);
130
	_putctlimage(t->light);
131
	_putctlimage(t->mask);
132
	_putctlimage(t->textcolor);
133
	_putctlimage(t->bordercolor);
134
	_putctlimage(t->paletextcolor);
135
	_putctlimage(t->pressedtextcolor);
136
	for(i=0; i<t->nline; i++)
137
		free(t->line[i]);
138
	free(t->line);
139
}
140
 
141
static void
142
textbuttonshow(Textbutton *t)
143
{
144
	Rectangle r, clipr;
145
	int i, dx, dy, w;
146
	Font *f;
147
	Point p, q;
148
	Image *im;
149
 
150
	if(t->hidden || (t->lastshow == t->pressed && t->showoff == t->off))
151
		return;
152
	f = t->font->font;
153
	draw(t->screen, t->rect, t->image->image, nil, t->image->image->r.min);
154
	if(t->border > 0)
155
		border(t->screen, t->rect, t->border, t->bordercolor->image, ZP);
156
	/* text goes here */
157
	dx = 0;
158
	for(i=0; i<t->nline; i++){
159
		w = stringwidth(f, t->line[i]);
160
		if(dx < w)
161
			dx = w;
162
	}
163
	dy = t->nline*f->height;
164
	clipr = insetrect(t->rect, t->border);
165
	p = _ctlalignpoint(clipr, dx, dy, t->align);
166
	im = t->textcolor->image;
167
	if(t->off)
168
		im = t->paletextcolor->image;
169
	else if(t->pressed)
170
		im = t->pressedtextcolor->image;
171
	for(i=0; i<t->nline; i++){
172
		r.min = p;
173
		r.max.x = p.x+dx;
174
		r.max.y = p.y+f->height;
175
		q = _ctlalignpoint(r, stringwidth(f, t->line[i]), f->height, t->align%3);
176
		_string(t->screen, q, im,
177
			ZP, f, t->line[i], nil, strlen(t->line[i]),
178
			clipr, nil, ZP, SoverD);
179
		p.y += f->height;
180
	}
181
	if(t->off || t->pressed)
182
		draw(t->screen, t->rect, t->light->image, t->mask->image, t->mask->image->r.min);
183
	t->lastshow = t->pressed;
184
	t->showoff = t->off;
185
	flushimage(display, 1);
186
}
187
 
188
static void
189
textbuttonctl(Control *c, CParse *cp)
190
{
191
	int cmd, i;
192
	Rectangle r;
193
	Textbutton *t;
194
 
195
	t = (Textbutton*)c;
196
	cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
197
	switch(cmd){
198
	default:
199
		ctlerror("%q: unrecognized message '%s'", t->name, cp->str);
200
		break;
201
	case EAlign:
202
		_ctlargcount(t, cp, 2);
203
		t->align = _ctlalignment(cp->args[1]);
204
		t->lastshow = -1;	/* force redraw */
205
		break;
206
	case EBorder:
207
		_ctlargcount(t, cp, 2);
208
		t->border = cp->iargs[1];
209
		t->lastshow = -1;	/* force redraw */
210
		break;
211
	case EBordercolor:
212
		_ctlargcount(t, cp, 2);
213
		_setctlimage(t, &t->bordercolor, cp->args[1]);
214
		t->lastshow = -1;	/* force redraw */
215
		break;
216
	case EFocus:
217
		break;
218
	case EFont:
219
		_ctlargcount(t, cp, 2);
220
		_setctlfont(t, &t->font, cp->args[1]);
221
		t->lastshow = -1;	/* force redraw */
222
		break;
223
	case EFormat:
224
		_ctlargcount(t, cp, 2);
225
		t->format = ctlstrdup(cp->args[1]);
226
		break;
227
	case EHide:
228
		_ctlargcount(t, cp, 1);
229
		t->hidden = 1;
230
		break;
231
	case EImage:
232
		_ctlargcount(t, cp, 2);
233
		_setctlimage(t, &t->image, cp->args[1]);
234
		t->lastshow = -1;	/* force redraw */
235
		break;
236
	case ELight:
237
		_ctlargcount(t, cp, 2);
238
		_setctlimage(t, &t->light, cp->args[1]);
239
		t->lastshow = -1;	/* force redraw */
240
		break;
241
	case EMask:
242
		_ctlargcount(t, cp, 2);
243
		_setctlimage(t, &t->mask, cp->args[1]);
244
		t->lastshow = -1;	/* force redraw */
245
		break;
246
	case EPaletextcolor:
247
		_ctlargcount(t, cp, 2);
248
		_setctlimage(t, &t->paletextcolor, cp->args[1]);
249
		t->lastshow = -1;	/* force redraw */
250
		break;
251
	case EPressedtextcolor:
252
		_ctlargcount(t, cp, 2);
253
		_setctlimage(t, &t->pressedtextcolor, cp->args[1]);
254
		t->lastshow = -1;	/* force redraw */
255
		break;
256
	case ERect:
257
		_ctlargcount(t, cp, 5);
258
		r.min.x = cp->iargs[1];
259
		r.min.y = cp->iargs[2];
260
		r.max.x = cp->iargs[3];
261
		r.max.y = cp->iargs[4];
262
		if(Dx(r)<=0 || Dy(r)<=0)
263
			ctlerror("%q: bad rectangle: %s", t->name, cp->str);
264
		t->rect = r;
265
		t->lastshow = -1;	/* force redraw */
266
		break;
267
	case EReveal:
268
		_ctlargcount(t, cp, 1);
269
		t->hidden = 0;
270
		t->lastshow = -1;	/* force redraw */
271
		textbuttonshow(t);
272
		break;
273
	case EShow:
274
		_ctlargcount(t, cp, 1);
275
		t->lastshow = -1;	/* force redraw */
276
		textbuttonshow(t);
277
		break;
278
	case ESize:
279
		if (cp->nargs == 3)
280
			r.max = Pt(0x7fffffff, 0x7fffffff);
281
		else{
282
			_ctlargcount(t, cp, 5);
283
			r.max.x = cp->iargs[3];
284
			r.max.y = cp->iargs[4];
285
		}
286
		r.min.x = cp->iargs[1];
287
		r.min.y = cp->iargs[2];
288
		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)
289
			ctlerror("%q: bad sizes: %s", t->name, cp->str);
290
		t->size.min = r.min;
291
		t->size.max = r.max;
292
		break;
293
	case EText:
294
		/* free existing text */
295
		for(i=0; i<t->nline; i++)
296
			free(t->line[i]);
297
		t->nline = cp->nargs-1;
298
		t->line = ctlrealloc(t->line, t->nline*sizeof(char*));
299
		for(i=0; i<t->nline; i++)
300
			t->line[i] = ctlstrdup(cp->args[i+1]);
301
		t->lastshow = -1;	/* force redraw */
302
		textbuttonshow(t);
303
		break;
304
	case ETextcolor:
305
		_ctlargcount(t, cp, 2);
306
		_setctlimage(t, &t->textcolor, cp->args[1]);
307
		t->lastshow = -1;	/* force redraw */
308
		break;
309
	case EValue:
310
		_ctlargcount(t, cp, 2);
311
		if((cp->iargs[1]!=0) != t->pressed){
312
			t->pressed ^= 1;
313
			textbuttonshow(t);
314
		}
315
		break;
316
	}
317
}
318
 
319
Control*
320
createtextbutton(Controlset *cs, char *name)
321
{
322
	Textbutton *t;
323
 
324
	t = (Textbutton *)_createctl(cs, "textbutton", sizeof(Textbutton), name);
325
	t->line = ctlmalloc(sizeof(char*));
326
	t->nline = 0;
327
	t->image = _getctlimage("white");
328
	t->light = _getctlimage("yellow");
329
	t->mask = _getctlimage("opaque");
330
	t->bordercolor = _getctlimage("black");
331
	t->textcolor = _getctlimage("black");
332
	t->pressedtextcolor = _getctlimage("black");
333
	t->paletextcolor = _getctlimage("paleyellow");
334
	t->font = _getctlfont("font");
335
	t->format = ctlstrdup("%q: value %d");
336
	t->lastshow = -1;
337
	t->mouse = textbuttonmouse;
338
	t->ctl = textbuttonctl;
339
	t->exit = textbuttonfree;
340
	t->prepress = 0;
341
	t->off = 0;
342
	t->showoff = -1;
343
	return (Control *)t;
344
}