diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-08-23 18:39:55 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-08-23 18:39:55 +0300 |
commit | 31c297274b9f1212bd8043fb062bf157afe8859f (patch) | |
tree | 1ba14fc913b777cca7c1b3c9c8df751dbeb27b8d /src/ui/widget.c | |
parent | cabaecd2a7cb20b6bf6b31bdde287d6c24c632f7 (diff) |
Widget: Optional padding for child arrangement
Diffstat (limited to 'src/ui/widget.c')
-rw-r--r-- | src/ui/widget.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/src/ui/widget.c b/src/ui/widget.c index 1175b217..8277b921 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -76,6 +76,7 @@ void init_Widget(iWidget *d) { | |||
76 | d->children = NULL; | 76 | d->children = NULL; |
77 | d->parent = NULL; | 77 | d->parent = NULL; |
78 | d->commandHandler = NULL; | 78 | d->commandHandler = NULL; |
79 | iZap(d->padding); | ||
79 | } | 80 | } |
80 | 81 | ||
81 | void deinit_Widget(iWidget *d) { | 82 | void deinit_Widget(iWidget *d) { |
@@ -142,6 +143,13 @@ void setSize_Widget(iWidget *d, iInt2 size) { | |||
142 | setFlags_Widget(d, fixedSize_WidgetFlag, iTrue); | 143 | setFlags_Widget(d, fixedSize_WidgetFlag, iTrue); |
143 | } | 144 | } |
144 | 145 | ||
146 | void setPadding_Widget(iWidget *d, int left, int top, int right, int bottom) { | ||
147 | d->padding[0] = left; | ||
148 | d->padding[1] = top; | ||
149 | d->padding[2] = right; | ||
150 | d->padding[3] = bottom; | ||
151 | } | ||
152 | |||
145 | void setBackgroundColor_Widget(iWidget *d, int bgColor) { | 153 | void setBackgroundColor_Widget(iWidget *d, int bgColor) { |
146 | d->bgColor = bgColor; | 154 | d->bgColor = bgColor; |
147 | } | 155 | } |
@@ -191,19 +199,26 @@ iLocalDef iBool isCollapsed_Widget_(const iWidget *d) { | |||
191 | (hidden_WidgetFlag | collapse_WidgetFlag); | 199 | (hidden_WidgetFlag | collapse_WidgetFlag); |
192 | } | 200 | } |
193 | 201 | ||
202 | iLocalDef iRect innerRect_Widget_(const iWidget *d) { | ||
203 | return init_Rect(d->padding[0], | ||
204 | d->padding[1], | ||
205 | width_Rect(d->rect) - d->padding[0] - d->padding[2], | ||
206 | height_Rect(d->rect) - d->padding[1] - d->padding[3]); | ||
207 | } | ||
208 | |||
194 | void arrange_Widget(iWidget *d) { | 209 | void arrange_Widget(iWidget *d) { |
195 | if (isCollapsed_Widget_(d)) { | 210 | if (isCollapsed_Widget_(d)) { |
196 | setFlags_Widget(d, wasCollapsed_WidgetFlag, iTrue); | 211 | setFlags_Widget(d, wasCollapsed_WidgetFlag, iTrue); |
197 | return; | 212 | return; |
198 | } | 213 | } |
199 | if (d->flags & moveToParentRightEdge_WidgetFlag) { | 214 | if (d->flags & moveToParentRightEdge_WidgetFlag) { |
200 | d->rect.pos.x = width_Rect(d->parent->rect) - width_Rect(d->rect); | 215 | d->rect.pos.x = width_Rect(innerRect_Widget_(d->parent)) - width_Rect(d->rect); |
201 | } | 216 | } |
202 | if (d->flags & resizeToParentWidth_WidgetFlag) { | 217 | if (d->flags & resizeToParentWidth_WidgetFlag) { |
203 | setWidth_Widget_(d, d->parent->rect.size.x); | 218 | setWidth_Widget_(d, width_Rect(innerRect_Widget_(d->parent))); |
204 | } | 219 | } |
205 | if (d->flags & resizeToParentHeight_WidgetFlag) { | 220 | if (d->flags & resizeToParentHeight_WidgetFlag) { |
206 | setHeight_Widget_(d, d->parent->rect.size.y); | 221 | setHeight_Widget_(d, height_Rect(innerRect_Widget_(d->parent))); |
207 | } | 222 | } |
208 | /* The rest of the arrangement depends on child widgets. */ | 223 | /* The rest of the arrangement depends on child widgets. */ |
209 | if (!d->children) { | 224 | if (!d->children) { |
@@ -236,7 +251,7 @@ void arrange_Widget(iWidget *d) { | |||
236 | const int expCount = numExpandingChildren_Widget_(d); | 251 | const int expCount = numExpandingChildren_Widget_(d); |
237 | /* Only resize the expanding children, not touching the others. */ | 252 | /* Only resize the expanding children, not touching the others. */ |
238 | if (expCount > 0) { | 253 | if (expCount > 0) { |
239 | iInt2 avail = d->rect.size; | 254 | iInt2 avail = innerRect_Widget_(d).size; |
240 | iConstForEach(ObjectList, i, d->children) { | 255 | iConstForEach(ObjectList, i, d->children) { |
241 | const iWidget *child = constAs_Widget(i.object); | 256 | const iWidget *child = constAs_Widget(i.object); |
242 | if (~child->flags & expand_WidgetFlag) { | 257 | if (~child->flags & expand_WidgetFlag) { |
@@ -250,27 +265,27 @@ void arrange_Widget(iWidget *d) { | |||
250 | if (child->flags & expand_WidgetFlag) { | 265 | if (child->flags & expand_WidgetFlag) { |
251 | if (d->flags & arrangeHorizontal_WidgetFlag) { | 266 | if (d->flags & arrangeHorizontal_WidgetFlag) { |
252 | if (dirs.x) setWidth_Widget_(child, avail.x); | 267 | if (dirs.x) setWidth_Widget_(child, avail.x); |
253 | if (dirs.y) setHeight_Widget_(child, d->rect.size.y); | 268 | if (dirs.y) setHeight_Widget_(child, height_Rect(innerRect_Widget_(d))); |
254 | } | 269 | } |
255 | else if (d->flags & arrangeVertical_WidgetFlag) { | 270 | else if (d->flags & arrangeVertical_WidgetFlag) { |
256 | if (dirs.x) setWidth_Widget_(child, d->rect.size.x); | 271 | if (dirs.x) setWidth_Widget_(child, width_Rect(innerRect_Widget_(d))); |
257 | if (dirs.y) setHeight_Widget_(child, avail.y); | 272 | if (dirs.y) setHeight_Widget_(child, avail.y); |
258 | } | 273 | } |
259 | } | 274 | } |
260 | else { | 275 | else { |
261 | /* Fill the off axis, though. */ | 276 | /* Fill the off axis, though. */ |
262 | if (d->flags & arrangeHorizontal_WidgetFlag) { | 277 | if (d->flags & arrangeHorizontal_WidgetFlag) { |
263 | if (dirs.y) setHeight_Widget_(child, d->rect.size.y); | 278 | if (dirs.y) setHeight_Widget_(child, height_Rect(innerRect_Widget_(d))); |
264 | } | 279 | } |
265 | else if (d->flags & arrangeVertical_WidgetFlag) { | 280 | else if (d->flags & arrangeVertical_WidgetFlag) { |
266 | if (dirs.x) setWidth_Widget_(child, d->rect.size.x); | 281 | if (dirs.x) setWidth_Widget_(child, width_Rect(innerRect_Widget_(d))); |
267 | } | 282 | } |
268 | } | 283 | } |
269 | } | 284 | } |
270 | } | 285 | } |
271 | else { | 286 | else { |
272 | /* Evenly size all children. */ | 287 | /* Evenly size all children. */ |
273 | iInt2 childSize = d->rect.size; | 288 | iInt2 childSize = innerRect_Widget_(d).size; |
274 | if (d->flags & arrangeHorizontal_WidgetFlag) { | 289 | if (d->flags & arrangeHorizontal_WidgetFlag) { |
275 | childSize.x /= childCount; | 290 | childSize.x /= childCount; |
276 | } | 291 | } |
@@ -292,7 +307,7 @@ void arrange_Widget(iWidget *d) { | |||
292 | setWidth_Widget_(as_Widget(i.object), widest); | 307 | setWidth_Widget_(as_Widget(i.object), widest); |
293 | } | 308 | } |
294 | } | 309 | } |
295 | iInt2 pos = zero_I2(); | 310 | iInt2 pos = initv_I2(d->padding); |
296 | iForEach(ObjectList, i, d->children) { | 311 | iForEach(ObjectList, i, d->children) { |
297 | iWidget *child = as_Widget(i.object); | 312 | iWidget *child = as_Widget(i.object); |
298 | arrange_Widget(child); | 313 | arrange_Widget(child); |
@@ -308,6 +323,9 @@ void arrange_Widget(iWidget *d) { | |||
308 | pos.y += child->rect.size.y; | 323 | pos.y += child->rect.size.y; |
309 | } | 324 | } |
310 | } | 325 | } |
326 | else if (d->flags & resizeChildren_WidgetFlag) { | ||
327 | child->rect.pos = pos; | ||
328 | } | ||
311 | } | 329 | } |
312 | /* Update the size of the widget according to the arrangement. */ | 330 | /* Update the size of the widget according to the arrangement. */ |
313 | if (d->flags & arrangeSize_WidgetFlag) { | 331 | if (d->flags & arrangeSize_WidgetFlag) { |
@@ -321,6 +339,7 @@ void arrange_Widget(iWidget *d) { | |||
321 | bounds = union_Rect(bounds, child->rect); | 339 | bounds = union_Rect(bounds, child->rect); |
322 | } | 340 | } |
323 | } | 341 | } |
342 | adjustEdges_Rect(&bounds, -d->padding[1], d->padding[2], d->padding[3], -d->padding[0]); | ||
324 | if (d->flags & arrangeWidth_WidgetFlag) { | 343 | if (d->flags & arrangeWidth_WidgetFlag) { |
325 | setWidth_Widget_(d, bounds.size.x); | 344 | setWidth_Widget_(d, bounds.size.x); |
326 | /* Parent size changed, must update the children.*/ | 345 | /* Parent size changed, must update the children.*/ |