--- 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**)¤t_builder->menus_begin, + (void**)¤t_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); +}