]> git.ipfire.org Git - thirdparty/newt.git/blob - checkbox.c
added a getvalue call
[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, LISTITEM };
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 };
21
22 static void cbDrawIt(newtComponent c, int active);
23 static void makeActive(newtComponent co);
24
25 static void cbDraw(newtComponent c);
26 static void cbDestroy(newtComponent co);
27 struct eventResult cbEvent(newtComponent co, struct event ev);
28
29 static struct componentOps cbOps = {
30 cbDraw,
31 cbEvent,
32 cbDestroy,
33 newtDefaultPlaceHandler,
34 newtDefaultMappedHandler,
35 } ;
36
37 newtComponent newtListitem(int left, int top, const char * text, int isDefault,
38 newtComponent prevItem, const void * data, int flags) {
39 newtComponent co;
40 struct checkbox * li;
41
42 co = newtRadiobutton(left, top, text, isDefault, prevItem);
43 li = co->data;
44 li->type = LISTITEM;
45 li->flags = flags & (NEWT_FLAG_RETURNEXIT);
46 li->inactive = COLORSET_LISTBOX;
47 li->active = COLORSET_ACTLISTBOX;
48 li->data = data;
49
50 return co;
51 }
52
53 void * newtListitemGetData(newtComponent co) {
54 struct checkbox * rb = co->data;
55
56 return (void *)rb->data;
57 }
58
59 void newtListitemSet(newtComponent co, const char * text) {
60 struct checkbox * li = co->data;
61
62 free(li->text);
63 li->text = strdup(text);
64
65 if (strlen(text) + 4 > (unsigned int)co->width)
66 co->width = strlen(text) + 4;
67 }
68
69 newtComponent newtRadiobutton(int left, int top, const char * text, int isDefault,
70 newtComponent prevButton) {
71 newtComponent co;
72 newtComponent curr;
73 struct checkbox * rb;
74 char initialValue;
75
76 if (isDefault)
77 initialValue = '*';
78 else
79 initialValue = ' ';
80
81 co = newtCheckbox(left, top, text, initialValue, " *", NULL);
82 rb = co->data;
83 rb->type = RADIO;
84
85 rb->prevButton = prevButton;
86
87 for (curr = co; curr; curr = rb->prevButton) {
88 rb = curr->data;
89 rb->lastButton = co;
90 }
91
92 return co;
93 }
94
95 newtComponent newtRadioGetCurrent(newtComponent setMember) {
96 struct checkbox * rb = setMember->data;
97
98 setMember = rb->lastButton;
99 rb = setMember->data;
100
101 while (rb && rb->value != '*') {
102 setMember = rb->prevButton;
103 rb = setMember->data;
104 }
105
106 return setMember;
107 }
108
109 char newtCheckboxGetValue(newtComponent co) {
110 struct checkbox * cb = co->data;
111
112 return cb->value;
113 }
114
115 newtComponent newtCheckbox(int left, int top, const char * text, char defValue,
116 const char * seq, char * result) {
117 newtComponent co;
118 struct checkbox * cb;
119
120 if (!seq) seq = " *";
121
122 co = malloc(sizeof(*co));
123 cb = malloc(sizeof(struct checkbox));
124 co->data = cb;
125 cb->flags = 0;
126 if (result)
127 cb->result = result;
128 else
129 cb->result = &cb->value;
130
131 cb->text = strdup(text);
132 cb->seq = strdup(seq);
133 cb->type = CHECK;
134 cb->inactive = COLORSET_CHECKBOX;
135 cb->active = COLORSET_ACTCHECKBOX;
136 defValue ? (*cb->result = defValue) : (*cb->result = cb->seq[0]);
137
138 co->ops = &cbOps;
139
140 co->callback = NULL;
141 co->height = 1;
142 co->width = strlen(text) + 4;
143 co->top = top;
144 co->left = left;
145 co->takesFocus = 1;
146
147 return co;
148 }
149
150 static void cbDraw(newtComponent c) {
151 cbDrawIt(c, 0);
152 }
153
154 static void cbDrawIt(newtComponent c, int active) {
155 struct checkbox * cb = c->data;
156
157 if (c->top == -1) return;
158
159 if (cb->type == LISTITEM && *cb->result != ' ')
160 SLsmg_set_color(cb->active);
161 else
162 SLsmg_set_color(cb->inactive);
163
164 newtGotorc(c->top, c->left);
165
166 switch (cb->type) {
167 case RADIO:
168 SLsmg_write_string("( ) ");
169 break;
170
171 case CHECK:
172 SLsmg_write_string("[ ] ");
173 break;
174
175 default:
176 break;
177 }
178
179 SLsmg_write_string(cb->text);
180
181 if (active)
182 SLsmg_set_color(cb->active);
183
184 if (cb->type != LISTITEM) {
185 newtGotorc(c->top, c->left + 1);
186 SLsmg_write_char(*cb->result);
187 }
188 }
189
190 static void cbDestroy(newtComponent co) {
191 struct checkbox * cb = co->data;
192
193 free(cb->text);
194 free(cb->seq);
195 free(cb);
196 free(co);
197 }
198
199 struct eventResult cbEvent(newtComponent co, struct event ev) {
200 struct checkbox * cb = co->data;
201 struct eventResult er;
202 const char * cur;
203
204 if (ev.when == EV_NORMAL) {
205 switch (ev.event) {
206 case EV_FOCUS:
207 if (cb->type == LISTITEM)
208 makeActive(co);
209 else
210 cbDrawIt(co, 1);
211
212 er.result = ER_SWALLOWED;
213 break;
214
215 case EV_UNFOCUS:
216 cbDrawIt(co, 0);
217 er.result = ER_SWALLOWED;
218 break;
219
220 case EV_KEYPRESS:
221 if (ev.u.key == ' ') {
222 if (cb->type == RADIO) {
223 makeActive(co);
224 } else if (cb->type == CHECK) {
225 cur = strchr(cb->seq, *cb->result);
226 if (!cur)
227 *cb->result = *cb->seq;
228 else {
229 cur++;
230 if (! *cur)
231 *cb->result = *cb->seq;
232 else
233 *cb->result = *cur;
234 }
235 cbDrawIt(co, 1);
236 er.result = ER_SWALLOWED;
237 } else {
238 er.result = ER_IGNORED;
239 }
240 } else if(ev.u.key == NEWT_KEY_ENTER) {
241 if((cb->type == LISTITEM)
242 && (cb->flags | NEWT_FLAG_RETURNEXIT)) {
243 er.u.focus = co;
244 er.result = ER_EXITFORM;
245 } else
246 er.result = ER_IGNORED;
247 } else {
248 er.result = ER_IGNORED;
249 }
250 break;
251 }
252 } else
253 er.result = ER_IGNORED;
254
255 if (er.result == ER_SWALLOWED && co->callback)
256 co->callback(co, co->callbackData);
257
258 return er;
259 }
260
261 static void makeActive(newtComponent co) {
262 struct checkbox * cb = co->data;
263 struct checkbox * rb;
264 newtComponent curr;
265
266 /* find the one that's turned off */
267 curr = cb->lastButton;
268 rb = curr->data;
269 while (curr && rb->value == rb->seq[0]) {
270 curr = rb->prevButton;
271 if (curr) rb = curr->data;
272 }
273 if (curr) {
274 rb->value = rb->seq[0];
275 cbDrawIt(curr, 0);
276 }
277 cb->value = cb->seq[1];
278 cbDrawIt(co, 1);
279 }