1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include "button.h"
33 #include "container.h"
34 #include "../common/context.h"
35 #include <cx/mempool.h>
36
37 #include <cx/linked_list.h>
38 #include <cx/array_list.h>
39 #include <cx/compare.h>
40
41 #include <Xm/XmAll.h>
42
43
44 UIWIDGET ui_button_create(UiObject* obj, UiButtonArgs args) {
45 Arg xargs[
16];
46 int n =
0;
47
48 UiContainerPrivate *ctn = ui_obj_container(obj);
49 UI_APPLY_LAYOUT(ctn->layout, args);
50
51 Widget parent = ctn->prepare(ctn, xargs, &n);
52
53 XmString label =
NULL;
54 if(args.label) {
55 label = XmStringCreateLocalized((
char*)args.label);
56 XtSetArg(xargs[n], XmNlabelString, label); n++;
57 }
58
59 char *name = args.name ? (
char*)args.name :
"button";
60 Widget button = XmCreatePushButton(parent, name, xargs, n);
61 XtManageChild(button);
62 ctn->add(ctn, button);
63
64 ui_set_widget_groups(obj->ctx, button, args.groups);
65
66 if(args.onclick) {
67 UiEventData *eventdata = malloc(
sizeof(UiEventData));
68 eventdata->callback = args.onclick;
69 eventdata->userdata = args.onclickdata;
70 eventdata->obj = obj;
71 eventdata->value =
0;
72 XtAddCallback(
73 button,
74 XmNactivateCallback,
75 (XtCallbackProc)ui_push_button_callback,
76 eventdata);
77 XtAddCallback(
78 button,
79 XmNdestroyCallback,
80 (XtCallbackProc)ui_destroy_eventdata,
81 eventdata);
82 }
83
84
85 XmStringFree(label);
86 return button;
87 }
88
89 void ui_push_button_callback(Widget widget, UiEventData *event, XtPointer d) {
90 UiEvent e;
91 e.obj = event->obj;
92 e.window = event->obj->window;
93 e.document = event->obj->ctx->document;
94 e.intval = event->value;
95 event->callback(&e, event->userdata);
96 }
97
98 UIWIDGET ui_togglebutton_create(UiObject* obj, UiToggleArgs args) {
99 Arg xargs[
16];
100 int n =
0;
101
102 UiContainerPrivate *ctn = ui_obj_container(obj);
103 UI_APPLY_LAYOUT(ctn->layout, args);
104
105 Widget parent = ctn->prepare(ctn, xargs, &n);
106 XtSetArg(xargs[n], XmNfillOnSelect, True); n++;
107 XtSetArg(xargs[n], XmNindicatorOn, False); n++;
108
109 XmString label =
NULL;
110 if(args.label) {
111 label = XmStringCreateLocalized((
char*)args.label);
112 XtSetArg(xargs[n], XmNlabelString, label); n++;
113 }
114
115 char *name = args.name ? (
char*)args.name :
"togglebutton";
116 Widget button = XmCreateToggleButton(parent, name, xargs, n);
117 XtManageChild(button);
118 ctn->add(ctn, button);
119
120 ui_set_widget_groups(obj->ctx, button, args.groups);
121
122 ui_bind_togglebutton(obj, button, args.varname, args.value, args.onchange, args.onchangedata, args.enable_group);
123
124 XmStringFree(label);
125 return button;
126 }
127
128 UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) {
129 Arg xargs[
16];
130 int n =
0;
131
132 UiContainerPrivate *ctn = ui_obj_container(obj);
133 UI_APPLY_LAYOUT(ctn->layout, args);
134
135 Widget parent = ctn->prepare(ctn, xargs, &n);
136
137 XmString label =
NULL;
138 if(args.label) {
139 label = XmStringCreateLocalized((
char*)args.label);
140 XtSetArg(xargs[n], XmNlabelString, label); n++;
141 }
142
143 char *name = args.name ? (
char*)args.name :
"button";
144 Widget button = XmCreateToggleButton(parent, name, xargs, n);
145 XtManageChild(button);
146 ctn->add(ctn, button);
147
148 ui_set_widget_groups(obj->ctx, button, args.groups);
149
150 ui_bind_togglebutton(obj, button, args.varname, args.value, args.onchange, args.onchangedata, args.enable_group);
151
152 XmStringFree(label);
153 return button;
154 }
155
156 UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs args) {
157 return ui_checkbox_create(obj, args);
158 }
159
160 static void togglebutton_changed(Widget w, UiVarEventData *event, XmToggleButtonCallbackStruct *tb) {
161 if(event->value >
0) {
162
163 if(tb->set) {
164 ui_set_group(event->obj->ctx, event->value);
165 }
else {
166 ui_unset_group(event->obj->ctx, event->value);
167 }
168 }
169
170 UiEvent e;
171 e.obj = event->obj;
172 e.window = e.obj->window;
173 e.document = e.obj->ctx->document;
174 e.eventdata =
NULL;
175 e.intval = XmToggleButtonGetState(w);
176
177 if(event->callback) {
178 event->callback(&e, event->userdata);
179 }
180
181 if(event->var && event->var->value) {
182 UiInteger *v = event->var->value;
183 v->value = e.intval;
184 ui_notify_evt(v->observers, &e);
185 }
186 }
187
188 void ui_bind_togglebutton(
189 UiObject *obj,
190 Widget widget,
191 const char *varname,
192 UiInteger *value,
193 ui_callback onchange,
194 void *onchangedata,
195 int enable_state)
196 {
197 UiVar* var = uic_widget_var(obj->ctx, obj->ctx, value, varname,
UI_VAR_INTEGER);
198 if(var) {
199 value = (UiInteger*)var->value;
200 value->obj = widget;
201 value->get = ui_togglebutton_get;
202 value->set = ui_togglebutton_set;
203
204 if(value->value) {
205 XmToggleButtonSetState(widget, True, False);
206 }
207 }
208
209 UiVarEventData *event = malloc(
sizeof(UiVarEventData));
210 event->obj = obj;
211 event->callback = onchange;
212 event->userdata = onchangedata;
213 event->var = var;
214 event->observers =
NULL;
215 event->value = enable_state;
216 XtAddCallback(
217 widget,
218 XmNvalueChangedCallback,
219 (XtCallbackProc)togglebutton_changed,
220 event);
221 XtAddCallback(
222 widget,
223 XmNdestroyCallback,
224 (XtCallbackProc)ui_destroy_eventdata,
225 event);
226 }
227
228 int64_t ui_togglebutton_get(UiInteger *i) {
229 Widget togglebutton = i->obj;
230 Boolean state = XmToggleButtonGetState(togglebutton);
231 i->value = state;
232 return state;
233 }
234
235 void ui_togglebutton_set(UiInteger *i,
int64_t value) {
236 Widget togglebutton = i->obj;
237 i->value = value;
238 XmToggleButtonSetState(togglebutton, (Boolean)value, False);
239 }
240
241 static void destroy_list(Widget w, CxList *list, XtPointer d) {
242 cxListFree(list);
243 }
244
245 static void radiobutton_changed(Widget w, UiVarEventData *event, XmToggleButtonCallbackStruct *tb) {
246 if(event->value >
0) {
247
248 if(tb->set) {
249 ui_set_group(event->obj->ctx, event->value);
250 }
else {
251 ui_unset_group(event->obj->ctx, event->value);
252 }
253 }
254
255 if(!tb->set) {
256 return;
257 }
258
259 UiInteger *value =
NULL;
260 int64_t v =
0;
261 if(event->var) {
262 value = event->var->value;
263
264
265 CxList *list = value->obj;
266 CxIterator i = cxListIterator(list);
267 cx_foreach(Widget, button, i) {
268 Boolean state = False;
269 if(button == w) {
270 value->value = i.index+
1;
271 state = True;
272 }
273 XmToggleButtonSetState(button, state, False);
274 }
275 v = value->value;
276 }
277
278 UiEvent e;
279 e.obj = event->obj;
280 e.window = e.obj->window;
281 e.document = e.obj->ctx->document;
282 e.eventdata = value;
283 e.intval = v;
284
285 if(event->callback) {
286 event->callback(&e, event->userdata);
287 }
288
289 if(value) {
290 ui_notify_evt(value->observers, &e);
291 }
292 }
293
294 void ui_bind_radiobutton(UiObject *obj, Widget rbutton, UiInteger *value,
const char *varname, ui_callback onchange,
void *onchangedata,
int enable_group) {
295 UiVar* var = uic_widget_var(obj->ctx, obj->ctx, value, varname,
UI_VAR_INTEGER);
296 if(var) {
297 UiInteger *value = var->value;
298 CxList *rb = value->obj;
299 if(!rb) {
300
301
302 rb = cxArrayListCreateSimple(
CX_STORE_POINTERS,
4);
303 value->obj = rb;
304 value->get = ui_radiobutton_get;
305 value->set = ui_radiobutton_set;
306
307
308 XtAddCallback(
309 rbutton,
310 XmNdestroyCallback,
311 (XtCallbackProc)destroy_list,
312 rb);
313 }
314 cxListAdd(rb, rbutton);
315
316
317 if(cxListSize(rb) == value->value) {
318 XmToggleButtonSetState(rbutton, True, False);
319 }
320 }
321
322
323
324 UiVarEventData *event = malloc(
sizeof(UiVarEventData));
325 event->obj = obj;
326 event->callback = onchange;
327 event->userdata = onchangedata;
328 event->observers =
NULL;
329 event->var = var;
330 event->value = enable_group;
331 XtAddCallback(
332 rbutton,
333 XmNvalueChangedCallback,
334 (XtCallbackProc)radiobutton_changed,
335 event);
336 XtAddCallback(
337 rbutton,
338 XmNdestroyCallback,
339 (XtCallbackProc)ui_destroy_eventdata,
340 event);
341 }
342
343 UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs args) {
344 Arg xargs[
16];
345 int n =
0;
346
347 UiContainerPrivate *ctn = ui_obj_container(obj);
348 UI_APPLY_LAYOUT(ctn->layout, args);
349
350 Widget parent = ctn->prepare(ctn, xargs, &n);
351 XtSetArg(xargs[n], XmNindicatorType, XmONE_OF_MANY_ROUND); n++;
352 XmString label =
NULL;
353 if(args.label) {
354 label = XmStringCreateLocalized((
char*)args.label);
355 XtSetArg(xargs[n], XmNlabelString, label); n++;
356 }
357
358 char *name = args.name ? (
char*)args.name :
"button";
359 Widget button = XmCreateToggleButton(parent, name, xargs, n);
360 XtManageChild(button);
361 ctn->add(ctn, button);
362
363 ui_set_widget_groups(obj->ctx, button, args.groups);
364
365 UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname,
UI_VAR_INTEGER);
366 if(var) {
367 UiInteger *value = var->value;
368 CxList *rb = value->obj;
369 if(!rb) {
370
371
372 rb = cxArrayListCreateSimple(
CX_STORE_POINTERS,
4);
373 value->obj = rb;
374 value->get = ui_radiobutton_get;
375 value->set = ui_radiobutton_set;
376
377
378 XtAddCallback(
379 button,
380 XmNdestroyCallback,
381 (XtCallbackProc)destroy_list,
382 rb);
383 }
384 cxListAdd(rb, button);
385
386
387 if(cxListSize(rb) == value->value) {
388 XmToggleButtonSetState(button, True, False);
389 }
390 }
391
392
393
394 UiVarEventData *event = malloc(
sizeof(UiVarEventData));
395 event->obj = obj;
396 event->callback = args.onchange;
397 event->userdata = args.onchangedata;
398 event->observers =
NULL;
399 event->var = var;
400 event->value = args.enable_group;
401 XtAddCallback(
402 button,
403 XmNvalueChangedCallback,
404 (XtCallbackProc)radiobutton_changed,
405 event);
406 XtAddCallback(
407 button,
408 XmNdestroyCallback,
409 (XtCallbackProc)ui_destroy_eventdata,
410 event);
411
412 XmStringFree(label);
413 return button;
414
415
416 }
417
418 int64_t ui_radiobutton_get(UiInteger *i) {
419
420 return i->value;
421 }
422
423 void ui_radiobutton_set(UiInteger *i,
int64_t value) {
424 CxList *list = i->obj;
425 if(i->value >
0) {
426 Widget current = cxListAt(list, i->value-
1);
427 if(current) {
428 XmToggleButtonSetState(current, False, False);
429 }
430 }
431 if(value >
0 && value <= cxListSize(list)) {
432 Widget button = cxListAt(list, value-
1);
433 if(button) {
434 XmToggleButtonSetState(button, True, False);
435 i->value = value;
436 }
437 }
438 }
439