Skip to content

ToggleButton

Header: winui/ui/input/ToggleButton.hpp. Spec: winui/ui/input/ToggleButton.hpp.

A Button that stays pressed, with a nullable checked state.

Everything a Button has (text or content, style, padding, focus, Enter/Space, on_click()) still applies. Each activation first advances the state (unchecked -> checked -> unchecked, or -> indeterminate when three_state() is on) and then runs the click handler. A checked toggle draws the theme's accent button; eras without an accent button draw it sunken.

Example:

ui::Property<std::optional<bool>> bold{false};

auto toolbar = std::make_unique<ui::StackControl>(ui::Orientation::Horizontal);
auto* toggle = toolbar->add(std::make_unique<ui::ToggleButtonControl>("Bold"));
toggle->on_checked_changed([&](std::optional<bool> on) { bold = on; });

// Or declaratively, bound both ways through the Property:
toolbar->add(ui::ToggleButton{
    .text               = "Italic",
    .checked            = bold,
}.build());
window.set_content(std::move(toolbar));

ui::ToggleButton

A button that stays pressed. Builds a ui::ToggleButtonControl. checked is nullable, as ui::CheckBox's is, and two-way with ui::bind() of a Property<std::optional<bool>>. three_state lets a click reach indeterminate.

Example:

ui::Property<std::optional<bool>> bold{false};

window.set_content(ui::ToggleButton{.text = "Bold", .checked = bold});

Every field, in the order a designated initializer names them:

ui::ToggleButton{
    .text, .checked, .three_state, .padding, .style, .margin, .width, .height, .min_width,
    .min_height, .max_width, .max_height, .horizontal_alignment, .vertical_alignment, .visible,
    .tool_tip, .enabled, .accessibility, .command, .command_parameter, .on_click,
    .on_checked_changed, .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
text ui::Binding<std::string> The label, ignored while .content is set.
checked ui::CheckedField {false} True, false, or std::nullopt for indeterminate. Seeding it raises nothing. Two-way with a Property<bool> (a click writes true or false; an indeterminate state set on the control writes nothing) or a Property<std::optional<bool>> (every state). See ui::CheckedField.
three_state bool false A click also reaches indeterminate: unchecked, checked, indeterminate, unchecked. Without it, a click on an indeterminate button checks it. Needs checked bound to a Property<std::optional<bool>> (or one-way), since a Property<bool> cannot hold the third state; a debug build asserts on that. Read once, when the spec is built.
padding ui::Binding<std::optional<ui::Thickness>> The padding around the text or content; nullopt keeps the theme's button padding.
command ui::CommandRef A shared, named action (ui/Command.hpp), as ui::Button's: run after .on_click with .command_parameter, and the button is enabled only while both the command and .enabled allow it. An unset .tool_tip falls back to the command's description.
command_parameter std::string Handed to .command when it runs.
on_click ui::Action Click, as ui::Button's. The checked state has already changed when it runs.
on_checked_changed ui::Callback<void(std::optional<bool>)> The new state after any change, including into and out of indeterminate.
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::ToggleButton> Out: the handle that receives the built control.
content ui::Spec Arbitrary content instead of a plain label, as ui::Button's.

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

std::unique_ptr<Element> build()&&

Consumes the spec and returns the built ui::ToggleButtonControl; the caller owns it.

ui::ToggleButtonControl

Derives from ui::ButtonControl, ui::ToggleProvider.

A Button that stays pressed, with a nullable checked state.

Everything a Button has (text or content, style, padding, focus, Enter/Space, on_click()) still applies. Each activation first advances the state (unchecked -> checked -> unchecked, or -> indeterminate when three_state() is on) and then runs the click handler. A checked toggle draws the theme's accent button; eras without an accent button draw it sunken.

Example:

ui::Property<std::optional<bool>> bold{false};

auto toolbar = std::make_unique<ui::StackControl>(ui::Orientation::Horizontal);
auto* toggle = toolbar->add(std::make_unique<ui::ToggleButtonControl>("Bold"));
toggle->on_checked_changed([&](std::optional<bool> on) { bold = on; });

// Or declaratively, bound both ways through the Property:
toolbar->add(ui::ToggleButton{
    .text               = "Italic",
    .checked            = bold,
}.build());
window.set_content(std::move(toolbar));

ToggleButtonControl

ToggleButtonControl() = default

An unchecked toggle with no text; give it text with set_text() or content with set_content().

ToggleButtonControl

ToggleButtonControl(std::string text, std::optional<bool> checked = false)

A toggle labeled text, starting in checked (std::nullopt is indeterminate).

checked

std::optional<bool> checked() const

The checked state: true, false, or std::nullopt for indeterminate. Defaults to false.

set_checked

void set_checked(std::optional<bool> checked)

Changes the state and redraws. A no-op when unchanged; otherwise fires on_checked_changed(). Any value may be set, even std::nullopt without three_state().

three_state

bool three_state() const

Whether a click can reach indeterminate (checked -> indeterminate -> unchecked). Off by default.

set_three_state

void set_three_state(bool three_state)

Takes effect on the next activation; does not change the current state.

on_checked_changed

void on_checked_changed(Callback<void(std::optional<bool>)> handler)

Invoked with the new state whenever checked changes (click, Enter/Space, UI Automation or set_checked()), including into and out of indeterminate. Replaces any previous handler.

on_activated

void on_activated() override

Advances the checked state before the click handler runs.

current_visual

ButtonVisual current_visual(const Theme& theme) const override

The accent button's colors while checked; the standard button's otherwise.

Tests

  • tests/test_toggle_button.cpp