Skip to content

Commit 423bc10

Browse files
committed
Better flex calculation
1 parent 6d9e686 commit 423bc10

1 file changed

Lines changed: 41 additions & 47 deletions

File tree

server/src/layout/flex_layout.cpp

Lines changed: 41 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -26,84 +26,78 @@ namespace fensterserver
2626
bool horizontal = orientation == fenster::Orientation::Horizontal;
2727

2828
fenster::Rectangle bounds = component->getBounds();
29-
if (dynamic_cast<ScrollPane*>(component->getParent())) {
30-
bounds = component->getParent()->getBounds();
31-
}
3229

3330
bounds.x = padding.left;
3431
bounds.y = padding.top;
3532
bounds.width -= padding.left + padding.right;
3633
bounds.height -= padding.top + padding.bottom;
3734

3835
auto& children = component->acquireChildren();
39-
int totalSpace = horizontal ? bounds.width : bounds.height;
40-
int totalFlexGrow = 0;
41-
int totalFixedSpace = 0;
4236

43-
// Calculate required space for fixed-size
37+
float totalBasis = 0.f;
38+
float totalGrow = 0.f;
39+
float totalShrink = 0.f;
40+
4441
for(auto& ref: children)
4542
{
4643
Component* child = ref.component;
47-
FlexInfo flex = flexInfo[child];
48-
49-
int basis = (flex.basis >= 0)
50-
? flex.basis
51-
: (horizontal
52-
? child->getPreferredSize().width
53-
: child->getPreferredSize().height);
54-
totalFixedSpace += basis;
55-
totalFlexGrow += flex.grow;
44+
auto info = flexInfo[child];
45+
46+
fenster::Dimension pref = child->getPreferredSize();
47+
int childPref = horizontal ? pref.width : pref.height;
48+
49+
int basis = (info.basis >= 0) ? info.basis : childPref;
50+
totalBasis += basis;
51+
totalGrow += info.grow;
52+
totalShrink += info.shrink;
53+
54+
info.basis = basis;
55+
flexInfo[child] = info;
5656
}
5757

58-
// Calculate remaining space, considering the gaps
59-
int remainingSize = totalSpace - totalFixedSpace - (space * (children.size() - 1));
58+
int mainSize = horizontal ? bounds.width : bounds.height;
59+
int crossSize = horizontal ? bounds.height : bounds.width;
6060

61-
// Distribute space
62-
int xOffset = bounds.x;
63-
int yOffset = bounds.y;
61+
float remaining = mainSize - totalBasis;
6462

65-
int endX = 0;
66-
int endY = 0;
63+
int pos = horizontal ? bounds.x : bounds.y;
64+
int totalMainUsed = 0;
6765

6866
for(auto& ref: children)
6967
{
7068
Component* child = ref.component;
71-
FlexInfo flex = flexInfo[child];
69+
auto info = flexInfo[child];
7270

73-
int basis = (flex.basis >= 0)
74-
? flex.basis
75-
: (horizontal
76-
? child->getEffectivePreferredSize().width
77-
: child->getEffectivePreferredSize().height);
78-
int allocatedSize = basis;
71+
float size = info.basis;
7972

80-
if(remainingSize > 0 && flex.grow > 0)
73+
if(remaining > 0 && totalGrow > 0)
74+
{
75+
size += (info.grow / totalGrow) * remaining;
76+
} else if(remaining < 0 && totalShrink > 0)
8177
{
82-
float proportion = flex.grow / static_cast<float>(totalFlexGrow);
83-
allocatedSize += static_cast<int>(proportion * remainingSize);
78+
float overflow = -remaining;
79+
size -= (info.shrink / totalShrink) * overflow;
8480
}
8581

82+
int finalSize = std::max(0, (int) size);
83+
8684
if(horizontal)
8785
{
88-
fenster::Rectangle childBounds(xOffset, yOffset, allocatedSize, bounds.height);
89-
child->setBounds(childBounds);
90-
endX = std::max(childBounds.getEnd().x, endX);
91-
endY = std::max(childBounds.getEnd().y, endY);
92-
93-
xOffset += allocatedSize + space;
94-
}
95-
else
86+
child->setBounds(fenster::Rectangle(pos, bounds.y, finalSize, crossSize));
87+
pos += finalSize;
88+
} else
9689
{
97-
fenster::Rectangle childBounds(xOffset, yOffset, bounds.width, allocatedSize);
98-
child->setBounds(childBounds);
99-
endX = std::max(childBounds.getEnd().x, endX);
100-
endY = std::max(childBounds.getEnd().y, endY);
101-
102-
yOffset += allocatedSize + space;
90+
child->setBounds(fenster::Rectangle(bounds.x, pos, crossSize, finalSize));
91+
pos += finalSize;
10392
}
93+
94+
totalMainUsed += finalSize;
10495
}
10596

10697
component->releaseChildren();
98+
99+
int endX = horizontal ? totalMainUsed : crossSize;
100+
int endY = horizontal ? crossSize : totalMainUsed;
107101
component->setPreferredSize(fenster::Dimension(endX, endY));
108102
}
109103
}

0 commit comments

Comments
 (0)