28 const ElementRect &elementRect, int32_t& minContentWidth);
41 template <
int axis>
requires(axis == 0 || axis == 1)
42 static inline int32_t
CalcLayoutAdd(std::span<const ElementRect> childRects, int32_t& count)
48 if (!childElem.constraints.IsInFlowAxis(axis))
50 size += childElem.rect.size[axis];
59 template <
int axis>
requires(axis == 0 || axis == 1)
68 return std::max({ chrome, int32_t(size.
min + margin), content });
73 template <
int axis>
requires(axis == 0 || axis == 1)
85 template <
int axis>
requires(axis == 0 || axis == 1)
94 c.
rect.size[axis] = basis;
105 template <
int axis>
requires(axis == 0 || axis == 1)
108 if (freeSpace == 0)
return 0;
109 const bool grow = freeSpace > 0;
111 struct Item { uint64_t weight; int32_t base; int32_t target;
bool active; };
112 static thread_local std::vector<Item> state;
113 state.assign(items.size(), Item{ 0, 0, 0, false });
114 for (
size_t i = 0; i < items.size(); ++i)
118 const int32_t size = c.
rect.size[axis];
124 if (weight == 0)
continue;
125 state[i] = Item{ weight, size, size,
true };
128 int64_t remaining = freeSpace;
130 for (
size_t pass = 0; pass <= items.size() && remaining != 0; ++pass)
132 uint64_t totalWeight = 0;
133 for (
const Item& it : state)
if (it.active) totalWeight += it.weight;
134 if (totalWeight == 0)
break;
136 uint64_t cumWeight = 0;
137 int64_t prevBound = 0;
138 int64_t violation = 0;
139 for (
size_t i = 0; i < items.size(); ++i)
142 if (!it.active)
continue;
143 cumWeight += it.weight;
144 const int64_t bound = remaining * int64_t(cumWeight) / int64_t(totalWeight);
145 it.target = int32_t(it.base + (bound - prevBound));
152 for (
size_t i = 0; i < items.size(); ++i)
153 if (state[i].active) items[i].rect.size[axis] = state[i].target;
154 applied += remaining;
160 for (
size_t i = 0; i < items.size(); ++i)
163 if (!it.active)
continue;
165 if ((violation > 0 && clamped > it.target) || (violation < 0 && clamped < it.target))
167 items[i].rect.size[axis] = clamped;
168 remaining -= (clamped - it.base);
169 applied += (clamped - it.base);
174 return int32_t(applied);
177 template <
int axis>
requires(axis == 0 || axis == 1)
178 static inline int32_t
CalcLayoutMax(std::span<const ElementRect> childRects)
183 if (!childElem.constraints.IsInFlowAxis(axis))
185 size = std::max(size,
static_cast<int32_t
>(childElem.rect.size[axis]));
190 template <
int axis>
requires(axis == 0 || axis == 1)
191 static inline void Place(std::span<ElementRect> childRects, int32_t start, int32_t spacing)
195 if (!childElem.constraints.IsInFlowAxis(axis))
197 childElem.rect.position[axis] = start;
198 start += childElem.rect.size[axis] + spacing;
205 template <
int axis>
requires(axis == 0 || axis == 1)
213 template <
int axis>
requires(axis == 0 || axis == 1)
214 static inline void ReversePlace(std::span<ElementRect> childRects, int32_t start, int32_t spacing)
218 if (!childElem.constraints.IsInFlowAxis(axis))
220 start -= childElem.rect.size[axis];
221 childElem.rect.position[axis] = start;
230 template <
int axis,
bool reverse>
requires(axis == 0 || axis == 1)
233 int totalContentSize,
int totalChildrenInFlow)
235 const JustifySpacing s =
Justify(justify, parentContentRect.size[axis] - totalContentSize, gap, totalChildrenInFlow);
236 if constexpr (reverse)
255 int32_t offset = 0, spacing = gap;
263 if (count > 1) spacing += freeSpace / (count - 1);
266 if (count > 0) { spacing += freeSpace / count; offset = (spacing - gap) / 2; }
269 offset = freeSpace / (count + 1);
273 return { offset, spacing };
276 template <
int axis>
requires(axis == 0 || axis == 1)
287 case AlignItems::FlexEnd: { childRect.
rect.position[axis] = (parentContentRect.position[axis] + parentContentRect.size[axis]) - childRect.
rect.size[axis];
break; }
288 case AlignItems::Center: { childRect.
rect.position[axis] = parentContentRect.position[axis] + (parentContentRect.size[axis] - childRect.
rect.size[axis]) / 2;
break; }
291 childRect.
rect.position[axis] = parentContentRect.position[axis];
297 int32_t s = parentContentRect.size[axis];
300 childRect.
rect.size[axis] = s;
The frame's element tree.
Definition gui_element_storage.h:100
Text and icon registration, measurement, rendering and editing.
Definition gui_text_system.h:178
Keeps the OS windows (through an IWindowBackend) and their window contexts for the GUI's window eleme...
Definition gui_os_window_manager.h:61
IntRect rect
Computed during layout.
Definition gui_element.h:60
JustifyContent
Main-axis distribution of items (CSS: justify-content; grids also justify-items).
Definition gui_style.h:191
AlignItems
Cross-axis alignment of items (CSS: align-items, align-self).
Definition gui_style.h:181
@ SpaceEvenly
Equal space between all items.
Definition gui_style.h:197
@ Center
Pack to center.
Definition gui_style.h:194
@ FlexStart
Pack to start.
Definition gui_style.h:192
@ FlexEnd
Pack to end.
Definition gui_style.h:193
@ SpaceAround
Space around items.
Definition gui_style.h:196
@ SpaceBetween
Space between items.
Definition gui_style.h:195
@ Auto
align-self only: inherit from container's align-items
Definition gui_style.h:182
@ Center
Center on cross axis.
Definition gui_style.h:185
@ FlexStart
Align to start of cross axis.
Definition gui_style.h:183
@ FlexEnd
Align to end of cross axis.
Definition gui_style.h:184
@ Stretch
Stretch to fill container.
Definition gui_style.h:186
Definition gui_logging.h:24
constexpr uint16_t Vertical() const
top + bottom
Definition gui_style.h:81
constexpr uint16_t Horizontal() const
left + right
Definition gui_style.h:80
Definition gui_element.h:57
int16_t minContentWidth
Leaf with visibly overflowing text: the margin box width flex shrink stops at (CSS min-content).
Definition gui_element.h:80
const LayoutStyle * layoutStyle
Definition gui_element.h:69
LayoutOverride constraints
Definition gui_element.h:67
An element's slot in ElementStorage: its depth and index within that depth.
Definition gui_element.h:127
Definition gui_element.h:33
int16_t flexBasis
CSS: flex-basis; kAuto = auto.
Definition gui_style.h:354
Definition gui_base_types.h:407
int32_t Max(int axis) const
Definition gui_base_types.h:417
FlexProperties flex
used when display is Flex (and by flex items)
Definition gui_style.h:443
Where justify-content puts the first of count items, measured from the main start,...
Definition gui_layout_helpers.h:244
int32_t spacing
Definition gui_layout_helpers.h:244
int32_t offset
Definition gui_layout_helpers.h:244
Definition gui_layout_helpers.h:21
static int32_t FlexMinSize(const ElementRect &c)
The smallest margin-box size an item may be flexed to on axis: its CSS min (border box) plus its marg...
Definition gui_layout_helpers.h:60
static int2 ClampScrollOffsetToContent(int2 childOffset, const ElementRect &parent)
static JustifySpacing Justify(JustifyContent justify, int32_t freeSpace, int16_t gap, int count)
Definition gui_layout_helpers.h:245
static void ApplyHorizontalPositionConstraints(OSWindowManager &osWindowManager, ElementStorage &storage, ElementRect &elementRect, const ElementRef &elementRef)
static int32_t FlexMaxSize(const ElementRect &c)
The largest margin-box size an item may be flexed to on axis: its CSS max plus its margin (kUnbounded...
Definition gui_layout_helpers.h:74
static int32_t RecalculateContentHeight(ITextSystem &textSystem, const Element &element, const ElementRect &elementRect)
static void ApplyFlexBasis(std::span< ElementRect > items)
Sets each in-flow item's size on axis to its flex-basis, the starting main size before free space is ...
Definition gui_layout_helpers.h:86
static int32_t FixedContentSize(const ElementRect &rect)
Content size along axis of an element with a fixed size on that axis.
Definition gui_layout_helpers.h:206
static void ApplyVerticalStyleOffset(ElementRect &elementRect)
static int32_t ResolveFlexibleLengths(std::span< ElementRect > items, int32_t freeSpace)
Resolves flexible lengths on axis (CSS "resolve flexible lengths"): positive freeSpace grows the in-f...
Definition gui_layout_helpers.h:106
static void Align(AlignItems align, const IntRect &parentContentRect, ElementRect &childRect)
Definition gui_layout_helpers.h:277
static int2 CalculateLeafSize(ITextSystem &textSystem, const Element &element, const ElementRect &elementRect, int32_t &minContentWidth)
A leaf's MARGIN BOX at its natural (max-content) size.
static void ApplyVerticalStyleSize(ElementRect &elementRect, const int32_t contentHeight)
static void Place(std::span< ElementRect > childRects, int32_t start, int32_t spacing)
Definition gui_layout_helpers.h:191
static int32_t CalcLayoutAdd(std::span< const ElementRect > childRects, int32_t &count)
Definition gui_layout_helpers.h:42
static void ApplyHorizontalStyleOffset(ElementRect &elementRect)
static void ReversePlace(std::span< ElementRect > childRects, int32_t start, int32_t spacing)
Definition gui_layout_helpers.h:214
static void JustifyChildren(std::span< ElementRect > childRects, JustifyContent justify, int16_t gap, const IntRect &parentContentRect, int totalContentSize, int totalChildrenInFlow)
Positions the children on the main axis per justify.
Definition gui_layout_helpers.h:231
static void ApplyVerticalPositionConstraints(OSWindowManager &osWindowManager, ElementStorage &storage, ElementRect &elementRect, const ElementRef &elementRef)
static int32_t CalcLayoutMax(std::span< const ElementRect > childRects)
Definition gui_layout_helpers.h:178
static void ApplyHorizontalStyleSize(ElementRect &elementRect, const int32_t contentWidth)
constexpr bool HasFixedAxis(int axis) const
Definition gui_constraints.h:196
uint32_t GetFlexShrink(const LayoutStyle *ls) const
Definition gui_constraints.h:356
constexpr int32_t ClampHeight(int32_t h) const
Definition gui_constraints.h:202
SizeConstraintAxis height
Size constraints; set with the size builders.
Definition gui_constraints.h:151
SizeConstraintAxis width
Definition gui_constraints.h:151
constexpr bool IsInFlowAxis(int axis) const
Definition gui_constraints.h:216
uint32_t GetFlexGrow(const LayoutStyle *ls) const
Resolvers take the element's layout style (may be null) and return the effective value.
Definition gui_constraints.h:351
constexpr int32_t ClampWidth(int32_t w) const
Clamps a size to the min / max constraints, ignoring the explicit size.
Definition gui_constraints.h:201
The layout part of a registered Style, in pixels; shared by every style with the same values.
Definition gui_style.h:755
BoxEdges padding
pixels
Definition gui_style.h:759
LayoutData layoutData
flex, grid and size properties, in pixels
Definition gui_style.h:762
BoxEdges borderWidths
pixels
Definition gui_style.h:760
AlignItems alignSelf
see Style::alignSelf
Definition gui_style.h:775
constexpr int16_t GetMinWidth() const
Horizontal margin + border + padding: the narrowest the element can be.
Definition gui_style.h:808
constexpr int16_t GetMinHeight() const
Vertical margin + border + padding: the shortest the element can be.
Definition gui_style.h:814
BoxEdges margin
pixels
Definition gui_style.h:758
Per-axis size constraint: an explicit size, or a min / max clamp on the content-driven size.
Definition gui_constraints.h:19
int32_t value
Explicit size (kAuto = content-driven).
Definition gui_constraints.h:23
int32_t min
Lower clamp for the content-driven size.
Definition gui_constraints.h:24
static constexpr int32_t kUnbounded
No maximum.
Definition gui_constraints.h:21
int32_t max
Upper clamp for the content-driven size.
Definition gui_constraints.h:25
Integer 2D vector.
Definition gui_base_types.h:19