TwoPane¶
Header: winui/ui/panes/TwoPane.hpp. Spec: winui/ui/panes/TwoPane.hpp.
Two content panes that sit side by side when there is width, stacked when there is height, and collapse to one pane when there is neither.
Each measure pass picks the mode from the available size. It is Wide when the width exceeds min_wide_mode_width(), else Tall when the height exceeds min_tall_mode_height(), else a single pane chosen by pane_priority(). The two panes share the split axis by pane1_length() and pane2_length(), like two Grid tracks. The pane not shown takes no part in layout, rendering, focus or accessibility. There is no mode-changed event, so read mode() after layout. Panes are not wrapped in a Scroll, so put one in a pane that needs to scroll. Spanning two screens is not supported.
Example:
auto view = std::make_unique<ui::TwoPaneControl>();
auto* list = view->set_pane1(std::make_unique<ui::ListViewControl>());
view->set_pane2(std::make_unique<ui::TextControl>("Select an item"));
view->set_pane1_length(ui::GridLength::dip(320.0f));
view->set_min_wide_mode_width(500.0f);
view->set_tall_mode_configuration(ui::TwoPaneTallModeConfiguration::SinglePane);
window.set_content(std::move(view));
// Or declaratively:
window.set_content(ui::TwoPane{
.pane1_length = ui::GridLength::dip(320.0f),
.min_wide_mode_width = 500.0f,
.pane1 = ui::Text{.text = "Master"},
.pane2 = ui::Text{.text = "Detail"},
});
ui::TwoPane¶
Two regions that sit side by side, stacked or alone, depending on the space they get. Builds a ui::TwoPaneControl. No event reports the mode. Read TwoPaneControl::mode() after layout.
Each measure picks the mode from the available size. It is Wide when the width exceeds min_wide_mode_width, else Tall when the height exceeds min_tall_mode_height, else the single pane pane_priority names.
Example:
using ui::operator""_dip;
window.set_content(ui::TwoPane{
.pane1_length = 320_dip,
.min_wide_mode_width = 500.0f,
.pane1 = ui::ListView<std::string>{.items = {"Inbox", "Sent", "Drafts"}},
.pane2 = ui::Text{.text = "Select an item"},
});
Every field, in the order a designated initializer names them:
ui::TwoPane{
.pane1_length, .pane2_length, .pane_priority, .wide_mode_configuration,
.tall_mode_configuration, .min_wide_mode_width, .min_tall_mode_height, .style, .margin,
.width, .height, .min_width, .min_height, .max_width, .max_height, .horizontal_alignment,
.vertical_alignment, .visible, .tool_tip, .accessibility, .on_pointer_entered,
.on_pointer_exited, .on_got_focus, .on_lost_focus, .on_key_down, .on_wheel, .control,
.pane1, .pane2
}
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
pane1_length |
ui::Binding<ui::GridLength> |
{ui::GridLength::auto_()} |
Pane 1's share of the split axis (Auto by default). |
pane2_length |
ui::Binding<ui::GridLength> |
{ui::GridLength::fraction()} |
Pane 2's share; one fraction by default, so it takes the rest. |
pane_priority |
ui::Binding<ui::TwoPanePriority> |
{ui::TwoPanePriority::Pane1} |
The pane shown alone in SinglePane mode. |
wide_mode_configuration |
ui::Binding<ui::TwoPaneWideModeConfiguration> |
{ui::TwoPaneWideModeConfiguration::LeftRight} |
The Wide arrangement: LeftRight (the default), RightLeft, or SinglePane to never split. |
tall_mode_configuration |
ui::Binding<ui::TwoPaneTallModeConfiguration> |
{ui::TwoPaneTallModeConfiguration::TopBottom} |
The Tall arrangement: TopBottom (the default), BottomTop, or SinglePane to never stack. |
min_wide_mode_width |
ui::Binding<float> |
{641.0f} |
The width threshold in DIPs. Wide needs more available width than this. |
min_tall_mode_height |
ui::Binding<float> |
{641.0f} |
The height threshold in DIPs. Tall needs more available height than this. |
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::TwoPane> |
Out: the handle that receives the built control. | |
pane1 |
ui::Spec |
The first region: left or top by default, and the one shown alone unless pane_priority says otherwise. |
|
pane2 |
ui::Spec |
The second region. |
Plus the common fields style, margin, width, height, min_width, min_height, max_width, max_height, horizontal_alignment, vertical_alignment, visible, tool_tip, accessibility every spec carries (conventions).
build¶
Consumes the spec and returns the built ui::TwoPaneControl; the caller owns it.
ui::TwoPaneControl¶
Derives from ui::Element.
Two content panes that sit side by side when there is width, stacked when there is height, and collapse to one pane when there is neither.
Each measure pass picks the mode from the available size. It is Wide when the width exceeds min_wide_mode_width(), else Tall when the height exceeds min_tall_mode_height(), else a single pane chosen by pane_priority(). The two panes share the split axis by pane1_length() and pane2_length(), like two Grid tracks. The pane not shown takes no part in layout, rendering, focus or accessibility. There is no mode-changed event, so read mode() after layout. Panes are not wrapped in a Scroll, so put one in a pane that needs to scroll. Spanning two screens is not supported.
Example:
auto view = std::make_unique<ui::TwoPaneControl>();
auto* list = view->set_pane1(std::make_unique<ui::ListViewControl>());
view->set_pane2(std::make_unique<ui::TextControl>("Select an item"));
view->set_pane1_length(ui::GridLength::dip(320.0f));
view->set_min_wide_mode_width(500.0f);
view->set_tall_mode_configuration(ui::TwoPaneTallModeConfiguration::SinglePane);
window.set_content(std::move(view));
// Or declaratively:
window.set_content(ui::TwoPane{
.pane1_length = ui::GridLength::dip(320.0f),
.min_wide_mode_width = 500.0f,
.pane1 = ui::Text{.text = "Master"},
.pane2 = ui::Text{.text = "Detail"},
});
TwoPaneControl¶
An empty view: no panes, pane 1 Auto, pane 2 one fraction, both thresholds 641 DIPs.
set_pane1¶
Takes ownership of pane 1 and returns a non-owning observer, like ExpanderControl::set_content(). Destroys any previous pane 1. Null clears it. Lays the view out again.
set_pane2¶
Takes ownership of pane 2 and returns a non-owning observer; see set_pane1().
pane1¶
Pane 1, or null before set_pane1(). Owned by the view.
pane2¶
Pane 2, or null before set_pane2(). Owned by the view.
pane1_length¶
Pane 1's track along the split axis, a GridLength as in a Grid track (DIPs, Auto or a fraction); Auto by default.
set_pane1_length¶
Changes pane 1's track and lays the view out again. Only used while both panes are shown.
pane2_length¶
Pane 2's track along the split axis; one fraction by default, so it takes the rest.
set_pane2_length¶
Changes pane 2's track and lays the view out again.
pane_priority¶
The pane shown in SinglePane mode; Pane1 by default.
set_pane_priority¶
Changes the single-pane choice and lays the view out again.
wide_mode_configuration¶
How the panes are arranged in Wide mode; LeftRight by default.
set_wide_mode_configuration¶
Changes the Wide arrangement and lays the view out again.
tall_mode_configuration¶
How the panes are arranged in Tall mode; TopBottom by default.
set_tall_mode_configuration¶
Changes the Tall arrangement and lays the view out again.
min_wide_mode_width¶
The width threshold in DIPs; 641 by default. Wide needs more available width than this. An unbounded width never qualifies.
set_min_wide_mode_width¶
Sets the Wide threshold, clamped to >= 0, and lays the view out again.
min_tall_mode_height¶
The height threshold in DIPs; 641 by default. Tall needs more available height than this. Only tested when Wide did not apply.
set_min_tall_mode_height¶
Sets the Tall threshold, clamped to >= 0, and lays the view out again.
mode¶
The mode the most recent measure() pass picked; SinglePane before the first. No event reports a change. A caller that reacts to it reads it after layout, for example from its own tick_override().
for_each_child¶
Only the panes the mode shows. A hidden pane takes no part in any walk over the tree, such as layout and rendering.
measure_override¶
The view itself is not focusable. Tab reaches into the shown panes.
arrange_override¶
Position children within the rect arrange() settled on (also in bounds(), window DIPs). Default: nothing, for a leaf.
render_override¶
What the control draws, in layout coordinates; render() has already applied the visual layer. A container draws its children through their render(), never their render_override().
Enumerations¶
TwoPanePriority¶
Which pane wins when the available space fits neither Wide nor Tall.
| Value | |
|---|---|
Pane1 |
Show pane 1 alone (the default). |
Pane2 |
Show pane 2 alone. |
TwoPaneMode¶
Which axis, if either, the two panes are split along, as mode() reports it. The order of the panes on that axis comes from TwoPaneWideModeConfiguration or TwoPaneTallModeConfiguration, so mode() does not tell LeftRight from RightLeft.
| Value | |
|---|---|
SinglePane |
Only the pane_priority() pane is shown. |
Wide |
Both panes, side by side. |
Tall |
Both panes, one above the other. |
TwoPaneWideModeConfiguration¶
How the panes are arranged once the width qualifies for Wide.
| Value | |
|---|---|
SinglePane |
Never split horizontally; fall through to the Tall test. |
LeftRight |
Pane 1 on the left (the default). |
RightLeft |
Pane 1 on the right. |
TwoPaneTallModeConfiguration¶
How the panes are arranged once the height qualifies for Tall.
| Value | |
|---|---|
SinglePane |
Never stack; show a single pane instead. |
TopBottom |
Pane 1 on top (the default). |
BottomTop |
Pane 1 at the bottom. |
Tests¶
tests/test_two_pane.cpp