implement new toolbar (GTK) newapi

Sun, 31 Mar 2024 16:19:01 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 31 Mar 2024 16:19:01 +0200
branch
newapi
changeset 275
132c7bcc6997
parent 274
9e2aee097b69
child 276
376921880a7f

implement new toolbar (GTK)

application/main.c file | annotate | diff | comparison | revisions
ui/gtk/image.c file | annotate | diff | comparison | revisions
ui/gtk/image.h file | annotate | diff | comparison | revisions
ui/gtk/menu.c file | annotate | diff | comparison | revisions
ui/gtk/menu.h file | annotate | diff | comparison | revisions
ui/gtk/toolbar.c file | annotate | diff | comparison | revisions
ui/gtk/toolbar.h file | annotate | diff | comparison | revisions
ui/gtk/toolkit.c file | annotate | diff | comparison | revisions
--- a/application/main.c	Sun Mar 31 09:58:07 2024 +0200
+++ b/application/main.c	Sun Mar 31 16:19:01 2024 +0200
@@ -38,6 +38,7 @@
     UiString *str2;
     UiDouble *progress;
     UiList *list;
+    UiInteger *radio;
 } MyDocument;
 
 MyDocument *doc1;
@@ -56,6 +57,9 @@
     
 }
 
+void action_toolbar_button(UiEvent *event, void *userdata) {
+    
+}
 
 MyDocument* create_doc(void) {
     MyDocument *doc = ui_document_new(sizeof(MyDocument));
@@ -67,6 +71,7 @@
     ui_list_append(doc->list, "test1");
     ui_list_append(doc->list, "test2");
     ui_list_append(doc->list, "test3");
+    doc->radio = ui_int_new(docctx, "radio");
     return doc;
 }
 
@@ -121,6 +126,13 @@
         //UiModel *model = ui_model(obj->ctx, UI_ICON_TEXT, "Col 1", UI_STRING, "Col 2", -1);
         //model->getvalue = list_getvalue;
         ui_combobox(obj, .hexpand = true, .vexpand = false, .colspan = 2, .varname = "list", .getvalue = list_getvalue);
+        ui_newline(obj);
+        
+        ui_hbox0(obj) {
+            ui_radiobutton(obj, .label = "Radio 1", .varname = "radio");
+            ui_radiobutton(obj, .label = "Radio 2", .varname = "radio");
+            ui_radiobutton(obj, .label = "Radio 3", .varname = "radio");
+        }
     }
     
     ui_show(obj);
@@ -135,7 +147,18 @@
         ui_menuitem(.label = "Test");
     }
     
-
+    ui_toolbar_item("Test", .label = "Test", .icon = "terminal", .onclick = action_toolbar_button);
+    ui_toolbar_toggleitem("Toggle", .label = "Toggle", .onchange = action_toolbar_button);
+    ui_toolbar_menu("Menu", .label = "Menu") {
+        ui_menuitem("Secondary Test", NULL, NULL);
+        ui_menu("Secondary Sub") {
+            ui_menuitem("Secondary subitem", NULL, NULL);
+        }
+    }
+    
+    ui_toolbar_add_default("Test", UI_TOOLBAR_LEFT);
+    ui_toolbar_add_default("Toggle", UI_TOOLBAR_LEFT);
+    ui_toolbar_add_default("Menu", UI_TOOLBAR_LEFT);
     
     ui_main();
     
--- a/ui/gtk/image.c	Sun Mar 31 09:58:07 2024 +0200
+++ b/ui/gtk/image.c	Sun Mar 31 16:19:01 2024 +0200
@@ -116,6 +116,13 @@
     return get_icon(name, size, 1);
 }
 
+GdkPixbuf* ui_icon_pixbuf(UiIcon *icon) {
+    if(!icon->pixbuf) {
+        GError *error = NULL;
+        icon->pixbuf = gtk_icon_info_load_icon(icon->info, &error);
+    }
+    return icon->pixbuf;
+}
 
 UiImage* ui_icon_image(UiIcon *icon) {
     GError *error = NULL;
--- a/ui/gtk/image.h	Sun Mar 31 09:58:07 2024 +0200
+++ b/ui/gtk/image.h	Sun Mar 31 16:19:01 2024 +0200
@@ -53,6 +53,7 @@
 
 GdkPixbuf* ui_get_image(const char *name);
 
+GdkPixbuf* ui_icon_pixbuf(UiIcon *icon);
 
 #ifdef	__cplusplus
 }
