ui/motif/menu.c

branch
newapi
changeset 176
bc63cb601f6d
parent 169
fe49cff3c571
equal deleted inserted replaced
175:2cb06c231057 176:bc63cb601f6d
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 "../ui/window.h" 39 #include "../ui/window.h"
40 40
41 UcxList *menus; 41 #include <cx/linked_list.h>
42 UcxList *current; 42 #include <cx/array_list.h>
43 43
44 void ui_menu(char *label) { 44 static ui_menu_add_f createMenuItem[] = {
45 // free current menu hierarchy 45 /* UI_MENU */ add_menu_widget,
46 ucx_list_free(current); 46 /* UI_MENU_SUBMENU */ add_menu_widget,
47 47 /* UI_MENU_ITEM */ add_menuitem_widget,
48 // create menu 48 /* UI_MENU_STOCK_ITEM */ add_menuitem_st_widget,
49 UiMenu *menu = malloc(sizeof(UiMenu)); 49 /* UI_MENU_CHECK_ITEM */ add_checkitem_widget,
50 menu->item.add_to = (ui_menu_add_f)add_menu_widget; 50 /* UI_MENU_CHECK_ITEM_NV */ add_checkitemnv_widget,
51 51 /* UI_MENU_ITEM_LIST */ add_menuitem_list_widget,
52 menu->label = label; 52 /* UI_MENU_ITEM_LIST_NV */ NULL, // TODO
53 menu->items = NULL; 53 /* UI_MENU_SEPARATOR */ add_menuseparator_widget
54 menu->parent = NULL; 54 };
55
56 current = ucx_list_prepend(NULL, menu);
57 menus = ucx_list_append(menus, menu);
58
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;
80 }
81 current = ucx_list_remove(current, current);
82 }
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 55
202 // private menu functions 56 // private menu functions
203 void ui_create_menubar(UiObject *obj) { 57 void ui_create_menubar(UiObject *obj) {
58 UiMenu *menus = uic_get_menu_list();
204 if(!menus) { 59 if(!menus) {
205 return; 60 return;
206 } 61 }
207 62
208 Widget menubar = XmCreateMenuBar(obj->widget, "main_list", NULL, 0); 63 Widget menubar = XmCreateMenuBar(obj->widget, "main_list", NULL, 0);
209 XtManageChild(menubar); 64 XtManageChild(menubar);
210 65
211 UcxList *ls = menus; 66 UiMenu *menu = menus;
212 int menu_index = 0; 67 int menu_index = 0;
213 while(ls) { 68 while(menu) {
214 UiMenu *menu = ls->data; 69 menu_index += add_menu_widget(menubar, menu_index, &menu->item, obj);
215 menu_index += menu->item.add_to(menubar, menu_index, &menu->item, obj);
216 70
217 ls = ls->next; 71 menu = (UiMenu*)menu->item.next;
218 } 72 }
219 } 73 }
220 74
221 int add_menu_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj) { 75 int add_menu_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj) {
222 UiMenu *menu = (UiMenu*)item; 76 UiMenu *menu = (UiMenu*)item;
226 xmCascadeButtonWidgetClass, 80 xmCascadeButtonWidgetClass,
227 parent, 81 parent,
228 NULL); 82 NULL);
229 Widget m = XmVaCreateSimplePulldownMenu(parent, menu->label, i, NULL, NULL); 83 Widget m = XmVaCreateSimplePulldownMenu(parent, menu->label, i, NULL, NULL);
230 84
231 UcxList *ls = menu->items; 85 UiMenuItemI *mi = menu->items_begin;
232 int menu_index = 0; 86 int menu_index = 0;
233 while(ls) { 87 while(mi) {
234 UiMenuItemI *mi = ls->data; 88 menu_index += createMenuItem[mi->type](m, menu_index, mi, obj);
235 menu_index += mi->add_to(m, menu_index, mi, obj); 89 mi = mi->next;
236 ls = ls->next;
237 } 90 }
238 91
239 return 1; 92 return 1;
240 } 93 }
241 94
258 args, 111 args,
259 1); 112 1);
260 XmStringFree(label); 113 XmStringFree(label);
261 114
262 if(mi->callback != NULL) { 115 if(mi->callback != NULL) {
263 UiEventData *event = ucx_mempool_malloc( 116 UiEventData *event = cxMalloc(
264 obj->ctx->mempool, 117 obj->ctx->allocator,
265 sizeof(UiEventData)); 118 sizeof(UiEventData));
266 event->obj = obj; 119 event->obj = obj;
267 event->userdata = mi->userdata; 120 event->userdata = mi->userdata;
268 event->callback = mi->callback; 121 event->callback = mi->callback;
269 event->value = 0; 122 event->value = 0;
317 if(at) { 170 if(at) {
318 XmStringFree(at); 171 XmStringFree(at);
319 } 172 }
320 173
321 if(mi->callback != NULL) { 174 if(mi->callback != NULL) {
322 UiEventData *event = ucx_mempool_malloc( 175 UiEventData *event = cxMalloc(
323 obj->ctx->mempool, 176 obj->ctx->allocator,
324 sizeof(UiEventData)); 177 sizeof(UiEventData));
325 event->obj = obj; 178 event->obj = obj;
326 event->userdata = mi->userdata; 179 event->userdata = mi->userdata;
327 event->callback = mi->callback; 180 event->callback = mi->callback;
328 event->value = 0; 181 event->value = 0;
370 args, 223 args,
371 2); 224 2);
372 XmStringFree(label); 225 XmStringFree(label);
373 226
374 if(ci->callback) { 227 if(ci->callback) {
375 UiEventData *event = ucx_mempool_malloc( 228 UiEventData *event = cxMalloc(
376 obj->ctx->mempool, 229 obj->ctx->allocator,
377 sizeof(UiEventData)); 230 sizeof(UiEventData));
378 event->obj = obj; 231 event->obj = obj;
379 event->userdata = ci->userdata; 232 event->userdata = ci->userdata;
380 event->callback = ci->callback; 233 event->callback = ci->callback;
381 XtAddCallback( 234 XtAddCallback(
427 int i, 280 int i,
428 UiMenuItemI *item, 281 UiMenuItemI *item,
429 UiObject *obj) 282 UiObject *obj)
430 { 283 {
431 UiMenuItemList *il = (UiMenuItemList*)item; 284 UiMenuItemList *il = (UiMenuItemList*)item;
432 UcxMempool *mp = obj->ctx->mempool; 285
433 286 UiActiveMenuItemList *ls = cxMalloc(
434 UiActiveMenuItemList *ls = ucx_mempool_malloc( 287 obj->ctx->allocator,
435 mp,
436 sizeof(UiActiveMenuItemList)); 288 sizeof(UiActiveMenuItemList));
437 289
438 ls->object = obj; 290 ls->object = obj;
439 ls->menu = parent; 291 ls->menu = parent;
440 ls->index = i; 292 ls->index = i;
573 if(!ct->menu) { 425 if(!ct->menu) {
574 return; 426 return;
575 } 427 }
576 428
577 // add groups 429 // add groups
578 UcxList *groups = NULL; 430 CxList *groups = NULL;
579 va_list ap; 431 va_list ap;
580 va_start(ap, userdata); 432 va_start(ap, userdata);
581 int group; 433 int group;
582 while((group = va_arg(ap, int)) != -1) { 434 while((group = va_arg(ap, int)) != -1) {
583 ucx_list_append(groups, (void*)(intptr_t)group); 435 if(!groups) {
436 groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16);
437 }
438 cxListAdd(groups, &group);
584 } 439 }
585 va_end(ap); 440 va_end(ap);
586 441
587 // create menuitem 442 // create menuitem
588 Arg args[4]; 443 Arg args[4];
603 if(!ct->menu) { 458 if(!ct->menu) {
604 return; 459 return;
605 } 460 }
606 461
607 // add groups 462 // add groups
608 UcxList *groups = NULL; 463 CxList *groups = NULL;
609 va_list ap; 464 va_list ap;
610 va_start(ap, userdata); 465 va_start(ap, userdata);
611 int group; 466 int group;
612 while((group = va_arg(ap, int)) != -1) { 467 while((group = va_arg(ap, int)) != -1) {
613 ucx_list_append(groups, (void*)(intptr_t)group); 468 if(!groups) {
469 groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16);
470 }
471 cxListAdd(groups, &group);
614 } 472 }
615 va_end(ap); 473 va_end(ap);
616 474
617 // create menuitem 475 // create menuitem
618 UiStockItem *stockItem = ui_get_stock_item(stockid); 476 UiStockItem *stockItem = ui_get_stock_item(stockid);

mercurial