Splitter¶
Header: winui/ui/panes/Splitter.hpp. Spec: winui/ui/panes/Splitter.hpp.
A draggable divider that resizes along one axis, between two Grid tracks or two panes.
Place it in a Grid track of its own with a track on either side: a column for a Vertical bar, a row for a Horizontal one. It then resizes those two tracks within their min and max (GridControl::resize_beside()). With an on_drag_delta() handler it resizes nothing and passes each delta to the handler, for a layout of the caller's own. While it has focus, the arrow keys along its axis resize too. It fills the available length along its axis and is thickness() across it. The declarative form is ui::Splitter.
Example:
using ui::operator""_fr;
using ui::operator""_dip;
window.set_content(ui::Grid{
.columns = {ui::minmax(80_dip, 1_fr), 6_dip, 1_fr},
.min_width = 420.0f,
.content = {
ui::Cell{.column = 0, .content = ui::Button{.text = "Left"}},
ui::Cell{.column = 1, .content = ui::Splitter{}}, // drag or arrow keys move the two columns
ui::Cell{.column = 2, .content = ui::Button{.text = "Right"}},
},
});
// A layout of your own: the handler gets the deltas and the splitter resizes nothing.
ui::Property<float> top_height{200.0f};
auto splitter = std::make_unique<ui::SplitterControl>(ui::Orientation::Horizontal);
splitter->on_drag_delta([&](float dy) { top_height = std::max(40.0f, top_height.get() + dy); });
ui::Splitter¶
A draggable divider. Builds a ui::SplitterControl.
In a Grid track of its own between two others it resizes those two tracks, by drag or by the arrow keys, within their ui::minmax() limits. For a layout of your own, set .on_drag_delta. The splitter then resizes nothing and passes on each delta in DIPs. Add the delta to GridControl::column_size(), not to a neighbor's bounds(). Bounds are already shrunk by margins, so feeding them back collapses the track on the first drag.
Example:
using ui::operator""_dip;
using ui::operator""_fr;
window.set_content(ui::Grid{
.columns = {ui::minmax(120_dip, 200_dip), ui::AutoSize, 1_fr},
.content = {
ui::Cell{.column = 0, .content = ui::Text{.text = "Folders"}},
ui::Cell{.column = 1, .content = ui::Splitter{}},
ui::Cell{.column = 2, .content = ui::Text{.text = "Messages"}},
},
});
Every field, in the order a designated initializer names them:
ui::Splitter{
.orientation, .thickness, .focusable, .keyboard_increment, .style, .margin, .width,
.height, .min_width, .min_height, .max_width, .max_height, .horizontal_alignment,
.vertical_alignment, .visible, .tool_tip, .enabled, .accessibility, .on_drag_delta,
.on_pointer_entered, .on_pointer_exited, .on_got_focus, .on_lost_focus, .on_key_down,
.on_wheel, .control
}
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
orientation |
ui::Orientation |
ui::Orientation::Vertical |
The bar's own axis. Vertical (the default) is a vertical bar dragged left and right to resize columns. Horizontal resizes rows. |
thickness |
ui::Binding<float> |
{6.0f} |
The bar's thickness across its axis, DIPs. |
focusable |
bool |
true |
Whether the bar takes focus. With focus, the arrow keys along the drag axis resize as a drag does, four times as far with Shift. On by default. |
keyboard_increment |
ui::Binding<float> |
{8.0f} |
One arrow-key step, DIPs; four times as far with Shift. |
on_drag_delta |
ui::Callback<void(float)> |
The drag or key step along the drag axis since the previous call, DIPs. Positive is right or down. Setting it turns off the resizing of the Grid tracks beside the bar. | |
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::Splitter> |
Out: the handle that receives the built control. |
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::SplitterControl; the caller owns it.
ui::SplitterControl¶
Derives from ui::Element.
A draggable divider that resizes along one axis, between two Grid tracks or two panes.
Place it in a Grid track of its own with a track on either side: a column for a Vertical bar, a row for a Horizontal one. It then resizes those two tracks within their min and max (GridControl::resize_beside()). With an on_drag_delta() handler it resizes nothing and passes each delta to the handler, for a layout of the caller's own. While it has focus, the arrow keys along its axis resize too. It fills the available length along its axis and is thickness() across it. The declarative form is ui::Splitter.
Example:
using ui::operator""_fr;
using ui::operator""_dip;
window.set_content(ui::Grid{
.columns = {ui::minmax(80_dip, 1_fr), 6_dip, 1_fr},
.min_width = 420.0f,
.content = {
ui::Cell{.column = 0, .content = ui::Button{.text = "Left"}},
ui::Cell{.column = 1, .content = ui::Splitter{}}, // drag or arrow keys move the two columns
ui::Cell{.column = 2, .content = ui::Button{.text = "Right"}},
},
});
// A layout of your own: the handler gets the deltas and the splitter resizes nothing.
ui::Property<float> top_height{200.0f};
auto splitter = std::make_unique<ui::SplitterControl>(ui::Orientation::Horizontal);
splitter->on_drag_delta([&](float dy) { top_height = std::max(40.0f, top_height.get() + dy); });
SplitterControl¶
A 6 DIP bar along orientation, focusable.
orientation¶
The bar's axis, fixed at construction.
thickness¶
The bar's size across its axis, in DIPs; 6 by default.
set_thickness¶
Changes the thickness and lays the bar out again.
on_drag_delta¶
Fired while the pointer drags or an arrow key steps, with the movement in DIPs since the previous call. The axis follows orientation: x for Vertical, y for Horizontal. Setting a handler turns off the resizing of the Grid tracks beside the bar.
dragging¶
Whether a pointer drag is in progress: the button went down on the bar and is still held.
hovered¶
Whether the pointer is over the bar. The bar draws the accent separator while hovered or dragged.
set_focusable¶
Whether the bar takes focus; true by default. With focus, ArrowLeft/Right (Vertical) or ArrowUp/Down (Horizontal) resize by +/- keyboard_increment(), or four times that with Shift held. False leaves it out of the tab order.
focusable¶
Whether the bar is a tab stop: set_focusable(), and only while enabled.
focused¶
Whether the bar has keyboard focus.
keyboard_increment¶
The arrow-key step, in DIPs; 8 by default. Set a different step, such as one grid unit, with set_keyboard_increment().
set_keyboard_increment¶
Sets the arrow-key step, in DIPs.
cursor_at¶
The resize arrow along the drag axis: west-east for a vertical bar, north-south for a horizontal one.
automation_role¶
Reported to screen readers as a Thumb with no value, because the splitter reports relative movement and has no bounded value of its own.
measure_override¶
thickness() across the axis by the available length along it (thickness() when unbounded).
render_override¶
A 1 pixel divider at rest, and a 2 pixel accent separator while hovered or dragged.
pointer_override¶
Starts a drag on a press over the bar, reports each move's delta and ends on release.
enabled_changed¶
is_enabled() flipped, through set_enabled() here or on an ancestor, or a move to another parent. Drop any press or hover state. The element is redrawn either way. No-op by default.
focus_changed¶
Called by the Window as focus arrives or leaves; redraws.
key_override¶
The arrow keys along the axis step by keyboard_increment(), four times as far with Shift.
Tests¶
tests/test_splitter.cpp