take manage status of child widgets into account in the grid layout (Motif)

Thu, 20 Nov 2025 20:09:00 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 20 Nov 2025 20:09:00 +0100
changeset 921
c2b318b93062
parent 920
10a783120051
child 922
20dff5f878e1

take manage status of child widgets into account in the grid layout (Motif)

application/main.c file | annotate | diff | comparison | revisions
ui/motif/Grid.c file | annotate | diff | comparison | revisions
ui/motif/Grid.h file | annotate | diff | comparison | revisions
--- a/application/main.c	Wed Nov 19 18:30:53 2025 +0100
+++ b/application/main.c	Thu Nov 20 20:09:00 2025 +0100
@@ -924,6 +924,8 @@
     UiDouble *num;
     UiInteger *toggle1;
     UiInteger *toggle2;
+    
+    UiInteger *checkbox1;
 } WData;
 
 
@@ -969,6 +971,15 @@
     printf("toggle2: %d\n\n", (int)ui_get(wdata->toggle2));
 }
 
+static void action_show_button1(UiEvent *event, void *data) {
+    WData *wdata = event->window;
+    if(event->intval) {
+        ui_set_group(event->obj->ctx, 10);
+    } else {
+        ui_unset_group(event->obj->ctx, 10);
+    }
+}
+
 void application_startup(UiEvent *event, void *data) {
     
     menulist = ui_list_new(ui_global_context(), "menulist");
@@ -987,6 +998,7 @@
     wdata->num = ui_double_new(obj->ctx, "num");
     wdata->toggle1 = ui_int_new(obj->ctx, "toggle1");
     wdata->toggle2 = ui_int_new(obj->ctx, "toggle2");
+    wdata->checkbox1 = ui_int_new(obj->ctx, NULL);
     obj->window = wdata;
     
     ui_list_append(wdata->list, "List Item 1");
@@ -1007,42 +1019,25 @@
     */
     
     ui_button(obj, .label = "Next Tab", .onclick = action_next_tab);
-    ui_tabview_w(obj, wdata->tabview, .value = wdata->tab, .fill = UI_ON) {
+    ui_tabview_w(obj, wdata->tabview, .value = wdata->tab, .fill = UI_ON) {  
         ui_tab(obj, "Tab 1") {
-            ui_textarea(obj, .varname = "text", .fill = UI_ON);
+            ui_vbox(obj, .margin = 10, .spacing = 10) {
+                UIWIDGET w = ui_button(obj, .label = "Button 1");
+                int state = 10;
+                ui_widget_set_visibility_states(obj->ctx, w, &state, 1);
+                ui_button(obj, .label = "Button 2");
+                ui_checkbox(obj, .label = "Hide Button 1", .value = wdata->checkbox1, .onchange = action_show_button1);
+            }
         }
         
         ui_tab(obj, "Tab 2") {
-            ui_combobox(obj, .list = wdata->list);
-            ui_label(obj, .label = "Test");
-            ui_separator(obj, .name = "s1");
-        }
-        
-        ui_tab(obj, "Tab 3") {
-            ui_button(obj, .label = "Test Tab 3", .onclick = action_remove_tab3);
-        }
-        
-        ui_tab(obj, "Tab 4") {
-            ui_grid(obj, .margin = 10) {
-                ui_spinbox(obj, .varname = "num");
-            }
-        }
-        
-        ui_tab(obj, "Tab 5") {
-            ui_grid(obj, .margin = 0, .columnspacing = 10, .rowspacing = 10) {
-                ui_button(obj, .label = "Button");
-                ui_button(obj, .label = "Button");
-                ui_button(obj, .label = "Button");
-                ui_newline(obj);
-                
-                for(int i=0;i<10;i++) {
-                    ui_button(obj, .label = "Margin", .margin_left = 2*i);
-                    ui_newline(obj);
-                }
-            }
+            
         }
     }
     
+    ui_set(wdata->checkbox1, 1);
+    ui_set_group(obj->ctx, 10);
+    
     
     ui_show(obj);
     
--- a/ui/motif/Grid.c	Wed Nov 19 18:30:53 2025 +0100
+++ b/ui/motif/Grid.c	Thu Nov 20 20:09:00 2025 +0100
@@ -60,7 +60,7 @@
         XmRDimension,
         sizeof (Dimension),
         XtOffsetOf( GridRec,
-                   mywidget.columnspacing),
+                   grid.columnspacing),
         XmRImmediate,
         (XtPointer) 0
     },
@@ -70,7 +70,7 @@
         XmRDimension,
         sizeof (Dimension),
         XtOffsetOf( GridRec,
-                   mywidget.rowspacing),
+                   grid.rowspacing),
         XmRImmediate,
         (XtPointer) 0
     },
@@ -80,7 +80,7 @@
         XmRDimension,
         sizeof (Dimension),
         XtOffsetOf( GridRec,
-                   mywidget.padding_left),
+                   grid.padding_left),
         XmRImmediate,
         (XtPointer) 0
     },
