]>
Commit | Line | Data |
---|---|---|
139f06bc | 1 | #include <slang.h> |
6fb96a3f | 2 | #include <stdlib.h> |
3 | #include <string.h> | |
4 | ||
5 | #include "newt.h" | |
6 | #include "newt_pr.h" | |
7 | ||
b64f7aeb | 8 | enum type { CHECK, RADIO }; |
274a0280 | 9 | |
6fb96a3f | 10 | struct checkbox { |
11 | char * text; | |
12 | char * seq; | |
13 | char * result; | |
14 | newtComponent prevButton, lastButton; | |
274a0280 | 15 | enum type type; |
6fb96a3f | 16 | char value; |
274a0280 | 17 | int active, inactive; |
d4109c37 | 18 | const void * data; |
9b95c64f | 19 | int flags; |
b6565704 | 20 | int hasFocus; |
6fb96a3f | 21 | }; |
22 | ||
6fb96a3f | 23 | static void cbDraw(newtComponent c); |
24 | static void cbDestroy(newtComponent co); | |
45c366b1 | 25 | struct eventResult cbEvent(newtComponent co, struct event ev); |
6fb96a3f | 26 | |
27 | static struct componentOps cbOps = { | |
28 | cbDraw, | |
29 | cbEvent, | |
30 | cbDestroy, | |
8f52cd47 | 31 | newtDefaultPlaceHandler, |
32 | newtDefaultMappedHandler, | |
6fb96a3f | 33 | } ; |
34 | ||
d4109c37 | 35 | newtComponent newtRadiobutton(int left, int top, const char * text, int isDefault, |
6f481af2 | 36 | newtComponent prevButton) { |
6fb96a3f | 37 | newtComponent co; |
38 | newtComponent curr; | |
39 | struct checkbox * rb; | |
40 | char initialValue; | |
41 | ||
42 | if (isDefault) | |
6f481af2 | 43 | initialValue = '*'; |
6fb96a3f | 44 | else |
6f481af2 | 45 | initialValue = ' '; |
6fb96a3f | 46 | |
47 | co = newtCheckbox(left, top, text, initialValue, " *", NULL); | |
48 | rb = co->data; | |
274a0280 | 49 | rb->type = RADIO; |
6fb96a3f | 50 | |
51 | rb->prevButton = prevButton; | |
52 | ||
53 | for (curr = co; curr; curr = rb->prevButton) { | |
6f481af2 | 54 | rb = curr->data; |
55 | rb->lastButton = co; | |
6fb96a3f | 56 | } |
57 | ||
58 | return co; | |
59 | } | |
60 | ||
133fc722 | 61 | newtComponent newtRadioGetCurrent(newtComponent setMember) { |
62 | struct checkbox * rb = setMember->data; | |
45f6c4fd | 63 | |
133fc722 | 64 | setMember = rb->lastButton; |
65 | rb = setMember->data; | |
66 | ||
67 | while (rb && rb->value != '*') { | |
6f481af2 | 68 | setMember = rb->prevButton; |
69 | if (!setMember) | |
70 | return NULL; | |
71 | rb = setMember->data; | |
133fc722 | 72 | } |
73 | ||
74 | return setMember; | |
75 | } | |
76 | ||
ef3f0be6 TJ |
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 | ||
a2620a83 | 100 | char newtCheckboxGetValue(newtComponent co) { |
101 | struct checkbox * cb = co->data; | |
102 | ||
feef2cb5 | 103 | return cb->value; |
a2620a83 | 104 | } |
105 | ||
b6565704 | 106 | void newtCheckboxSetValue(newtComponent co, char value) { |
107 | struct checkbox * cb = co->data; | |
108 | ||
109 | *cb->result = value; | |
110 | cbDraw(co); | |
111 | } | |
112 | ||
b3ddfdd7 | 113 | /* |
114 | * returns NULL on error. | |
115 | * FIXME: Check all calls. | |
116 | */ | |
d4109c37 | 117 | newtComponent newtCheckbox(int left, int top, const char * text, char defValue, |
6f481af2 | 118 | const char * seq, char * result) { |
6fb96a3f | 119 | newtComponent co; |
120 | struct checkbox * cb; | |
121 | ||
122 | if (!seq) seq = " *"; | |
123 | ||
124 | co = malloc(sizeof(*co)); | |
b3ddfdd7 | 125 | if (co == NULL) |
6f481af2 | 126 | return NULL; |
6fb96a3f | 127 | cb = malloc(sizeof(struct checkbox)); |
b3ddfdd7 | 128 | if (cb == NULL) { |
6f481af2 | 129 | free(co); |
130 | return NULL; | |
b3ddfdd7 | 131 | } |
6fb96a3f | 132 | co->data = cb; |
9b95c64f | 133 | cb->flags = 0; |
6fb96a3f | 134 | if (result) |
6f481af2 | 135 | cb->result = result; |
6fb96a3f | 136 | else |
6f481af2 | 137 | cb->result = &cb->value; |
6fb96a3f | 138 | |
139 | cb->text = strdup(text); | |
140 | cb->seq = strdup(seq); | |
274a0280 | 141 | cb->type = CHECK; |
b6565704 | 142 | cb->hasFocus = 0; |
274a0280 | 143 | cb->inactive = COLORSET_CHECKBOX; |
144 | cb->active = COLORSET_ACTCHECKBOX; | |
6fb96a3f | 145 | defValue ? (*cb->result = defValue) : (*cb->result = cb->seq[0]); |
6fb96a3f | 146 | |
147 | co->ops = &cbOps; | |
148 | ||
5809ecab | 149 | co->callback = NULL; |
c101e99e | 150 | co->destroyCallback = NULL; |
6fb96a3f | 151 | co->height = 1; |
349586bb | 152 | co->width = wstrlen(text, -1) + 4; |
6fb96a3f | 153 | co->top = top; |
154 | co->left = left; | |
155 | co->takesFocus = 1; | |
009f3ebf | 156 | co->isMapped = 0; |
6fb96a3f | 157 | |
158 | return co; | |
159 | } | |
160 | ||
60c6e639 | 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 | ||
feef2cb5 | 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 | ||
60c6e639 | 173 | if (!(cb->flags & NEWT_FLAG_DISABLED)) |
6f481af2 | 174 | co->takesFocus = 1; |
60c6e639 | 175 | else |
6f481af2 | 176 | co->takesFocus = 0; |
60c6e639 | 177 | |
178 | newtGetrc(&row, &col); | |
179 | cbDraw(co); | |
180 | newtGotorc(row, col); | |
181 | } | |
182 | ||
6fb96a3f | 183 | static void cbDraw(newtComponent c) { |
6fb96a3f | 184 | struct checkbox * cb = c->data; |
185 | ||
5d1e2567 | 186 | if (!c->isMapped) return; |
94396885 | 187 | |
60c6e639 | 188 | if (cb->flags & NEWT_FLAG_DISABLED) { |
6f481af2 | 189 | cb->inactive = NEWT_COLORSET_DISENTRY; |
190 | cb->active = NEWT_COLORSET_DISENTRY; | |
60c6e639 | 191 | } else { |
6f481af2 | 192 | cb->inactive = COLORSET_CHECKBOX; |
193 | cb->active = COLORSET_ACTCHECKBOX; | |
60c6e639 | 194 | } |
195 | ||
b64f7aeb | 196 | SLsmg_set_color(cb->inactive); |
6fb96a3f | 197 | |
198 | newtGotorc(c->top, c->left); | |
199 | ||
274a0280 | 200 | switch (cb->type) { |
201 | case RADIO: | |
6f481af2 | 202 | SLsmg_write_string("( ) "); |
203 | break; | |
274a0280 | 204 | |
205 | case CHECK: | |
6f481af2 | 206 | SLsmg_write_string("[ ] "); |
207 | break; | |
274a0280 | 208 | |
209 | default: | |
6f481af2 | 210 | break; |
274a0280 | 211 | } |
6fb96a3f | 212 | |
10de8f4a | 213 | SLsmg_write_string(cb->text); |
6fb96a3f | 214 | |
45f6c4fd | 215 | if (cb->hasFocus) |
6f481af2 | 216 | SLsmg_set_color(cb->active); |
6fb96a3f | 217 | |
b64f7aeb | 218 | newtGotorc(c->top, c->left + 1); |
219 | SLsmg_write_char(*cb->result); | |
b9b12605 | 220 | newtGotorc(c->top, c->left + 4); |
6fb96a3f | 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 | ||
45c366b1 | 232 | struct eventResult cbEvent(newtComponent co, struct event ev) { |
6fb96a3f | 233 | struct checkbox * cb = co->data; |
274a0280 | 234 | struct eventResult er; |
d4109c37 | 235 | const char * cur; |
6fb96a3f | 236 | |
c00a8d1b | 237 | er.result = ER_IGNORED; |
238 | ||
c1a075d9 | 239 | if (ev.when == EV_NORMAL) { |
6f481af2 | 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) { | |
ef3f0be6 | 256 | newtRadioSetCurrent(co); |
6f481af2 | 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) { | |
feef2cb5 | 277 | if (cb->flags & NEWT_FLAG_RETURNEXIT) |
278 | er.result = ER_EXITFORM; | |
279 | else | |
280 | er.result = ER_IGNORED; | |
6f481af2 | 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) { | |
ef3f0be6 | 288 | newtRadioSetCurrent(co); |
6f481af2 | 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 | } | |
c00a8d1b | 308 | } |
6fb96a3f | 309 | |
c1a075d9 | 310 | return er; |
6fb96a3f | 311 | } |