--- a/ui/gtk/menu.c	Sun Mar 31 09:58:07 2024 +0200
+++ b/ui/gtk/menu.c	Sun Mar 31 16:19:01 2024 +0200
@@ -74,6 +74,16 @@
     return mb;
 }
 
+void ui_add_menu_items(GtkWidget *parent, int i, UiMenu *menu, UiObject *obj) {
+    UiMenuItemI *it = menu->items_begin;
+    int index = 0;
+    while(it) {
+        createMenuItem[it->type](parent, index, it, obj);
+        it = it->next;
+        index++;
+    }
+}
+
 void add_menu_widget(GtkWidget *parent, int i, UiMenuItemI *item, UiObject *obj) {
     UiMenu *menu = (UiMenu*)item;
     
@@ -81,14 +91,8 @@
     GtkWidget *menu_item = gtk_menu_item_new_with_mnemonic(menu->label);
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), menu_widget);
     
-    UiMenuItemI *it = menu->items_begin;
-    int index = 0;
-    while(it) {
-        createMenuItem[it->type](menu_widget, index, it, obj);
-        
-        it = it->next;
-        index++;
-    }
+    ui_add_menu_items(menu_widget, i, menu, obj);
+    
     
     gtk_menu_shell_append(GTK_MENU_SHELL(parent), menu_item);
 }
--- a/ui/gtk/menu.h	Sun Mar 31 09:58:07 2024 +0200
+++ b/ui/gtk/menu.h	Sun Mar 31 16:19:01 2024 +0200
@@ -55,6 +55,8 @@
 
 GtkWidget *ui_create_menubar(UiObject *obj);
 
+void ui_add_menu_items(GtkWidget *parent, int i, UiMenu *menu, UiObject *obj);
+
 void add_menu_widget(GtkWidget *parent, int i, UiMenuItemI *item, UiObject *obj);
 void add_menuitem_widget(GtkWidget *parent, int i, UiMenuItemI *item, UiObject *obj);
 void add_menuitem_st_widget(GtkWidget *p, int i, UiMenuItemI *item, UiObject *obj);
--- a/ui/gtk/toolbar.c	Sun Mar 31 09:58:07 2024 +0200
+++ b/ui/gtk/toolbar.c	Sun Mar 31 16:19:01 2024 +0200
@@ -31,6 +31,7 @@
 #include <string.h>
 
 #include "toolbar.h"
+#include "menu.h"
 #include "button.h"
 #include "image.h"
 #include "tree.h"
@@ -40,192 +41,8 @@
 #include <cx/array_list.h>
 #include "../common/context.h"
 
