diff -r 0358f1d9c506 -r 2cb06c231057 ui/gtk/menu.c --- a/ui/gtk/menu.c Mon May 22 16:17:26 2023 +0200 +++ b/ui/gtk/menu.c Mon May 22 19:44:27 2023 +0200 @@ -34,6 +34,7 @@ #include "menu.h" #include "toolkit.h" #include "../common/context.h" +#include "../common/menu.h" #include "../ui/properties.h" #include "../ui/window.h" #include "container.h" @@ -41,207 +42,22 @@ #include #include -static UiMenu *menus_begin; -static UiMenu *menus_end; -static CxList *current; -static void add_menu(UiMenu *menu) { - cx_linked_list_add( - (void**)&menus_begin, - (void**)&menus_end, - offsetof(UiMenu, item.prev), - offsetof(UiMenu, item.next), - menu); -} - -static void add_item(UiMenuItemI *item) { - UiMenu *menu = cxListAt(current, 0); - cx_linked_list_add( - (void**)&menu->items_begin, - (void**)&menu->items_end, - offsetof(UiMenu, item.prev), - offsetof(UiMenu, item.next), - item); -} - -void ui_menu(char *label) { - if(!current) { - current = cxLinkedListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS); - } else { - // free current menu hierarchy - cxListClear(current); - } - - // create menu - UiMenu *menu = malloc(sizeof(UiMenu)); - menu->item.prev = NULL; - menu->item.next = NULL; - menu->item.add_to = (ui_menu_add_f)add_menu_widget; - - menu->label = label; - menu->items_begin = NULL; - menu->items_end = NULL; - menu->parent = NULL; - - 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.add_to = (ui_menu_add_f)add_menu_widget; - - menu->label = label; - menu->items_begin = NULL; - menu->items_end = NULL; - menu->parent = NULL; - - // add submenu to current menu - add_item((UiMenuItemI*)menu); - - // set the submenu to current menu - cxListInsert(current, 0, menu); -} - -void ui_submenu_end() { - if(current->size < 2) { - return; - } - 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_gr(char *label, ui_callback f, void *userdata, ...) { - if(!current) { - return; - } - - UiMenuItem *item = malloc(sizeof(UiMenuItem)); - item->item.prev = NULL; - item->item.next = NULL; - item->item.add_to = (ui_menu_add_f)add_menuitem_widget; - - 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.add_to = (ui_menu_add_f)add_menuitem_st_widget; - - 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); - - add_item((UiMenuItemI*)item); -} - -void ui_menuseparator() { - if(!current) { - return; - } - - UiMenuItemI *item = malloc(sizeof(UiMenuItemI)); - item->prev = NULL; - item->next = NULL; - item->add_to = (ui_menu_add_f)add_menuseparator_widget; - - add_item((UiMenuItemI*)item); -} - -void ui_checkitem(char *label, ui_callback f, void *userdata) { - if(!current) { - return; - } - - UiCheckItem *item = malloc(sizeof(UiCheckItem)); - item->item.prev = NULL; - item->item.next = NULL; - item->item.add_to = (ui_menu_add_f)add_checkitem_widget; - 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.add_to = (ui_menu_add_f)add_checkitemnv_widget; - item->varname = vname; - item->label = label; - - add_item((UiMenuItemI*)item); -} - -void ui_menuitem_list(UiList *items, ui_callback f, void *userdata) { - if(!current) { - return; - } - - UiMenuItemList *item = malloc(sizeof(UiMenuItemList)); - item->item.prev = NULL; - item->item.next = NULL; - item->item.add_to = (ui_menu_add_f)add_menuitem_list_widget; - item->callback = f; - item->userdata = userdata; - item->list = items; - - add_item((UiMenuItemI*)item); -} +static ui_menu_add_f createMenuItem[] = { + /* UI_MENU */ add_menu_widget, + /* UI_MENU_SUBMENU */ add_menu_widget, + /* UI_MENU_ITEM */ add_menuitem_widget, + /* UI_MENU_STOCK_ITEM */ add_menuitem_st_widget, + /* UI_MENU_CHECK_ITEM */ add_checkitem_widget, + /* UI_MENU_CHECK_ITEM_NV */ add_checkitemnv_widget, + /* UI_MENU_ITEM_LIST */ add_menuitem_list_widget, + /* UI_MENU_ITEM_LIST_NV */ NULL, // TODO + /* UI_MENU_SEPARATOR */ add_menuseparator_widget +}; // private menu functions GtkWidget *ui_create_menubar(UiObject *obj) { + UiMenu *menus_begin = uic_get_menu_list(); if(menus_begin == NULL) { return NULL; } @@ -251,7 +67,7 @@ UiMenu *ls = menus_begin; while(ls) { UiMenu *menu = ls; - menu->item.add_to(mb, 0, &menu->item, obj); + add_menu_widget(mb, 0, &menu->item, obj); ls = (UiMenu*)ls->item.next; } @@ -269,7 +85,7 @@ UiMenuItemI *it = menu->items_begin; int index = 0; while(it) { - it->add_to(menu_widget, index, it, obj); + createMenuItem[it->type](menu_widget, index, it, obj); it = it->next; index++;