WrapPanel¶
Header: winui/ui/panels/WrapPanel.hpp. Spec: winui/ui/panels/WrapPanel.hpp.
A panel that places its children one after another along a line and starts a new line when the next child would cross the far edge. Use it for tag chips, a toolbar of variable-width buttons, or a gallery of cards that reflows with the window.
Along the orientation children sit item_spacing() apart; lines sit line_spacing() apart, each as tall as its tallest child, and every child in a line is arranged at the line's full height. The panel asks for its widest line by the sum of its lines, plus the padding. A first child wider than the whole panel does not push an empty line in front of itself. Built declaratively by ui::WrapPanel.
Example:
// Declarative:
window.set_content(ui::WrapPanel{
.item_spacing = 8.0f,
.line_spacing = 8.0f,
.padding = ui::Thickness{12.0f},
.content = {
ui::Button{.text = "Alpha"},
ui::Button{.text = "Beta"},
ui::Button{.text = "A much longer gamma"},
ui::Button{.text = "Delta"},
},
});
// Imperative:
auto panel = std::make_unique<ui::WrapPanelControl>();
panel->set_orientation(ui::Orientation::Horizontal);
panel->set_item_spacing(8.0f);
panel->set_line_spacing(4.0f);
panel->set_items_stretch(ui::WrapPanelItemsStretch::Last);
for (const char* tag : {"red", "green", "blue", "cyan", "magenta"})
{
panel->add(std::make_unique<ui::ButtonControl>(tag));
}
window.set_content(std::move(panel));
ui::WrapPanel¶
Children in lines that wrap. Builds a ui::WrapPanelControl.
Children keep their desired size; a line breaks when the next child would not fit.
Example:
ui::Spec chip(const char* text) { return ui::Button{.text = text}; }
window.set_content(ui::WrapPanel{
.item_spacing = 8,
.line_spacing = 8,
.padding = ui::Thickness{12.0f},
.content = {chip("Alpha"), chip("Beta item"), chip("Gamma"), chip("Delta item")},
});
Every field, in the order a designated initializer names them:
ui::WrapPanel{
.orientation, .item_spacing, .line_spacing, .items_stretch, .padding, .background,
.border_brush, .border_thickness, .corner_radius, .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::Horizontal} |
Horizontal (the default) fills rows and wraps downward; Vertical fills columns. |
item_spacing |
ui::Binding<float> |
{0.0f} |
Gap between neighbors along a line, DIPs. |
line_spacing |
ui::Binding<float> |
{0.0f} |
Gap between lines, DIPs. |
items_stretch |
ui::Binding<ui::WrapPanelItemsStretch> |
{ui::WrapPanelItemsStretch::None} |
None keeps every child's length; Last widens the last child to the end of its line. |
padding |
ui::Binding<ui::Thickness> |
{ui::Thickness{}} |
Inset between the panel's edge and the children, DIPs. |
background |
ui::Binding<ui::Paint> |
Background: a Color, or a ThemeColor read from the theme; empty (the default) draws none. | |
border_brush |
ui::Binding<ui::Paint> |
Border color, a Color or a ThemeColor; empty (the default) draws no border. | |
border_thickness |
ui::Binding<ui::Thickness> |
{ui::Thickness{}} |
Border width per edge, DIPs; it insets the children like padding. |
corner_radius |
ui::Binding<float> |
{0.0f} |
Corner radius of the background and the border, DIPs. |
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::WrapPanel> |
Out: the handle that receives the built control. | |
content |
ui::SpecList |
The wrapped children, in reading order. |
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::WrapPanelControl; the caller owns it.
ui::WrapPanelControl¶
Derives from ui::Panel.
A panel that places its children one after another along a line and starts a new line when the next child would cross the far edge. Use it for tag chips, a toolbar of variable-width buttons, or a gallery of cards that reflows with the window.
Along the orientation children sit item_spacing() apart; lines sit line_spacing() apart, each as tall as its tallest child, and every child in a line is arranged at the line's full height. The panel asks for its widest line by the sum of its lines, plus the padding. A first child wider than the whole panel does not push an empty line in front of itself. Built declaratively by ui::WrapPanel.
Example:
// Declarative:
window.set_content(ui::WrapPanel{
.item_spacing = 8.0f,
.line_spacing = 8.0f,
.padding = ui::Thickness{12.0f},
.content = {
ui::Button{.text = "Alpha"},
ui::Button{.text = "Beta"},
ui::Button{.text = "A much longer gamma"},
ui::Button{.text = "Delta"},
},
});
// Imperative:
auto panel = std::make_unique<ui::WrapPanelControl>();
panel->set_orientation(ui::Orientation::Horizontal);
panel->set_item_spacing(8.0f);
panel->set_line_spacing(4.0f);
panel->set_items_stretch(ui::WrapPanelItemsStretch::Last);
for (const char* tag : {"red", "green", "blue", "cyan", "magenta"})
{
panel->add(std::make_unique<ui::ButtonControl>(tag));
}
window.set_content(std::move(panel));
WrapPanelControl¶
An empty horizontal panel with no spacing, no padding and no stretch.
add¶
Appends child, taking ownership, and returns a non-owning observer to it. Children are placed in the order added.
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.
orientation¶
The flow direction: Horizontal (rows, the default) or Vertical (columns).
set_orientation¶
Changes the flow direction; invalidates layout.
item_spacing¶
The gap between two children in a line, in DIPs. Default 0.
set_item_spacing¶
Sets the gap between children; invalidates layout.
line_spacing¶
The gap between two lines, in DIPs. Default 0.
set_line_spacing¶
Sets the gap between lines; invalidates layout.
items_stretch¶
Whether the last child is widened to the end of its line. Default None.
set_items_stretch¶
Sets whether the last child is widened; invalidates layout.
parallel_measure_safe¶
True: measuring touches only the panel and its children.
border_brush¶
The outline color; nullopt (the default) draws no border even with a non-zero border_thickness(). Nullopt as well while a ThemeColor is set.
border_brush_resource¶
The theme resource the border is drawn from, or null.
border_thickness¶
The border width in DIPs per side (default zero); it insets the children like padding.
corner_radius¶
The corner radius in DIPs, uniform for all four corners (default 0, square).
padding¶
The padding in DIPs between the border and the children (default zero).
set_border_brush¶
A fixed outline color; replaces any resource. Marks the panel for redraw.
set_border_brush¶
An outline color read from the theme each time the panel is drawn; replaces any fixed color. Marks the panel for redraw.
set_border_thickness¶
Sets the border width; marks the panel for layout and redraw.
set_corner_radius¶
Sets the corner radius; marks the panel for redraw.
set_padding¶
Sets the padding; marks the panel for layout.
measure_override¶
Lays the children out in lines against available (less the padding) and returns the widest line by the sum of the lines, plus the padding.
arrange_override¶
Wraps against final_rect's size and places each child in its slot, every child as tall as its line and the last one stretched when items_stretch() is Last.
Enumerations¶
WrapPanelItemsStretch¶
Whether a WrapPanel stretches its last child.
| Value | |
|---|---|
None |
every child keeps its desired length along the line (the default) |
Last |
the panel's last child is widened to the end of its line |
Tests¶
tests/test_layout_panels.cpp