-static CxMap *toolbar_items;
-static CxList *defaults;
-
-void ui_toolbar_init() {
-    toolbar_items = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16);
-    defaults = cxLinkedListCreateSimple(CX_STORE_POINTERS);
-}
-
-void ui_toolitem(char *name, char *label, ui_callback f, void *udata) {
-    ui_toolitem_img(name, label, NULL, f, udata);
-}
-
-void ui_toolitem_st(char *name, char *stockid, ui_callback f, void *userdata) {
-    ui_toolitem_stgr(name, stockid, f, userdata, -1);
-}
-
-void ui_toolitem_sti(char *name, char *stockid, ui_callback f, void *userdata) {
-    ui_toolitem_stgri(name, stockid, f, userdata, -1);
-}
-
-void ui_toolitem_stgr(char *name, char *stockid, ui_callback f, void *userdata, ...) {
-    va_list ap;
-    va_start(ap, userdata);
-    ui_toolitem_vstgr(name, stockid, 0, f, userdata, ap);
-    va_end(ap);
-}
-
-void ui_toolitem_stgri(char *name, char *stockid, ui_callback f, void *userdata, ...) {
-    va_list ap;
-    va_start(ap, userdata);
-    ui_toolitem_vstgr(name, stockid, 1, f, userdata, ap);
-    va_end(ap);
-}
-
-void ui_toolitem_img(char *name, char *label, char *img, ui_callback f, void *udata) {
-    UiToolItem *item = malloc(sizeof(UiToolItem));
-    item->item.add_to = (ui_toolbar_add_f)add_toolitem_widget;
-    item->label = label;
-    item->image = img;
-    item->callback = f;
-    item->userdata = udata;
-    item->isimportant = 0;
-    item->groups = NULL;
-    
-    cxMapPut(toolbar_items, name, item);
-}
-
-void ui_toolitem_vstgr(
-        char *name,
-        char *stockid,
-        int isimportant,
-        ui_callback f,
-        void *userdata,
-        va_list ap)
-{
-    UiStToolItem *item = malloc(sizeof(UiStToolItem));
-    item->item.add_to = (ui_toolbar_add_f)add_toolitem_st_widget;
-    item->stockid = stockid;
-    item->callback = f;
-    item->userdata = userdata;
-    item->groups = NULL;
-    item->isimportant = isimportant;
-    
-    // add groups
-    int group;
-    while((group = va_arg(ap, int)) != -1) {
-        if(!item->groups) {
-            item->groups = cxArrayListCreateSimple(sizeof(int), 16);
-        }
-        cxListAdd(item->groups, &group);
-    }
-    
-    cxMapPut(toolbar_items, name, item);
-}
-
-void ui_toolitem_toggle(const char *name, const char *label, const char *img, UiInteger *i) {
-    UiToggleToolItem *item = malloc(sizeof(UiToggleToolItem));
-    item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget;
-    item->label = label;
-    item->image = img;
-    item->stockid = NULL;
-    item->groups = NULL;
-    item->isimportant = 0;
-    item->value = i;
-    item->var = NULL;
-    
-    cxMapPut(toolbar_items, name, item);
-}
-
-void ui_toolitem_toggle_st(const char *name, const char *stockid, UiInteger *i) {
-    UiToggleToolItem *item = malloc(sizeof(UiToggleToolItem));
-    item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget;
-    item->label = NULL;
-    item->image = NULL;
-    item->stockid = stockid;
-    item->groups = NULL;
-    item->isimportant = 0;
-    item->value = i;
-    item->var = NULL;
-    
-    cxMapPut(toolbar_items, name, item);
-}
-
-void ui_toolitem_toggle_nv(const char *name, const char *label, const char *img, const char *intvar) {
-    UiToggleToolItem *item = malloc(sizeof(UiToggleToolItem));
-    item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget;
-    item->label = label;
-    item->image = img;
-    item->stockid = NULL;
-    item->groups = NULL;
-    item->isimportant = 0;
-    item->value = NULL;
-    item->var = intvar;
-    
-    cxMapPut(toolbar_items, name, item);
-}
-
-void ui_toolitem_toggle_stnv(const char *name, const char *stockid, const char *intvar) {
-    UiToggleToolItem *item = malloc(sizeof(UiToggleToolItem));
-    item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget;
-    item->label = NULL;
-    item->image = NULL;
-    item->stockid = stockid;
-    item->groups = NULL;
-    item->isimportant = 0;
-    item->value = NULL;
-    item->var = intvar;
-    
-    cxMapPut(toolbar_items, name, item);
-}
-
-
-void ui_toolbar_combobox(
-        char *name,
-        UiList *list,
-        ui_getvaluefunc getvalue,
-        ui_callback f,
-        void *udata)
-{
-    UiToolbarComboBox *cb = malloc(sizeof(UiToolbarComboBox));
-    cb->item.add_to = (ui_toolbar_add_f)add_toolbar_combobox;
-    UiVar *var = malloc(sizeof(UiVar));
-    var->value = list;
-    var->type = UI_VAR_SPECIAL;
-    var->from = NULL;
-    var->from_ctx = NULL;
-    cb->var = var;
-    cb->getvalue = getvalue;
-    cb->callback = f;
-    cb->userdata = udata;
-    
-    cxMapPut(toolbar_items, name, cb);
-}
-
-void ui_toolbar_combobox_str(
-        char *name,
-        UiList *list,
-        ui_callback f,
-        void *udata)
-{
-    ui_toolbar_combobox(name, list, ui_strmodel_getvalue, f, udata);
-}
-
-void ui_toolbar_combobox_nv(
-        char *name,
-        char *listname,
-        ui_getvaluefunc getvalue,
-        ui_callback f,
-        void *udata)
-{
-    UiToolbarComboBoxNV *cb = malloc(sizeof(UiToolbarComboBoxNV));
-    cb->item.add_to = (ui_toolbar_add_f)add_toolbar_combobox_nv;  
-    cb->listname = listname;
-    cb->getvalue = getvalue;
-    cb->callback = f;
-    cb->userdata = udata;
-    
-    cxMapPut(toolbar_items, name, cb);
-}
-
 
 GtkWidget* ui_create_toolbar(UiObject *obj) {
-    if(!defaults) {
-        return NULL;
-    }
-    
     GtkWidget *toolbar = gtk_toolbar_new();
 #ifdef UI_GTK3
     gtk_style_context_add_class(
@@ -233,6 +50,16 @@
             GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
 #endif
     
+    CxMap *items = uic_get_toolbar_items();
+    CxList *left_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_LEFT);
+    CxList *center_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_CENTER);
+    CxList *right_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_RIGHT);
+    
+    ui_toolbar_add_items(obj, toolbar, items, left_defaults);
+    ui_toolbar_add_items(obj, toolbar, items, center_defaults);
+    ui_toolbar_add_items(obj, toolbar, items, right_defaults);
+    
+    /*
     GtkToolbar *tb = GTK_TOOLBAR(toolbar);
     CxIterator i = cxListIterator(defaults);
     cx_foreach(char *, def, i) {
@@ -245,57 +72,84 @@
             fprintf(stderr, "UI Error: Unknown toolbar item: %s\n", def);
         }
     }
+    */
     
     return toolbar;
 }
 
