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 <thread.h>
4
#include <draw.h>
5
#include <mouse.h>
6
#include <keyboard.h>
7
#include <control.h>
8
#include "group.h"
9
 
10
typedef struct Tab Tab;
11
 
12
struct Tab {
13
	Control;
14
	int		border;
15
	int		selected;
16
	int		separation;
17
	char		*format;
18
	CImage	*bordercolor;
19
	CImage	*image;
20
	Control	*tabrow;
21
	Control	*tabstack;
22
	Control	*tabcolumn;
23
	int		ntabs;
24
	int		nbuttons;
25
	Control	**buttons;
26
};
27
 
28
enum{
29
	EAdd,
30
	EBorder,
31
	EBordercolor,
32
	EButton,
33
	EFocus,
34
	EFormat,
35
	EHide,
36
	EImage,
37
	ERect,
38
	EReveal,
39
	ESeparation,
40
	ESeparatorcolor,
41
	EShow,
42
	ESize,
43
	EValue,
44
};
45
 
46
static char *cmds[] = {
47
	[EAdd] =			"add",
48
	[EBorder] =		"border",
49
	[EBordercolor] =	"bordercolor",
50
	[EButton] =		"button",
51
	[EFocus] = 		"focus",
52
	[EFormat] = 		"format",
53
	[EHide] =			"hide",
54
	[EImage] =		"image",
55
	[ERect] =			"rect",
56
	[EReveal] =		"reveal",
57
	[ESeparation] =		"separation",
58
	[ESeparatorcolor] =	"separatorcolor",
59
	[EShow] =			"show",
60
	[ESize] =			"size",
61
	[EValue] =			"value",
62
};
63
 
64
static void
65
tabshow(Tab *t)
66
{
67
	int i;
68
	Rectangle r;
69
	Group *g;
70
 
71
	if (t->hidden)
72
		return;
73
	for(i=0; i<t->nbuttons; i++){
74
		_ctlprint(t->buttons[i], "value %d", (t->selected==i));
75
	}
76
	_ctlprint(t->tabstack, "reveal %d", t->selected);
77
	_ctlprint(t->tabcolumn, "show");
78
	if (t->selected < 0)
79
		return;
80
	g = (Group*)t->tabcolumn;
81
	if (g->nseparators == 0){
82
		return;
83
	}
84
	r = g->separators[0];
85
	r.min.x = t->buttons[t->selected]->rect.min.x;
86
	r.max.x = t->buttons[t->selected]->rect.max.x;
87
	draw(t->screen, r, t->image->image, nil, t->image->image->r.min);
88
	flushimage(display, 1);
89
}
90
 
91
static void
92
tabsize(Control *c)
93
{
94
	Tab *t = (Tab*)c;
95
	if (t->tabcolumn && t->tabcolumn->setsize)
96
		t->tabcolumn->setsize((Control*)t->tabcolumn);
97
}
98
 
