diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-11-29 13:06:25 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-11-29 13:06:25 +0200 |
commit | afbad514d97a217af3f51efe59cb2d0f0022b2fc (patch) | |
tree | 26b7d6ed12850d5af5c6d4671f2686dfcd654255 | |
parent | 286ab6f8fc51575095eba59c5299a476f2463968 (diff) |
Widget: More accurate division of available space
Take fractional pixels into account when laying out widgets. This ensures that the entire available space is used, particularly when there are many children.
IssueID #403
-rw-r--r-- | src/ui/widget.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/ui/widget.c b/src/ui/widget.c index 61bbf43a..a171a6cd 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -692,8 +692,16 @@ static void arrange_Widget_(iWidget *d) { | |||
692 | } | 692 | } |
693 | } | 693 | } |
694 | } | 694 | } |
695 | /* Keep track of the fractional pixels so a large number to children will cover | ||
696 | the full area. */ | ||
697 | const iInt2 totalAvail = avail; | ||
695 | avail = divi_I2(max_I2(zero_I2(), avail), expCount); | 698 | avail = divi_I2(max_I2(zero_I2(), avail), expCount); |
699 | float availFract[2] = { | ||
700 | iMax(0, (totalAvail.x - avail.x * expCount) / (float) expCount), | ||
701 | iMax(0, (totalAvail.y - avail.y * expCount) / (float) expCount) | ||
702 | }; | ||
696 | TRACE(d, "available for expansion (per child): %d\n", d->flags & arrangeHorizontal_WidgetFlag ? avail.x : avail.y); | 703 | TRACE(d, "available for expansion (per child): %d\n", d->flags & arrangeHorizontal_WidgetFlag ? avail.x : avail.y); |
704 | float fract[2] = { 0, 0 }; | ||
697 | iForEach(ObjectList, j, d->children) { | 705 | iForEach(ObjectList, j, d->children) { |
698 | iWidget *child = as_Widget(j.object); | 706 | iWidget *child = as_Widget(j.object); |
699 | if (!isArrangedSize_Widget_(child)) { | 707 | if (!isArrangedSize_Widget_(child)) { |
@@ -703,12 +711,16 @@ static void arrange_Widget_(iWidget *d) { | |||
703 | iBool sizeChanged = iFalse; | 711 | iBool sizeChanged = iFalse; |
704 | if (child->flags & expand_WidgetFlag) { | 712 | if (child->flags & expand_WidgetFlag) { |
705 | if (d->flags & arrangeHorizontal_WidgetFlag) { | 713 | if (d->flags & arrangeHorizontal_WidgetFlag) { |
706 | sizeChanged |= setWidth_Widget_(child, avail.x); | 714 | const int fracti = (int) (fract[0] += availFract[0]); |
715 | fract[0] -= fracti; | ||
716 | sizeChanged |= setWidth_Widget_(child, avail.x + fracti); | ||
707 | sizeChanged |= setHeight_Widget_(child, height_Rect(innerRect)); | 717 | sizeChanged |= setHeight_Widget_(child, height_Rect(innerRect)); |
708 | } | 718 | } |
709 | else if (d->flags & arrangeVertical_WidgetFlag) { | 719 | else if (d->flags & arrangeVertical_WidgetFlag) { |
710 | sizeChanged |= setWidth_Widget_(child, width_Rect(innerRect)); | 720 | sizeChanged |= setWidth_Widget_(child, width_Rect(innerRect)); |
711 | sizeChanged |= setHeight_Widget_(child, avail.y); | 721 | const int fracti = (int) (fract[1] += availFract[1]); |
722 | fract[1] -= fracti; | ||
723 | sizeChanged |= setHeight_Widget_(child, avail.y + fracti); | ||
712 | } | 724 | } |
713 | } | 725 | } |
714 | if (sizeChanged) { | 726 | if (sizeChanged) { |