Item Layouts¶
Headers: winui/ui/layouts/Layout.hpp, winui/ui/layouts/StackLayout.hpp, winui/ui/layouts/TileLayout.hpp, winui/ui/layouts/WrapLayout.hpp, winui/ui/layouts/LinedFlowLayout.hpp. Spec: winui/ui/layouts/StackLayout.hpp.
The base of every attachable layout. Not copyable: it belongs to one host.
Derive from NonVirtualizingLayout or VirtualizingLayout, not from this class. A host takes the layout by std::unique_ptr (LayoutPanelControl::set_layout(), ForEachControl::set_layout()) and becomes its owner(). The layout keeps its per-host state in its own members and calls invalidate_measure() when one of its properties changes.
Example:
auto panel = std::make_unique<ui::LayoutPanelControl>();
auto* layout = panel->set_layout(std::make_unique<ui::StackLayoutEngine>());
layout->set_spacing(8.0f); // the layout invalidates the panel
ui::StackLayout¶
Items one after another in a line, like the children of a ui::VerticalStack or ui::HorizontalStack. Builds a ui::StackLayoutEngine.
Example:
window.set_content(ui::ForEach<std::string>{
.items = {"One", "Two", "Three"},
.layout = ui::StackLayout{.orientation = ui::Orientation::Horizontal, .spacing = 8.0f},
.item = [](const std::string& text) -> ui::Spec { return ui::Text{.text = text}; },
});
Every field, in the order a designated initializer names them:
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
orientation |
ui::Orientation |
ui::Orientation::Vertical |
The direction items follow each other in. |
spacing |
float |
0.0f |
Gap between adjacent items, DIPs. |
build¶
Consumes the value and returns the layout object.
ui::WrapLayout¶
Items at their own size in a line that wraps, like the children of a ui::WrapPanel. Builds a ui::WrapLayoutEngine.
Example:
window.set_content(ui::ForEach<std::string>{
.items = {"news", "sport", "travel"},
.layout = ui::WrapLayout{.min_item_spacing = 8.0f, .line_spacing = 8.0f},
.item = [](const std::string& tag) -> ui::Spec { return ui::Button{.text = tag}; },
});
Every field, in the order a designated initializer names them:
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
orientation |
ui::Orientation |
ui::Orientation::Horizontal |
The direction of a line. |
min_item_spacing |
float |
0.0f |
Least gap between items on a line, DIPs. |
line_spacing |
float |
0.0f |
Gap between lines, DIPs. |
line_alignment |
ui::ItemsJustification |
ui::ItemsJustification::Start |
How a line's leftover space is distributed. |
build¶
Consumes the value and returns the layout object.
ui::TileLayout¶
Equal cells, as many per line as fit, wrapping to the next line. The layout of a ui::TileView. Builds a ui::TileLayoutEngine.
Example:
window.set_content(ui::ForEach<std::string>{
.items = {"Ada", "Grace", "Linus", "Margaret"},
.layout = ui::TileLayout{.min_item_width = 120.0f, .min_row_spacing = 8.0f, .min_column_spacing = 8.0f},
.item = [](const std::string& name) -> ui::Spec { return ui::Text{.text = name}; },
});
Every field, in the order a designated initializer names them:
ui::TileLayout{
.orientation, .min_item_width, .min_item_height, .min_row_spacing, .min_column_spacing,
.items_justification, .items_stretch, .maximum_rows_or_columns
}
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
orientation |
ui::Orientation |
ui::Orientation::Horizontal |
The direction of a line of cells. |
min_item_width |
ui::OptionalFloat |
Cell width, DIPs; unset takes the first item's. | |
min_item_height |
ui::OptionalFloat |
Cell height, DIPs; unset takes the first item's. | |
min_row_spacing |
float |
0.0f |
Least gap between rows, DIPs. |
min_column_spacing |
float |
0.0f |
Least gap between columns, DIPs. |
items_justification |
ui::ItemsJustification |
ui::ItemsJustification::Start |
How a line's leftover space is distributed between the cells. |
items_stretch |
ui::TileLayoutItemsStretch |
ui::TileLayoutItemsStretch::None |
Whether cells grow to use a line's leftover space. |
maximum_rows_or_columns |
std::size_t |
0 |
The most cells on a line; 0 is as many as fit. |
build¶
Consumes the value and returns the layout object.
ui::LinedFlowLayout¶
Justified lines of one height, each item as wide as its aspect ratio asks, like a photo wall. Builds a ui::LinedFlowLayoutEngine.
Example:
ui::Property<std::vector<ui::ImageSource>> photos;
window.set_content(ui::ForEach<ui::ImageSource>{
.items = photos,
.layout = ui::LinedFlowLayout{.line_height = 160.0f, .min_item_spacing = 4.0f, .line_spacing = 4.0f},
.item = [](const ui::ImageSource& photo) -> ui::Spec { return ui::Image{.source = photo}; },
});
Every field, in the order a designated initializer names them:
ui::LinedFlowLayout{
.line_height, .min_item_spacing, .line_spacing, .items_stretch, .items_justification
}
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
line_height |
ui::OptionalFloat |
Height of every line, DIPs; unset takes the first item's. | |
min_item_spacing |
float |
0.0f |
Least gap between items on a line, DIPs. |
line_spacing |
float |
0.0f |
Gap between lines, DIPs. |
items_stretch |
ui::LinedFlowLayoutItemsStretch |
ui::LinedFlowLayoutItemsStretch::None |
Whether items grow to fill their line. |
items_justification |
ui::ItemsJustification |
ui::ItemsJustification::Start |
How a line's leftover space is distributed. |
build¶
Consumes the value and returns the layout object.
ui::Layout¶
The base of every attachable layout. Not copyable: it belongs to one host.
Derive from NonVirtualizingLayout or VirtualizingLayout, not from this class. A host takes the layout by std::unique_ptr (LayoutPanelControl::set_layout(), ForEachControl::set_layout()) and becomes its owner(). The layout keeps its per-host state in its own members and calls invalidate_measure() when one of its properties changes.
Example:
auto panel = std::make_unique<ui::LayoutPanelControl>();
auto* layout = panel->set_layout(std::make_unique<ui::StackLayoutEngine>());
layout->set_spacing(8.0f); // the layout invalidates the panel
~Layout¶
Layout¶
operator=¶
owner¶
The host this layout is attached to (non-owning), or nullptr.
parallel_measure_safe¶
Whether the host may be measured on a layout worker thread (ParallelLayout) with this layout. Return true only when measure() touches nothing but the layout's own state and the context it is given. It must not realize or recycle an element, read the viewport or invalidate anything. False by default. The built-in layouts virtualize and return false.
invalidate_measure¶
Measures and arranges the host again. Call it after a property of the layout changed. Does nothing while detached.
invalidate_arrange¶
Arranges the host again without measuring. Does nothing while detached.
class NonVirtualizingLayout¶
Derives from ui::Layout.
A layout that measures and arranges every child of the host.
Derive a custom layout for a fixed set of children from it and give it to a LayoutPanel. Each pass sees all children through the context. Keep any state between measure() and arrange() in members.
Example:
// Every child in one column, each as tall as it wants.
class ColumnLayout final : public ui::NonVirtualizingLayout
{
public:
ui::Size measure(ui::NonVirtualizingLayoutContext& context, ui::Size available) override
{
ui::Size total{};
for (std::size_t i = 0; i < context.item_count(); ++i)
{
const ui::Size d = context.measure(i, {available.width, ui::Unbounded});
total.width = std::max(total.width, d.width);
total.height += d.height;
}
return total;
}
ui::Size arrange(ui::NonVirtualizingLayoutContext& context, ui::Size final_size) override
{
float y = 0.0f;
for (std::size_t i = 0; i < context.item_count(); ++i)
{
const float h = context.desired_size(i).height;
context.arrange(i, ui::Rect{0.0f, y, final_size.width, h});
y += h;
}
return final_size;
}
};
window.set_content(ui::LayoutPanel{
.layout = std::make_unique<ColumnLayout>(),
.content = {ui::Text{.text = "One"}, ui::Text{.text = "Two"}},
});
measure¶
Returns the size the children need within available (infinity on an unbounded axis). It must measure every child it will arrange.
arrange¶
Places every child within final_size and returns the size used.
class VirtualizingLayout¶
Derives from ui::Layout.
A layout that measures and arranges the part of a collection that is in view.
Derive a custom layout from it and give it to a ForEach, which can then virtualize, or to a LayoutPanel, where every child is in view. measure() realizes only the items inside VirtualizingLayoutContext::realization_rect() and returns the extent of the whole collection. arrange() places the items measure() realized.
Example:
// Fixed-height rows; only the rows in the realization rect are realized.
class RowLayout final : public ui::VirtualizingLayout
{
public:
ui::Size measure(ui::VirtualizingLayoutContext& context, ui::Size available) override
{
const ui::Rect view = context.realization_rect();
const std::size_t count = context.item_count();
first_ = std::min(count, static_cast<std::size_t>(std::max(0.0f, view.y) / Row));
last_ = std::min(count, static_cast<std::size_t>(std::max(0.0f, view.bottom()) / Row) + 1);
for (std::size_t i = first_; i < last_; ++i)
{
(void)context.measure(context.get_or_create_element_at(i), {available.width, Row});
}
return {std::isfinite(available.width) ? available.width : 0.0f, static_cast<float>(count) * Row};
}
ui::Size arrange(ui::VirtualizingLayoutContext& context, ui::Size final_size) override
{
for (std::size_t i = first_; i < last_; ++i)
{
context.arrange(context.get_or_create_element_at(i),
ui::Rect{0.0f, static_cast<float>(i) * Row, final_size.width, Row});
}
return final_size;
}
private:
static constexpr float Row = 32.0f;
std::size_t first_ = 0;
std::size_t last_ = 0;
};
auto repeater = std::make_unique<ui::ForEachControl>();
repeater->set_layout(std::make_unique<RowLayout>());
initialize_for_context¶
Called when a host starts using this layout. uninitialize_for_context() is called when it stops. The default does nothing.
uninitialize_for_context¶
Called when the host stops using this layout. Drop per-host state here.
measure¶
Returns the size of the whole collection laid out within available (infinity on an unbounded axis). Realizes and measures only the items in the context's realization rect.
arrange¶
Places the items realized by the last measure() within final_size and returns the size used.
on_items_changed¶
Called when the collection changed. The default calls invalidate_measure(), which lays out everything again.
class StackLayoutEngine¶
Derives from ui::VirtualizingLayout.
A virtualizing layout that places items one after another, spacing apart. A ui::ForEach or a TileView stacks its items with it.
Only the items in or near the viewport are realized. The rest are estimated at the average measured size, so the scroll extent stays stable. Every item gets the full cross extent. It also works in a LayoutPanel, where every child is realized.
Example:
std::vector<std::string> rows = {"Inbox", "Drafts", "Sent"}; // outlives the window
auto scroll = std::make_unique<ui::ScrollControl>();
auto* repeater = scroll->set_child(std::make_unique<ui::ForEachControl>());
auto* stack = repeater->set_layout(std::make_unique<ui::StackLayoutEngine>());
stack->set_orientation(ui::Orientation::Vertical);
stack->set_spacing(8.0f);
repeater->set_item_template([&rows](std::size_t i) { return std::make_unique<ui::TextControl>(rows[i]); });
repeater->set_item_count(rows.size());
window.set_content(std::move(scroll));
StackLayoutEngine¶
A vertical stack with no spacing and virtualization on.
~StackLayoutEngine¶
orientation¶
The stacking direction; Vertical by default.
set_orientation¶
Changes the direction and invalidates the host's measure.
spacing¶
The gap between neighboring items along the stack, in DIPs; 0 by default.
set_spacing¶
Changes the gap and invalidates the host's measure.
is_virtualization_enabled¶
Whether only the items in or near the viewport are realized. When off, every item is realized, however few of them show.
set_virtualization_enabled¶
Switches virtualization and invalidates the host's measure.
measure¶
Realizes and measures the items the viewport and its cache need, each unbounded along the stack. Returns the estimated extent of all items along the stack and the widest item across.
arrange¶
Places the realized items one after another, each stretched across final_size.
on_items_changed¶
Shifts the realized range to follow an insert, remove or reset of the source.
uninitialize_for_context¶
Drops the per-host layout state when a host stops using this layout.
class TileLayoutEngine¶
Derives from ui::VirtualizingLayout.
A virtualizing layout that puts every item in an equal-sized cell, as many cells per line as fit, line after line.
The cell is exactly min_item_width() x min_item_height() where those are set, else item 0's desired size. Hand it to a ui::ForEach or a TileView through set_layout() or the spec's .layout. Only the lines inside the realization window are realized, but the extent covers every line, so a scroller can jump anywhere. Every setter lays out the host again.
Example:
std::vector<std::string> names = {"Ada", "Grace", "Linus", "Margaret"};
auto grid = std::make_unique<ui::TileLayoutEngine>();
grid->set_min_item_width(120.0f);
grid->set_min_item_height(80.0f);
grid->set_min_row_spacing(8.0f);
grid->set_min_column_spacing(8.0f);
grid->set_items_stretch(ui::TileLayoutItemsStretch::Fill);
window.set_content(ui::Scroll{
.height = 400.0f,
.content = ui::ForEach<std::string>{
.items = names,
.layout = std::move(grid),
.virtualize = true,
.item = [](const std::string& name) -> ui::Spec { return ui::Text{.text = name}; },
},
});
TileLayoutEngine¶
Horizontal, cells sized from item 0, no spacing, Start, None, unlimited per line.
~TileLayoutEngine¶
orientation¶
The direction a line of cells runs in; Horizontal by default.
set_orientation¶
Changes the fill direction and lays out the host again.
min_item_width¶
The cell width in DIPs; nullopt (the default) takes the width from item 0.
set_min_item_width¶
Sets or clears the cell width and lays out the host again.
min_item_height¶
The cell height in DIPs; nullopt (the default) takes it from item 0.
set_min_item_height¶
Sets or clears the cell height and lays out the host again.
min_row_spacing¶
The least gap between rows in DIPs; 0 by default. Justification may widen it.
set_min_row_spacing¶
Sets the row gap and lays out the host again.
min_column_spacing¶
The gap between columns in DIPs; 0 by default.
set_min_column_spacing¶
Sets the column gap and lays out the host again.
items_justification¶
How the cells are spread along a line; Start by default.
set_items_justification¶
Changes the justification and lays out the host again.
items_stretch¶
Whether cells grow to use the leftover room on a line; None by default. The leftover room is shared out in whole pixels per cell, so a line may still fall a few pixels short.
set_items_stretch¶
Changes the stretch and lays out the host again.
maximum_rows_or_columns¶
The most cells per line. 0 (the default) is unlimited.
set_maximum_rows_or_columns¶
Caps the cells per line and lays out the host again.
set_group_sizes¶
Lays the indices out in groups: each group is one index for its header, which takes a line of its own across the whole width, then sizes[g] indices in cells, from the start of a new line. The indices run header, its items, the next header, and so on. Every header is as tall as the first one, the cells are sized from the first item, and a line's cells start at its leading edge. An empty vector (the default) lays every index out as a cell. Lays out the host again. A grouped ui::TileView sets it.
group_sizes¶
The sizes set_group_sizes() was given.
measure¶
Returns the size of the whole collection laid out within available (infinity on an unbounded axis). Realizes and measures only the items in the context's realization rect.
arrange¶
Places the items realized by the last measure() within final_size and returns the size used.
on_items_changed¶
Called when the collection changed. The default calls invalidate_measure(), which lays out everything again.
uninitialize_for_context¶
Called when the host stops using this layout. Drop per-host state here.
effective_item_size¶
The cell size of the last measure in DIPs, stretch included. Zero before the first measure.
class WrapLayoutEngine¶
Derives from ui::VirtualizingLayout.
A virtualizing ForEach layout that places items of any size one after another and wraps to a new line when the next one would not fit. Only the items that show are realized.
Every item keeps its own desired size. Items sit min_item_spacing() apart along a line. Lines are as thick as their largest item and line_spacing() apart, and line_alignment() spreads the items of each line. Lines outside the viewport are not realized. Their extent is estimated from the average of the last hundred measured lines, so the scroll extent can shift slightly as more of the collection is seen. Use TileLayoutEngine when every item is the same size.
Example:
std::vector<std::string> tags = {"news", "sport", "travel", "food", "music"};
auto flow = std::make_unique<ui::WrapLayoutEngine>();
flow->set_min_item_spacing(8.0f);
flow->set_line_spacing(8.0f);
flow->set_line_alignment(ui::ItemsJustification::SpaceBetween);
ui::WrapLayoutEngine* layout = flow.get(); // observer; the repeater owns it
window.set_content(ui::Scroll{
.height = 320.0f,
.content = ui::ForEach<std::string>{
.items = tags,
.layout = std::move(flow),
.virtualize = true,
.item = [](const std::string& tag) -> ui::Spec { return ui::Button{.text = tag}; },
},
});
// Later: switch to columns that scroll horizontally.
layout->set_orientation(ui::Orientation::Vertical);
WrapLayoutEngine¶
Horizontal rows, no spacing, Start alignment.
~WrapLayoutEngine¶
orientation¶
The line direction; Horizontal by default.
set_orientation¶
Changes the line direction, discards the collected line estimates and measures the host again.
min_item_spacing¶
The least gap between neighbors along a line, in DIPs; 0 by default. The Space* alignments widen it.
set_min_item_spacing¶
Changes the item spacing and measures the host again.
line_spacing¶
The gap between consecutive lines, in DIPs; 0 by default.
set_line_spacing¶
Changes the line spacing and measures the host again.
line_alignment¶
How each line distributes its spare room; ItemsJustification::Start by default.
set_line_alignment¶
Changes the line alignment and arranges the host again.
measure¶
Realizes and measures the items that fall in the context's realization window, wraps them into lines and returns the estimated size of the whole collection.
arrange¶
Positions the realized items within their lines according to line_alignment().
on_items_changed¶
Updates the realized range and the line estimates after an insert, removal or reset.
uninitialize_for_context¶
Drops the realized-line state when the layout leaves its host.
class LinedFlowLayoutEngine¶
Derives from ui::VirtualizingLayout.
A virtualizing layout that puts items of any width on lines of one fixed height, like a photo wall.
Each item keeps its own aspect ratio. Items are measured at the line height and fill each line greedily. One scale factor per line shrinks its items to fit, and with LinedFlowLayoutItemsStretch::Fill it also widens them to reach the edge. Only the lines in the realization rect are realized. The widths of items never measured are estimated from the average aspect ratio. Host it in a ForEach inside a Scroll, or in a LayoutPanel.
Example:
ui::Property<std::vector<ui::ImageSource>> photos; // filled as the pictures load
auto layout = std::make_unique<ui::LinedFlowLayoutEngine>();
layout->set_line_height(160.0f);
layout->set_line_spacing(4.0f);
layout->set_min_item_spacing(4.0f);
layout->set_items_stretch(ui::LinedFlowLayoutItemsStretch::Fill);
window.set_content(ui::Scroll{
.height = 480.0f,
.content = ui::ForEach<ui::ImageSource>{
.items = photos,
.layout = std::move(layout),
.virtualize = true,
.item = [](const ui::ImageSource& photo) -> ui::Spec {
return ui::Image{.source = photo};
},
},
});
line_height¶
The line height in DIPs; nullopt (the default) takes the height of item 0.
set_line_height¶
Sets the line height and lays out the host again.
actual_line_height¶
The line height of the last measure.
line_spacing¶
The vertical gap between lines, DIPs; 0 by default.
set_line_spacing¶
Sets the gap between lines and lays out the host again.
min_item_spacing¶
The smallest horizontal gap between items on a line, DIPs; 0 by default. Justification may widen it.
set_min_item_spacing¶
Sets the minimum item gap and lays out the host again.
items_stretch¶
Whether short lines are stretched to fill; None by default.
set_items_stretch¶
Sets the stretch mode and lays out the host again.
items_justification¶
How short lines are placed with LinedFlowLayoutItemsStretch::None; Start by default.
set_items_justification¶
Sets the justification and lays out the host again.
invalidate_items_info¶
Forgets every measured width and lays out again. Call it when items changed size while the collection stayed the same.
measure¶
Returns the size of the whole collection laid out within available (infinity on an unbounded axis). Realizes and measures only the items in the context's realization rect.
arrange¶
Places the items realized by the last measure() within final_size and returns the size used.
on_items_changed¶
Called when the collection changed. The default calls invalidate_measure(), which lays out everything again.
line_count¶
How many lines the last measure laid out.
class LayoutOwner¶
What a layout's host does when the layout asks to be redone.
LayoutPanelControl and ForEachControl, the two hosts a Layout attaches to, implement it by measuring or arranging themselves again. A layout reaches it through Layout::invalidate_measure() and Layout::invalidate_arrange().
Example:
// A custom layout: a property change redoes the host only while one is attached.
class GapLayout : public ui::NonVirtualizingLayout
{
public:
void set_gap(float gap)
{
gap_ = gap;
if (owner() != nullptr)
{
invalidate_measure(); // the host's layout_invalidated(true)
}
}
private:
float gap_ = 0.0f;
};
LayoutOwner¶
LayoutOwner¶
operator=¶
layout_invalidated¶
The layout's properties changed. Measure and arrange again when measure is true, else only arrange.
~LayoutOwner¶
struct ItemsChange¶
A change to a virtualizing layout's collection, as the host hands it to VirtualizingLayout::on_items_changed().
Hosts build it from their notify_*() calls, such as ForEachControl::notify_inserted(). A layout that caches per-item state uses it to shift or drop that state.
Example:
// A layout that caches each item's height.
class CachedRowLayout : public ui::VirtualizingLayout
{
public:
void on_items_changed(ui::VirtualizingLayoutContext&, const ui::ItemsChange& change) override
{
if (change.action == ui::ItemsChangeAction::Add)
{
const auto at = heights_.begin() + static_cast<std::ptrdiff_t>(change.new_index);
heights_.insert(at, change.new_count, 0.0f);
}
else
{
heights_.clear();
}
invalidate_measure();
}
private:
std::vector<float> heights_;
};
| Field | Type | Default | |
|---|---|---|---|
action |
ItemsChangeAction |
ItemsChangeAction::Reset |
The kind of change. The ItemsChangeAction says which index and count fields apply. |
old_index |
std::size_t |
0 |
The first affected item before the change (Remove, Replace, Move). |
old_count |
std::size_t |
0 |
How many items were removed, replaced or moved. |
new_index |
std::size_t |
0 |
The first affected item after the change (Add, Replace, Move). |
new_count |
std::size_t |
0 |
How many items were inserted or replaced in. |
class NonVirtualizingLayoutContext¶
The children of a panel, as a non-virtualizing layout sees them.
The host implements it. A layout calls it only from its measure() and arrange(). Children are addressed by index, in the host's child order, and all of them exist up front.
Example:
class ColumnLayout : public ui::NonVirtualizingLayout
{
public:
ui::Size measure(ui::NonVirtualizingLayoutContext& context, ui::Size available) override
{
ui::Size total{};
for (std::size_t i = 0; i < context.item_count(); ++i)
{
const ui::Size d = context.measure(i, {available.width, ui::Unbounded});
total.width = std::max(total.width, d.width);
total.height += d.height;
}
return total;
}
};
~NonVirtualizingLayoutContext¶
item_count¶
How many children the host has.
measure¶
Measures child index in available (infinity on an unbounded axis) and returns its desired size. desired_size() returns the same size until the next measure.
desired_size¶
The desired size child index reported at its last measure().
arrange¶
Places child index, in coordinates relative to the host's content box.
class VirtualizingLayoutContext¶
A collection, as a virtualizing layout sees it.
The host implements it: ForEachControl, or LayoutPanelControl, where every child counts as realized. A layout calls it only from its measure() and arrange(). It asks only for the items that fall in realization_rect(), measures and arranges them through the context, and lets the host recycle the rest.
Example:
// Realizes and measures the rows, 32 high, that fall in the realization rect.
void measure_rows(ui::VirtualizingLayoutContext& context, ui::Size available)
{
const ui::Rect view = context.realization_rect();
const auto first = static_cast<std::size_t>(std::max(0.0f, view.y) / 32.0f);
for (std::size_t i = first; i < context.item_count() && static_cast<float>(i) * 32.0f < view.bottom(); ++i)
{
ui::Element& e = context.get_or_create_element_at(i);
(void)context.measure(e, {available.width, ui::Unbounded});
}
}
~VirtualizingLayoutContext¶
item_count¶
How many items the collection holds.
get_or_create_element_at¶
The element for item index, realized from the host's item template if it is not already. Asking for it keeps it realized through this measure pass. The host owns the element.
get_or_create_element_at¶
get_or_create_element_at() with ElementRealizationOptions::None.
recycle_element¶
Lets the host clear an element now instead of at the end of the pass.
index_of¶
The item an element was realized for; unset when it is not one of this collection's.
realization_rect¶
The part of the layout worth realizing: the viewport plus the cache buffer around it, in layout coordinates. Unbounded (a huge rect) when the host has nothing to scroll it.
visible_rect¶
The viewport alone.
recommended_anchor_index¶
The item to lay out first after a long scroll jump, such as a bring-into-view target, if any.
layout_origin¶
Where the layout's origin sits in the host's content box. A layout that places items at negative positions moves it.
set_layout_origin¶
Moves the layout origin; see layout_origin().
measure¶
Measures an element in available (infinity on an unbounded axis) and returns its desired size, which desired_size() keeps.
desired_size¶
The desired size element reported at its last measure() through this context.
arrange¶
Places an element in the host's content box, in layout coordinates minus layout_origin().
Enumerations¶
ItemsJustification¶
Where the items of a line go in the room left over along it (a LinedFlowLayout's or TileLayout's ItemsJustification, a WrapLayout's line alignment).
| Value | |
|---|---|
Start |
Packed at the start (the default). |
Center |
Packed in the middle. |
End |
Packed at the end. |
SpaceAround |
Equal room around each item, so half as much at the ends. |
SpaceBetween |
First and last item at the ends, equal gaps between the rest. |
SpaceEvenly |
Equal gaps between the items and at both ends. |
ItemsChangeAction¶
What kind of change it was.
| Value | |
|---|---|
Add |
new_count items inserted at new_index |
Remove |
old_count items removed from old_index |
Replace |
old_count items at old_index replaced by new_count new ones |
Move |
old_count items moved from old_index to new_index |
Reset |
anything else: the whole collection is new |
ElementRealizationOptions¶
How get_or_create_element_at() hands an element out. Combine with |, test with has_flag().
| Value | |
|---|---|
None |
Realize it normally; the host recycles it after a pass that did not ask for it. |
ForceCreate |
Realize it even outside the collection's realized range, where the host would otherwise refuse. Use it to measure a representative item. |
SuppressAutoRecycle |
The layout keeps track of it and recycles it itself. The host does not clear it at the end of a pass that did not ask for it. |
LinedFlowLayoutItemsStretch¶
Whether lines narrower than the room are widened to fill it.
| Value | |
|---|---|
None |
lines keep their natural width and are placed by ItemsJustification (the default) |
Fill |
every line but the last is scaled up to run edge to edge |
TileLayoutItemsStretch¶
Whether cells grow to use the leftover room on a line.
| Value | |
|---|---|
None |
Cells keep their size (the default). |
Fill |
Cells widen (along the line) so the line fills the available size. |
Uniform |
As Fill, and the other dimension grows in proportion. |
Functions¶
has_flag¶
Whether set contains flag.
operator|¶
The union of two option sets.
unbounded_rect¶
A rect that stands for no limit. A host with nothing to scroll it reports it as its realization rect. It is huge but finite, because infinite bounds would make its right edge NaN.
is_unbounded¶
Whether a realization rect is unbounded along either axis, as in a non-virtualizing context.
Tests¶
tests/test_layout_panels.cpptests/test_for_each.cpp