ui/gtk/menu.c

branch
newapi
changeset 178
7c3ff86ee9d4
parent 175
2cb06c231057
child 253
087cc9216f28
equal deleted inserted replaced
177:e79a60b3a7cb 178:7c3ff86ee9d4
32 #include <stdarg.h> 32 #include <stdarg.h>
33 33
34 #include "menu.h" 34 #include "menu.h"
35 #include "toolkit.h" 35 #include "toolkit.h"
36 #include "../common/context.h" 36 #include "../common/context.h"
37 #include "../common/menu.h"
37 #include "../ui/properties.h" 38 #include "../ui/properties.h"
38 #include "../ui/window.h" 39 #include "../ui/window.h"
39 #include "container.h" 40 #include "container.h"
40 41
41 static UcxList *menus; 42 #include <cx/linked_list.h>
42 static UcxList *current; 43 #include <cx/array_list.h>
43 44
44 void ui_menu(char *label) { 45
45 // free current menu hierarchy 46 static ui_menu_add_f createMenuItem[] = {
46 ucx_list_free(current); 47 /* UI_MENU */ add_menu_widget,
47 48 /* UI_MENU_SUBMENU */ add_menu_widget,
48 // create menu 49 /* UI_MENU_ITEM */ add_menuitem_widget,
49 UiMenu *menu = malloc(sizeof(UiMenu)); 50 /* UI_MENU_STOCK_ITEM */ add_menuitem_st_widget,
50 menu->item.add_to = (ui_menu_add_f)add_menu_widget; 51 /* UI_MENU_CHECK_ITEM */ add_checkitem_widget,
51 52 /* UI_MENU_CHECK_ITEM_NV */ add_checkitemnv_widget,
52 menu->label = label; 53 /* UI_MENU_ITEM_LIST */ add_menuitem_list_widget,
53 menu->items = NULL; 54 /* UI_MENU_ITEM_LIST_NV */ NULL, // TODO
54 menu->parent = NULL; 55 /* UI_MENU_SEPARATOR */ add_menuseparator_widget
55 56 };
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 //UcxList *c = current;
83 }
84
85 void ui_menuitem(char *label, ui_callback f, void *userdata) {
86 ui_menuitem_gr(label, f, userdata, -1);
87 }
88
89 void ui_menuitem_st(char *stockid, ui_callback f, void *userdata) {
90 ui_menuitem_stgr(stockid, f, userdata, -1);
91 }
92
93 void ui_menuitem_gr(char *label, ui_callback f, void *userdata, ...) {
94 if(!current) {
95 return;
96 }
97
98 UiMenuItem *item = malloc(sizeof(UiMenuItem));
99 item->item.add_to = (ui_menu_add_f)add_menuitem_widget;
100
101 item->label = label;
102 item->userdata = userdata;
103 item->callback = f;
104 item->groups = NULL;
105
106 // add groups
107 va_list ap;
108 va_start(ap, userdata);
109 int group;
110 while((group = va_arg(ap, int)) != -1) {
111 item->groups = ucx_list_append(item->groups, (void*)(intptr_t)group);
112 }
113 va_end(ap);
114
115 UiMenu *cm = current->data;
116 cm->items = ucx_list_append(cm->items, item);
117 }
118
119 void ui_menuitem_stgr(char *stockid, ui_callback f, void *userdata, ...) {
120 if(!current) {
121 return;
122 }
123
124 UiStMenuItem *item = malloc(sizeof(UiStMenuItem));
125 item->item.add_to = (ui_menu_add_f)add_menuitem_st_widget;
126
127 item->stockid = stockid;
128 item->userdata = userdata;
129 item->callback = f;
130 item->groups = NULL;
131
132 // add groups
133 va_list ap;
134 va_start(ap, userdata);
135 int group;
136 while((group = va_arg(ap, int)) != -1) {
137 item->groups = ucx_list_append(item->groups, (void*)(intptr_t)group);
138 }
139 va_end(ap);
140
141 UiMenu *cm = current->data;
142 cm->items = ucx_list_append(cm->items, item);
143 }
144
145 void ui_menuseparator() {
146 if(!current) {
147 return;
148 }
149
150 UiMenuItemI *item = malloc(sizeof(UiMenuItemI));
151 item->add_to = (ui_menu_add_f)add_menuseparator_widget;
152
153 UiMenu *cm = current->data;
154 cm->items = ucx_list_append(cm->items, item);
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 57
201 // private menu functions 58 // private menu functions
202 GtkWidget *ui_create_menubar(UiObject *obj) { 59 GtkWidget *ui_create_menubar(UiObject *obj) {
203 if(menus == NULL) { 60 UiMenu *menus_begin = uic_get_menu_list();
61 if(menus_begin == NULL) {
204 return NULL; 62 return NULL;
205 } 63 }
206 64
207 GtkWidget *mb = gtk_menu_bar_new(); 65 GtkWidget *mb = gtk_menu_bar_new();
208 66
209 UcxList *ls = menus; 67 UiMenu *ls = menus_begin;
210 while(ls) { 68 while(ls) {
211 UiMenu *menu = ls->data; 69 UiMenu *menu = ls;
212 menu->item.add_to(mb, 0, &menu->item, obj); 70 add_menu_widget(mb, 0, &menu->item, obj);
213 71
214 ls = ls->next; 72 ls = (UiMenu*)ls->item.next;
215 } 73 }
216 74
217 return mb; 75 return mb;
218 } 76 }
219 77
222 80
223 GtkWidget *menu_widget = gtk_menu_new(); 81 GtkWidget *menu_widget = gtk_menu_new();
224 GtkWidget *menu_item = gtk_menu_item_new_with_mnemonic(menu->label); 82 GtkWidget *menu_item = gtk_menu_item_new_with_mnemonic(menu->label);
225 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), menu_widget); 83 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), menu_widget);
226 84
227 UcxList *ls = menu->items; 85 UiMenuItemI *it = menu->items_begin;
228 int index = 0; 86 int index = 0;
229 while(ls) { 87 while(it) {
230 UiMenuItemI *i = ls->data; 88 createMenuItem[it->type](menu_widget, index, it, obj);
231 i->add_to(menu_widget, index, i, obj);
232 89
233 ls = ls->next; 90 it = it->next;
234 index++; 91 index++;
235 } 92 }
236 93
237 gtk_menu_shell_append(GTK_MENU_SHELL(parent), menu_item); 94 gtk_menu_shell_append(GTK_MENU_SHELL(parent), menu_item);
238 } 95 }
358 } 215 }
359 } 216 }
360 217
361 void add_menuitem_list_widget(GtkWidget *p, int index, UiMenuItemI *item, UiObject *obj) { 218 void add_menuitem_list_widget(GtkWidget *p, int index, UiMenuItemI *item, UiObject *obj) {
362 UiMenuItemList *il = (UiMenuItemList*)item; 219 UiMenuItemList *il = (UiMenuItemList*)item;
363 UcxMempool *mp = obj->ctx->mempool; 220 const CxAllocator *a = obj->ctx->allocator;
364 221
365 UiActiveMenuItemList *ls = ucx_mempool_malloc( 222 UiActiveMenuItemList *ls = cxMalloc(
366 mp, 223 a,
367 sizeof(UiActiveMenuItemList)); 224 sizeof(UiActiveMenuItemList));
368 225
369 ls->object = obj; 226 ls->object = obj;
370 ls->menu = GTK_MENU_SHELL(p); 227 ls->menu = GTK_MENU_SHELL(p);
371 ls->index = index; 228 ls->index = index;
517 if(!ct->menu) { 374 if(!ct->menu) {
518 return; 375 return;
519 } 376 }
520 377
521 // add groups 378 // add groups
522 UcxList *groups = NULL; 379 CxList *groups = NULL;
523 va_list ap; 380 va_list ap;
524 va_start(ap, userdata); 381 va_start(ap, userdata);
525 int group; 382 int group;
526 while((group = va_arg(ap, int)) != -1) { 383 while((group = va_arg(ap, int)) != -1) {
527 ucx_list_append(groups, (void*)(intptr_t)group); 384 if(!groups) {
385 groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16);
386 }
387 cxListAdd(groups, &group);
528 } 388 }
529 va_end(ap); 389 va_end(ap);
530 390
531 // create menuitem 391 // create menuitem
532 GtkWidget *widget = gtk_menu_item_new_with_mnemonic(label); 392 GtkWidget *widget = gtk_menu_item_new_with_mnemonic(label);
553 413
554 gtk_menu_shell_append(GTK_MENU_SHELL(ct->menu), widget); 414 gtk_menu_shell_append(GTK_MENU_SHELL(ct->menu), widget);
555 415
556 if(groups) { 416 if(groups) {
557 uic_add_group_widget(obj->ctx, widget, (ui_enablefunc)ui_set_enabled, groups); 417 uic_add_group_widget(obj->ctx, widget, (ui_enablefunc)ui_set_enabled, groups);
418 cxListDestroy(groups);
558 } 419 }
559 } 420 }
560 421
561 void ui_widget_menuitem_st(UiObject *obj, char *stockid, ui_callback f, void *userdata) { 422 void ui_widget_menuitem_st(UiObject *obj, char *stockid, ui_callback f, void *userdata) {
562 ui_widget_menuitem_stgr(obj, stockid, f, userdata, -1); 423 ui_widget_menuitem_stgr(obj, stockid, f, userdata, -1);
567 if(!ct->menu) { 428 if(!ct->menu) {
568 return; 429 return;
569 } 430 }
570 431
571 // add groups 432 // add groups
572 UcxList *groups = NULL; 433 CxList *groups = NULL;
573 va_list ap; 434 va_list ap;
574 va_start(ap, userdata); 435 va_start(ap, userdata);
575 int group; 436 int group;
576 while((group = va_arg(ap, int)) != -1) { 437 while((group = va_arg(ap, int)) != -1) {
577 ucx_list_append(groups, (void*)(intptr_t)group); 438 if(!groups) {
439 groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16);
440 }
441 cxListAdd(groups, &group);
578 } 442 }
579 va_end(ap); 443 va_end(ap);
580 444
581 // create menuitem 445 // create menuitem
582 GtkWidget *widget = gtk_image_menu_item_new_from_stock(stockid, obj->ctx->accel_group); 446 GtkWidget *widget = gtk_image_menu_item_new_from_stock(stockid, obj->ctx->accel_group);
603 467
604 gtk_menu_shell_append(GTK_MENU_SHELL(ct->menu), widget); 468 gtk_menu_shell_append(GTK_MENU_SHELL(ct->menu), widget);
605 469
606 if(groups) { 470 if(groups) {
607 uic_add_group_widget(obj->ctx, widget, (ui_enablefunc)ui_set_enabled, groups); 471 uic_add_group_widget(obj->ctx, widget, (ui_enablefunc)ui_set_enabled, groups);
608 } 472 cxListDestroy(groups);
609 } 473 }
474 }

mercurial