ui/gtk/container.c

changeset 110
c00e968d018b
parent 108
77254bd6dccb
child 112
c3f2f16fa4b8
--- a/ui/gtk/container.c	Sun Aug 24 15:24:16 2025 +0200
+++ b/ui/gtk/container.c	Sat Oct 04 14:52:59 2025 +0200
@@ -28,6 +28,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <limits.h>
 
 #include "container.h"
@@ -37,6 +38,8 @@
 #include "../common/context.h"
 #include "../common/object.h"
 
+#include "../ui/properties.h"
+
 
 void ui_container_begin_close(UiObject *obj) {
     UiContainer *ct = uic_get_current_container(obj);
@@ -193,14 +196,14 @@
     if(!ct->layout.override_defaults) {
         if(grid->def_hexpand) {
             hexpand = TRUE;
-            hfill = TRUE;
-        } else if(grid->def_hfill) {
+        }
+        if(grid->def_hfill) {
             hfill = TRUE;
         }
         if(grid->def_vexpand) {
             vexpand = TRUE;
-            vfill = TRUE;
-        } else if(grid->def_vfill) {
+        }
+        if(grid->def_vfill) {
             vfill = TRUE;
         }
     }
@@ -208,19 +211,21 @@
     UiBool fill = ct->layout.fill;
     if(ct->layout.hexpand) {
         hexpand = TRUE;
-        hfill = TRUE;
-    } else if(ct->layout.hfill) {
+    }
+    if(ct->layout.hfill) {
         hfill = TRUE;
     }
     if(ct->layout.vexpand) {
         vexpand = TRUE;
-        vfill = TRUE;
-    } else if(ct->layout.vfill) {
+    }
+    if(ct->layout.vfill) {
         vfill = TRUE;
     }
     if(fill) {
         hfill = TRUE;
         vfill = TRUE;
+        hexpand = TRUE;
+        vexpand = TRUE;
     }
     
     if(!hfill) {
@@ -1048,6 +1053,35 @@
 }
 #endif
 
+/* ------------------------ Split Window Panels ------------------------ */
+
+static UIWIDGET splitwindow_panel(UiObject *obj, GtkWidget *pbox, UiSidebarArgs *args) {
+    if(!pbox) {
+        fprintf(stderr, "Error: window is not a splitview window\n");
+        return NULL;
+    }
+    
+    GtkWidget *box = ui_gtk_vbox_new(args->spacing);
+    ui_set_name_and_style(box, args->name, args->style_class);
+    ui_box_set_margin(box, args->margin);
+    BOX_ADD_EXPAND(pbox, box);
+    
+    UiObject *newobj = uic_object_new(obj, box);
+    newobj->container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
+    uic_obj_add(obj, newobj);
+    
+    return box;
+}
+
+UIWIDGET ui_left_panel_create(UiObject *obj, UiSidebarArgs *args) {
+    return splitwindow_panel(obj, g_object_get_data(G_OBJECT(obj->widget), "ui_left_panel"), args);
+}
+
+UIWIDGET ui_right_panel_create(UiObject *obj, UiSidebarArgs *args) {
+    return splitwindow_panel(obj, g_object_get_data(G_OBJECT(obj->widget), "ui_right_panel"), args);
+}
+
+
 /* -------------------- Splitpane -------------------- */
 
 static GtkWidget* create_paned(UiOrientation orientation) {
@@ -1065,7 +1099,13 @@
     return NULL;
 }
 
-
+static void save_pane_pos(GtkWidget *widget, char *property_name) {
+    int pos = gtk_paned_get_position(GTK_PANED(widget));
+    char buf[32];
+    snprintf(buf, 32, "%d", pos);
+    ui_set_property(property_name, buf);
+    free(property_name);
+}
 
 static UIWIDGET splitpane_create(UiObject *obj, UiOrientation orientation, UiSplitPaneArgs *args) {
     UiObject* current = uic_current_obj(obj);
@@ -1077,12 +1117,40 @@
     
     int max = args->max_panes == 0 ? 2 : args->max_panes;
     
+    if(args->position_property) {
+        const char *pos_str = ui_get_property(args->position_property);
+        if(pos_str) {
+            char *end;
+            long pos = strtol(pos_str, &end, 10);
+            if(*end == '\0') {
+                args->initial_position = (int)pos;
+            }
+        }
+        
+        g_signal_connect(
+                pane0,
+                "destroy",
+                G_CALLBACK(save_pane_pos),
+                strdup(args->position_property));
+    }
+    
     UiObject *newobj = uic_object_new(obj, pane0);
     newobj->container = ui_splitpane_container(obj, pane0, orientation, max, args->initial_position);
     uic_obj_add(obj, newobj);
     
     g_object_set_data(G_OBJECT(pane0), "ui_splitpane", newobj->container);
     
+    UiVar *var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_INTEGER);
+    if(var) {
+        UiSplitPaneContainer *s = (UiSplitPaneContainer*)newobj->container;
+        UiInteger *i = var->value;
+        s->initial_position = i->value;
+        
+        i->obj = s;
+        i->get = ui_splitpane_get;
+        i->set = ui_splitpane_set;
+    }
+    
     return pane0;
 }
 
@@ -1138,6 +1206,18 @@
     }
 }
 
+int64_t ui_splitpane_get(UiInteger *i) {
+    UiSplitPaneContainer *s = i->obj;
+    i->value = gtk_paned_get_position(GTK_PANED(s->container.widget));
+    return i->value;
+}
+
+void ui_splitpane_set(UiInteger *i, int64_t value) {
+    UiSplitPaneContainer *s = i->obj;
+    i->value = value;
+    gtk_paned_set_position(GTK_PANED(s->container.widget), (int)value);
+}
+
 UIEXPORT void ui_splitpane_set_visible(UIWIDGET splitpane, int child_index, UiBool visible) {
     UiSplitPaneContainer *ct = g_object_get_data(G_OBJECT(splitpane), "ui_splitpane");
     if(!ct) {

mercurial