@@ -90,7 +90,7 @@
         XmRDimension,
         sizeof (Dimension),
         XtOffsetOf( GridRec,
-                   mywidget.padding_right),
+                   grid.padding_right),
         XmRImmediate,
         (XtPointer) 0
     },
@@ -100,7 +100,7 @@
         XmRDimension,
         sizeof (Dimension),
         XtOffsetOf( GridRec,
-                   mywidget.padding_top),
+                   grid.padding_top),
         XmRImmediate,
         (XtPointer) 0
     },
@@ -110,7 +110,7 @@
         XmRDimension,
         sizeof (Dimension),
         XtOffsetOf( GridRec,
-                   mywidget.padding_bottom),
+                   grid.padding_bottom),
         XmRImmediate,
         (XtPointer) 0
     }
@@ -335,8 +335,8 @@
 void grid_initialize(Widget request, Widget new, ArgList args, Cardinal num_args) {
     Grid mn = (Grid)new;
     
-    mn->mywidget.max_col = 0;
-    mn->mywidget.max_row = 0;
+    mn->grid.max_col = 0;
+    mn->grid.max_row = 0;
     
 }
 void grid_realize(Widget w,XtValueMask *valueMask,XSetWindowAttributes *attributes) {
@@ -394,17 +394,17 @@
 }
 
 void GridChangeManaged(Widget widget) {
-    
+    grid_place_children((Grid)widget);
 }
 
 Boolean ConstraintSetValues(Widget old, Widget request, Widget neww, ArgList args, Cardinal *num_args) {
     GridConstraintRec *constraints = neww->core.constraints;
     Grid grid = (Grid)XtParent(neww);
-    if(constraints->grid.x > grid->mywidget.max_col) {
-        grid->mywidget.max_col = constraints->grid.x;
+    if(constraints->grid.x > grid->grid.max_col) {
+        grid->grid.max_col = constraints->grid.x;
     }
-    if(constraints->grid.y > grid->mywidget.max_row) {
-        grid->mywidget.max_row = constraints->grid.y;
+    if(constraints->grid.y > grid->grid.max_row) {
+        grid->grid.max_row = constraints->grid.y;
     }
 }
 
@@ -419,25 +419,29 @@
     GridConstraintRec *constraints = neww->core.constraints;
     
     Grid grid = (Grid)XtParent(neww);
-    if(constraints->grid.x > grid->mywidget.max_col) {
-        grid->mywidget.max_col = constraints->grid.x;
+    if(constraints->grid.x > grid->grid.max_col) {
+        grid->grid.max_col = constraints->grid.x;
     }
-    if(constraints->grid.y > grid->mywidget.max_row) {
-        grid->mywidget.max_row = constraints->grid.y;
+    if(constraints->grid.y > grid->grid.max_row) {
+        grid->grid.max_row = constraints->grid.y;
     }
     constraints->grid.pref_width = neww->core.width;
     constraints->grid.pref_height = neww->core.height;
 }
 
 void grid_place_children(Grid w) {
-    int ncols = w->mywidget.max_col+1;
-    int nrows = w->mywidget.max_row+1;
+    if(!XtIsRealized((Widget)w)) {
+        return;
+    }
+    
+    int ncols = w->grid.max_col+1;
+    int nrows = w->grid.max_row+1;
     GridDef *cols = calloc(ncols, sizeof(GridDef));
     GridDef *rows = calloc(nrows, sizeof(GridDef));
     int num_cols_expanding = 0;
     int num_rows_expanding = 0;
-    int req_width = w->mywidget.padding_left + w->mywidget.padding_right;
-    int req_height = w->mywidget.padding_top + w->mywidget.padding_bottom;
+    int req_width = w->grid.padding_left + w->grid.padding_right;
+    int req_height = w->grid.padding_top + w->grid.padding_bottom;
     int width = w->core.width;
     int height = w->core.height;
     
@@ -462,6 +466,10 @@
             }
             int elm_width = constraints->grid.pref_width + constraints->grid.margin_left + constraints->grid.margin_right;
             int elm_height = constraints->grid.pref_height + constraints->grid.margin_top + constraints->grid.margin_bottom;
+            if(!XtIsManaged(child)) {
+                elm_width = 0;
+                elm_height = 0;
+            }
             
             if(constraints->grid.colspan > span_max || constraints->grid.rowspan > span_max) {
                 continue;
@@ -564,10 +572,23 @@
         req_height += rows[i].size;
     }
     
+    int total_colspacing = 0;
+    int total_rowspacing = 0;
+    for(int i=0;i+1<ncols;i++) {
+        if(cols[i].size > 0) {
+            total_colspacing += w->grid.columnspacing;
+        }
+    }
+    for(int i=0;i+1<nrows;i++) {
+        if(rows[i].size > 0) {
+            total_rowspacing += w->grid.rowspacing;
+        }
+    }
+    
     if(req_width > 0 && req_height > 0) {
         // add col/row spacing
-        req_width += (ncols-1)*w->mywidget.columnspacing;
-        req_height += (nrows-1)*w->mywidget.rowspacing;
+        req_width += total_colspacing; //(ncols-1)*w->grid.columnspacing;
+        req_height += total_rowspacing; //(nrows-1)*w->grid.rowspacing;
         
         Widget parent = w->core.parent;
         Dimension rwidth = req_width;
@@ -579,9 +600,9 @@
             //rheight = w->core.height;
         }
         
-        if(!w->mywidget.sizerequest) {
+        if(!w->grid.sizerequest) {
             Dimension actual_width, actual_height;
-            w->mywidget.sizerequest = TRUE;
+            w->grid.sizerequest = TRUE;
             
             //printf("sizerequest: %d x %d\n", (int)req_width, (int)req_height);
             
@@ -592,7 +613,7 @@
             //XtGeometryResult result = XtMakeGeometryRequest((Widget)w, &request, &reply);
             
             XtMakeResizeRequest((Widget)w, req_width, req_height, &actual_width, &actual_height);
-            w->mywidget.sizerequest = FALSE;
+            w->grid.sizerequest = FALSE;
             //printf("size request: %d %d\n", (int)actual_width, (int)actual_height);
         }
         
@@ -608,13 +629,15 @@
         hexpand = width_diff / num_cols_expanding;
         hexpand2 = width_diff-hexpand*num_cols_expanding;
     }
-    int x = w->mywidget.padding_left;
+    int x = w->grid.padding_left;
     for(int i=0;i<ncols;i++) {
         cols[i].pos = x;
         if(cols[i].expand) {
             cols[i].size += hexpand + hexpand2;
         }
-        x += cols[i].size + w->mywidget.columnspacing;
+        if(cols[i].size > 0) {
+            x += cols[i].size + w->grid.columnspacing;
+        }
         
         hexpand2 = 0;
     }
@@ -626,13 +649,15 @@
         vexpand = height_diff / num_rows_expanding;
         vexpand2 = height_diff-vexpand*num_rows_expanding;
     }
-    int y = w->mywidget.padding_bottom;
+    int y = w->grid.padding_bottom;
     for(int i=0;i<nrows;i++) {
         rows[i].pos = y;
         if(rows[i].expand) {
             rows[i].size += vexpand + vexpand2;
         }
-        y += rows[i].size += w->mywidget.rowspacing;
+        if(rows[i].size > 0) {
+            y += rows[i].size += w->grid.rowspacing;
+        }
         
         vexpand2 = 0;
     }
@@ -651,12 +676,12 @@
                 Dimension cwidth = 0;
                 for(int j=0;j<constraints->grid.colspan;j++) {
                     if(constraints->grid.x+j < ncols) {
-                        cwidth += cols[constraints->grid.x+j].size + (j > 0 ? w->mywidget.columnspacing : 0);
+                        cwidth += cols[constraints->grid.x+j].size + (j > 0 ? w->grid.columnspacing : 0);
                     }
                 }
                 width = cwidth;
             } else {
-                width = c.size - w->mywidget.columnspacing - constraints->grid.margin_left - constraints->grid.margin_right;
+                width = c.size - w->grid.columnspacing - constraints->grid.margin_left - constraints->grid.margin_right;
             }
         }
         if(constraints->grid.vfill) {
@@ -664,12 +689,12 @@
                 Dimension cheight = 0;
                 for(int j=0;j<constraints->grid.rowspan;j++) {
                     if(constraints->grid.y+j < nrows) {
-                        cheight += rows[constraints->grid.y+j].size + (j > 0 ? w->mywidget.rowspacing : 0);
+                        cheight += rows[constraints->grid.y+j].size + (j > 0 ? w->grid.rowspacing : 0);
                     }
                 }
                 height = cheight;
             } else {
-                height = r.size - w->mywidget.rowspacing - constraints->grid.margin_top - constraints->grid.margin_bottom;
+                height = r.size - w->grid.rowspacing - constraints->grid.margin_top - constraints->grid.margin_bottom;
             }
         }
               
--- a/ui/motif/Grid.h	Wed Nov 19 18:30:53 2025 +0100
+++ b/ui/motif/Grid.h	Thu Nov 20 20:09:00 2025 +0100
@@ -78,8 +78,8 @@
     CoreClassPart        core_class;
     CompositeClassPart   composite_class;
     ConstraintClassPart  constraint_class;
-    XmManagerClassPart  manager_class;
-    GridClassPart    mywidgetclass;
+    XmManagerClassPart   manager_class;
+    GridClassPart        gridwidgetclass;
 } GridClassRec;
 
 
@@ -101,7 +101,7 @@
     CompositePart   composite;
     ConstraintPart  constraint;
     XmManagerPart   manager;
-    GridPart    mywidget;
+    GridPart        grid;
 } GridRec;
 
 typedef struct GridContraintPart {

mercurial