ui/common/menu.c

branch
newapi
changeset 208
f632bc0589ab
parent 207
93b9f502cb88
child 229
a952760955b4
--- a/ui/common/menu.c	Wed Oct 11 19:11:38 2023 +0200
+++ b/ui/common/menu.c	Wed Oct 11 22:59:42 2023 +0200
@@ -29,6 +29,7 @@
 #include "menu.h"
 
 #include <stdarg.h>
+#include <string.h>
 
 #include <cx/linked_list.h>
 #include <cx/array_list.h>
@@ -56,12 +57,31 @@
             item);
 }
 
-void ui_menu(char *label) {
+static char* nl_strdup(const char* s) {
+    return s ? strdup(s) : NULL;
+}
+
+static int* copy_groups(int* groups, size_t *ngroups) {
+    *ngroups = 0;
+    if (!groups) {
+        return NULL;
+    }
+
+    size_t n;
+    for (n = 0; groups[n] > -1; n++) { }
+
+    if (ngroups > 0) {
+        int* newarray = calloc(n, sizeof(int));
+        memcpy(newarray, groups, n);
+        *ngroups = n;
+        return newarray;
+    }
+    return NULL;
+}
+
+void ui_menu_create(const char *label) {
     if(!current) {
         current = cxLinkedListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS);
-    } else {
-        // free current menu hierarchy
-        cxListClear(current);
     }
     
     // create menu
@@ -76,107 +96,39 @@
     menu->parent       = NULL;    
 
     menu->end = 0;
-    
-    add_menu(menu);
-    cxListAdd(current, menu);
-}
 
-void ui_submenu(char *label) {
-    UiMenu *menu = malloc(sizeof(UiMenu));
-    menu->item.prev = NULL;
-    menu->item.next = NULL;
-    menu->item.type = UI_MENU_SUBMENU;
-    
-    menu->label       = label;
-    menu->items_begin = NULL;
-    menu->items_end   = NULL;
-    menu->parent      = NULL;
-
-    menu->end = 0;
-    
-    // add submenu to current menu
-    add_item((UiMenuItemI*)menu);
-    
-    // set the submenu to current menu
+    if (current->size == 0) {
+        add_menu(menu);
+    }
+    else {
+        add_item((UiMenuItemI*)menu);
+    }
     uic_add_menu_to_stack(menu);
 }
 
-void ui_submenu_end() {
-    if(current->size < 2) {
-        return;
-    }
-    cxListRemove(current, 0);
-}
-
 UIEXPORT void ui_menu_end(void) {
     cxListRemove(current, 0);
 }
 
-void ui_menuitem(char *label, ui_callback f, void *userdata) {
-    ui_menuitem_gr(label, f, userdata, -1);
-}
+
 
-void ui_menuitem_st(char *stockid, ui_callback f, void *userdata) {
-    ui_menuitem_stgr(stockid, f, userdata, -1);
-}
+void ui_menuitem_create(UiMenuItemArgs args) {
+    if (!current) {
+        return; // error?
+    }
 
-void ui_menuitem_gr(char *label, ui_callback f, void *userdata, ...) {
-    if(!current) {
-        return;
-    }
-    
-    UiMenuItem *item = malloc(sizeof(UiMenuItem));
+    UiMenuItem* item = malloc(sizeof(UiMenuItem));
     item->item.prev = NULL;
     item->item.next = NULL;
     item->item.type = UI_MENU_ITEM;
-    
-    item->label = label;
-    item->userdata = userdata;
-    item->callback = f;
-    item->groups = NULL;
-    
-    // add groups
-    va_list ap;
-    va_start(ap, userdata);
-    int group;
-    while((group = va_arg(ap, int)) != -1) {
-        if(!item->groups) {
-            item->groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 8);
-        }
-        cxListAdd(item->groups, &group);
-    }
-    va_end(ap);
-    
-    add_item((UiMenuItemI*)item);
-}
 
-void ui_menuitem_stgr(char *stockid, ui_callback f, void *userdata, ...) {
-    if(!current) {
-        return;
-    }
-    
-    UiStMenuItem *item = malloc(sizeof(UiStMenuItem));
-    item->item.prev = NULL;
-    item->item.next = NULL;
-    item->item.type = UI_MENU_STOCK_ITEM;
-    
-    item->stockid = stockid;
-    item->userdata = userdata;
-    item->callback = f;
-    item->groups = NULL;
-    
-    // add groups
-    va_list ap;
-    va_start(ap, userdata);
-    int group;
-    while((group = va_arg(ap, int)) != -1) {
-        if(!item->groups) {
-            item->groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 8);
-        }
-        cxListAdd(item->groups, &group);
-    }
-    va_end(ap);
-    
+    item->label = nl_strdup(args.label);
+    item->stockid = nl_strdup(args.stockid);
+    item->icon = nl_strdup(args.icon);
+    item->userdata = args.onclickdata;
+    item->callback = args.onclick;
+    item->groups = copy_groups(args.groups, &item->ngroups);
+
     add_item((UiMenuItemI*)item);
 }
 