99
static void
100
tabctl(Control *c, CParse *cp)
101
{
102
	int cmd, i;
103
	Control *cbut, *cwin;
104
	Tab *t;
105
	Rectangle r;
106
 
107
	t = (Tab*)c;
108
	cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
109
	switch(cmd){
110
	case EAdd:
111
		if ((cp->nargs & 1) == 0)
112
			ctlerror("%q: arg count: %s", t->name, cp->args[1]);
113
		for (i = 1; i < cp->nargs; i += 2){
114
			cbut = controlcalled(cp->args[i]);
115
			if (cbut == nil)
116
				ctlerror("%q: no such control: %s", t->name, cp->args[i]);
117
			cwin = controlcalled(cp->args[i+1]);
118
			if (cwin == nil)
119
				ctlerror("%q: no such control: %s", t->name, cp->args[i+1]);
120
			_ctladdgroup(t->tabrow, cbut);
121
			_ctlprint(t->tabstack, "add %q", cp->args[i+1]);
122
			_ctlprint(cbut, "format '%%s: %q button %%d'", t->name);
123
			controlwire(cbut, "event", t->controlset->ctl);
124
			t->buttons = ctlrealloc(t->buttons, (t->nbuttons+1)*sizeof(Control*));
125
			t->buttons[t->nbuttons] = cbut;
126
			t->nbuttons++;
127
			t->selected = -1;
128
		}
129
		_ctlprint(t->tabcolumn, "size");
130
		t->size = t->tabcolumn->size;
131
		break;
132
	case EBorder:
133
		_ctlargcount(t, cp, 2);
134
		if(cp->iargs[1] < 0)
135
			ctlerror("%q: bad border: %c", t->name, cp->str);
136
		t->border = cp->iargs[1];
137
		break;
138
	case EBordercolor:
139
		_ctlargcount(t, cp, 2);
140
		_setctlimage(t, &t->bordercolor, cp->args[1]);
141
		break;
142
	case EButton:
143
		_ctlargcount(t, cp, 2);
144
		if (cp->sender == nil)
145
			ctlerror("%q: senderless buttonevent: %q", t->name, cp->str);
146
		cbut = controlcalled(cp->sender);
147
		for(i=0; i<t->nbuttons; i++)
148
			if (cbut == t->buttons[i])
149
				break;
150
		if (i == t->nbuttons)
151
			ctlerror("%q: not my event: %q", t->name, cp->str);
152
		if(cp->iargs[1] == 0){
153
			/* button was turned off; turn it back on */
154
			_ctlprint(cbut, "value 1");
155
		}else{
156
			t->selected = i;
157
			if (t->format)
158
				chanprint(t->event, t->format, t->name, i);
159
			tabshow(t);
160
		}
161
		break;
162
	case EFocus:
163
		/* ignore focus change */
164
		break;
165
	case EFormat:
166
		_ctlargcount(t, cp, 2);
167
		t->format = ctlstrdup(cp->args[1]);
168
		break;
169
	case EImage:
170
		_ctlargcount(t, cp, 2);
171
		_setctlimage(t, &t->image, cp->args[1]);
172
		break;
173
	case ESeparation:
174
		t->tabrow->ctl(t->tabrow, cp);
175
		t->tabcolumn->ctl(t->tabcolumn, cp);
176
		break;
177
	case ERect:
178
		_ctlargcount(t, cp, 5);
179
		r.min.x = cp->iargs[1];
180
		r.min.y = cp->iargs[2];
181
		r.max.x = cp->iargs[3];
182
		r.max.y = cp->iargs[4];
183
		if(Dx(r)<=0 || Dy(r)<=0)
184
			ctlerror("%q: bad rectangle: %s", t->name, cp->str);
185
		t->rect = r;
186
		r = insetrect(r, t->border);
187
		_ctlprint(t->tabcolumn, "rect %R", r);
188
		break;
189
	case EReveal:
190
		_ctlargcount(t, cp, 1);
191
	case EHide:
192
	case ESize:
193
		t->tabcolumn->ctl(t->tabcolumn, cp);
194
		break;
195
	case EShow:
196
		tabshow(t);
197
		break;
198
	case EValue:
199
		_ctlargcount(t, cp, 2);
200
		if (cp->iargs[1] < 0 || cp->iargs[1] >= t->nbuttons)
201
			ctlerror("%q: illegal value '%s'", t->name, cp->str);
202
		t->selected = cp->iargs[1];
203
		tabshow(t);
204
		break;
205
	default:
206
		ctlerror("%q: unrecognized message '%s'", t->name, cp->str);
207
		break;
208
	}
209
}
210
 
211
static void
212
tabfree(Control*c)
213
{
214
	Tab *t = (Tab*)c;
215
	t->nbuttons = 0;
216
	free(t->buttons);
217
	t->buttons = 0;
218
}
219
 
220
static void
221
activatetab(Control *c, int act)
222
{
223
	Tab *t;
224
 
225
	t = (Tab*)c;
226
	if (act)
227
		activate(t->tabcolumn);
228
	else
229
		deactivate(t->tabcolumn);
230
}
231
 
232
Control *
233
createtab(Controlset *cs, char *name)
234
{
235
	char s[128];
236
 
237
	Tab *t;
238
	t = (Tab*)_createctl(cs, "tab", sizeof(Tab), name);
239
	t->selected = -1;
240
	t->nbuttons = 0;
241
	t->ctl = tabctl;
242
	t->mouse = nil;
243
	t->exit = tabfree;
244
	snprint(s, sizeof s, "_%s-row", name);
245
	t->tabrow = createrow(cs, s);
246
	snprint(s, sizeof s, "_%s-stack", name);
247
	t->tabstack = createstack(cs, s);
248
	snprint(s, sizeof s, "_%s-column", name);
249
	t->tabcolumn = createcolumn(cs, s);
250
	ctlprint(t->tabcolumn, "add %q %q", t->tabrow->name, t->tabstack->name);
251
	t->bordercolor = _getctlimage("black");
252
	t->image = _getctlimage("white");
253
	t->setsize = tabsize;
254
	t->activate = activatetab;
255
	return (Control*)t;
256
}