ui/gtk/list.c

changeset 1248
8a428e2f8ae7
parent 1247
070d0472e6af
child 1249
6bb45d356481
--- a/ui/gtk/list.c	Fri Sep 11 19:26:51 2026 +0200
+++ b/ui/gtk/list.c	Sat Sep 12 10:06:47 2026 +0200
@@ -3154,27 +3154,40 @@
     }
 }
 
+static void listbox2_toggle_node(UiListBox2Row *rowdata) {
+    rowdata->expanded = !rowdata->expanded;
+    if(rowdata->expanded) {
+        IMAGE_SET_ICON(rowdata->expander, "pan-down-symbolic");
+    } else {
+        IMAGE_SET_ICON(rowdata->expander, "pan-end-symbolic");
+    }
+    listbox2_node_children_update_visibility(rowdata, rowdata->expanded);
+}
+
 #if GTK_CHECK_VERSION(4, 0, 0)
 
-void listbox2_node_expand(
+static void listbox2_node_expand(
         GtkGestureClick *self,
         gint n_press,
         gdouble x,
         gdouble y,
         UiListBox2Row *rowdata)
 {
-    rowdata->expanded = !rowdata->expanded;
-    if(rowdata->expanded) {
-        gtk_image_set_from_icon_name(GTK_IMAGE(rowdata->expander), "pan-down-symbolic");
-    } else {
-        gtk_image_set_from_icon_name(GTK_IMAGE(rowdata->expander), "pan-end-symbolic");
-    }
-    listbox2_node_children_update_visibility(rowdata, rowdata->expanded);
+    listbox2_toggle_node(rowdata);
 }
 
 #endif
 #if GTK_MAJOR_VERSION == 3
 
+static gboolean listbox2_node_expand(
+        GtkWidget *widget,
+        GdkEventButton *event,
+        UiListBox2Row *rowdata)
+{
+    listbox2_toggle_node(rowdata);
+    return TRUE;
+}
+
 #endif
 
 #define LISTBOX2_ITEM_HBOX_SPACING 10
@@ -3182,7 +3195,9 @@
     GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, LISTBOX2_ITEM_HBOX_SPACING);
     
     rowdata->expanded = 1;
-    GtkWidget *expander = gtk_image_new_from_icon_name("pan-down-symbolic");
+    GtkWidget *expander = gtk_image_new();
+    GtkWidget *expander0 = expander;
+    IMAGE_SET_ICON(expander, "pan-down-symbolic");
     int exp_width = 0;
 #if GTK_CHECK_VERSION(4, 0, 0)
     gtk_widget_measure(expander,
@@ -3199,6 +3214,16 @@
 #else
     int exp_height;
     gtk_widget_get_preferred_width(expander, &exp_width, &exp_height);
+    
+    expander0 = gtk_event_box_new();
+    gtk_container_add(GTK_CONTAINER(expander0), expander);
+    
+    gtk_widget_set_events(expander, GDK_BUTTON_PRESS_MASK);
+    g_signal_connect(
+            expander0,
+            "button-release-event",
+            G_CALLBACK(listbox2_node_expand),
+            rowdata);
 #endif
     gtk_widget_set_margin_start(hbox, identation * (exp_width+LISTBOX2_ITEM_HBOX_SPACING));
     
@@ -3206,7 +3231,7 @@
     gtk_widget_set_visible(expander, FALSE);
     // normal items have the expander icon in the front
     if(!item->is_header) {
-        BOX_ADD(hbox, expander);
+        BOX_ADD(hbox, expander0);
     }
     rowdata->expander = expander;
     
@@ -3239,7 +3264,7 @@
     
     // headings have the expander at the end
     if(item->is_header) {
-        BOX_ADD(hbox, expander);
+        BOX_ADD(hbox, expander0);
         WIDGET_ADD_CSS_CLASS(label, "ui-listbox-header-row");
         rowdata->heading = TRUE;
     }
@@ -3248,9 +3273,16 @@
     g_object_set_data(G_OBJECT(row), "ui-listbox-row-data", rowdata);
 }
 
+static void listbox2_remove_all(UiListBox2 *listbox) {
+    CxIterator i = cxListIterator(listbox->rows);
+    cx_foreach(UiListBox2Row *, row, i) {
+        LISTBOX_REMOVE(listbox->listbox, row->row);
+    }
+    cxListClear(listbox->rows);
+}
+
 static void listbox2_update_all(UiListBox2 *listbox) {
-    gtk_list_box_remove_all(listbox->listbox);
-    cxListClear(listbox->rows);
+    listbox2_remove_all(listbox);
     if(!listbox->var) {
         return;
     }
@@ -3284,7 +3316,7 @@
         g_signal_connect(row, "leave-notify-event", G_CALLBACK(listbox_row_leave), NULL);
 #endif
         
-        gtk_list_box_append(listbox->listbox, row);
+        gtk_list_box_insert(listbox->listbox, row, -1);
         UiListBox2Row row_data = {0};
         row_data.listbox = listbox;
         row_data.row = row;

mercurial