34 #include "button.h" |
34 #include "button.h" |
35 #include "toolkit.h" |
35 #include "toolkit.h" |
36 #include "stock.h" |
36 #include "stock.h" |
37 #include "container.h" |
37 #include "container.h" |
38 #include "../common/context.h" |
38 #include "../common/context.h" |
|
39 #include "../common/menu.h" |
|
40 #include "../common/types.h" |
39 #include "../ui/window.h" |
41 #include "../ui/window.h" |
40 |
42 |
41 UcxList *menus; |
43 #include <cx/linked_list.h> |
42 UcxList *current; |
44 #include <cx/array_list.h> |
43 |
45 |
44 void ui_menu(char *label) { |
46 |
45 // free current menu hierarchy |
47 static ui_menu_add_f createMenuItem[] = { |
46 ucx_list_free(current); |
48 /* UI_MENU */ add_menu_widget, |
47 |
49 /* UI_MENU_ITEM */ add_menuitem_widget, |
48 // create menu |
50 /* UI_MENU_CHECK_ITEM */ add_checkitem_widget, |
49 UiMenu *menu = malloc(sizeof(UiMenu)); |
51 /* UI_MENU_RADIO_ITEM */ add_radioitem_widget, |
50 menu->item.add_to = (ui_menu_add_f)add_menu_widget; |
52 /* UI_MENU_ITEM_LIST */ add_menuitem_list_widget, |
51 |
53 /* UI_MENU_CHECKITEM_LIST */ add_menuitem_list_widget, |
52 menu->label = label; |
54 /* UI_MENU_RADIOITEM_LIST */ add_menuitem_list_widget, |
53 menu->items = NULL; |
55 /* UI_MENU_SEPARATOR */ add_menuseparator_widget |
54 menu->parent = NULL; |
56 }; |
55 |
57 |
56 current = ucx_list_prepend(NULL, menu); |
58 void ui_create_menubar(UiObject *obj, Widget window) { |
57 menus = ucx_list_append(menus, menu); |
59 UiMenu *menus_begin = uic_get_menu_list(); |
58 |
60 if(!menus_begin) { |
59 } |
|
60 |
|
61 void ui_submenu(char *label) { |
|
62 UiMenu *menu = malloc(sizeof(UiMenu)); |
|
63 menu->item.add_to = (ui_menu_add_f)add_menu_widget; |
|
64 |
|
65 menu->label = label; |
|
66 menu->items = NULL; |
|
67 menu->parent = NULL; |
|
68 |
|
69 // add submenu to current menu |
|
70 UiMenu *cm = current->data; |
|
71 cm->items = ucx_list_append(cm->items, menu); |
|
72 |
|
73 // set the submenu to current menu |
|
74 current = ucx_list_prepend(current, menu); |
|
75 } |
|
76 |
|
77 void ui_submenu_end() { |
|
78 if(ucx_list_size(current) < 2) { |
|
79 return; |
61 return; |
80 } |
62 } |
81 current = ucx_list_remove(current, current); |
63 |
82 } |
64 Widget menubar = XmCreateMenuBar(window, "menubar", NULL, 0); |
83 |
|
84 void ui_menuitem(char *label, ui_callback f, void *userdata) { |
|
85 ui_menuitem_gr(label, f, userdata, -1); |
|
86 } |
|
87 |
|
88 void ui_menuitem_st(char *stockid, ui_callback f, void *userdata) { |
|
89 ui_menuitem_stgr(stockid, f, userdata, -1); |
|
90 } |
|
91 |
|
92 void ui_menuitem_gr(char *label, ui_callback f, void *userdata, ...) { |
|
93 if(!current) { |
|
94 return; |
|
95 } |
|
96 |
|
97 UiMenuItem *item = malloc(sizeof(UiMenuItem)); |
|
98 item->item.add_to = (ui_menu_add_f)add_menuitem_widget; |
|
99 |
|
100 item->label = label; |
|
101 item->userdata = userdata; |
|
102 item->callback = f; |
|
103 item->groups = NULL; |
|
104 |
|
105 // add groups |
|
106 va_list ap; |
|
107 va_start(ap, userdata); |
|
108 int group; |
|
109 while((group = va_arg(ap, int)) != -1) { |
|
110 item->groups = ucx_list_append(item->groups, (void*)(intptr_t)group); |
|
111 } |
|
112 va_end(ap); |
|
113 |
|
114 UiMenu *cm = current->data; |
|
115 cm->items = ucx_list_append(cm->items, item); |
|
116 } |
|
117 |
|
118 void ui_menuitem_stgr(char *stockid, ui_callback f, void *userdata, ...) { |
|
119 if(!current) { |
|
120 return; |
|
121 } |
|
122 |
|
123 UiStMenuItem *item = malloc(sizeof(UiStMenuItem)); |
|
124 item->item.add_to = (ui_menu_add_f)add_menuitem_st_widget; |
|
125 |
|
126 item->stockid = stockid; |
|
127 item->userdata = userdata; |
|
128 item->callback = f; |
|
129 item->groups = NULL; |
|
130 |
|
131 // add groups |
|
132 va_list ap; |
|
133 va_start(ap, userdata); |
|
134 int group; |
|
135 while((group = va_arg(ap, int)) != -1) { |
|
136 item->groups = ucx_list_append(item->groups, (void*)(intptr_t)group); |
|
137 } |
|
138 va_end(ap); |
|
139 |
|
140 UiMenu *cm = current->data; |
|
141 cm->items = ucx_list_append(cm->items, item); |
|
142 } |
|
143 |
|
144 void ui_menuseparator() { |
|
145 if(!current) { |
|
146 return; |
|
147 } |
|
148 |
|
149 UiMenuItemI *item = malloc(sizeof(UiMenuItemI)); |
|
150 item->add_to = (ui_menu_add_f)add_menuseparator_widget; |
|
151 |
|
152 UiMenu *cm = current->data; |
|
153 cm->items = ucx_list_append(cm->items, item); |
|
154 } |
|
155 |
|
156 |
|
157 void ui_checkitem(char *label, ui_callback f, void *userdata) { |
|
158 if(!current) { |
|
159 return; |
|
160 } |
|
161 |
|
162 UiCheckItem *item = malloc(sizeof(UiCheckItem)); |
|
163 item->item.add_to = (ui_menu_add_f)add_checkitem_widget; |
|
164 item->label = label; |
|
165 item->callback = f; |
|
166 item->userdata = userdata; |
|
167 |
|
168 UiMenu *cm = current->data; |
|
169 cm->items = ucx_list_append(cm->items, item); |
|
170 } |
|
171 |
|
172 void ui_checkitem_nv(char *label, char *vname) { |
|
173 if(!current) { |
|
174 return; |
|
175 } |
|
176 |
|
177 UiCheckItemNV *item = malloc(sizeof(UiCheckItemNV)); |
|
178 item->item.add_to = (ui_menu_add_f)add_checkitemnv_widget; |
|
179 item->varname = vname; |
|
180 item->label = label; |
|
181 |
|
182 UiMenu *cm = current->data; |
|
183 cm->items = ucx_list_append(cm->items, item); |
|
184 } |
|
185 |
|
186 void ui_menuitem_list(UiList *items, ui_callback f, void *userdata) { |
|
187 if(!current) { |
|
188 return; |
|
189 } |
|
190 |
|
191 UiMenuItemList *item = malloc(sizeof(UiMenuItemList)); |
|
192 item->item.add_to = (ui_menu_add_f)add_menuitem_list_widget; |
|
193 item->callback = f; |
|
194 item->userdata = userdata; |
|
195 item->list = items; |
|
196 |
|
197 UiMenu *cm = current->data; |
|
198 cm->items = ucx_list_append(cm->items, item); |
|
199 } |
|
200 |
|
201 |
|
202 // private menu functions |
|
203 void ui_create_menubar(UiObject *obj) { |
|
204 if(!menus) { |
|
205 return; |
|
206 } |
|
207 |
|
208 Widget menubar = XmCreateMenuBar(obj->widget, "main_list", NULL, 0); |
|
209 XtManageChild(menubar); |
65 XtManageChild(menubar); |
210 |
66 |
211 UcxList *ls = menus; |
67 UiMenu *ls = menus_begin; |
212 int menu_index = 0; |
|
213 while(ls) { |
68 while(ls) { |
214 UiMenu *menu = ls->data; |
69 UiMenu *menu = ls; |
215 menu_index += menu->item.add_to(menubar, menu_index, &menu->item, obj); |
70 add_menu_widget(menubar, 0, &menu->item, obj); |
216 |
71 ls = (UiMenu*)ls->item.next; |
217 ls = ls->next; |
72 } |
218 } |
73 } |
219 } |
74 |
220 |
75 void ui_add_menu_items(Widget parent, int i, UiMenu *menu, UiObject *obj) { |
221 int add_menu_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj) { |
76 UiMenuItemI *it = menu->items_begin; |
|
77 int index = 0; |
|
78 while(it) { |
|
79 createMenuItem[it->type](parent, index, it, obj); |
|
80 it = it->next; |
|
81 index++; |
|
82 } |
|
83 } |
|
84 |
|
85 void add_menu_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj) { |
222 UiMenu *menu = (UiMenu*)item; |
86 UiMenu *menu = (UiMenu*)item; |
223 |
87 Arg args[4]; |
224 Widget menuItem = XtVaCreateManagedWidget( |
88 int n = 0; |
225 menu->label, |
89 |
|
90 XmString s = NULL; |
|
91 if(menu->label) { |
|
92 s = XmStringCreateLocalized((char*)menu->label); |
|
93 XtSetArg(args[n], XmNlabelString, s); n++; |
|
94 } |
|
95 |
|
96 Widget submenu = XmVaCreateSimplePulldownMenu(parent, "menu_pulldown", i, NULL, NULL); |
|
97 XtSetArg(args[n], XmNsubMenuId, submenu); n++; |
|
98 Widget menuItem = XtCreateManagedWidget( |
|
99 "menuitem", |
226 xmCascadeButtonWidgetClass, |
100 xmCascadeButtonWidgetClass, |
227 parent, |
101 parent, |
228 NULL); |
|
229 Widget m = XmVaCreateSimplePulldownMenu(parent, menu->label, i, NULL, NULL); |
|
230 |
|
231 UcxList *ls = menu->items; |
|
232 int menu_index = 0; |
|
233 while(ls) { |
|
234 UiMenuItemI *mi = ls->data; |
|
235 menu_index += mi->add_to(m, menu_index, mi, obj); |
|
236 ls = ls->next; |
|
237 } |
|
238 |
|
239 return 1; |
|
240 } |
|
241 |
|
242 int add_menuitem_widget( |
|
243 Widget parent, |
|
244 int i, |
|
245 UiMenuItemI *item, |
|
246 UiObject *obj) |
|
247 { |
|
248 UiMenuItem *mi = (UiMenuItem*)item; |
|
249 |
|
250 Arg args[1]; |
|
251 XmString label = XmStringCreateLocalized(mi->label); |
|
252 XtSetArg(args[0], XmNlabelString, label); |
|
253 |
|
254 Widget mitem = XtCreateManagedWidget( |
|
255 "menubutton", |
|
256 xmPushButtonWidgetClass, |
|
257 parent, |
|
258 args, |
102 args, |
259 1); |
103 n); |
260 XmStringFree(label); |
104 |
261 |
105 |
262 if(mi->callback != NULL) { |
106 if(s) { |
263 UiEventData *event = ucx_mempool_malloc( |
107 XmStringFree(s); |
264 obj->ctx->mempool, |
108 } |
265 sizeof(UiEventData)); |
109 |
266 event->obj = obj; |
110 ui_add_menu_items(submenu, i, menu, obj); |
267 event->userdata = mi->userdata; |
111 } |
268 event->callback = mi->callback; |
112 |
269 event->value = 0; |
113 void add_menuitem_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj) { |
270 XtAddCallback( |
114 UiMenuItem *it = (UiMenuItem*)item; |
271 mitem, |
115 |
272 XmNactivateCallback, |
116 XmString s = NULL; |
273 (XtCallbackProc)ui_push_button_callback, |
117 Arg args[4]; |
274 event); |
|
275 } |
|
276 |
|
277 if(mi->groups) { |
|
278 uic_add_group_widget(obj->ctx, mitem, (ui_enablefunc)XtSetSensitive, mi->groups); |
|
279 } |
|
280 |
|
281 return 1; |
|
282 } |
|
283 |
|
284 int add_menuitem_st_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj) { |
|
285 UiStMenuItem *mi = (UiStMenuItem*)item; |
|
286 |
|
287 UiStockItem *si = ui_get_stock_item(mi->stockid); |
|
288 if(!si) { |
|
289 fprintf(stderr, "UI Error: unknown stock id: %s\n", mi->stockid); |
|
290 return 0; |
|
291 } |
|
292 |
|
293 int n = 0; |
118 int n = 0; |
294 Arg args[4]; |
119 if(it->label) { |
295 XmString label = XmStringCreateLocalized(si->label); |
120 s = XmStringCreateLocalized((char*)it->label); |
296 XmString at = NULL; |
121 XtSetArg(args[n], XmNlabelString, s); n++; |
297 |
|
298 XtSetArg(args[n], XmNlabelString, label); |
|
299 n++; |
|
300 if(si->accelerator) { |
|
301 XtSetArg(args[n], XmNaccelerator, si->accelerator); |
|
302 n++; |
|
303 } |
|
304 if(si->accelerator_label) { |
|
305 at = XmStringCreateLocalized(si->accelerator_label); |
|
306 XtSetArg(args[n], XmNacceleratorText, at); |
|
307 n++; |
|
308 } |
122 } |
309 |
123 |
310 Widget mitem = XtCreateManagedWidget( |
124 Widget mitem = XtCreateManagedWidget( |
311 "menubutton", |
125 "menubutton", |
312 xmPushButtonWidgetClass, |
126 xmPushButtonWidgetClass, |
313 parent, |
127 parent, |
314 args, |
128 args, |
315 n); |
129 n); |
316 XmStringFree(label); |
130 if(s) { |
317 if(at) { |
131 XmStringFree(s); |
318 XmStringFree(at); |
132 } |
319 } |
133 |
320 |
134 if(it->callback) { |
321 if(mi->callback != NULL) { |
135 UiEventData *eventdata = malloc(sizeof(UiEventData)); |
322 UiEventData *event = ucx_mempool_malloc( |
136 eventdata->callback = it->callback; |
323 obj->ctx->mempool, |
137 eventdata->userdata = it->userdata; |
324 sizeof(UiEventData)); |
138 eventdata->obj = obj; |
325 event->obj = obj; |
139 eventdata->value = 0; |
326 event->userdata = mi->userdata; |
|
327 event->callback = mi->callback; |
|
328 event->value = 0; |
|
329 XtAddCallback( |
140 XtAddCallback( |
330 mitem, |
141 mitem, |
331 XmNactivateCallback, |
142 XmNactivateCallback, |
332 (XtCallbackProc)ui_push_button_callback, |
143 (XtCallbackProc)ui_push_button_callback, |
333 event); |
144 eventdata); |
334 } |
145 XtAddCallback( |
335 |
146 mitem, |
336 if(mi->groups) { |
147 XmNdestroyCallback, |
337 uic_add_group_widget(obj->ctx, mitem, (ui_enablefunc)XtSetSensitive, mi->groups); |
148 (XtCallbackProc)ui_destroy_eventdata, |
338 } |
149 eventdata); |
339 |
150 } |
340 return 1; |
151 |
341 } |
152 ui_set_widget_groups(obj->ctx, mitem, it->groups); |
342 |
153 } |
343 int add_menuseparator_widget( |
154 |
344 Widget parent, |
155 void add_menuseparator_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj) { |
345 int i, |
156 Widget s = XmCreateSeparatorGadget (p, "menuseparator", NULL, 0); |
346 UiMenuItemI *item, |
|
347 UiObject *obj) |
|
348 { |
|
349 Widget s = XmCreateSeparatorGadget (parent, "menu_separator", NULL, 0); |
|
350 XtManageChild(s); |
157 XtManageChild(s); |
351 return 1; |
158 } |
352 } |
159 |
353 |
160 void add_checkitem_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj) { |
354 int add_checkitem_widget( |
161 UiMenuCheckItem *it = (UiMenuCheckItem*)item; |
355 Widget parent, |
162 |
356 int i, |
163 Arg args[4]; |
357 UiMenuItemI *item, |
164 int n = 0; |
358 UiObject *obj) |
165 XmString s = NULL; |
359 { |
166 if(it->label) { |
360 UiCheckItem *ci = (UiCheckItem*)item; |
167 s = XmStringCreateLocalized(it->label); |
361 |
168 XtSetArg(args[n], XmNlabelString, s); n++; |
362 Arg args[3]; |
169 } |
363 XmString label = XmStringCreateLocalized(ci->label); |
170 |
364 XtSetArg(args[0], XmNlabelString, label); |
171 //XtSetArg(args[n], XmNvisibleWhenOff, 0); n++; |
365 XtSetArg(args[1], XmNvisibleWhenOff, 1); |
|
366 Widget checkbox = XtCreateManagedWidget( |
172 Widget checkbox = XtCreateManagedWidget( |
367 "menutogglebutton", |
173 "menutogglebutton", |
368 xmToggleButtonWidgetClass, |
174 xmToggleButtonWidgetClass, |
369 parent, |
175 p, |
370 args, |
176 args, |
371 2); |
177 n); |
372 XmStringFree(label); |
178 if(s) { |
373 |
179 XmStringFree(s); |
374 if(ci->callback) { |
180 } |
375 UiEventData *event = ucx_mempool_malloc( |
181 |
376 obj->ctx->mempool, |
182 ui_bind_togglebutton(obj, checkbox, it->varname, NULL, it->callback, it->userdata, 0); |
377 sizeof(UiEventData)); |
183 |
378 event->obj = obj; |
184 ui_set_widget_groups(obj->ctx, checkbox, it->groups); |
379 event->userdata = ci->userdata; |
185 } |
380 event->callback = ci->callback; |
186 |
381 XtAddCallback( |
187 void add_radioitem_widget(Widget p, int index, UiMenuItemI *item, UiObject *obj) { |
382 checkbox, |
188 UiMenuRadioItem *it = (UiMenuRadioItem*)item; |
383 XmNvalueChangedCallback, |
189 |
384 (XtCallbackProc)ui_toggle_button_callback, |
190 Arg args[4]; |
385 event); |
191 int n = 0; |
386 } |
192 XmString s = NULL; |
387 |
193 if(it->label) { |
388 return 1; |
194 s = XmStringCreateLocalized(it->label); |
389 } |
195 XtSetArg(args[n], XmNlabelString, s); n++; |
390 |
196 } |
391 int add_checkitemnv_widget( |
197 XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY_ROUND); n++; |
392 Widget parent, |
198 |
393 int i, |
199 Widget button = XmCreateToggleButton(p, "menuradiobutton", args, n); |
394 UiMenuItemI *item, |
200 XtManageChild(button); |
395 UiObject *obj) |
201 |
396 { |
202 ui_bind_radiobutton(obj, button, NULL, it->varname, it->callback, it->userdata, 0); |
397 UiCheckItemNV *ci = (UiCheckItemNV*)item; |
203 } |
398 |
204 |
399 Arg args[3]; |
205 void add_menuitem_list_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj) { |
400 XmString label = XmStringCreateLocalized(ci->label); |
|
401 XtSetArg(args[0], XmNlabelString, label); |
|
402 XtSetArg(args[1], XmNvisibleWhenOff, 1); |
|
403 Widget checkbox = XtCreateManagedWidget( |
|
404 "menutogglebutton", |
|
405 xmToggleButtonWidgetClass, |
|
406 parent, |
|
407 args, |
|
408 2); |
|
409 XmStringFree(label); |
|
410 |
|
411 UiVar *var = uic_create_var(obj->ctx, ci->varname, UI_VAR_INTEGER); |
|
412 if(var) { |
|
413 UiInteger *value = var->value; |
|
414 value->obj = checkbox; |
|
415 value->get = ui_toggle_button_get; |
|
416 value->set = ui_toggle_button_set; |
|
417 value = 0; |
|
418 } else { |
|
419 // TODO: error |
|
420 } |
|
421 |
|
422 return 1; |
|
423 } |
|
424 |
|
425 int add_menuitem_list_widget( |
|
426 Widget parent, |
|
427 int i, |
|
428 UiMenuItemI *item, |
|
429 UiObject *obj) |
|
430 { |
|
431 UiMenuItemList *il = (UiMenuItemList*)item; |
206 UiMenuItemList *il = (UiMenuItemList*)item; |
432 UcxMempool *mp = obj->ctx->mempool; |
207 const CxAllocator *a = obj->ctx->allocator; |
433 |
208 |
434 UiActiveMenuItemList *ls = ucx_mempool_malloc( |
209 UiActiveMenuItemList *ls = cxMalloc( |
435 mp, |
210 a, |
436 sizeof(UiActiveMenuItemList)); |
211 sizeof(UiActiveMenuItemList)); |
437 |
|
438 ls->object = obj; |
212 ls->object = obj; |
439 ls->menu = parent; |
213 ls->menu = p; |
440 ls->index = i; |
214 ls->index = i; |
441 ls->oldcount = 0; |
215 ls->oldcount = 0; |
442 ls->list = il->list; |
216 ls->getvalue = il->getvalue; |
443 ls->callback = il->callback; |
217 ls->callback = il->callback; |
444 ls->userdata = il->userdata; |
218 ls->userdata = il->userdata; |
445 |
219 ls->addseparator = il->addseparator; |
446 ls->list->observers = ui_add_observer( |
220 |
447 ls->list->observers, |
221 ls->var = uic_create_var(ui_global_context(), il->varname, UI_VAR_LIST); //uic_widget_var(obj->ctx, obj->ctx, NULL, il->varname, UI_VAR_LIST); |
448 (ui_callback)ui_update_menuitem_list, |
222 UiList *list = ls->var->value; |
449 ls); |
223 |
|
224 UiObserver *observer = ui_observer_new((ui_callback)ui_update_menuitem_list, ls); |
|
225 list->observers = ui_obsvlist_add(list->observers, observer); |
|
226 uic_list_register_observer_destructor(obj->ctx, list, observer); |
450 |
227 |
451 ui_update_menuitem_list(NULL, ls); |
228 ui_update_menuitem_list(NULL, ls); |
452 |
|
453 return 0; |
|
454 } |
229 } |
455 |
230 |
456 void ui_update_menuitem_list(UiEvent *event, UiActiveMenuItemList *list) { |
231 void ui_update_menuitem_list(UiEvent *event, UiActiveMenuItemList *list) { |
457 Arg args[4]; |
232 XmString s = NULL; |
458 |
233 Arg args[4]; |
459 // remove old items |
234 int n; |
|
235 |
|
236 UiList *ls; |
|
237 if(list->var && list->var->value) { |
|
238 ls = list->var->value; |
|
239 } else { |
|
240 return; |
|
241 } |
|
242 |
460 if(list->oldcount > 0) { |
243 if(list->oldcount > 0) { |
461 Widget *children; |
244 Widget *children; |
462 int nc; |
245 int nc; |
463 |
246 |
464 XtVaGetValues( |
247 XtVaGetValues( |
472 for(int i=0;i<list->oldcount;i++) { |
255 for(int i=0;i<list->oldcount;i++) { |
473 XtDestroyWidget(children[list->index + i]); |
256 XtDestroyWidget(children[list->index + i]); |
474 } |
257 } |
475 } |
258 } |
476 |
259 |
477 char *str = ui_list_first(list->list); |
260 void* elm = ui_list_first(ls); |
478 if(str) { |
261 int i = 0; |
479 // add separator |
262 if(elm && list->addseparator) { |
480 XtSetArg(args[0], XmNpositionIndex, list->index); |
263 XtSetArg(args[0], XmNpositionIndex, list->index); |
481 Widget s = XmCreateSeparatorGadget (list->menu, "menu_separator", args, 1); |
264 Widget s = XmCreateSeparatorGadget(list->menu, "menuseparator", args, 1); |
482 XtManageChild(s); |
265 XtManageChild(s); |
483 } |
266 i++; |
484 int i = 1; |
267 } |
485 while(str) { |
268 |
486 XmString label = XmStringCreateLocalized(str); |
269 ui_getvaluefunc getvalue = list->getvalue; |
487 XtSetArg(args[0], XmNlabelString, label); |
270 int pos = list->index; |
488 XtSetArg(args[1], XmNpositionIndex, list->index + i); |
271 while(elm) { |
489 |
272 n = 0; |
|
273 char *label = (char*) (getvalue ? getvalue(elm, 0) : elm); |
|
274 if(label) { |
|
275 s = XmStringCreateLocalized(label); |
|
276 XtSetArg(args[n], XmNlabelString, s); n++; |
|
277 } |
|
278 XtSetArg(args[n], XmNpositionIndex, pos+i); n++; |
|
279 |
490 Widget mitem = XtCreateManagedWidget( |
280 Widget mitem = XtCreateManagedWidget( |
491 "menubutton", |
281 "menubutton", |
492 xmPushButtonWidgetClass, |
282 xmPushButtonWidgetClass, |
493 list->menu, |
283 list->menu, |
494 args, |
284 args, |
495 2); |
285 n); |
496 XmStringFree(label); |
286 if(s) { |
497 |
287 XmStringFree(s); |
|
288 } |
|
289 |
498 if(list->callback) { |
290 if(list->callback) { |
499 // TODO: use mempool |
291 UiEventData *eventdata = malloc(sizeof(UiEventData)); |
500 UiEventData *event = malloc(sizeof(UiEventData)); |
292 eventdata->callback = list->callback; |
501 event->obj = list->object; |
293 eventdata->userdata = list->userdata; |
502 event->userdata = list->userdata; |
294 eventdata->obj = list->object; |
503 event->callback = list->callback; |
295 eventdata->value = 0; |
504 event->value = i - 1; |
|
505 |
|
506 XtAddCallback( |
296 XtAddCallback( |
507 mitem, |
297 mitem, |
508 XmNactivateCallback, |
298 XmNactivateCallback, |
509 (XtCallbackProc)ui_push_button_callback, |
299 (XtCallbackProc)ui_push_button_callback, |
510 event); |
300 eventdata); |
|
301 XtAddCallback( |
|
302 mitem, |
|
303 XmNdestroyCallback, |
|
304 (XtCallbackProc)ui_destroy_eventdata, |
|
305 eventdata); |
511 } |
306 } |
512 |
307 |
513 str = ui_list_next(list->list); |
308 elm = ui_list_next(ls); |
514 i++; |
309 i++; |
515 } |
310 } |
516 |
311 |
517 list->oldcount = i; |
312 list->oldcount = i; |
518 } |
313 } |
519 |
|
520 void ui_menu_event_wrapper(Widget widget, XtPointer udata, XtPointer cdata) { |
|
521 UiEventData *event = udata; |
|
522 UiEvent e; |
|
523 e.obj = event->obj; |
|
524 e.window = event->obj->window; |
|
525 e.document = event->obj->ctx->document; |
|
526 e.intval = 0; |
|
527 event->callback(&e, event->userdata); |
|
528 } |
|
529 |
|
530 |
|
531 /* |
|
532 * widget menu functions |
|
533 */ |
|
534 |
|
535 static void ui_popup_handler(Widget widget, XtPointer data, XEvent *event, Boolean *c) { |
|
536 Widget menu = data; |
|
537 XmMenuPosition(menu, (XButtonPressedEvent *)event); |
|
538 XtManageChild(menu); |
|
539 |
|
540 *c = FALSE; |
|
541 } |
|
542 |
|
543 UIMENU ui_contextmenu(UiObject *obj) { |
|
544 UiContainer *ct = uic_get_current_container(obj); |
|
545 if(ct->current) { |
|
546 return ui_contextmenu_w(obj, ct->current); |
|
547 } else { |
|
548 return NULL; // TODO: warn |
|
549 } |
|
550 } |
|
551 |
|
552 UIMENU ui_contextmenu_w(UiObject *obj, UIWIDGET widget) { |
|
553 UiContainer *ct = uic_get_current_container(obj); |
|
554 |
|
555 Widget menu = XmCreatePopupMenu(widget, "popup_menu", NULL, 0); |
|
556 ct->menu = menu; |
|
557 |
|
558 XtAddEventHandler(widget, ButtonPressMask, FALSE, ui_popup_handler, menu); |
|
559 |
|
560 return menu; |
|
561 } |
|
562 |
|
563 void ui_contextmenu_popup(UIMENU menu) { |
|
564 |
|
565 } |
|
566 |
|
567 void ui_widget_menuitem(UiObject *obj, char *label, ui_callback f, void *userdata) { |
|
568 ui_widget_menuitem_gr(obj, label, f, userdata, -1); |
|
569 } |
|
570 |
|
571 void ui_widget_menuitem_gr(UiObject *obj, char *label, ui_callback f, void *userdata, ...) { |
|
572 UiContainer *ct = uic_get_current_container(obj); |
|
573 if(!ct->menu) { |
|
574 return; |
|
575 } |
|
576 |
|
577 // add groups |
|
578 UcxList *groups = NULL; |
|
579 va_list ap; |
|
580 va_start(ap, userdata); |
|
581 int group; |
|
582 while((group = va_arg(ap, int)) != -1) { |
|
583 ucx_list_append(groups, (void*)(intptr_t)group); |
|
584 } |
|
585 va_end(ap); |
|
586 |
|
587 // create menuitem |
|
588 Arg args[4]; |
|
589 XmString labelstr = XmStringCreateLocalized(label); |
|
590 XtSetArg(args[0], XmNlabelString, labelstr); |
|
591 |
|
592 Widget item = XmCreatePushButton(ct->menu, "menu_button", args, 1); |
|
593 XtManageChild(item); |
|
594 XmStringFree(labelstr); |
|
595 } |
|
596 |
|
597 void ui_widget_menuitem_st(UiObject *obj, char *stockid, ui_callback f, void *userdata) { |
|
598 ui_widget_menuitem_stgr(obj, stockid, f, userdata, -1); |
|
599 } |
|
600 |
|
601 void ui_widget_menuitem_stgr(UiObject *obj, char *stockid, ui_callback f, void *userdata, ...) { |
|
602 UiContainer *ct = uic_get_current_container(obj); |
|
603 if(!ct->menu) { |
|
604 return; |
|
605 } |
|
606 |
|
607 // add groups |
|
608 UcxList *groups = NULL; |
|
609 va_list ap; |
|
610 va_start(ap, userdata); |
|
611 int group; |
|
612 while((group = va_arg(ap, int)) != -1) { |
|
613 ucx_list_append(groups, (void*)(intptr_t)group); |
|
614 } |
|
615 va_end(ap); |
|
616 |
|
617 // create menuitem |
|
618 UiStockItem *stockItem = ui_get_stock_item(stockid); |
|
619 Arg args[4]; |
|
620 XmString labelstr = XmStringCreateLocalized(stockItem->label); |
|
621 XtSetArg(args[0], XmNlabelString, labelstr); |
|
622 |
|
623 Widget item = XmCreatePushButton(ct->menu, "menu_button", args, 1); |
|
624 XtManageChild(item); |
|
625 XmStringFree(labelstr); |
|
626 } |
|