TilePanel¶
Header: winui/ui/panels/TilePanel.hpp. Spec: winui/ui/panels/TilePanel.hpp.
A grid of equal cells that children fill in order, each spanning as many rows and columns of cells as it asks for, wrapping to a new line when one is full.
The cell is item_width() x item_height(), each taken from the first child when unset. Children go first-fit into the free cells, so a small child fills a hole a larger one left behind. A child bigger than the lines is clipped to them. Children that don't fit anywhere are not placed and get an empty rect. The panel asks for the cells it used, plus any alignment offsets. Use it for tile layouts such as a start screen or a photo mosaic. For many items, prefer a virtualizing TileLayoutEngine.
Example:
auto grid = std::make_unique<ui::TilePanelControl>();
grid->set_orientation(ui::Orientation::Horizontal);
grid->set_item_width(80.0f);
grid->set_item_height(80.0f);
grid->set_maximum_rows_or_columns(4);
grid->add(std::make_unique<ui::ButtonControl>("Mail"), 2, 2); // a 2x2 tile
grid->add(std::make_unique<ui::ButtonControl>("Photos"), 1, 2); // one row, two columns
grid->add(std::make_unique<ui::ButtonControl>("Maps"));
// Or declaratively:
window.set_content(ui::TilePanel{
.orientation = ui::Orientation::Horizontal,
.item_width = 80.0f,
.item_height = 80.0f,
.maximum_rows_or_columns = 4,
.content = {
ui::TilePanelItem{.row_span = 2, .column_span = 2, .content = ui::Button{.text = "Mail"}},
ui::TilePanelItem{.column_span = 2, .content = ui::Button{.text = "Photos"}},
ui::TilePanelItem{.content = ui::Button{.text = "Maps"}},
},
});
ui::TilePanel¶
Equal cells filled in order, children spanning several. Builds a ui::TilePanelControl.
Example:
ui::Spec tile(ui::Color c) { return ui::Border{.background = c}; }
window.set_content(ui::TilePanel{
.orientation = ui::Orientation::Horizontal,
.item_width = 44.0f,
.item_height = 44.0f,
.maximum_rows_or_columns = 3,
.content = {
ui::TilePanelItem{.content = tile(ui::colors::Black)},
ui::TilePanelItem{.row_span = 2, .content = tile(ui::colors::White)},
ui::TilePanelItem{.column_span = 2, .content = tile(ui::Color::from_rgba(0, 120, 215))},
},
});
Every field, in the order a designated initializer names them:
ui::TilePanel{
.orientation, .item_width, .item_height, .maximum_rows_or_columns,
.horizontal_children_alignment, .vertical_children_alignment, .background, .style, .margin,
.width, .height, .min_width, .min_height, .max_width, .max_height, .horizontal_alignment,
.vertical_alignment, .visible, .tool_tip, .enabled, .accessibility, .on_pointer_entered,
.on_pointer_exited, .on_got_focus, .on_lost_focus, .on_key_down, .on_wheel, .control,
.content
}
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
orientation |
ui::Binding<ui::Orientation> |
{ui::Orientation::Vertical} |
Vertical (the default) fills columns top to bottom, then wraps right; Horizontal fills rows. |
item_width |
ui::Binding<std::optional<float>> |
The cell width, DIPs; unset takes the first child's width. | |
item_height |
ui::Binding<std::optional<float>> |
The cell height, DIPs; unset takes the first child's height. | |
maximum_rows_or_columns |
ui::Binding<std::size_t> |
{0} |
Cells per line before wrapping; 0 is no cap. |
horizontal_children_alignment |
ui::Binding<ui::Alignment> |
{ui::Alignment::Leading} |
Where the block of cells sits horizontally; see TilePanelControl::horizontal_children_alignment(). |
vertical_children_alignment |
ui::Binding<ui::Alignment> |
{ui::Alignment::Leading} |
Where the block of cells sits vertically. |
background |
ui::Binding<ui::Paint> |
Background: a Color, or a ThemeColor read from the theme; empty (the default) draws none. | |
on_pointer_entered |
ui::Action |
The pointer moved onto the control. | |
on_pointer_exited |
ui::Action |
The pointer left the control. | |
on_got_focus |
ui::Action |
Keyboard focus arrived on the control, or on anything inside it, from outside it. A control with nothing focusable in it never gets focus, and never raises this. | |
on_lost_focus |
ui::Action |
Keyboard focus left the control and everything inside it. | |
on_key_down |
ui::Callback<ui::Handling(const ui::KeyEvent&)> |
A key pressed while focus is on the control or inside it, before the control's own handling; ui::Handled stops it there (Element::on_key_down()). | |
on_wheel |
ui::Callback<ui::Handling(const ui::PointerEvent&)> |
A wheel turn over the control, before the control scrolls; ui::Handled stops it there (Element::on_wheel()). | |
control |
ui::ControlOut<ui::TilePanel> |
Out: the handle that receives the built control. | |
content |
ui::TilePanelItemList |
The children with their spans; see ui::TilePanelItem. |
Plus the common fields style, margin, width, height, min_width, min_height, max_width, max_height, horizontal_alignment, vertical_alignment, visible, tool_tip, enabled, accessibility every spec carries (conventions).
build¶
Consumes the spec and returns the built ui::TilePanelControl; the caller owns it.
ui::TilePanelItem¶
One child of a TilePanel with the cell rows and columns it spans. Written inline in the grid's .content; see ui::TilePanel for an example.
Every field, in the order a designated initializer names them:
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
row_span |
int |
1 |
Cells covered along the column axis. |
column_span |
int |
1 |
Cells covered along the row axis. |
content |
ui::Spec |
The placed child. |
ui::TilePanelControl¶
Derives from ui::Panel.
A grid of equal cells that children fill in order, each spanning as many rows and columns of cells as it asks for, wrapping to a new line when one is full.
The cell is item_width() x item_height(), each taken from the first child when unset. Children go first-fit into the free cells, so a small child fills a hole a larger one left behind. A child bigger than the lines is clipped to them. Children that don't fit anywhere are not placed and get an empty rect. The panel asks for the cells it used, plus any alignment offsets. Use it for tile layouts such as a start screen or a photo mosaic. For many items, prefer a virtualizing TileLayoutEngine.
Example:
auto grid = std::make_unique<ui::TilePanelControl>();
grid->set_orientation(ui::Orientation::Horizontal);
grid->set_item_width(80.0f);
grid->set_item_height(80.0f);
grid->set_maximum_rows_or_columns(4);
grid->add(std::make_unique<ui::ButtonControl>("Mail"), 2, 2); // a 2x2 tile
grid->add(std::make_unique<ui::ButtonControl>("Photos"), 1, 2); // one row, two columns
grid->add(std::make_unique<ui::ButtonControl>("Maps"));
// Or declaratively:
window.set_content(ui::TilePanel{
.orientation = ui::Orientation::Horizontal,
.item_width = 80.0f,
.item_height = 80.0f,
.maximum_rows_or_columns = 4,
.content = {
ui::TilePanelItem{.row_span = 2, .column_span = 2, .content = ui::Button{.text = "Mail"}},
ui::TilePanelItem{.column_span = 2, .content = ui::Button{.text = "Photos"}},
ui::TilePanelItem{.content = ui::Button{.text = "Maps"}},
},
});
TilePanelControl¶
An empty grid: Vertical, cells sized from the first child, no line cap, Leading alignment.
add¶
Takes ownership of a child spanning row_span x column_span cells (0 counts as 1), appends it after the existing children, and returns a non-owning observer to it.
add¶
The declarative overload: builds spec (or takes the node a ui::Spec holds) and adds it as add() does a control. Returns the built node as an Element, or nullptr for an empty ui::Spec, which adds nothing; a spec's .control field gives a typed observer.
set_row_span¶
Changes how many cell rows child covers and updates the layout on a change. Ignored when child is not one of this grid's children.
set_column_span¶
Changes how many cell columns child covers.
row_span¶
The row span given for child, or 1 when it is not a child of this grid.
column_span¶
The column span given for child, or 1 when it is not a child of this grid.
orientation¶
Orientation: Vertical (the default) fills a column top to bottom before moving right.
set_orientation¶
Changes the fill direction and updates the layout.
item_width¶
The cell width in DIPs; nullopt (the default) takes the first child's desired size on that axis.
set_item_width¶
Sets or clears the cell width and updates the layout.
item_height¶
The cell height in DIPs; see item_width().
set_item_height¶
Sets or clears the cell height and updates the layout.
maximum_rows_or_columns¶
The most cells in a line; 0 (the default) is no cap.
set_maximum_rows_or_columns¶
Caps the cells per line and updates the layout.
horizontal_children_alignment¶
Where the block of cells sits horizontally; Leading (Left/Top) by default. In a panel larger than the used cells, Center and Trailing offset the whole block and Stretch spreads the lines apart.
set_horizontal_children_alignment¶
Changes the horizontal alignment and updates the layout.
vertical_children_alignment¶
The vertical alignment of the cell block; see horizontal_children_alignment().
set_vertical_children_alignment¶
Changes the vertical alignment and updates the layout.
cell_size¶
The size of one cell from the last measure.
items_per_line¶
Cells per line from the last measure.
line_count¶
Lines used by the last measure.
parallel_measure_safe¶
True: measuring touches only the panel and its children.
measure_override¶
Implement these instead of measure() and arrange(). The base class has already applied margin, size limits and alignment by the time these run. measure_override() is pure (every concrete Element must size itself); arrange_override() defaults to a no-op since most leaves need nothing beyond having bounds() set, which the base already did.
arrange_override¶
Position children within the rect arrange() settled on (also in bounds(), window DIPs). Default: nothing, for a leaf.
class TilePanelItemList¶
A TilePanel's children, built, in the same shape as CellList. Callers write it as a braced list of ui::TilePanelItem{...}.
items_¶
The placed children, in fill order.
TilePanelItemList¶
An empty list.
TilePanelItemList¶
template <typename... S>
TilePanelItemList(S&& ... items)
requires (sizeof...(S) > 0 && (std::same_as<S, TilePanelItem> && ...))
Builds every item's content and takes ownership of it.
TilePanelItemList¶
operator=¶
TilePanelItemList¶
operator=¶
add¶
Builds item's content and appends it, as one more entry of the braced list would.
struct Placed¶
One built child with its spans; the node is already owned by the list.
| Field | Type | Default | |
|---|---|---|---|
row_span |
int |
Cell rows covered. | |
column_span |
int |
Cell columns covered. | |
node |
std::unique_ptr<Element> |
The built child. |
Tests¶
tests/test_layout_panels.cpp