ToggleSwitch¶
Header: winui/ui/input/ToggleSwitch.hpp. Spec: winui/ui/input/ToggleSwitch.hpp.
A boolean on/off switch: a pill-shaped track with a sliding thumb, an optional header above it and a label beside it that follows the state.
Use it for a setting that takes effect immediately (a CheckBox is for a choice confirmed later). A click released over the control, or Space on key-up while focused, flips checked() and fires on_checked_changed(). The control reserves the width of the wider of its two labels, so flipping it never reflows its row. With animations running, the thumb slides and grows on hover. Otherwise it snaps.
Example:
ui::Property<bool> wifi{true};
auto stack = std::make_unique<ui::StackControl>(ui::Orientation::Vertical);
auto* sw = stack->add(std::make_unique<ui::ToggleSwitchControl>(true));
sw->set_header("Wi-Fi");
sw->on_checked_changed([&](bool on) { wifi = on; });
// Or declaratively, kept in step with the Property:
stack->add(ui::ToggleSwitch{
.header = "Airplane mode",
.checked = ui::bind(wifi, [](bool w) { return !w; }),
.checked_text = "Flying",
.unchecked_text = "Grounded",
.on_checked_changed = [&](bool on) { wifi = !on; },
}.build());
window.set_content(std::move(stack));
ui::ToggleSwitch¶
A boolean on/off switch, with a header above it and a label beside it that follows the state. Builds a ui::ToggleSwitchControl.
Example:
ui::Property<bool> wifi{true};
window.set_content(ui::ToggleSwitch{
.header = "Wi-Fi",
.checked = wifi,
.checked_text = "Connected",
.unchecked_text = "Off",
});
Every field, in the order a designated initializer names them:
ui::ToggleSwitch{
.header, .checked, .checked_text, .unchecked_text, .checked_icon, .unchecked_icon, .style,
.margin, .width, .height, .min_width, .min_height, .max_width, .max_height,
.horizontal_alignment, .vertical_alignment, .visible, .tool_tip, .enabled, .accessibility,
.on_checked_changed, .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 | |
|---|---|---|---|
header |
ui::Binding<std::string> |
The label above the control. Empty draws none. | |
checked |
ui::TwoWayField<bool> |
{false} |
On or off. Seeding it raises no .on_checked_changed. |
checked_text |
ui::Binding<std::optional<std::string>> |
The label beside the track while on; unset uses strings().toggle_switch.on ("On"). The same text in both checked_text and unchecked_text makes a label that does not change with the state. Both empty shows no label. |
|
unchecked_text |
ui::Binding<std::optional<std::string>> |
The label while off; unset uses strings().toggle_switch.off ("Off"). | |
checked_icon |
ui::Binding<ui::IconSource> |
An icon in place of the on state's text, which then only names that state for UI Automation. | |
unchecked_icon |
ui::Binding<ui::IconSource> |
The off state's icon, as checked_icon. |
|
on_checked_changed |
ui::Callback<void(bool)> |
The new state, whenever it changes. | |
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::ToggleSwitch> |
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::ToggleSwitchControl; the caller owns it.
ui::ToggleSwitchControl¶
Derives from ui::Element, ui::ToggleProvider.
A boolean on/off switch: a pill-shaped track with a sliding thumb, an optional header above it and a label beside it that follows the state.
Use it for a setting that takes effect immediately (a CheckBox is for a choice confirmed later). A click released over the control, or Space on key-up while focused, flips checked() and fires on_checked_changed(). The control reserves the width of the wider of its two labels, so flipping it never reflows its row. With animations running, the thumb slides and grows on hover. Otherwise it snaps.
Example:
ui::Property<bool> wifi{true};
auto stack = std::make_unique<ui::StackControl>(ui::Orientation::Vertical);
auto* sw = stack->add(std::make_unique<ui::ToggleSwitchControl>(true));
sw->set_header("Wi-Fi");
sw->on_checked_changed([&](bool on) { wifi = on; });
// Or declaratively, kept in step with the Property:
stack->add(ui::ToggleSwitch{
.header = "Airplane mode",
.checked = ui::bind(wifi, [](bool w) { return !w; }),
.checked_text = "Flying",
.unchecked_text = "Grounded",
.on_checked_changed = [&](bool on) { wifi = !on; },
}.build());
window.set_content(std::move(stack));
ToggleSwitchControl¶
An enabled switch, off, with the "On"/"Off" labels and no header.
ToggleSwitchControl¶
A switch starting in on; the initial state never fires on_checked_changed() or animates.
header¶
The header text; empty by default. See set_header().
set_header¶
The label above the switch. Empty (the default) draws none. A change updates the layout.
checked_text¶
The label beside the track while on: the control's own, else strings().toggle_switch.on ("On").
set_checked_text¶
Replaces the on label, or with nullopt goes back to strings().toggle_switch.on. Updates the layout, since the control is as wide as its wider label.
unchecked_text¶
The label beside the track while off: the control's own, else strings().toggle_switch.off ("Off").
set_unchecked_text¶
Replaces the off label, or with nullopt goes back to strings().toggle_switch.off. Updates the layout, as set_checked_text() does.
checked_icon¶
An icon shown beside the track while on, in place of checked_text(). Unset (the default) shows the text; with an icon, checked_text() still names the state for UI Automation.
set_checked_icon¶
Sets the on icon, or clears it with an empty source. Updates the layout.
unchecked_icon¶
An icon shown beside the track while off, in place of unchecked_text().
set_unchecked_icon¶
Sets the off icon, or clears it with an empty source. Updates the layout.
checked¶
Whether the switch is on. Off by default.
set_checked¶
Changes the state and redraws. Does nothing when unchanged. Otherwise fires on_checked_changed(), also when called from code.
on_checked_changed¶
Invoked with the new state whenever checked() changes (click, Space, UI Automation or set_checked()). Replaces any previous handler.
parallel_measure_safe¶
True: measuring reads only the switch's own state, the measurer and the theme.
focused¶
Whether the switch holds keyboard focus (and so draws its focus ring around the track).
focusable¶
Only an enabled switch joins the tab ring.
is_pressed¶
True while the pointer is held down over the switch or Space is held; never while disabled.
automation_role¶
Role Button; UI Automation has no dedicated toggle switch role.
automation_name_fallback¶
The header when there is one, since it names the switch; otherwise the state's text.
visual_state¶
Disabled, Pressed, Hover or Normal, in that priority; picks the track and thumb colors.
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.
pointer_override¶
A pointer event for this element: the element under the pointer, one inside it that did not handle the event, or the element holding the capture. The position is in layout coordinates (handle_pointer()). Return true when the event did something here, and it goes no further up; a handled press also captures the pointer until its release. A control that acts on a press (a click, a toggle, a caret placed, a drag started) returns true for the press and its release, so a list row or a card around it does not act on the same click. Default: false.
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().
tick_override¶
Advances the knob's slide and resize, and the Aero theme's sliding knob, which is redrawn every frame because its fill is a gradient.
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¶
Keyboard focus arrived (true) or left (false); is_focused() already says so. The element is redrawn either way. No-op by default.
key_override¶
A key for this element: the focused one, or one inside it that did not handle it. Return true when the key did something here, and it goes no further; false lets it bubble on to the parent and then to the shortcuts, a dialog's default button and arrow-key focus moves. Default: false.
focus_ring_rect¶
Around switch and label, or the switch alone in Metro's era.
focus_ring_corner_radius¶
The ring's corner radius: the theme's control radius by default.
Tests¶
tests/test_toggle_switch.cpp