ui/common/menu.c

changeset 88
e27526429d85
parent 77
5de33c2d94c6
child 90
f501f0efc9a8
equal deleted inserted replaced
87:5360027fb282 88:e27526429d85
33 33
34 #include <cx/linked_list.h> 34 #include <cx/linked_list.h>
35 #include <cx/array_list.h> 35 #include <cx/array_list.h>
36 36
37 37
38 static UiMenu *menus_begin; 38 static UiMenuBuilder *current_builder;
39 static UiMenu *menus_end; 39 static UiMenuBuilder global_builder;
40 static CxList *current;
41 40
42 static int menu_item_counter = 0; 41 static int menu_item_counter = 0;
42
43 void uic_menu_init(void) {
44 global_builder.current = cxLinkedListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS);
45 current_builder = &global_builder;
46 }
43 47
44 static void add_menu(UiMenu *menu) { 48 static void add_menu(UiMenu *menu) {
45 cx_linked_list_add( 49 cx_linked_list_add(
46 (void**)&menus_begin, 50 (void**)&current_builder->menus_begin,
47 (void**)&menus_end, 51 (void**)&current_builder->menus_end,
48 offsetof(UiMenu, item.prev), 52 offsetof(UiMenu, item.prev),
49 offsetof(UiMenu, item.next), 53 offsetof(UiMenu, item.next),
50 menu); 54 menu);
51 } 55 }
52 56
53 static void add_item(UiMenuItemI *item) { 57 static void add_item(UiMenuItemI *item) {
54 UiMenu *menu = cxListAt(current, 0); 58 UiMenu *menu = cxListAt(current_builder->current, 0);
55 cx_linked_list_add( 59 cx_linked_list_add(
56 (void**)&menu->items_begin, 60 (void**)&menu->items_begin,
57 (void**)&menu->items_end, 61 (void**)&menu->items_end,
58 offsetof(UiMenu, item.prev), 62 offsetof(UiMenu, item.prev),
59 offsetof(UiMenu, item.next), 63 offsetof(UiMenu, item.next),
84 return newarray; 88 return newarray;
85 } 89 }
86 return NULL; 90 return NULL;
87 } 91 }
88 92
89 void ui_menu_create(const char *label) { 93 void ui_menu_create(const char *label) {
90 if(!current) {
91 current = cxLinkedListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS);
92 }
93
94 // create menu 94 // create menu
95 UiMenu *menu = malloc(sizeof(UiMenu)); 95 UiMenu *menu = malloc(sizeof(UiMenu));
96 mitem_set_id(&menu->item); 96 mitem_set_id(&menu->item);
97 menu->item.prev = NULL; 97 menu->item.prev = NULL;
98 menu->item.next = NULL; 98 menu->item.next = NULL;
103 menu->items_end = NULL; 103 menu->items_end = NULL;
104 menu->parent = NULL; 104 menu->parent = NULL;
105 105
106 menu->end = 0; 106 menu->end = 0;
107 107
108 if (cxListSize(current) == 0) { 108 if (cxListSize(current_builder->current) == 0) {
109 add_menu(menu); 109 add_menu(menu);
110 } 110 }
111 else { 111 else {
112 add_item((UiMenuItemI*)menu); 112 add_item((UiMenuItemI*)menu);
113 } 113 }
114 uic_add_menu_to_stack(menu); 114 uic_add_menu_to_stack(menu);
115 } 115 }
116 116
117 UIEXPORT void ui_menu_end(void) { 117 UIEXPORT void ui_menu_end(void) {
118 cxListRemove(current, 0); 118 cxListRemove(current_builder->current, 0);
119 if(cxListSize(current_builder->current) == 0) {
120 current_builder = &global_builder;
121 }
119 } 122 }
120 123
121 124
122 125
123 void ui_menuitem_create(UiMenuItemArgs args) { 126 void ui_menuitem_create(UiMenuItemArgs args) {
124 if (!current) {
125 return; // error?
126 }
127
128 UiMenuItem* item = malloc(sizeof(UiMenuItem)); 127 UiMenuItem* item = malloc(sizeof(UiMenuItem));
129 mitem_set_id(&item->item); 128 mitem_set_id(&item->item);
130 item->item.prev = NULL; 129 item->item.prev = NULL;
131 item->item.next = NULL; 130 item->item.next = NULL;
132 item->item.type = UI_MENU_ITEM; 131 item->item.type = UI_MENU_ITEM;
140 139
141 add_item((UiMenuItemI*)item); 140 add_item((UiMenuItemI*)item);
142 } 141 }
143 142
144 void ui_menuseparator() { 143 void ui_menuseparator() {
145 if(!current) {
146 return;
147 }
148
149 UiMenuItemI *item = malloc(sizeof(UiMenuItemI)); 144 UiMenuItemI *item = malloc(sizeof(UiMenuItemI));
150 item->id[0] = 0; 145 item->id[0] = 0;
151 item->prev = NULL; 146 item->prev = NULL;
152 item->next = NULL; 147 item->next = NULL;
153 item->type = UI_MENU_SEPARATOR; 148 item->type = UI_MENU_SEPARATOR;
154 149
155 add_item((UiMenuItemI*)item); 150 add_item((UiMenuItemI*)item);
156 } 151 }
157 152
158 void ui_menu_toggleitem_create(UiMenuToggleItemArgs args) { 153 void ui_menu_toggleitem_create(UiMenuToggleItemArgs args) {
159 if(!current) {
160 return;
161 }
162
163 UiMenuCheckItem *item = malloc(sizeof(UiMenuCheckItem)); 154 UiMenuCheckItem *item = malloc(sizeof(UiMenuCheckItem));
164 mitem_set_id(&item->item); 155 mitem_set_id(&item->item);
165 item->item.prev = NULL; 156 item->item.prev = NULL;
166 item->item.next = NULL; 157 item->item.next = NULL;
167 item->item.type = UI_MENU_CHECK_ITEM; 158 item->item.type = UI_MENU_CHECK_ITEM;
176 167
177 add_item((UiMenuItemI*)item); 168 add_item((UiMenuItemI*)item);
178 } 169 }
179 170
180 void ui_menu_radioitem_create(UiMenuToggleItemArgs args) { 171 void ui_menu_radioitem_create(UiMenuToggleItemArgs args) {
181 if (!current) {
182 return;
183 }
184
185 UiMenuCheckItem* item = malloc(sizeof(UiMenuCheckItem)); 172 UiMenuCheckItem* item = malloc(sizeof(UiMenuCheckItem));
186 mitem_set_id(&item->item); 173 mitem_set_id(&item->item);
187 item->item.prev = NULL; 174 item->item.prev = NULL;
188 item->item.next = NULL; 175 item->item.next = NULL;
189 item->item.type = UI_MENU_CHECK_ITEM; 176 item->item.type = UI_MENU_CHECK_ITEM;
198 185
199 add_item((UiMenuItemI*)item); 186 add_item((UiMenuItemI*)item);
200 } 187 }
201 188
202 void ui_menu_itemlist_create(UiMenuItemListArgs args) { 189 void ui_menu_itemlist_create(UiMenuItemListArgs args) {
203 if(!current) {
204 return;
205 }
206
207 UiMenuItemList*item = malloc(sizeof(UiMenuItemList)); 190 UiMenuItemList*item = malloc(sizeof(UiMenuItemList));
208 mitem_set_id(&item->item); 191 mitem_set_id(&item->item);
209 item->item.prev = NULL; 192 item->item.prev = NULL;
210 item->item.next = NULL; 193 item->item.next = NULL;
211 item->item.type = UI_MENU_ITEM_LIST; 194 item->item.type = UI_MENU_ITEM_LIST;
216 199
217 add_item((UiMenuItemI*)item); 200 add_item((UiMenuItemI*)item);
218 } 201 }
219 202
220 void ui_menu_checkitemlist_create(UiMenuItemListArgs args) { 203 void ui_menu_checkitemlist_create(UiMenuItemListArgs args) {
221 if (!current) {
222 return;
223 }
224
225 UiMenuItemList* item = malloc(sizeof(UiMenuItemList)); 204 UiMenuItemList* item = malloc(sizeof(UiMenuItemList));
226 mitem_set_id(&item->item); 205 mitem_set_id(&item->item);
227 item->item.prev = NULL; 206 item->item.prev = NULL;
228 item->item.next = NULL; 207 item->item.next = NULL;
229 item->item.type = UI_MENU_CHECKITEM_LIST; 208 item->item.type = UI_MENU_CHECKITEM_LIST;
233 212
234 add_item((UiMenuItemI*)item); 213 add_item((UiMenuItemI*)item);
235 } 214 }
236 215
237 void ui_menu_radioitemlist_create(UiMenuItemListArgs args) { 216 void ui_menu_radioitemlist_create(UiMenuItemListArgs args) {
238 if (!current) {
239 return;
240 }
241
242 UiMenuItemList* item = malloc(sizeof(UiMenuItemList)); 217 UiMenuItemList* item = malloc(sizeof(UiMenuItemList));
243 mitem_set_id(&item->item); 218 mitem_set_id(&item->item);
244 item->item.prev = NULL; 219 item->item.prev = NULL;
245 item->item.next = NULL; 220 item->item.next = NULL;
246 item->item.type = UI_MENU_RADIOITEM_LIST; 221 item->item.type = UI_MENU_RADIOITEM_LIST;
251 add_item((UiMenuItemI*)item); 226 add_item((UiMenuItemI*)item);
252 } 227 }
253 228
254 229
255 void uic_add_menu_to_stack(UiMenu* menu) { 230 void uic_add_menu_to_stack(UiMenu* menu) {
256 if (!current) { 231 cxListInsert(current_builder->current, 0, menu);
257 current = cxLinkedListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS);
258 }
259
260 cxListInsert(current, 0, menu);
261 } 232 }
262 233
263 UiMenu* uic_get_menu_list(void) { 234 UiMenu* uic_get_menu_list(void) {
264 return menus_begin; 235 return current_builder->menus_begin;
265 } 236 }
266 237
267 UIEXPORT void ui_menu_close(void) { 238 UIEXPORT void ui_menu_close(void) {
268 UiMenu* menu = cxListAt(current, 0); 239 UiMenu* menu = cxListAt(current_builder->current, 0);
269 menu->end = 1; 240 menu->end = 1;
270 } 241 }
271 242
272 UIEXPORT int ui_menu_is_open(void) { 243 UIEXPORT int ui_menu_is_open(void) {
273 UiMenu* menu = cxListAt(current, 0); 244 UiMenu* menu = cxListAt(current_builder->current, 0);
274 if (menu->end) { 245 if (menu->end) {
275 ui_menu_end(); 246 ui_menu_end();
276 return 0; 247 return 0;
277 } 248 }
278 return 1; 249 return 1;
279 } 250 }
251
252
253 void ui_contextmenu_builder(UiMenuBuilder **out_builder) {
254 UiMenuBuilder *builder = malloc(sizeof(UiMenuBuilder));
255 builder->menus_begin = NULL;
256 builder->menus_end = NULL;
257 builder->current = cxLinkedListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS);
258 current_builder = builder;
259 *out_builder = builder;
260
261 ui_menu_create(NULL);
262 }
263
264
265
266 static void free_menuitem(UiMenuItemI *item) {
267 switch(item->type) {
268 default: break;
269 case UI_MENU: {
270 UiMenu *menu = (UiMenu*)item;
271 UiMenuItemI *m = menu->items_begin;
272 while(m) {
273 UiMenuItemI *next = m->next;
274 free_menuitem(m);
275 m = next;
276 }
277 break;
278 }
279 case UI_MENU_ITEM: {
280 UiMenuItem *i = (UiMenuItem*)item;
281 free(i->groups);
282 free(i->label);
283 free(i->stockid);
284 free(i->icon);
285 break;
286 }
287 case UI_MENU_CHECK_ITEM: {
288 UiMenuCheckItem *i = (UiMenuCheckItem*)item;
289 free(i->groups);
290 free(i->label);
291 free(i->stockid);
292 free(i->icon);
293 free(i->varname);
294 break;
295 }
296 case UI_MENU_RADIO_ITEM: {
297 UiMenuRadioItem *i = (UiMenuRadioItem*)item;
298 free(i->groups);
299 free(i->label);
300 free(i->stockid);
301 free(i->icon);
302 //free(i->varname);
303 break;
304 }
305 case UI_MENU_ITEM_LIST: {
306 break;
307 }
308 case UI_MENU_CHECKITEM_LIST: {
309 break;
310 }
311 case UI_MENU_RADIOITEM_LIST: {
312 break;
313 }
314 }
315
316 free(item);
317 }
318
319 void ui_menubuilder_free(UiMenuBuilder *builder) {
320 UiMenuItemI *m = &builder->menus_begin->item;
321 while(m) {
322 UiMenuItemI *next = m->next;
323 free_menuitem(m);
324 m = next;
325 }
326 cxListDestroy(builder->current);
327 free(builder);
328 }

mercurial