move toolbar items to the next pane, when splitpane is hidden (GTK)

Sat, 13 Jun 2026 14:12:43 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 13 Jun 2026 14:12:43 +0200
changeset 1194
91696f7fa475
parent 1193
28c603de3f21
child 1195
6ec3c71ba298

move toolbar items to the next pane, when splitpane is hidden (GTK)

application/main.c file | annotate | diff | comparison | revisions
ui/gtk/headerbar.c file | annotate | diff | comparison | revisions
ui/gtk/headerbar.h file | annotate | diff | comparison | revisions
ui/gtk/toolkit.c file | annotate | diff | comparison | revisions
ui/gtk/window.c file | annotate | diff | comparison | revisions
--- a/application/main.c	Sat Jun 13 12:03:09 2026 +0200
+++ b/application/main.c	Sat Jun 13 14:12:43 2026 +0200
@@ -271,6 +271,12 @@
     ui_dialog(event->obj, .title = "Dialog Title", .content = "Content Label", .button1_label = "btn1", .button2_label = "btn2", .input = TRUE, .closebutton_label = "Cancel");
 }
 
+static int toggle_pane0 = 0;
+void action_toolbar_pane0(UiEvent *event, void *userdata) {
+    ui_splitview_window_set_visible(event->obj, 0, toggle_pane0);
+    toggle_pane0 = !toggle_pane0;
+}
+
 void action_dialog_button(UiEvent *event, void *userdata) {
     ui_close(event->obj);
 }
@@ -945,6 +951,8 @@
     }
     
     ui_toolbar_item("Test", .label = "Test", .onclick = action_toolbar_button);
+    ui_toolbar_item("Pane0", .label = "Pane0", .onclick = action_toolbar_pane0);
+    ui_toolbar_item("Test1", .label = "Test1", .onclick = action_toolbar_button);
     ui_toolbar_item("Test2", .label = "New Window", .onclick = action_toolbar_newwindow);
     ui_toolbar_item("Test3", .label = "Dialog", .onclick = action_toolbar_dialog);
     ui_toolbar_item("Test4", .label = "Unref Window", .onclick = action_toolbar_unrefwindow);
@@ -979,6 +987,7 @@
         ui_menuitem("Close");
     }
     
+    ui_toolbar_add_default("Pane0", UI_TOOLBAR_LEFT);
     ui_toolbar_add_default("Test", UI_TOOLBAR_LEFT);
     ui_toolbar_add_default("Test6", UI_TOOLBAR_LEFT);
     ui_toolbar_add_default("Toggle", UI_TOOLBAR_LEFT);
@@ -990,6 +999,8 @@
     ui_toolbar_add_default("Test4", UI_TOOLBAR_RIGHT);
     ui_toolbar_add_default("Test5", UI_TOOLBAR_RIGHT);
     
+    ui_toolbar_add_default("Test1", UI_TOOLBAR_RIGHTPANEL_LEFT);
+    
     threadpool = ui_threadpool_create(10);
     
     // test
--- a/ui/gtk/headerbar.c	Sat Jun 13 12:03:09 2026 +0200
+++ b/ui/gtk/headerbar.c	Sat Jun 13 14:12:43 2026 +0200
@@ -30,6 +30,9 @@
 
 #include "button.h"
 #include "menu.h"
+#include "../ui/widget.h"
+
+#include <cx/array_list.h>
 
 #include "../ui/properties.h"
 
@@ -66,53 +69,63 @@
     }
     
     // main toolbar
-    ui_headerbar_add_items(obj, main_headerbar, left_defaults, UI_TOOLBAR_LEFT);
-    ui_headerbar_add_items(obj, main_headerbar, center_defaults, UI_TOOLBAR_CENTER);
+    ui_headerbar_add_items(obj, main_headerbar, left_defaults, UI_TOOLBAR_LEFT, NULL);
+    ui_headerbar_add_items(obj, main_headerbar, center_defaults, UI_TOOLBAR_CENTER, NULL);
     
     if(appmenu && appmenu_pos == UI_TOOLBAR_RIGHT) {
         ui_add_headerbar_menu(main_headerbar, NULL, appmenu, obj, UI_TOOLBAR_RIGHT);
     }
-    ui_headerbar_add_items(obj, main_headerbar, right_defaults, UI_TOOLBAR_RIGHT);
+    ui_headerbar_add_items(obj, main_headerbar, right_defaults, UI_TOOLBAR_RIGHT, NULL);
     
     // sidebar
     if(sidebar_headerbar) {
         // ui_headerbar_add_items pos parameter uses only UI_TOOLBAR_LEFT, UI_TOOLBAR_CENTER, UI_TOOLBAR_RIGHT
-        ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_left_defaults, UI_TOOLBAR_LEFT);
+        ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_left_defaults, UI_TOOLBAR_LEFT, NULL);
 
         if(appmenu && appmenu_pos == UI_TOOLBAR_SIDEBAR_RIGHT) {
             ui_add_headerbar_menu(sidebar_headerbar, NULL, appmenu, obj, UI_TOOLBAR_RIGHT);
         }
