--- 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;