ui/common/menu.c

branch
newapi
changeset 388
473c03f85197
parent 379
958bae372271
child 393
3099bf907e21
--- a/ui/common/menu.c	Sun Nov 17 15:21:50 2024 +0100
+++ b/ui/common/menu.c	Thu Nov 21 12:04:53 2024 +0100
@@ -35,23 +35,27 @@
 #include <cx/array_list.h>
 
 
-static UiMenu *menus_begin;
-static UiMenu *menus_end;
-static CxList *current;
+static UiMenuBuilder *current_builder;
+static UiMenuBuilder global_builder;
 
 static int menu_item_counter = 0;
 
+void uic_menu_init(void) {
+    global_builder.current = cxLinkedListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS);
+    current_builder = &global_builder;
+}
+
 static void add_menu(UiMenu *menu) {
     cx_linked_list_add(
-            (void**)&menus_begin,
-            (void**)&menus_end,
+            (void**)&current_builder->menus_begin,
+            (void**)&current_builder->menus_end,
             offsetof(UiMenu, item.prev),
             offsetof(UiMenu, item.next),
             menu);
 }
 
 static void add_item(UiMenuItemI *item) {
-    UiMenu *menu = cxListAt(current, 0);
+    UiMenu *menu = cxListAt(current_builder->current, 0);
     cx_linked_list_add(
             (void**)&menu->items_begin,
             (void**)&menu->items_end,
@@ -86,11 +90,7 @@
     return NULL;
 }
 
-void ui_menu_create(const char *label) {
-    if(!current) {
-        current = cxLinkedListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS);
-    }
-    
+void ui_menu_create(const char *label) {   
     // create menu
     UiMenu *menu = malloc(sizeof(UiMenu));
     mitem_set_id(&menu->item);
@@ -105,7 +105,7 @@
 
     menu->end = 0;
 
-    if (cxListSize(current) == 0) {
+    if (cxListSize(current_builder->current) == 0) {
         add_menu(menu);
     }
     else {
@@ -115,16 +115,15 @@
 }
 
 UIEXPORT void ui_menu_end(void) {
-    cxListRemove(current, 0);
+    cxListRemove(current_builder->current, 0);
+    if(cxListSize(current_builder->current) == 0) {
+        current_builder = &global_builder;
+    }
 }
 
 
 
 void ui_menuitem_create(UiMenuItemArgs args) {
-    if (!current) {
-        return; // error?
-    }
-
     UiMenuItem* item = malloc(sizeof(UiMenuItem));
     mitem_set_id(&item->item);
     item->item.prev = NULL;
@@ -142,10 +141,6 @@
 }
 
 void ui_menuseparator() {
-    if(!current) {
-        return;
-    }
-    
     UiMenuItemI  *item = malloc(sizeof(UiMenuItemI));
     item->id[0] = 0;
     item->prev = NULL;
@@ -156,10 +151,6 @@
 }
 
 void ui_menu_toggleitem_create(UiMenuToggleItemArgs args) {
-    if(!current) {
-        return;
-    }
-    
     UiMenuCheckItem *item = malloc(sizeof(UiMenuCheckItem));
     mitem_set_id(&item->item);
     item->item.prev = NULL;
@@ -178,10 +169,6 @@
 }
 
 void ui_menu_radioitem_create(UiMenuToggleItemArgs args) {
-    if (!current) {
-        return;
-    }
-
     UiMenuCheckItem* item = malloc(sizeof(UiMenuCheckItem));
     mitem_set_id(&item->item);
     item->item.prev = NULL;
@@ -200,10 +187,6 @@
 }
 
 void ui_menu_itemlist_create(UiMenuItemListArgs args) {
-    if(!current) {
-        return;
-    }
-    
     UiMenuItemList*item = malloc(sizeof(UiMenuItemList));
     mitem_set_id(&item->item);
     item->item.prev = NULL;
@@ -218,10 +201,6 @@
 }
 
 void ui_menu_checkitemlist_create(UiMenuItemListArgs args) {
-    if (!current) {
-        return;
-    }
-
     UiMenuItemList* item = malloc(sizeof(UiMenuItemList));
     mitem_set_id(&item->item);
     item->item.prev = NULL;
@@ -235,10 +214,6 @@
 }
 
 void ui_menu_radioitemlist_create(UiMenuItemListArgs args) {
-    if (!current) {
-        return;
-    }
-
     UiMenuItemList* item = malloc(sizeof(UiMenuItemList));
     mitem_set_id(&item->item);
     item->item.prev = NULL;
@@ -253,27 +228,101 @@
 
 
 void uic_add_menu_to_stack(UiMenu* menu) {
-    if (!current) {
-        current = cxLinkedListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS);
-    }
-
-    cxListInsert(current, 0, menu);
+    cxListInsert(current_builder->current, 0, menu);
 }
 
 UiMenu* uic_get_menu_list(void) {
-    return menus_begin;
+    return current_builder->menus_begin;
 }
 
 UIEXPORT void ui_menu_close(void) {
-    UiMenu* menu = cxListAt(current, 0);
+    UiMenu* menu = cxListAt(current_builder->current, 0);
     menu->end = 1;
 }
 
 UIEXPORT int ui_menu_is_open(void) {
-    UiMenu* menu = cxListAt(current, 0);
+    UiMenu* menu = cxListAt(current_builder->current, 0);
     if (menu->end) {
         ui_menu_end();
         return 0;
     }
     return 1;
 }
+
+
+void ui_contextmenu_builder(UiMenuBuilder **out_builder) {
+    UiMenuBuilder *builder = malloc(sizeof(UiMenuBuilder));
+    builder->menus_begin = NULL;
+    builder->menus_end = NULL;
+    builder->current = cxLinkedListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS);
+    current_builder = builder;
+    *out_builder = builder;
+    
+    ui_menu_create(NULL);
+}
+
+
+
+static void free_menuitem(UiMenuItemI *item) {
+    switch(item->type) {
+        default: break;
+        case UI_MENU: {
+            UiMenu *menu = (UiMenu*)item;
+            UiMenuItemI *m = menu->items_begin;
+            while(m) {
+                UiMenuItemI *next = m->next;
+                free_menuitem(m);
+                m = next;
+            }
+            break;
+        }
+        case UI_MENU_ITEM: {
+            UiMenuItem *i = (UiMenuItem*)item;
+            free(i->groups);
+            free(i->label);
+            free(i->stockid);
+            free(i->icon);
+            break;
+        }
+        case UI_MENU_CHECK_ITEM: {
+            UiMenuCheckItem *i = (UiMenuCheckItem*)item;
+            free(i->groups);
+            free(i->label);
+            free(i->stockid);
+            free(i->icon);
+            free(i->varname);
+            break;
+        }
+        case UI_MENU_RADIO_ITEM: {
+            UiMenuRadioItem *i = (UiMenuRadioItem*)item;
+            free(i->groups);
+            free(i->label);
+            free(i->stockid);
+            free(i->icon);
+            //free(i->varname);
+            break;
+        }
+        case UI_MENU_ITEM_LIST: {
+            break;
+        }
+        case UI_MENU_CHECKITEM_LIST: {
+            break;
+        }
+        case UI_MENU_RADIOITEM_LIST: {
+            break;
+        }
+    }
+    
+    free(item);
+}
+
+void ui_menubuilder_free(UiMenuBuilder *builder) {
+    UiMenuItemI *m = &builder->menus_begin->item;
+    while(m) {
+        UiMenuItemI *next = m->next;
+        free_menuitem(m);
+        m = next;
+    }
+    cxListDestroy(builder->current);
+    free(builder);
+}

mercurial