summaryrefslogtreecommitdiff
path: root/src/ui/widget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-08-23 18:39:55 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-08-23 18:39:55 +0300
commit31c297274b9f1212bd8043fb062bf157afe8859f (patch)
tree1ba14fc913b777cca7c1b3c9c8df751dbeb27b8d /src/ui/widget.c
parentcabaecd2a7cb20b6bf6b31bdde287d6c24c632f7 (diff)
Widget: Optional padding for child arrangement
Diffstat (limited to 'src/ui/widget.c')
-rw-r--r--src/ui/widget.c39
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
81void deinit_Widget(iWidget *d) { 82void 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
146void 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
145void setBackgroundColor_Widget(iWidget *d, int bgColor) { 153void 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
202iLocalDef 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
194void arrange_Widget(iWidget *d) { 209void 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.*/