ui/motif/Grid.c

branch
newapi
changeset 408
b06e43f1edd4
parent 407
8ea123dd89db
--- a/ui/motif/Grid.c	Wed Dec 04 20:36:16 2024 +0100
+++ b/ui/motif/Grid.c	Thu Dec 05 08:40:37 2024 +0100
@@ -367,31 +367,103 @@
     int req_width = 0;
     int req_height = 0;
     
-    for(int i=0;i<w->composite.num_children;i++) {
-        Widget child = w->composite.children[i];
-        GridConstraintRec *constraints = child->core.constraints;
-        if(constraints->grid.x < ncols) {
+    // calculate the minimum size requirements for all columns and rows
+    // we need to run this 2 times: for widgets without colspan/rowspan first
+    // and then again for colspan/rowspan > 1
+    int span_max = 1;
+    for(int r=0;r<2;r++) {
+        for(int i=0;i<w->composite.num_children;i++) {
+            Widget child = w->composite.children[i];
+            GridConstraintRec *constraints = child->core.constraints;
+            
+            if(constraints->grid.colspan > span_max || constraints->grid.rowspan > span_max) {
+                continue;
+            }
+            
+            int x = constraints->grid.x;
+            int y = constraints->grid.y;
+            // make sure ncols/nrows is correct
+            // errors shouldn't happen, unless someone messes up the grid internals
+            if(x >= ncols) {
+                fprintf(stderr, "Error: widget x out of bounds\n");
+                continue;
+            }
+            if(y >= nrows) {
+                fprintf(stderr, "Error: widget y out of bounds\n");
+                continue;
+            }
+            GridDef *col = &cols[x];
+            GridDef *row = &rows[y];
+            
             if(constraints->grid.hexpand) {
-                cols[constraints->grid.x].expand = TRUE;
-            }
-            if(constraints->grid.pref_width > cols[constraints->grid.x].size) {
-                cols[constraints->grid.x].size = constraints->grid.pref_width;
+                if(constraints->grid.colspan > 1) {
+                    // check if any column in the span is expanding
+                    // if not, make the last column expanding
+                    GridDef *last_col = col;
+                    for(int c=x;c<ncols;c++) {
+                        last_col = &cols[c];
+                        if(last_col->expand) {
+                            break;
+                        }
+                    }
+                    last_col->expand = TRUE;
+                } else {
+                    col->expand = TRUE;
+                }
             }
-        } else {
-            fprintf(stderr, "Error: x >= ncols\n");
-        }
-        if(constraints->grid.y < nrows) {
             if(constraints->grid.vexpand) {
-                rows[constraints->grid.y].expand = TRUE;
+                if(constraints->grid.rowspan > 1) {
+                    GridDef *last_row = row;
+                    for(int c=x;c<nrows;c++) {
+                        last_row = &rows[c];
+                        if(last_row->expand) {
+                            break;
+                        }
+                    }
+                    last_row->expand = TRUE;
+                } else {
+                    row->expand = TRUE;
+                }
+            } 
+            
+            // column size
+            if(constraints->grid.colspan > 1) {
+                // check size of all columns in span
+                Dimension span_width = col->size;
+                GridDef *last_col = col;
+                for(int s=x+1;s<ncols;s++) {
+                    last_col = &cols[s];
+                    span_width = last_col->size;
+                    
+                }
+                int diff = constraints->grid.pref_width - span_width;
+                if(diff > 0) {
+                    last_col->size += diff; 
+                }
+            } else if(constraints->grid.pref_width > col->size) {
+                col->size = constraints->grid.pref_width;
             }
-            if(constraints->grid.pref_height > rows[constraints->grid.y].size) {
-                rows[constraints->grid.y].size = constraints->grid.pref_height;
+            // row size
+            if(constraints->grid.rowspan > 1) {
+                Dimension span_height = row->size;
+                GridDef *last_row = row;
+                for(int s=x+1;s<nrows;s++) {
+                    last_row = &rows[s];
+                    span_height = last_row->size;
+                    
+                }
+                int diff = constraints->grid.pref_height - span_height;
+                if(diff > 0) {
+                    last_row->size += diff; 
+                }
+            } else if(constraints->grid.pref_height > row->size) {
+                row->size = constraints->grid.pref_height;
             }
-        } else {
-            fprintf(stderr, "Error: y >= nrows\n");
         }
+        span_max = 50000; // not sure if this is unreasonable low or high
     }
     
+    
     for(int i=0;i<ncols;i++) {
         if(cols[i].expand) {
             num_cols_expanding++;

mercurial