Sun, 07 Dec 2025 20:00:33 +0100
fix settings dialog doesn't open when there is no .dav/config.xml file
|
108
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
1 | /* |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
3 | * |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
4 | * Copyright 2025 Olaf Wintermann. All rights reserved. |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
5 | * |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
6 | * Redistribution and use in source and binary forms, with or without |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
7 | * modification, are permitted provided that the following conditions are met: |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
8 | * |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
9 | * 1. Redistributions of source code must retain the above copyright |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
10 | * notice, this list of conditions and the following disclaimer. |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
11 | * |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
12 | * 2. Redistributions in binary form must reproduce the above copyright |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
13 | * notice, this list of conditions and the following disclaimer in the |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
14 | * documentation and/or other materials provided with the distribution. |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
15 | * |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
26 | * POSSIBILITY OF SUCH DAMAGE. |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
27 | */ |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
28 | |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
29 | #include "grid.h" |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
30 | |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
31 | #include "../../ucx/cx/array_list.h" |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
32 | #include "../common/context.h" |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
33 | |
| 112 | 34 | #include <stdio.h> |
| 35 | #include <stdlib.h> | |
| 36 | ||
| 37 | UiGridLayout* ui_grid_layout_create(const CxAllocator *a, short columnspacing, short rowspacing) { | |
| 38 | UiGridLayout *grid = cxZalloc(a, sizeof(UiGridLayout)); | |
| 39 | grid->widgets = cxArrayListCreate(a, NULL, sizeof(GridElm), 32); | |
|
108
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
40 | grid->columnspacing = columnspacing; |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
41 | grid->rowspacing = rowspacing; |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
42 | return grid; |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
43 | } |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
44 | |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
45 | void ui_grid_add_widget( |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
46 | UiGridLayout *grid, |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
47 | short x, |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
48 | short y, |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
49 | W32Widget *widget, |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
50 | GridLayoutInfo *layout) |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
51 | { |
| 112 | 52 | // add the widget |
|
108
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
53 | GridElm elm; |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
54 | elm.widget = widget; |
| 112 | 55 | elm.gridx = x; |
| 56 | elm.gridy = y; | |
|
108
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
57 | elm.layout = *layout; |
| 112 | 58 | cxListAdd(grid->widgets, &elm); |
| 59 | ||
| 60 | // adjust max col/row count | |
| 61 | if (x > grid->max_column) { | |
| 62 | grid->max_column = x; | |
| 63 | } | |
| 64 | if (y > grid->max_row) { | |
| 65 | grid->max_row = y; | |
| 66 | } | |
|
108
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
67 | } |
|
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
68 | |
| 112 | 69 | void ui_grid_layout(UiGridLayout *grid, int width, int height) { |
| 70 | if (width == 0 || height == 0) { | |
| 71 | return; | |
| 72 | } | |
| 73 | ||
| 74 | int ncols = grid->max_column+1; | |
| 75 | int nrows = grid->max_row+1; | |
| 76 | ||
| 77 | GridDef *cols = calloc(ncols, sizeof(GridDef)); | |
| 78 | GridDef *rows = calloc(nrows, sizeof(GridDef)); | |
| 79 | ||
| 80 | int colspacing = grid->columnspacing; | |
| 81 | int rowspacing = grid->rowspacing; | |
| 82 | ||
| 83 | int span_max = 1; | |
| 84 | for(int r=0;r<2;r++) { | |
| 85 | CxIterator i = cxListIterator(grid->widgets); | |
| 86 | cx_foreach(GridElm *, elm, i) { | |
| 87 | int x = elm->gridx; | |
| 88 | int y = elm->gridy; | |
| 89 | GridDef *col = &cols[x]; | |
| 90 | GridDef *row = &rows[y]; | |
| 91 | ||
| 92 | W32Size size = w32_widget_get_preferred_size(elm->widget); | |
| 93 | elm->layout.preferred_width = size.width; | |
| 94 | elm->layout.preferred_height = size.height; | |
| 95 | ||
| 96 | int elm_width = size.width + elm->layout.margin.left + elm->layout.margin.right; | |
| 97 | if(elm_width > cols[elm->gridx].preferred_size && elm->layout.colspan <= 1 && span_max == 1) { | |
| 98 | cols[elm->gridx].preferred_size = elm_width; | |
| 99 | } | |
| 100 | int elm_height = size.height + elm->layout.margin.top + elm->layout.margin.bottom; | |
| 101 | if(elm_height > rows[elm->gridy].preferred_size && elm->layout.rowspan <= 1 && span_max == 1) { | |
| 102 | rows[elm->gridy].preferred_size = elm_height; | |
| 103 | } | |
| 104 | ||
| 105 | if(elm->layout.rowspan > span_max || elm->layout.colspan > span_max) { | |
| 106 | continue; | |
| 107 | } | |
| 108 | ||
| 109 | int end_col = x+elm->layout.colspan; | |
| 110 | if(end_col > ncols) { | |
| 111 | end_col = ncols; | |
| 112 | } | |
| 113 | int end_row = y+elm->layout.rowspan; | |
| 114 | if(end_row > nrows) { | |
| 115 | end_row = nrows; | |
| 116 | } | |
| 117 | ||
| 118 | // are all columns in the span > preferred_width? | |
| 119 | if(elm->layout.colspan > 1) { | |
| 120 | int span_width = 0; | |
| 121 | GridDef *last_col = col; | |
| 122 | for(int c=x;c<end_col;c++) { | |
| 123 | span_width += cols[c].size; | |
| 124 | last_col = &cols[c]; | |
| 125 | } | |
| 126 | if(span_width < elm->layout.preferred_width) { | |
| 127 | last_col->size += elm->layout.preferred_width - span_width; | |
| 128 | } | |
| 129 | } | |
| 130 | ||
| 131 | // are all rows in the span > preferred_height? | |
| 132 | if(elm->layout.rowspan > 1) { | |
| 133 | int span_height = 0; | |
| 134 | GridDef *last_row = row; | |
| 135 | for(int c=x;c<end_row;c++) { | |
| 136 | span_height += rows[c].size; | |
| 137 | last_row = &rows[c]; | |
| 138 | } | |
| 139 | if(span_height < elm->layout.preferred_height) { | |
| 140 | last_row->size += elm->layout.preferred_height - span_height; | |
| 141 | } | |
| 142 | } | |
| 143 | ||
| 144 | if(elm->layout.hexpand) { | |
| 145 | if(elm->layout.colspan > 1) { | |
| 146 | // check if any column in the span is expanding | |
| 147 | // if not, make the last column expanding | |
| 148 | GridDef *last_col = col; | |
| 149 | for(int c=x;c<end_col;c++) { | |
| 150 | last_col = &cols[c]; | |
| 151 | if(last_col->expand) { | |
| 152 | break; | |
| 153 | } | |
| 154 | } | |
| 155 | last_col->expand = TRUE; | |
| 156 | } else { | |
| 157 | col->expand = TRUE; | |
| 158 | } | |
| 159 | } | |
| 160 | if(elm->layout.vexpand) { | |
| 161 | if(elm->layout.rowspan > 1) { | |
| 162 | // same as colspan | |
| 163 | GridDef *last_row = row; | |
| 164 | for(int c=x;c<nrows;c++) { | |
| 165 | last_row = &rows[c]; | |
| 166 | if(last_row->expand) { | |
| 167 | break; | |
| 168 | } | |
| 169 | } | |
| 170 | last_row->expand = TRUE; | |
| 171 | } else { | |
| 172 | row->expand = TRUE; | |
| 173 | } | |
| 174 | } | |
| 175 | } | |
| 176 | span_max = 50000; // not sure if this is unreasonable low or high | |
| 177 | } | |
| 178 | ||
| 179 | int col_ext = 0; | |
| 180 | int row_ext = 0; | |
| 181 | ||
| 182 | int preferred_width = 0; | |
| 183 | int preferred_height = 0; | |
| 184 | for(int j=0;j<ncols;j++) { | |
| 185 | preferred_width += cols[j].preferred_size; | |
| 186 | if(cols[j].expand) { | |
| 187 | col_ext++; | |
| 188 | } | |
| 189 | } | |
| 190 | for(int j=0;j<nrows;j++) { | |
| 191 | preferred_height += rows[j].preferred_size; | |
| 192 | if(rows[j].expand) { | |
| 193 | row_ext++; | |
| 194 | } | |
| 195 | } | |
| 196 | if(ncols > 0) { | |
| 197 | preferred_width += (ncols-1) * colspacing; | |
| 198 | } | |
| 199 | if(nrows > 0) { | |
| 200 | preferred_height += (nrows-1) * rowspacing; | |
| 201 | } | |
| 202 | ||
| 203 | grid->preferred_width = preferred_width; | |
| 204 | grid->preferred_height = preferred_height; | |
| 205 | ||
| 206 | int hremaining = width - preferred_width; | |
| 207 | int vremaining = height - preferred_height; | |
| 208 | int hext = col_ext > 0 ? hremaining/col_ext : 0; | |
| 209 | int vext = row_ext > 0 ? vremaining/row_ext : 0; | |
| 210 | ||
| 211 | for(int j=0;j<ncols;j++) { | |
| 212 | GridDef *col = &cols[j]; | |
| 213 | if(col->expand) { | |
| 214 | col->size = col->preferred_size + hext; | |
| 215 | } else { | |
| 216 | col->size = col->preferred_size; | |
| 217 | } | |
| 218 | } | |
| 219 | for(int j=0;j<nrows;j++) { | |
| 220 | GridDef *row = &rows[j]; | |
| 221 | if(row->expand) { | |
| 222 | row->size = row->preferred_size + vext; | |
| 223 | } else { | |
| 224 | row->size = row->preferred_size; | |
| 225 | } | |
| 226 | } | |
| 227 | ||
| 228 | int pos = 0; | |
| 229 | for(int j=0;j<ncols;j++) { | |
| 230 | cols[j].pos = pos; | |
| 231 | pos += cols[j].size + colspacing; | |
| 232 | } | |
| 233 | pos = 0; | |
| 234 | for(int j=0;j<nrows;j++) { | |
| 235 | rows[j].pos = pos; | |
| 236 | pos += rows[j].size + rowspacing; | |
| 237 | } | |
| 238 | ||
| 239 | CxIterator i = cxListIterator(grid->widgets); | |
| 240 | cx_foreach(GridElm *, elm, i) { | |
| 241 | GridDef *col = &cols[elm->gridx]; | |
| 242 | GridDef *row = &rows[elm->gridy]; | |
| 243 | ||
| 244 | int child_width = 0; | |
| 245 | int child_height = 0; | |
| 246 | int child_x = 0; | |
| 247 | int child_y = 0; | |
| 248 | if(elm->layout.hfill) { | |
| 249 | if(elm->layout.colspan > 1) { | |
| 250 | int cwidth = 0; | |
| 251 | int end_col = elm->gridx + elm->layout.colspan; | |
| 252 | if(end_col > ncols) { | |
| 253 | end_col = ncols; | |
| 254 | } | |
| 255 | int real_span = 0; | |
| 256 | for(int c=elm->gridx;c<end_col;c++) { | |
| 257 | cwidth += cols[c].size; | |
| 258 | real_span++; | |
| 259 | } | |
| 260 | if(real_span > 0) { | |
| 261 | cwidth += (real_span-1) * colspacing; | |
| 262 | } | |
| 263 | child_width = cwidth; | |
| 264 | } else { | |
| 265 | child_width = col->size; | |
| 266 | } | |
| 267 | child_width -= elm->layout.margin.left + elm->layout.margin.right; | |
| 268 | } else { | |
| 269 | child_width = elm->layout.preferred_width; | |
| 270 | } | |
| 271 | ||
| 272 | if(elm->layout.vfill) { | |
| 273 | if(elm->layout.rowspan > 1) { | |
| 274 | int rheight = 0; | |
| 275 | int end_row = elm->gridy + elm->layout.rowspan; | |
| 276 | if(end_row > nrows) { | |
| 277 | end_row = nrows; | |
| 278 | } | |
| 279 | int real_span = 0; | |
| 280 | for(int r=elm->gridy;r<end_row;r++) { | |
| 281 | rheight += rows[r].size; | |
| 282 | real_span++; | |
| 283 | } | |
| 284 | if(real_span > 0) { | |
| 285 | rheight += (real_span-1) * rowspacing; | |
| 286 | } | |
| 287 | child_height = rheight; | |
| 288 | } | |
| 289 | child_height = row->size - elm->layout.margin.top - elm->layout.margin.bottom; | |
| 290 | } else { | |
| 291 | child_height = elm->layout.preferred_height; | |
| 292 | } | |
| 293 | ||
| 294 | child_x = col->pos + elm->layout.margin.left; | |
| 295 | child_y = row->pos + elm->layout.margin.top; | |
| 296 | SetWindowPos(elm->widget->hwnd, NULL, child_x, child_y, child_width, child_height, SWP_NOZORDER); | |
| 297 | if (elm->widget->layout) { | |
| 298 | elm->widget->layout(elm->widget->layoutmanager, child_width, child_height); | |
| 299 | } | |
| 300 | } | |
| 301 | ||
| 302 | free(cols); | |
| 303 | free(rows); | |
|
108
77254bd6dccb
update toolkit, adjust UI code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
304 | } |