Subversion Repositories planix.SVN

Rev

Details | 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 Button Button;
10
 
11
struct Button
12
{
13
	Control;
14
	CImage	*image;
15
	CImage	*mask;
16
	CImage	*light;
17
	CImage	*pale;
18
	CImage	*bordercolor;
19
	int		pressed;
20
	int		lastbut;
21
	int		lastshow;
22
	int		border;
23
	int		align;
24
	int		off;
25
	int		prepress;
26
};
27
 
28
enum{
29
	EAlign,
30
	EBorder,
31
	EBordercolor,
32
	EFocus,
33
	EFormat,
34
	EHide,
35
	EImage,
36
	ELight,
37
	EMask,
38
	EPale,
39
	ERect,
40
	EReveal,
41
	EShow,
42
	ESize,
43
	EValue,
44
};
45
 
46
static char *cmds[] = {
47
	[EAlign] = 		"align",
48
	[EBorder] = 	"border",
49
	[EBordercolor] = "bordercolor",
50
	[EFocus] = 	"focus",
51
	[EFormat] = 	"format",
52
	[EHide] =		"hide",
53
	[EImage] =	"image",
54
	[ELight] =		"light",
55
	[EMask] =		"mask",
56
	[EPale] =		"pale",
57
	[ERect] =		"rect",
58
	[EReveal] =	"reveal",
59
	[EShow] =		"show",
60
	[ESize] =		"size",
61
	[EValue] =		"value",
62
	nil
63
};
64
 
65
static void
66
buttonfree(Control *c)
67
{
68
	Button *b;
69
 
70
	b = (Button *)c;
71
	_putctlimage(b->image);
72
	_putctlimage(b->mask);
73
	_putctlimage(b->light);
74
	_putctlimage(b->pale);
75
	_putctlimage(b->bordercolor);
76
}
77
 
78
static void
79
buttonshow(Button *b)
80
{
81
	Rectangle r;
82
 
83
	if (b->hidden)
84
		return;
85
	r = b->rect;
86
	if(b->border > 0){
87
		border(b->screen, r, b->border, b->bordercolor->image, ZP);
88
		r = insetrect(b->rect, b->border);
89
	}
90
	draw(b->screen, r, b->image->image, nil, b->image->image->r.min);
91
	if(b->off)
92
		draw(b->screen, r, b->pale->image, b->mask->image, b->mask->image->r.min);
93
	else if(b->pressed)
94
		draw(b->screen, r, b->light->image, b->mask->image, b->mask->image->r.min);
95
	b->lastshow = b->pressed;
96
	flushimage(display, 1);
97
}
98
 
99
static void
100
buttonmouse(Control *c, Mouse *m)
101
{
102
	Button *b;
103
 
104
	b = (Button*)c;
105
 
106
	if(m->buttons&7) {
107
		if (ptinrect(m->xy,b->rect)) {
108
			if (b->off) {
109
				b->off = 0;
110
				buttonshow(b);
111
			}
112
		} else {
113
			if (!b->off) {
114
				b->off = 1;
115
				buttonshow(b);
116
			}
117
		}
118
	}
119
	if((m->buttons&7) != b->lastbut){
120
		if(m->buttons & 7){
121
			b->prepress = b->pressed;
122
			if (b->pressed)
123
				b->pressed = 0;
124
			else
125
				b->pressed = m->buttons & 7;
126
			buttonshow(b);
127
		}else	/* generate event on button up */
128
			if (ptinrect(m->xy,b->rect))
129
				chanprint(b->event, b->format, b->name, b->pressed);
130
			else {
131
				b->off = 0;
132
				b->pressed = b->prepress;
133
				buttonshow(b);
134
			}
135
	}
136
	b->lastbut = m->buttons & 7;
137
}
138
 
