--- 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++;