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 |