-        ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_right_defaults, UI_TOOLBAR_RIGHT);
+        ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_right_defaults, UI_TOOLBAR_RIGHT, NULL);
     }
     
     // right panel
     if(right_headerbar) {
-        ui_headerbar_add_items(obj, right_headerbar, rightpanel_left_defaults, UI_TOOLBAR_LEFT);
-        ui_headerbar_add_items(obj, right_headerbar, rightpanel_center_defaults, UI_TOOLBAR_CENTER);
+        // also add central toolbar items, in case the central pane is hidden
+        CxList *backup_toolbar_widgets = cxArrayListCreate(obj->ctx->allocator, CX_STORE_POINTERS, 16);
+        ui_headerbar_add_items(obj, right_headerbar, left_defaults, UI_TOOLBAR_LEFT, backup_toolbar_widgets);
+        ui_headerbar_add_items(obj, right_headerbar, center_defaults, UI_TOOLBAR_LEFT, backup_toolbar_widgets);
+        ui_headerbar_add_items(obj, right_headerbar, right_defaults, UI_TOOLBAR_LEFT, backup_toolbar_widgets);
+        CxIterator i = cxListIterator(backup_toolbar_widgets);
+        cx_foreach(GtkWidget *, w, i) {
+            ui_set_visible(w, FALSE);
+        }
+        g_object_set_data(G_OBJECT(obj->widget), "ui_toolbar_center_backup", backup_toolbar_widgets);
+        
+        // main items for the right panel
+        ui_headerbar_add_items(obj, right_headerbar, rightpanel_left_defaults, UI_TOOLBAR_LEFT, NULL);
+        ui_headerbar_add_items(obj, right_headerbar, rightpanel_center_defaults, UI_TOOLBAR_CENTER, NULL);
 
         if(appmenu && appmenu_pos == UI_TOOLBAR_RIGHTPANEL_RIGHT) {
             ui_add_headerbar_menu(right_headerbar, NULL, appmenu, obj, UI_TOOLBAR_RIGHT);
         }
-        ui_headerbar_add_items(obj, right_headerbar, rightpanel_right_defaults, UI_TOOLBAR_RIGHT);
+        ui_headerbar_add_items(obj, right_headerbar, rightpanel_right_defaults, UI_TOOLBAR_RIGHT, NULL);
     }
 }
 
-static void create_item(UiObject *obj, GtkWidget *headerbar, GtkWidget *box, UiToolbarItemI *i, enum UiToolbarPos pos) {
+static GtkWidget* create_item(UiObject *obj, GtkWidget *headerbar, GtkWidget *box, UiToolbarItemI *i, enum UiToolbarPos pos) {
     switch(i->type) {
         case UI_TOOLBAR_ITEM: {
-            ui_add_headerbar_item(headerbar, box, (UiToolbarItem*)i, obj, pos);
-            break;
+            return ui_add_headerbar_item(headerbar, box, (UiToolbarItem*)i, obj, pos);
         }
         case UI_TOOLBAR_TOGGLEITEM: {
-            ui_add_headerbar_toggleitem(headerbar, box, (UiToolbarToggleItem*)i, obj, pos);
-            break;
+            return ui_add_headerbar_toggleitem(headerbar, box, (UiToolbarToggleItem*)i, obj, pos);
         }
         case UI_TOOLBAR_MENU: {
-            ui_add_headerbar_menu(headerbar, box, (UiToolbarMenuItem*)i, obj, pos);
-            break;
+            return ui_add_headerbar_menu(headerbar, box, (UiToolbarMenuItem*)i, obj, pos);
         }
         default: fprintf(stderr, "toolbar item type unimplemented: %d\n", (int)i->type);
     }
+    return NULL;
 }
 
 static void headerbar_add(GtkWidget *headerbar, GtkWidget *box, GtkWidget *item, enum UiToolbarPos pos) {
@@ -137,12 +150,15 @@
     }
 }
 
-void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos) {
+void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos, CxList *out_items) {
     GtkWidget *box = NULL;
     
     if(pos == UI_TOOLBAR_CENTER && cxListSize(items) > 0) {
         box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
         UI_HEADERBAR_SET_TITLE_WIDGET(headerbar, box);
+        if(out_items) {
+            cxListAdd(out_items, box);
+        }
     }
     
     CxIterator i = pos == UI_TOOLBAR_RIGHT ? cxListBackwardsIterator(items) : cxListIterator(items);
@@ -152,11 +168,14 @@
             fprintf(stderr, "unknown toolbar item: %s\n", def);
             continue;
         }
