7 weeks ago
implement grid colspan/rowspan (Cocoa)
make/xcode/toolkit/toolkit/main.m | file | annotate | diff | comparison | revisions | |
ui/cocoa/GridLayout.m | file | annotate | diff | comparison | revisions |
--- a/make/xcode/toolkit/toolkit/main.m Wed Jan 22 22:06:10 2025 +0100 +++ b/make/xcode/toolkit/toolkit/main.m Thu Jan 23 21:08:43 2025 +0100 @@ -45,6 +45,10 @@ ui_button(obj, .label = "Button X4", .hfill = 1); ui_newline(obj); ui_button(obj, .label = "Button X5", .hfill = 0); + ui_button(obj, .label = "Button X5.1", .hfill = 1); + ui_button(obj, .label = "Button X5.6", .rowspan = 2); + ui_newline(obj); + ui_button(obj, .label = "Button X6", .hfill = 1, .colspan = 2); ui_show(obj);
--- a/ui/cocoa/GridLayout.m Wed Jan 22 22:06:10 2025 +0100 +++ b/ui/cocoa/GridLayout.m Thu Jan 23 21:08:43 2025 +0100 @@ -70,34 +70,107 @@ int colspacing = _columnspacing; int rowspacing = _rowspacing; - CxIterator i = cxListIterator(_children); - cx_foreach(GridElm *, elm, i) { - NSSize size = elm->view.intrinsicContentSize; - NSEdgeInsets alignment = elm->view.alignmentRectInsets; - if(size.width != NSViewNoIntrinsicMetric) { - CGFloat width = size.width + alignment.left + alignment.right; - if(width > cols[elm->x].preferred_size) { - cols[elm->x].preferred_size = width; + int span_max = 1; + for(int r=0;r<2;r++) { + CxIterator i = cxListIterator(_children); + cx_foreach(GridElm *, elm, i) { + int x = elm->x; + int y = elm->y; + GridDef *col = &cols[x]; + GridDef *row = &rows[y]; + + NSSize size = elm->view.intrinsicContentSize; + NSEdgeInsets alignment = elm->view.alignmentRectInsets; + if(size.width != NSViewNoIntrinsicMetric) { + CGFloat width = size.width + alignment.left + alignment.right; + if(width > cols[elm->x].preferred_size && elm->colspan <= 1 && span_max == 1) { + cols[elm->x].preferred_size = width; + } + elm->preferred_width = width; + } + if(size.height != NSViewNoIntrinsicMetric) { + CGFloat height = size.height + alignment.top + alignment.right; + //CGFloat height = size.height; + if(height > rows[elm->y].preferred_size && elm->rowspan <= 1 && span_max == 1) { + rows[elm->y].preferred_size = height; + } + elm->preferred_height = height; + } + + if(elm->rowspan > span_max || elm->colspan > span_max) { + continue; + } + + int end_col = x+elm->colspan; + if(end_col > ncols) { + end_col = ncols; + } + int end_row = y+elm->rowspan; + if(end_row > nrows) { + end_row = nrows; } - elm->preferred_width = width; + + // are all columns in the span > preferred_width? + if(elm->colspan > 1) { + int span_width = 0; + GridDef *last_col = col; + for(int c=x;c<end_col;c++) { + span_width += cols[c].size; + last_col = &cols[c]; + } + if(span_width < elm->preferred_width) { + last_col->size += elm->preferred_width - span_width; + } + } + // are all rows in the span > preferred_height? + if(elm->rowspan > 1) { + int span_height = 0; + GridDef *last_row = row; + for(int c=x;c<end_row;c++) { + span_height += rows[c].size; + last_row = &rows[c]; + } + if(span_height < elm->preferred_height) { + last_row->size += elm->preferred_height - span_height; + } + } + + if(elm->hexpand) { + if(elm->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<end_col;c++) { + last_col = &cols[c]; + if(last_col->expand) { + break; + } + } + last_col->expand = TRUE; + } else { + col->expand = TRUE; + } + } + if(elm->vexpand) { + if(elm->rowspan > 1) { + // same as colspan + 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; + } + } } - if(size.height != NSViewNoIntrinsicMetric) { - CGFloat height = size.height + alignment.top + alignment.right; - //CGFloat height = size.height; - if(height > rows[elm->y].preferred_size) { - rows[elm->y].preferred_size = height; - } - elm->preferred_height = height; - } - - if(elm->hexpand) { - cols[elm->x].expand = TRUE; - } - if(elm->vexpand) { - rows[elm->y].expand = TRUE; - } + span_max = 50000; // not sure if this is unreasonable low or high } + int col_ext = 0; int row_ext = 0; @@ -153,7 +226,7 @@ pos += rows[j].size + rowspacing; } - i = cxListIterator(_children); + CxIterator i = cxListIterator(_children); cx_foreach(GridElm *, elm, i) { //NSSize size = elm->view.intrinsicContentSize; GridDef *col = &cols[elm->x]; @@ -162,11 +235,34 @@ NSEdgeInsets alignment = elm->view.alignmentRectInsets; NSRect frame; if(elm->hfill) { - frame.size.width = col->size; + if(elm->colspan > 1) { + int cwidth = 0; + int end_col = elm->x + elm->colspan; + if(end_col > ncols) { + end_col = ncols; + } + for(int c=elm->x;c<end_col;c++) { + cwidth += cols[c].size; + } + frame.size.width = cwidth; + } else { + frame.size.width = col->size; + } } else { frame.size.width = elm->preferred_width; } if(elm->vfill) { + if(elm->rowspan > 1) { + int rheight = 0; + int end_row = elm->y + elm->rowspan; + if(end_row > nrows) { + end_row = nrows; + } + for(int r=elm->y;r<end_row;r++) { + rheight += rows[r].size; + } + frame.size.height = rheight; + } frame.size.height = row->size; } else { frame.size.height = elm->preferred_height;