Subversion Repositories planix.SVN

Rev

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

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