]> git.ipfire.org Git - thirdparty/newt.git/blob - checkbox.c
install python modules to purelib and platlib
[thirdparty/newt.git] / checkbox.c
1 #include <slang.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "newt.h"
6 #include "newt_pr.h"
7
8 enum type { CHECK, RADIO };
9
10 struct checkbox {
11 char * text;
12 char * seq;
13 char * result;
14 newtComponent prevButton, lastButton;
15 enum type type;
16 char value;
17 int active, inactive;
18 const void * data;
19 int flags;
20 int hasFocus;
21 };
22
23 static void cbDraw(newtComponent c);
24 static void cbDestroy(newtComponent co);
25 struct eventResult cbEvent(newtComponent co, struct event ev);
26
27 static struct componentOps cbOps = {
28 cbDraw,
29 cbEvent,
30 cbDestroy,
31 newtDefaultPlaceHandler,
32 newtDefaultMappedHandler,
33 } ;
34
35 newtComponent newtRadiobutton(int left, int top, const char * text, int isDefault,
36 newtComponent prevButton) {
37 newtComponent co;
38 newtComponent curr;
39 struct checkbox * rb;
40 char initialValue;
41
42 if (isDefault)
43 initialValue = '*';
44 else
45 initialValue = ' ';
46
47 co = newtCheckbox(left, top, text, initialValue, " *", NULL);
48 rb = co->data;
49 rb->type = RADIO;
50
51 rb->prevButton = prevButton;
52
53 for (curr = co; curr; curr = rb->prevButton) {
54 rb = curr->data;
55 rb->lastButton = co;
56 }
57
58 return co;
59 }
60
61 newtComponent newtRadioGetCurrent(newtComponent setMember) {
62 struct checkbox * rb = setMember->data;
63
64 setMember = rb->lastButton;
65 rb = setMember->data;
66
67 while (rb && rb->value != '*') {
68 setMember = rb->prevButton;
69 if (!setMember)
70 return NULL;
71 rb = setMember->data;
72 }
73
74 return setMember;
75 }
76
77 void newtRadioSetCurrent(newtComponent setMember) {
78 struct checkbox * cb = setMember->data;
79 struct checkbox * rb;
80 newtComponent curr;
81
82 /* find the one that's turned on */
83 curr = cb->lastButton;
84 rb = curr->data;
85 while (curr && rb->value == rb->seq[0]) {
86 curr = rb->prevButton;
87 if (curr) rb = curr->data;
88 }
89 if (curr) {
90 rb->value = rb->seq[0];
91 cbDraw(curr);
92 }
93 cb->value = cb->seq[1];
94 cbDraw(setMember);
95
96 if (setMember->callback)
97 setMember->callback(setMember, setMember->callbackData);
98 }
99
100 char newtCheckboxGetValue(newtComponent co) {
101 struct checkbox * cb = co->data;
102
103 return cb->value;
104 }
105
106 void newtCheckboxSetValue(newtComponent co, char value) {
107 struct checkbox * cb = co->data;
108
109 *cb->result = value;
110 cbDraw(co);
111 }
112
113 /*
114 * returns NULL on error.
115 * FIXME: Check all calls.
116 */
117 newtComponent newtCheckbox(int left, int top, const char * text, char defValue,
118 const char * seq, char * result) {
119 newtComponent co;
120 struct checkbox * cb;
121
122 if (!seq) seq = " *";
123
124 co = malloc(sizeof(*co));
125 if (co == NULL)
126 return NULL;
127 cb = malloc(sizeof(struct checkbox));
128 if (cb == NULL) {
129 free(co);
130 return NULL;
131 }
132 co->data = cb;
133 cb->flags = 0;
134 if (result)
135 cb->result = result;
136 else
137 cb->result = &cb->value;
138
139 cb->text = strdup(text);
140 cb->seq = strdup(seq);
141 cb->type = CHECK;
142 cb->hasFocus = 0;
143 cb->inactive = COLORSET_CHECKBOX;
144 cb->active = COLORSET_ACTCHECKBOX;
145 defValue ? (*cb->result = defValue) : (*cb->result = cb->seq[0]);
146
147 co->ops = &cbOps;
148
149 co->callback = NULL;
150 co->destroyCallback = NULL;
151 co->height = 1;
152 co->width = wstrlen(text, -1) + 4;
153 co->top = top;
154 co->left = left;
155 co->takesFocus = 1;
156 co->isMapped = 0;
157
158 return co;
159 }
160
161 void newtCheckboxSetFlags(newtComponent co, int flags, enum newtFlagsSense sense) {
162 struct checkbox * cb = co->data;
163 int row, col;
164
165 cb->flags = newtSetFlags(cb->flags, flags, sense);
166
167 // If the flag just sets a property (eg. NEWT_FLAG_RETURNEXIT),
168 // don't redraw, etc. as the component might be 'hidden' and not to
169 // be drawn (eg. in a scrolled list)
170 if (flags == NEWT_FLAG_RETURNEXIT)
171 return;
172
173 if (!(cb->flags & NEWT_FLAG_DISABLED))
174 co->takesFocus = 1;
175 else
176 co->takesFocus = 0;
177
178 newtGetrc(&row, &col);
179 cbDraw(co);
180 newtGotorc(row, col);
181 }
182
183 static void cbDraw(newtComponent c) {
184 struct checkbox * cb = c->data;
185
186 if (!c->isMapped) return;
187
188 if (cb->flags & NEWT_FLAG_DISABLED) {
189 cb->inactive = NEWT_COLORSET_DISENTRY;
190 cb->active = NEWT_COLORSET_DISENTRY;
191 } else {
192 cb->inactive = COLORSET_CHECKBOX;
193 cb->active = COLORSET_ACTCHECKBOX;
194 }
195
196 SLsmg_set_color(cb->inactive);
197
198 newtGotorc(c->top, c->left);
199
200 switch (cb->type) {
201 case RADIO:
202 SLsmg_write_string("( ) ");
203 break;
204
205 case CHECK:
206 SLsmg_write_string("[ ] ");
207 break;
208
209 default:
210 break;
211 }
212
213 SLsmg_write_string(cb->text);
214
215 if (cb->hasFocus)
216 SLsmg_set_color(cb->active);
217
218 newtGotorc(c->top, c->left + 1);
219 SLsmg_write_char(*cb->result);
220 newtGotorc(c->top, c->left + 4);
221 }
222
223 static void cbDestroy(newtComponent co) {
224 struct checkbox * cb = co->data;
225
226 free(cb->text);
227 free(cb->seq);
228 free(cb);
229 free(co);
230 }
231
232 struct eventResult cbEvent(newtComponent co, struct event ev) {
233 struct checkbox * cb = co->data;
234 struct eventResult er;
235 const char * cur;
236
237 er.result = ER_IGNORED;
238
239 if (ev.when == EV_NORMAL) {
240 switch (ev.event) {
241 case EV_FOCUS:
242 cb->hasFocus = 1;
243 cbDraw(co);
244 er.result = ER_SWALLOWED;
245 break;
246
247 case EV_UNFOCUS:
248 cb->hasFocus = 0;
249 cbDraw(co);
250 er.result = ER_SWALLOWED;
251 break;
252
253 case EV_KEYPRESS:
254 if (ev.u.key == ' ') {
255 if (cb->type == RADIO) {
256 newtRadioSetCurrent(co);
257 } else if (cb->type == CHECK) {
258 cur = strchr(cb->seq, *cb->result);
259 if (!cur)
260 *cb->result = *cb->seq;
261 else {
262 cur++;
263 if (! *cur)
264 *cb->result = *cb->seq;
265 else
266 *cb->result = *cur;
267 }
268 cbDraw(co);
269 er.result = ER_SWALLOWED;
270
271 if (co->callback)
272 co->callback(co, co->callbackData);
273 } else {
274 er.result = ER_IGNORED;
275 }
276 } else if(ev.u.key == NEWT_KEY_ENTER) {
277 if (cb->flags & NEWT_FLAG_RETURNEXIT)
278 er.result = ER_EXITFORM;
279 else
280 er.result = ER_IGNORED;
281 } else {
282 er.result = ER_IGNORED;
283 }
284 break;
285 case EV_MOUSE:
286 if (ev.u.mouse.type == MOUSE_BUTTON_DOWN) {
287 if (cb->type == RADIO) {
288 newtRadioSetCurrent(co);
289 } else if (cb->type == CHECK) {
290 cur = strchr(cb->seq, *cb->result);
291 if (!cur)
292 *cb->result = *cb->seq;
293 else {
294 cur++;
295 if (! *cur)
296 *cb->result = *cb->seq;
297 else
298 *cb->result = *cur;
299 }
300 cbDraw(co);
301 er.result = ER_SWALLOWED;
302
303 if (co->callback)
304 co->callback(co, co->callbackData);
305 }
306 }
307 }
308 }
309
310 return er;
311 }