139
static void
140
buttonctl(Control *c, CParse *cp)
141
{
142
	int cmd;
143
	Rectangle r;
144
	Button *b;
145
 
146
	b = (Button*)c;
147
	cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
148
	switch(cmd){
149
	default:
150
		ctlerror("%q: unrecognized message '%s'", b->name, cp->str);
151
		break;
152
	case EAlign:
153
		_ctlargcount(b, cp, 2);
154
		b->align = _ctlalignment(cp->args[1]);
155
		b->lastshow = -1;	/* force redraw */
156
		break;
157
	case EBorder:
158
		_ctlargcount(b, cp, 2);
159
		b->border = cp->iargs[1];
160
		b->lastshow = -1;	/* force redraw */
161
		break;
162
	case EBordercolor:
163
		_ctlargcount(b, cp, 2);
164
		_setctlimage(b, &b->bordercolor, cp->args[1]);
165
		b->lastshow = -1;	/* force redraw */
166
		break;
167
	case EFocus:
168
		/* ignore focus change */
169
		break;
170
	case EFormat:
171
		_ctlargcount(b, cp, 2);
172
		b->format = ctlstrdup(cp->args[1]);
173
		break;
174
	case EHide:
175
		_ctlargcount(b, cp, 1);
176
		b->hidden = 1;
177
		break;
178
	case EImage:
179
		_ctlargcount(b, cp, 2);
180
		_setctlimage(b, &b->image, cp->args[1]);
181
		b->lastshow = -1;	/* force redraw */
182
		break;
183
	case ELight:
184
		_ctlargcount(b, cp, 2);
185
		_setctlimage(b, &b->light, cp->args[1]);
186
		b->lastshow = -1;	/* force redraw */
187
		break;
188
	case EMask:
189
		_ctlargcount(b, cp, 2);
190
		_setctlimage(b, &b->mask, cp->args[1]);
191
		b->lastshow = -1;	/* force redraw */
192
		break;
193
	case EPale:
194
		_ctlargcount(b, cp, 2);
195
		_setctlimage(b, &b->pale, cp->args[1]);
196
		b->lastshow = -1;	/* force redraw */
197
		break;
198
	case ERect:
199
		_ctlargcount(b, cp, 5);
200
		r.min.x = cp->iargs[1];
201
		r.min.y = cp->iargs[2];
202
		r.max.x = cp->iargs[3];
203
		r.max.y = cp->iargs[4];
204
		if(Dx(r)<0 || Dy(r)<0)
205
			ctlerror("%q: bad rectangle: %s", b->name, cp->str);
206
		b->rect = r;
207
		b->lastshow = -1;	/* force redraw */
208
		break;
209
	case EReveal:
210
		_ctlargcount(b, cp, 1);
211
		b->hidden = 0;
212
		buttonshow(b);
213
		break;
214
	case EShow:
215
		_ctlargcount(b, cp, 1);
216
		buttonshow(b);
217
		break;
218
	case ESize:
219
		if (cp->nargs == 3)
220
			r.max = Pt(0x7fffffff, 0x7fffffff);
221
		else{
222
			_ctlargcount(b, cp, 5);
223
			r.max.x = cp->iargs[3];
224
			r.max.y = cp->iargs[4];
225
		}
226
		r.min.x = cp->iargs[1];
227
		r.min.y = cp->iargs[2];
228
		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)
229
			ctlerror("%q: bad sizes: %s", b->name, cp->str);
230
		b->size.min = r.min;
231
		b->size.max = r.max;
232
		break;
233
	case EValue:
234
		_ctlargcount(b, cp, 2);
235
		if((cp->iargs[1]!=0) != b->pressed){
236
			b->pressed ^= 1;
237
			buttonshow(b);
238
		}
239
		break;
240
	}
241
}
242
 
243
Control*
244
createbutton(Controlset *cs, char *name)
245
{
246
	Button *b;
247
	b = (Button*)_createctl(cs, "button", sizeof(Button), name);
248
	b->image = _getctlimage("white");
249
	b->mask = _getctlimage("opaque");
250
	b->light = _getctlimage("yellow");
251
	b->pale = _getctlimage("paleyellow");
252
	b->bordercolor = _getctlimage("black");
253
	b->format = ctlstrdup("%q: value %d");
254
	b->lastshow = -1;
255
	b->border = 0;
256
	b->align = Aupperleft;
257
	b->ctl = buttonctl;
258
	b->mouse = buttonmouse;
259
	b->key = nil;
260
	b->exit = buttonfree;
261
	b->off = 0;
262
	b->prepress = 0;
263
	return (Control*)b;
264
}