-        create_item(obj, headerbar, box, item, pos);
+        GtkWidget *item_widget = create_item(obj, headerbar, box, item, pos);
+        if(out_items && !box) {
+            cxListAdd(out_items, item_widget);
+        }
     }
 }
 
-void ui_add_headerbar_item(
+GtkWidget* ui_add_headerbar_item(
         GtkWidget *headerbar,
         GtkWidget *box,
         UiToolbarItem *item,
@@ -168,9 +187,10 @@
     ui_set_widget_visibility_states(obj->ctx, button, item->args.visibility_states);
     WIDGET_ADD_CSS_CLASS(button, "flat");
     headerbar_add(headerbar, box, button, pos);
+    return button;
 }
 
-void ui_add_headerbar_toggleitem(
+GtkWidget* ui_add_headerbar_toggleitem(
         GtkWidget *headerbar,
         GtkWidget *box,
         UiToolbarToggleItem *item,
@@ -183,9 +203,10 @@
     WIDGET_ADD_CSS_CLASS(button, "flat");
     ui_setup_togglebutton(obj, button, item->args.label, item->args.icon, item->args.tooltip, item->args.varname, NULL, item->args.onchange, item->args.onchangedata, item->args.action, 0);
     headerbar_add(headerbar, box, button, pos);
+    return button;
 }
 
-void ui_add_headerbar_menu(
+GtkWidget* ui_add_headerbar_menu(
         GtkWidget *headerbar,
         GtkWidget *box,
         UiToolbarMenuItem *item,
@@ -222,6 +243,8 @@
 #endif
     
     headerbar_add(headerbar, box, menubutton, pos);
+    
+    return menubutton;
 }
     
 #endif // GTK_CHECK_VERSION(3, 10, 0)
--- a/ui/gtk/headerbar.h	Sat Jun 13 12:03:09 2026 +0200
+++ b/ui/gtk/headerbar.h	Sat Jun 13 14:12:43 2026 +0200
@@ -65,23 +65,23 @@
     
 void ui_fill_headerbar(UiObject *obj, GtkWidget *sidebar_headerbar, GtkWidget *main_headerbar, GtkWidget *right_headerbar);
 
-void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos);
+void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos, CxList *out_items);
 
-void ui_add_headerbar_item(
+GtkWidget* ui_add_headerbar_item(
         GtkWidget *headerbar,
         GtkWidget *box,
         UiToolbarItem *item,
         UiObject *obj,
         enum UiToolbarPos pos);
 
-void ui_add_headerbar_toggleitem(
+GtkWidget* ui_add_headerbar_toggleitem(
         GtkWidget *headerbar,
         GtkWidget *box,
         UiToolbarToggleItem *item,
         UiObject *obj,
         enum UiToolbarPos pos);
 
-void ui_add_headerbar_menu(
+GtkWidget* ui_add_headerbar_menu(
         GtkWidget *headerbar,
         GtkWidget *box,
         UiToolbarMenuItem *item,
--- a/ui/gtk/toolkit.c	Sat Jun 13 12:03:09 2026 +0200
+++ b/ui/gtk/toolkit.c	Sat Jun 13 14:12:43 2026 +0200
@@ -259,7 +259,7 @@
 #endif
 }
 
-void ui_set_visible(UIWIDGET widget, UiBool visible) {
+void ui_set_visible(UIWIDGET widget, int visible) {
 #if GTK_MAJOR_VERSION >= 4
     gtk_widget_set_visible(widget, visible);
 #else
--- a/ui/gtk/window.c	Sat Jun 13 12:03:09 2026 +0200
+++ b/ui/gtk/window.c	Sat Jun 13 14:12:43 2026 +0200
@@ -45,6 +45,7 @@
 #include "headerbar.h"
 #include "button.h"
 #include "window.h"
+#include "widget.h"
 
 static int nwindows = 0;
 
@@ -481,10 +482,13 @@
 
 UIEXPORT void ui_splitview_window_set_visible(UiObject *obj, int pane, UiBool visible) {
     GtkWidget *panel = NULL;
+    CxList *backup_items = NULL;
     if(pane == 0) {
         panel = g_object_get_data(G_OBJECT(obj->widget), "ui_left_panel_top");
+        backup_items = g_object_get_data(G_OBJECT(obj->widget), "ui_toolbar_center_backup");
     } else if(pane == 1) {
         panel = g_object_get_data(G_OBJECT(obj->widget), "ui_right_panel_top");
+        // TODO: backup toolbar items
     }
     
     if(panel == NULL) {
@@ -493,6 +497,13 @@
     }
     
     gtk_widget_set_visible(panel, visible);
+    
+    if(backup_items) {
+        CxIterator i = cxListIterator(backup_items);
+        cx_foreach(GtkWidget*, w, i) {
+            ui_set_visible(w, !visible);
+        }
+    }
 }
 
 #ifdef UI_LIBADWAITA

mercurial