-void add_toolitem_widget(GtkToolbar *tb, UiToolItem *item, UiObject *obj) {
-    GtkToolItem *button = gtk_tool_button_new(NULL, item->label);
-    gtk_tool_item_set_homogeneous(button, FALSE);
-    if(item->image) {
-        GdkPixbuf *pixbuf = ui_get_image(item->image);
-        GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf);
-        gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(button), image);
+static void create_item(UiObject *obj, GtkWidget *toolbar, UiToolbarItemI *i) {
+    GtkToolbar *tb = GTK_TOOLBAR(toolbar);
+    switch(i->type) {
+        case UI_TOOLBAR_ITEM: {
+            add_toolitem_widget(tb, (UiToolbarItem*)i, obj);
+            break;
+        }
+        case UI_TOOLBAR_TOGGLEITEM: {
+            add_toolitem_toggle_widget(tb, (UiToolbarToggleItem*)i, obj);
+            break;
+        }
+        case UI_TOOLBAR_MENU: {
+            add_toolitem_menu_widget(tb, (UiToolbarMenuItem*)i, obj);
+            break;
+        }
+        default: fprintf(stderr, "toolbar item type unimplemented: %d\n", (int)i->type);
+    }
+}
+
+void ui_toolbar_add_items(UiObject *obj, GtkWidget *toolbar, CxMap *items, CxList *defaults) {
+    // add pre-configured items
+    CxIterator i = cxListIterator(defaults);
+    cx_foreach(char*, def, i) {
+        UiToolbarItemI* item = uic_toolbar_get_item(def);
+        if (!item) {
+            fprintf(stderr, "unknown toolbar item: %s\n", def);
+            continue;
+        }
+        create_item(obj, toolbar, item);
+    }
+}
+
+static void set_toolbutton_icon(GtkToolItem *item, const char *icon_name) {
+#if GTK_MAJOR_VERSION >= 3
+        gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(item), icon_name);
+#else
+        UiIcon *icon = ui_icon(icon_name, 24);
+        if(icon) {
+            GdkPixbuf *pixbuf = ui_icon_pixbuf(icon);
+            if(pixbuf) {
+                GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf);
+                gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(item), image);
+            }
+        }
+#endif
+}
+
+void add_toolitem_widget(GtkToolbar *tb, UiToolbarItem *item, UiObject *obj) {
+    GtkToolItem *button;
+    if(item->args.stockid) {
+#ifdef UI_GTK2
+        button = gtk_tool_button_new_from_stock(item->args.stockid);
+#else
+        // TODO: gtk3 stock
+        button = gtk_tool_button_new(NULL, item->args.label);
+#endif
     } else {
-        gtk_tool_item_set_is_important(button, TRUE);
+        button = gtk_tool_button_new(NULL, item->args.label);
     }
     
-    if(item->callback) {
+    gtk_tool_item_set_homogeneous(button, FALSE);
+    if(item->args.icon) {
+        set_toolbutton_icon(button, item->args.icon);
+    }
+    gtk_tool_item_set_is_important(button, TRUE);
+    
+    if(item->args.onclick) {
         UiEventData *event = cxMalloc(
                 obj->ctx->allocator,
                 sizeof(UiEventData));
         event->obj = obj;
-        event->userdata = item->userdata;
-        event->callback = item->callback;
-        
-        g_signal_connect(
-                button,
-                "clicked",
-                G_CALLBACK(ui_button_clicked),
-                event);
-    }
-    
-    gtk_toolbar_insert(tb, button, -1);
-    
-    if(item->groups) {
-        uic_add_group_widget(obj->ctx, button, (ui_enablefunc)ui_set_enabled, item->groups);
-    }
-}
-
-void add_toolitem_st_widget(GtkToolbar *tb, UiStToolItem *item, UiObject *obj) {
-    GtkToolItem *button = gtk_tool_button_new_from_stock(item->stockid);
-    gtk_tool_item_set_homogeneous(button, FALSE);
-    if(item->isimportant) {
-        gtk_tool_item_set_is_important(button, TRUE);
-    }
-    
-    if(item->callback) {
-        UiEventData *event = cxMalloc(
-                obj->ctx->allocator,
-                sizeof(UiEventData));
-        event->obj = obj;
-        event->userdata = item->userdata;
-        event->callback = item->callback;
+        event->callback = item->args.onclick;
+        event->userdata = item->args.onclickdata;
         
         g_signal_connect(
                 button,
@@ -306,74 +160,71 @@
     
     gtk_toolbar_insert(tb, button, -1);
     
+    /*
     if(item->groups) {
         uic_add_group_widget(obj->ctx, button, (ui_enablefunc)ui_set_enabled, item->groups);
     }
+    */
 }
 
-void add_toolitem_toggle_widget(GtkToolbar *tb, UiToggleToolItem *item, UiObject *obj) {
+void add_toolitem_toggle_widget(GtkToolbar *tb, UiToolbarToggleItem *item, UiObject *obj) {
     GtkToolItem *button;
-    if(item->stockid) {
-        button = gtk_toggle_tool_button_new_from_stock(item->stockid);
+    if(item->args.stockid) {
+#ifdef UI_GTK2
+        button = gtk_toggle_tool_button_new_from_stock(item->args.stockid);
+#else
+        button = gtk_toggle_tool_button_new_from_stock(item->args.stockid); // TODO: gtk3 stock
+#endif
     } else {
         button = gtk_toggle_tool_button_new();
         gtk_tool_item_set_homogeneous(button, FALSE);
-        if(item->label) {
-            gtk_tool_button_set_label(GTK_TOOL_BUTTON(button), item->label);
+        if(item->args.label) {
+            gtk_tool_button_set_label(GTK_TOOL_BUTTON(button), item->args.label);
         }
-        if(item->image) {
-            GdkPixbuf *pixbuf = ui_get_image(item->image);
-            GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf);
-            gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(button), image);
+        if(item->args.icon) {
+            set_toolbutton_icon(button, item->args.icon);
         }    
     }
     
-    UiVar *var;
-    if(item->value) {
-        var = malloc(sizeof(UiVar));
-        var->value = item->value;
-        var->type = UI_VAR_SPECIAL;
-        var->from = NULL;
-        var->from_ctx = NULL;
-    } else {
-        var = uic_create_var(obj->ctx, item->var, UI_VAR_INTEGER);
-    }
-    
-    if(var->value) {
-        UiInteger *i = var->value;
-        i->get = ui_tool_toggle_button_get;
-        i->set = ui_tool_toggle_button_set;
-        i->obj = button;
-        
-        if(i->value != 0) {
-            gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(button), TRUE);
+    UiVar* var = uic_widget_var(obj->ctx, obj->ctx, NULL, item->args.varname, UI_VAR_INTEGER);
+    if(var) {
+        UiInteger *i = (UiInteger*)var->value;
+	if(i) {
+            i->get = ui_tool_toggle_button_get;
+            i->set = ui_tool_toggle_button_set;
+            i->obj = button;
+
+            if(i->value != 0) {
+                gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(button), TRUE);
+            }
         }
     }
     
-    // register event
-    // the event func will call the UiInteger observer callbacks
-    UiEventData *event = cxMalloc(
-            obj->ctx->allocator,
-            sizeof(UiEventData));
+    UiVarEventData *event = cxMalloc(
+                obj->ctx->allocator,
+                sizeof(UiVarEventData));
     event->obj = obj;
-    event->userdata = var;
-    event->callback = NULL;
+    event->callback = item->args.onchange;
+    event->userdata = item->args.onchangedata;
+    event->var = var;
 
     g_signal_connect(
-            button,
-            "toggled",
-            G_CALLBACK(ui_tool_button_toggled),
-            event);
+        button,
+        "toggled",
+        G_CALLBACK(ui_tool_button_toggled),
+        event);
     
     // add item to toolbar
     gtk_toolbar_insert(tb, button, -1);
     
+    /*
     if(item->groups) {
         uic_add_group_widget(obj->ctx, button, (ui_enablefunc)ui_set_enabled, item->groups);
     }
+    */
 }
 
-void ui_tool_button_toggled(GtkToggleToolButton *widget, UiEventData *event) {
+void ui_tool_button_toggled(GtkToggleToolButton *widget, UiVarEventData *event) {
     UiEvent e;
     e.obj = event->obj;
     e.window = event->obj->window;
@@ -381,10 +232,16 @@
     e.eventdata = NULL;
     e.intval = gtk_toggle_tool_button_get_active(widget);
     
-    UiVar *var = event->userdata;
-    UiInteger *i = var->value;
+    if(event->callback) {
+        event->callback(&e, event->userdata);
+    }
     
-    ui_notify_evt(i->observers, &e);
+    UiVar *var = event->var;
+    UiInteger *i = var ? var->value : NULL;
+    
+    if(i) {
+        ui_notify_evt(i->observers, &e);
+    }
 }
 
 int64_t ui_tool_toggle_button_get(UiInteger *integer) {
@@ -398,6 +255,70 @@
     integer->value = s;
 }
 
+
+
+typedef struct UiToolbarMenuWidget {
+    GtkWidget *button;
+    GtkMenu *menu;
+} UiToolbarMenuWidget;
+
+static void ui_toolbar_menubutton_clicked(GtkWidget *widget, UiToolbarMenuWidget *menu) {
+    int x;
+    gtk_menu_popup_at_widget(menu->menu, menu->button, GDK_GRAVITY_SOUTH_WEST, GDK_GRAVITY_NORTH_WEST, NULL);
+}
+
+static void ui_toolbar_menubutton_destroy(GtkWidget *widget, UiToolbarMenuWidget *menu) {
+    free(menu);
+}
+
+void add_toolitem_menu_widget(GtkToolbar *tb, UiToolbarMenuItem *item, UiObject *obj) {
+    GtkToolItem *button;
+    if(item->args.stockid) {
+#ifdef UI_GTK2
+        button = gtk_tool_button_new_from_stock(item->args.stockid);
+#else
+        // TODO: gtk3 stock
+        button = gtk_tool_button_new(NULL, item->args.label);
+#endif
+    } else {
+        button = gtk_tool_button_new(NULL, item->args.label);
+    }
+    
+    gtk_tool_item_set_homogeneous(button, FALSE);
+    if(item->args.icon) {
+        set_toolbutton_icon(button, item->args.icon);
+    }
+    gtk_tool_item_set_is_important(button, TRUE);
+    
+    gtk_toolbar_insert(tb, button, -1);
+    
+    // menu
+    GtkWidget *menu_widget = gtk_menu_new();
+    ui_add_menu_items(menu_widget, 0, &item->menu, obj); 
+    gtk_widget_show_all(menu_widget);
+    
+    UiToolbarMenuWidget *tbmenu = malloc(sizeof(UiToolbarMenuWidget));
+    tbmenu->button = GTK_WIDGET(button);
+    tbmenu->menu = GTK_MENU(menu_widget);
+    
+    g_signal_connect(
+                button,
+                "clicked",
+                G_CALLBACK(ui_toolbar_menubutton_clicked),
+                tbmenu);
+    
+    g_signal_connect(
+                button,
+                "destroy",
+                G_CALLBACK(ui_toolbar_menubutton_destroy),
+                tbmenu);
+}
+
+
+
+
+// deprecated / unsupported
+/*
 void add_toolbar_combobox(GtkToolbar *tb, UiToolbarComboBox *cb, UiObject *obj) {
     UiModel *modelinfo = ui_model(obj->ctx, UI_STRING, "", -1);
     modelinfo->getvalue = cb->getvalue;
@@ -422,4 +343,5 @@
         gtk_toolbar_insert(tb, item, -1);
     }
 }
+*/
 
--- a/ui/gtk/toolbar.h	Sun Mar 31 09:58:07 2024 +0200
+++ b/ui/gtk/toolbar.h	Sun Mar 31 16:19:01 2024 +0200
@@ -30,10 +30,10 @@
 #define	TOOLBAR_H
 
 #include "../ui/toolbar.h"
+#include "../common/toolbar.h"
 #include <cx/map.h>
 #include <cx/list.h>
 
-#include "model.h"
 #include "tree.h"
 
 #ifdef	__cplusplus
@@ -102,7 +102,6 @@
     void                *userdata;
 };
 
-void ui_toolbar_init();
 
 void ui_toolitem_vstgr(
         char *name,
@@ -114,16 +113,20 @@
 
 GtkWidget* ui_create_toolbar(UiObject *obj);
 
-void add_toolitem_widget(GtkToolbar *tb, UiToolItem *item, UiObject *obj);
-void add_toolitem_st_widget(GtkToolbar *tb, UiStToolItem *item, UiObject *obj);
-void add_toolitem_toggle_widget(GtkToolbar *tb, UiToggleToolItem *item, UiObject *obj);
+void ui_toolbar_add_items(UiObject *obj, GtkWidget *toolbar, CxMap *items, CxList *defaults);
 
+void add_toolitem_widget(GtkToolbar *tb, UiToolbarItem *item, UiObject *obj);
+void add_toolitem_toggle_widget(GtkToolbar *tb, UiToolbarToggleItem *item, UiObject *obj);
+void add_toolitem_menu_widget(GtkToolbar *tb, UiToolbarMenuItem *item, UiObject *obj);
+
+/*
 void add_toolbar_combobox(GtkToolbar *tb, UiToolbarComboBox *cb, UiObject *obj);
 void add_toolbar_combobox_nv(GtkToolbar *tb, UiToolbarComboBoxNV *cb, UiObject *obj);
 void ui_combobox_change_event(GtkComboBox *widget, UiEventData *e);
 void ui_combobox_update(UiEvent *event, void *combobox);
+*/
 
-void ui_tool_button_toggled(GtkToggleToolButton *widget, UiEventData *event);
+void ui_tool_button_toggled(GtkToggleToolButton *widget, UiVarEventData *event);
 int64_t ui_tool_toggle_button_get(UiInteger *integer);
 void ui_tool_toggle_button_set(UiInteger *integer, int64_t value);
 
--- a/ui/gtk/toolkit.c	Sun Mar 31 09:58:07 2024 +0200
+++ b/ui/gtk/toolkit.c	Sun Mar 31 16:19:01 2024 +0200
@@ -33,7 +33,6 @@
 
 #include "toolkit.h"
 #include "toolbar.h"
-#include "model.h"
 #include "image.h"
 #include "../common/document.h"
 #include "../common/properties.h"
@@ -73,13 +72,9 @@
     application_name = appname;
     
     uic_docmgr_init();
-    ui_toolbar_init(); // TODO: remove
     
     uic_toolbar_init();
     
-    // init custom types
-    ui_list_init();
-    
     ui_image_init();
     
     uic_load_app_properties();

mercurial