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 cxListDestroy(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 UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs args) {
295 Arg xargs[
16];
296 int n =
0;
297
298 UiContainerPrivate *ctn = ui_obj_container(obj);
299 UI_APPLY_LAYOUT(ctn->layout, args);
300
301 Widget parent = ctn->prepare(ctn, xargs, &n);
302 XtSetArg(xargs[n], XmNindicatorType, XmONE_OF_MANY_ROUND); n++;
303 XmString label =
NULL;
304 if(args.label) {
305 label = XmStringCreateLocalized((
char*)args.label);
306 XtSetArg(xargs[n], XmNlabelString, label); n++;
307 }
308
309 char *name = args.name ? (
char*)args.name :
"button";
310 Widget button = XmCreateToggleButton(parent, name, xargs, n);
311 XtManageChild(button);
312 ctn->add(ctn, button);
313
314 ui_set_widget_groups(obj->ctx, button, args.groups);
315
316 UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname,
UI_VAR_INTEGER);
317 if(var) {
318 UiInteger *value = var->value;
319 CxList *rb = value->obj;
320 if(!rb) {
321
322
323 rb = cxArrayListCreateSimple(
CX_STORE_POINTERS,
4);
324 value->obj = rb;
325 value->get = ui_radiobutton_get;
326 value->set = ui_radiobutton_set;
327
328
329 XtAddCallback(
330 button,
331 XmNdestroyCallback,
332 (XtCallbackProc)destroy_list,
333 rb);
334 }
335 cxListAdd(rb, button);
336
337
338 if(cxListSize(rb) == value->value) {
339 XmToggleButtonSetState(button, True, False);
340 }
341 }
342
343
344
345 UiVarEventData *event = malloc(
sizeof(UiVarEventData));
346 event->obj = obj;
347 event->callback = args.onchange;
348 event->userdata = args.onchangedata;
349 event->observers =
NULL;
350 event->var = var;
351 event->value = args.enable_group;
352 XtAddCallback(
353 button,
354 XmNvalueChangedCallback,
355 (XtCallbackProc)radiobutton_changed,
356 event);
357 XtAddCallback(
358 button,
359 XmNdestroyCallback,
360 (XtCallbackProc)ui_destroy_eventdata,
361 event);
362
363 XmStringFree(label);
364 return button;
365
366
367 }
368
369 int64_t ui_radiobutton_get(UiInteger *i) {
370
371 return i->value;
372 }
373
374 void ui_radiobutton_set(UiInteger *i,
int64_t value) {
375 CxList *list = i->obj;
376 if(i->value >
0) {
377 Widget current = cxListAt(list, i->value-
1);
378 if(current) {
379 XmToggleButtonSetState(current, False, False);
380 }
381 }
382 if(value >
0 && value <= cxListSize(list)) {
383 Widget button = cxListAt(list, value-
1);
384 if(button) {
385 XmToggleButtonSetState(button, True, False);
386 i->value = value;
387 }
388 }
389 }
390