ui/gtk/menu.c

branch
newapi
changeset 174
0358f1d9c506
parent 168
1b99acacc5bb
child 175
2cb06c231057
--- a/ui/gtk/menu.c	Sat Apr 15 21:06:45 2023 +0200
+++ b/ui/gtk/menu.c	Mon May 22 16:17:26 2023 +0200
@@ -38,48 +38,78 @@
 #include "../ui/window.h"
 #include "container.h"
 
-static UcxList *menus;
-static UcxList *current;
+#include <cx/linked_list.h>
+#include <cx/array_list.h>
+
+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) {
-    // free current menu hierarchy
-    ucx_list_free(current);
+    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  = NULL;
-    menu->parent = NULL;    
+    menu->label        = label;
+    menu->items_begin  = NULL;
+    menu->items_end    = NULL;
+    menu->parent       = NULL;    
     
-    current = ucx_list_prepend(NULL, menu);
-    menus = ucx_list_append(menus, menu);
-    
+    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  = NULL;
-    menu->parent = NULL;
+    menu->label       = label;
+    menu->items_begin = NULL;
+    menu->items_end   = NULL;
+    menu->parent      = NULL;
     
     // add submenu to current menu
-    UiMenu *cm = current->data;
-    cm->items = ucx_list_append(cm->items, menu);
+    add_item((UiMenuItemI*)menu);
     
     // set the submenu to current menu
-    current = ucx_list_prepend(current, menu);
+    cxListInsert(current, 0, menu);
 }
 
 void ui_submenu_end() {
-    if(ucx_list_size(current) < 2) {
+    if(current->size < 2) {
         return;
     }
-    current = ucx_list_remove(current, current);
-    //UcxList *c = current;
+    cxListRemove(current, 0);
 }
 
 void ui_menuitem(char *label, ui_callback f, void *userdata) {
@@ -96,6 +126,8 @@
     }
     
     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;
@@ -108,12 +140,14 @@
     va_start(ap, userdata);
     int group;
     while((group = va_arg(ap, int)) != -1) {
-        item->groups = ucx_list_append(item->groups, (void*)(intptr_t)group);
+        if(!item->groups) {
+            item->groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 8);
+        }
+        cxListAdd(item->groups, &group);
     }
     va_end(ap);
     
-    UiMenu *cm = current->data;
-    cm->items = ucx_list_append(cm->items, item);
+    add_item((UiMenuItemI*)item);
 }
 
 void ui_menuitem_stgr(char *stockid, ui_callback f, void *userdata, ...) {
@@ -122,6 +156,8 @@
     }
     
     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;
@@ -134,12 +170,14 @@
     va_start(ap, userdata);
     int group;
     while((group = va_arg(ap, int)) != -1) {
-        item->groups = ucx_list_append(item->groups, (void*)(intptr_t)group);
+        if(!item->groups) {
+            item->groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 8);
+        }
+        cxListAdd(item->groups, &group);
     }
     va_end(ap);
     
-    UiMenu *cm = current->data;
-    cm->items = ucx_list_append(cm->items, item);
+    add_item((UiMenuItemI*)item);
 }
 
 void ui_menuseparator() {
@@ -148,10 +186,11 @@
     }
     
     UiMenuItemI  *item = malloc(sizeof(UiMenuItemI));
+    item->prev = NULL;
+    item->next = NULL;
     item->add_to = (ui_menu_add_f)add_menuseparator_widget;
     
-    UiMenu *cm = current->data;
-    cm->items = ucx_list_append(cm->items, item);
+    add_item((UiMenuItemI*)item);
 }
 
 void ui_checkitem(char *label, ui_callback f, void *userdata) {
@@ -160,13 +199,14 @@
     }
     
     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;
     
-    UiMenu *cm = current->data;
-    cm->items = ucx_list_append(cm->items, item);
+    add_item((UiMenuItemI*)item);
 }
 
 void ui_checkitem_nv(char *label, char *vname) {
@@ -175,12 +215,13 @@
     }
     
     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;
     
-    UiMenu *cm = current->data;
-    cm->items = ucx_list_append(cm->items, item);
+    add_item((UiMenuItemI*)item);
 }
 
 void ui_menuitem_list(UiList *items, ui_callback f, void *userdata) {
@@ -189,29 +230,30 @@
     }
     
     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;
     
-    UiMenu *cm = current->data;
-    cm->items = ucx_list_append(cm->items, item);
+    add_item((UiMenuItemI*)item);
 }
 
 // private menu functions
 GtkWidget *ui_create_menubar(UiObject *obj) {
-    if(menus == NULL) {
+    if(menus_begin == NULL) {
         return NULL;
     }
     
     GtkWidget *mb = gtk_menu_bar_new();
     
-    UcxList *ls = menus;
+    UiMenu *ls = menus_begin;
     while(ls) {
-        UiMenu *menu = ls->data;
+        UiMenu *menu = ls;
         menu->item.add_to(mb, 0, &menu->item, obj);
         
-        ls = ls->next;
+        ls = (UiMenu*)ls->item.next;
     }
     
     return mb;
@@ -224,13 +266,12 @@
     GtkWidget *menu_item = gtk_menu_item_new_with_mnemonic(menu->label);
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), menu_widget);
     
-    UcxList *ls = menu->items;
+    UiMenuItemI *it = menu->items_begin;
     int index = 0;
-    while(ls) {
-        UiMenuItemI *i = ls->data;
-        i->add_to(menu_widget, index, i, obj);
+    while(it) {
+        it->add_to(menu_widget, index, it, obj);
         
-        ls = ls->next;
+        it = it->next;
         index++;
     }
     
@@ -360,10 +401,10 @@
 
 void add_menuitem_list_widget(GtkWidget *p, int index, UiMenuItemI *item, UiObject *obj) {
     UiMenuItemList *il = (UiMenuItemList*)item;
-    UcxMempool *mp = obj->ctx->mempool;
+    const CxAllocator *a = obj->ctx->allocator;
     
-    UiActiveMenuItemList *ls = ucx_mempool_malloc(
-            mp,
+    UiActiveMenuItemList *ls = cxMalloc(
+            a,
             sizeof(UiActiveMenuItemList));
     
     ls->object = obj;
@@ -519,12 +560,15 @@
     }
     
     // add groups
-    UcxList *groups = NULL;
+    CxList *groups = NULL;
     va_list ap;
     va_start(ap, userdata);
     int group;
     while((group = va_arg(ap, int)) != -1) {
-        ucx_list_append(groups, (void*)(intptr_t)group);
+        if(!groups) {
+            groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16);
+        }
+        cxListAdd(groups, &group);
     }
     va_end(ap);
     
@@ -555,6 +599,7 @@
     
     if(groups) {
         uic_add_group_widget(obj->ctx, widget, (ui_enablefunc)ui_set_enabled, groups);
+        cxListDestroy(groups);
     }
 }
 
@@ -569,12 +614,15 @@
     }
     
     // add groups
-    UcxList *groups = NULL;
+    CxList *groups = NULL;
     va_list ap;
     va_start(ap, userdata);
     int group;
     while((group = va_arg(ap, int)) != -1) {
-        ucx_list_append(groups, (void*)(intptr_t)group);
+        if(!groups) {
+            groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16);
+        }
+        cxListAdd(groups, &group);
     }
     va_end(ap);
     
@@ -605,5 +653,6 @@
     
     if(groups) {
         uic_add_group_widget(obj->ctx, widget, (ui_enablefunc)ui_set_enabled, groups);
+        cxListDestroy(groups);
     }
 }

mercurial