summaryrefslogtreecommitdiff
path: root/src/ui/widget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/widget.c')
-rw-r--r--src/ui/widget.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/src/ui/widget.c b/src/ui/widget.c
index 3ff2e713..43bbe56e 100644
--- a/src/ui/widget.c
+++ b/src/ui/widget.c
@@ -314,50 +314,48 @@ static void printf_Widget_(const iWidget *d, const char *format, ...) {
314 delete_String(msg); 314 delete_String(msg);
315} 315}
316 316
317static void setWidth_Widget_(iWidget *d, int width) { 317static iBool setWidth_Widget_(iWidget *d, int width) {
318 iAssert(width >= 0); 318 iAssert(width >= 0);
319 TRACE(d, "attempt to set width to %d (current: %d, min width: %d)", width, d->rect.size.x, d->minSize.x); 319 TRACE(d, "attempt to set width to %d (current: %d, min width: %d)", width, d->rect.size.x, d->minSize.x);
320 width = iMax(width, d->minSize.x); 320 width = iMax(width, d->minSize.x);
321 if (~d->flags & fixedWidth_WidgetFlag) { //} || d->flags & collapse_WidgetFlag) { 321 if (~d->flags & fixedWidth_WidgetFlag) {
322 if (d->rect.size.x != width) { 322 if (d->rect.size.x != width) {
323 d->rect.size.x = width; 323 d->rect.size.x = width;
324 TRACE(d, "width has changed to %d", width); 324 TRACE(d, "width has changed to %d", width);
325 if (class_Widget(d)->sizeChanged) { 325 if (class_Widget(d)->sizeChanged) {
326 const int oldHeight = d->rect.size.y; 326 const int oldHeight = d->rect.size.y;
327 class_Widget(d)->sizeChanged(d); 327 class_Widget(d)->sizeChanged(d);
328 if (d->rect.size.y != oldHeight) {
329 TRACE(d, "sizeChanged() cuased height change to %d; redoing parent", d->rect.size.y);
330 /* Widget updated its height. */
331 arrange_Widget_(d->parent);
332 TRACE(d, "parent layout redone");
333 }
334 } 328 }
329 return iTrue;
335 } 330 }
336 } 331 }
337 else { 332 else {
338 TRACE(d, "changing width not allowed; flags: %x", d->flags); 333 TRACE(d, "changing width not allowed; flags: %x", d->flags);
339 } 334 }
335 return iFalse;
340} 336}
341 337
342static void setHeight_Widget_(iWidget *d, int height) { 338static iBool setHeight_Widget_(iWidget *d, int height) {
343 iAssert(height >= 0); 339 iAssert(height >= 0);
344 if (d->sizeRef) { 340 if (d->sizeRef) {
345 return; /* height defined by another widget */ 341 return; /* height defined by another widget */
346 } 342 }
347 TRACE(d, "attempt to set height to %d (current: %d, min height: %d)", height, d->rect.size.y, d->minSize.y); 343 TRACE(d, "attempt to set height to %d (current: %d, min height: %d)", height, d->rect.size.y, d->minSize.y);
348 height = iMax(height, d->minSize.y); 344 height = iMax(height, d->minSize.y);
349 if (~d->flags & fixedHeight_WidgetFlag) { //} || d->flags & collapse_WidgetFlag) { 345 if (~d->flags & fixedHeight_WidgetFlag) {
350 if (d->rect.size.y != height) { 346 if (d->rect.size.y != height) {
351 d->rect.size.y = height; 347 d->rect.size.y = height;
352 TRACE(d, "height has changed to %d", height); 348 TRACE(d, "height has changed to %d", height);
353 if (class_Widget(d)->sizeChanged) { 349 if (class_Widget(d)->sizeChanged) {
354 class_Widget(d)->sizeChanged(d); 350 class_Widget(d)->sizeChanged(d);
355 } 351 }
352 return iTrue;
356 } 353 }
357 } 354 }
358 else { 355 else {
359 TRACE(d, "changing height not allowed; flags: %x", d->flags); 356 TRACE(d, "changing height not allowed; flags: %x", d->flags);
360 } 357 }
358 return iFalse;
361} 359}
362 360
363iLocalDef iRect innerRect_Widget_(const iWidget *d) { 361iLocalDef iRect innerRect_Widget_(const iWidget *d) {
@@ -578,6 +576,12 @@ static void arrange_Widget_(iWidget *d) {
578 TRACE(d, "...done changing child sizes (EVEN mode)"); 576 TRACE(d, "...done changing child sizes (EVEN mode)");
579 } 577 }
580 } 578 }
579 /* Children arrange themselves. */ {
580 iForEach(ObjectList, i, d->children) {
581 iWidget *child = as_Widget(i.object);
582 arrange_Widget_(child);
583 }
584 }
581 /* Resize the expanding children to fill the remaining available space. */ 585 /* Resize the expanding children to fill the remaining available space. */
582 if (expCount > 0 && (d->flags & (arrangeHorizontal_WidgetFlag | arrangeVertical_WidgetFlag))) { 586 if (expCount > 0 && (d->flags & (arrangeHorizontal_WidgetFlag | arrangeVertical_WidgetFlag))) {
583 TRACE(d, "%d expanding children, resizing them %s...", expCount, 587 TRACE(d, "%d expanding children, resizing them %s...", expCount,
@@ -600,16 +604,20 @@ static void arrange_Widget_(iWidget *d) {
600 TRACE(d, "child %p size is not arranged", child); 604 TRACE(d, "child %p size is not arranged", child);
601 continue; 605 continue;
602 } 606 }
607 iBool sizeChanged = iFalse;
603 if (child->flags & expand_WidgetFlag) { 608 if (child->flags & expand_WidgetFlag) {
604 if (d->flags & arrangeHorizontal_WidgetFlag) { 609 if (d->flags & arrangeHorizontal_WidgetFlag) {
605 setWidth_Widget_(child, avail.x); 610 sizeChanged |= setWidth_Widget_(child, avail.x);
606 setHeight_Widget_(child, height_Rect(innerRect)); 611 sizeChanged |= setHeight_Widget_(child, height_Rect(innerRect));
607 } 612 }
608 else if (d->flags & arrangeVertical_WidgetFlag) { 613 else if (d->flags & arrangeVertical_WidgetFlag) {
609 setWidth_Widget_(child, width_Rect(innerRect)); 614 sizeChanged |= setWidth_Widget_(child, width_Rect(innerRect));
610 setHeight_Widget_(child, avail.y); 615 sizeChanged |= setHeight_Widget_(child, avail.y);
611 } 616 }
612 } 617 }
618 if (sizeChanged) {
619 arrange_Widget_(child); /* its children may need rearranging */
620 }
613 } 621 }
614 } 622 }
615 if (d->flags & resizeChildrenToWidestChild_WidgetFlag) { 623 if (d->flags & resizeChildrenToWidestChild_WidgetFlag) {
@@ -618,7 +626,9 @@ static void arrange_Widget_(iWidget *d) {
618 iForEach(ObjectList, i, d->children) { 626 iForEach(ObjectList, i, d->children) {
619 iWidget *child = as_Widget(i.object); 627 iWidget *child = as_Widget(i.object);
620 if (isArrangedSize_Widget_(child)) { 628 if (isArrangedSize_Widget_(child)) {
621 setWidth_Widget_(child, widest); 629 if (setWidth_Widget_(child, widest)) {
630 arrange_Widget_(child); /* its children may need rearranging */
631 }
622 } 632 }
623 else { 633 else {
624 TRACE(d, "child %p cannot be resized (parentCannotResize: %d)", child, 634 TRACE(d, "child %p cannot be resized (parentCannotResize: %d)", child,
@@ -633,7 +643,6 @@ static void arrange_Widget_(iWidget *d) {
633 d->flags & arrangeVertical_WidgetFlag ? " vert" : ""); 643 d->flags & arrangeVertical_WidgetFlag ? " vert" : "");
634 iForEach(ObjectList, i, d->children) { 644 iForEach(ObjectList, i, d->children) {
635 iWidget *child = as_Widget(i.object); 645 iWidget *child = as_Widget(i.object);
636 arrange_Widget_(child);
637 if (isCollapsed_Widget_(child) || !isArrangedPos_Widget_(child)) { 646 if (isCollapsed_Widget_(child) || !isArrangedPos_Widget_(child)) {
638 TRACE(d, "child %p arranging prohibited", child); 647 TRACE(d, "child %p arranging prohibited", child);
639 continue; 648 continue;
@@ -743,6 +752,11 @@ static void resetArrangement_Widget_(iWidget *d) {
743 752
744void arrange_Widget(iWidget *d) { 753void arrange_Widget(iWidget *d) {
745 if (d) { 754 if (d) {
755#if !defined (NDEBUG)
756 if (tracing_) {
757 puts("\n==== NEW WIDGET ARRANGEMENT ====\n");
758 }
759#endif
746 resetArrangement_Widget_(d); /* back to initial default sizes */ 760 resetArrangement_Widget_(d); /* back to initial default sizes */
747 arrange_Widget_(d); 761 arrange_Widget_(d);
748 } 762 }