@@ -193,69 +145,97 @@
     add_item((UiMenuItemI*)item);
 }
 
-void ui_checkitem(char *label, ui_callback f, void *userdata) {
+void ui_menu_toggleitem_create(UiMenuToggleItemArgs args) {
     if(!current) {
         return;
     }
     
-    UiCheckItem *item = malloc(sizeof(UiCheckItem));
+    UiMenuCheckItem *item = malloc(sizeof(UiMenuCheckItem));
     item->item.prev = NULL;
     item->item.next = NULL;
     item->item.type = UI_MENU_CHECK_ITEM;
-    item->label = label;
-    item->callback = f;
-    item->userdata = userdata;
-    
-    add_item((UiMenuItemI*)item);
-}
 
-void ui_checkitem_nv(char *label, char *vname) {
-    if(!current) {
-        return;
-    }
-    
-    UiCheckItemNV *item = malloc(sizeof(UiCheckItemNV));
-    item->item.prev = NULL;
-    item->item.next = NULL;
-    item->item.type = UI_MENU_CHECK_ITEM_NV;
-    item->varname = vname;
-    item->label = label;
+    item->label = nl_strdup(args.label);
+    item->stockid = nl_strdup(args.stockid);
+    item->icon = nl_strdup(args.icon);
+    item->varname = nl_strdup(args.varname);
+    item->userdata = args.onchangedata;
+    item->callback = args.onchange;
+    item->groups = copy_groups(args.groups, &item->ngroups);
     
     add_item((UiMenuItemI*)item);
 }
 
-void ui_menuitem_list(UiList *items, ui_callback f, void *userdata) {
+void ui_menu_radioitem_create(UiMenuToggleItemArgs args) {
+    if (!current) {
+        return;
+    }
+
+    UiMenuCheckItem* item = malloc(sizeof(UiMenuCheckItem));
+    item->item.prev = NULL;
+    item->item.next = NULL;
+    item->item.type = UI_MENU_CHECK_ITEM;
+
+    item->label = nl_strdup(args.label);
+    item->stockid = nl_strdup(args.stockid);
+    item->icon = nl_strdup(args.icon);
+    item->varname = nl_strdup(args.varname);
+    item->userdata = args.onchangedata;
+    item->callback = args.onchange;
+    item->groups = copy_groups(args.groups, &item->ngroups);
+
+    add_item((UiMenuItemI*)item);
+}
+
+void ui_menu_itemlist_create(UiMenuItemListArgs args) {
     if(!current) {
         return;
     }
     
-    UiMenuItemList *item = malloc(sizeof(UiMenuItemList));
+    UiMenuItemList*item = malloc(sizeof(UiMenuItemList));
     item->item.prev = NULL;
     item->item.next = NULL;
     item->item.type = UI_MENU_ITEM_LIST;
-    item->callback = f;
-    item->userdata = userdata;
-    item->list = items;
+    item->callback = args.onselect;
+    item->userdata = args.onselectdata;
+    item->varname = nl_strdup(args.varname);
     
     add_item((UiMenuItemI*)item);
 }
 
-void ui_menuitem_list_nv(const char *varname, ui_callback f, void *userdata) {
-    if(!current) {
+void ui_menu_checkitemlist_create(UiMenuItemListArgs args) {
+    if (!current) {
         return;
     }
-    
-    UiMenuItemListNV *item = malloc(sizeof(UiMenuItemListNV));
+
+    UiMenuItemList* item = malloc(sizeof(UiMenuItemList));
     item->item.prev = NULL;
     item->item.next = NULL;
     item->item.type = UI_MENU_ITEM_LIST;
-    item->callback = f;
-    item->userdata = userdata;
-    item->varname = varname;
-    
+    item->callback = args.onselect;
+    item->userdata = args.onselectdata;
+    item->varname = nl_strdup(args.varname);
+
     add_item((UiMenuItemI*)item);
 }
 
+void ui_menu_radioitemlist_create(UiMenuItemListArgs args) {
+    if (!current) {
+        return;
+    }
+
+    UiMenuItemList* item = malloc(sizeof(UiMenuItemList));
+    item->item.prev = NULL;
+    item->item.next = NULL;
+    item->item.type = UI_MENU_ITEM_LIST;
+    item->callback = args.onselect;
+    item->userdata = args.onselectdata;
+    item->varname = nl_strdup(args.varname);
+
+    add_item((UiMenuItemI*)item);
+}
+
+
 void uic_add_menu_to_stack(UiMenu* menu) {
     cxListInsert(current, 0, menu);
 }
@@ -264,9 +244,6 @@
     return menus_begin;
 }
 
-
-
-
 UIEXPORT void ui_menu_close(void) {
     UiMenu* menu = cxListAt(current, 0);
     menu->end = 1;

mercurial