ml::docs | Your First App Manifests Events Messaging Plugins Scenes Resources
See all tutorials →
Beginner 4 sections ~15 min C++17/20

Toggle Controls

Three toggle controls — ButtonToggle, PillToggle, and SegmentToggle — each with animated state transitions, Settings/Theme/Style layering, and a single onToggled callback.

interactive preview
ButtonToggle
Muted
PillToggle
Off
Dark mode
SegmentToggle
Light
Dark
Introduction

Three Toggle Styles

Each toggle inherits its geometry from a Settings type and its colors from a Theme type. The active app theme is applied automatically via Themeable. Use applySettings(), applyTheme(), or applyStyle() to customize, and onToggled() to react to state changes.

ClassVisual styleManifestVariant template
ml::ButtonToggleRectangular button, label swaps on toggleButtonToggleManifestButtonToggleWith<M>
ml::PillToggleiOS-style oval with animated sliding thumbPillToggleManifestPillToggleWith<M>
ml::SegmentToggleTwo-segment pill with animated pill indicatorSegmentToggleManifestSegmentToggleWith<M>

All three share the same state API: setOn(bool), toggle(), isOn(), setEnabled(bool), isEnabled(), and onToggled(std::function<void(bool)>).


1Controls

ButtonToggle

A rectangular button that changes its label and colors when toggled on or off. Inherits ButtonSettings (geometry, labels, icons) and ButtonTheme (colors).

ButtonToggle — basic usage cpp
ml::ButtonToggle toggle;
toggle.setOffLabel("Muted");
toggle.setOnLabel("Live");
toggle.setPosition({200.f, 100.f});

toggle.onToggled([](bool on) {
    setStreamActive(on);
});

addComponent(toggle);

The toggle state can be driven programmatically too:

ButtonToggle — state API cpp
toggle.setOn(true);      // force on
toggle.toggle();         // flip current state
bool on = toggle.isOn(); // query state

toggle.setEnabled(false); // disable interactions
bool en = toggle.isEnabled();

Use applySettings(), applyTheme(), or applyStyle() to bulk-configure the toggle. Any type that derives from ButtonSettings works with applySettings(), and any type that derives from ButtonTheme works with applyTheme(). applyStyle() requires both.

FlagStateMeaning
Flag::ONState::ONToggle is currently active
Flag::DISABLEDState::DISABLEDInteractions are suppressed
State::IDLEDefault, not hovered
State::HOVEREDMouse is over the button

2Controls

PillToggle

An iOS-style oval pill switch. The circular thumb slides left (off) or right (on) with a smooth animation driven internally by an sf::Clock. Inherits PillSettings (layout, labels, animation speed) and PillTheme (colors).

PillToggle — basic usage cpp
ml::PillToggle darkMode;
darkMode.setRightLabel("Dark mode");  // label drawn to the right of the pill
darkMode.setPosition({200.f, 100.f});

darkMode.onToggled([](bool on) {
    ThemeManager::apply(on ? DarkTheme{} : LightTheme{});
});

addComponent(darkMode);
PillToggle — font size convenience aliases cpp
// Both names work — match whichever convention you prefer
darkMode.setCharacterSize(14);      // SFML-style alias
darkMode.setFontSize(14);           // Settings-style name
unsigned sz = darkMode.getCharacterSize(); // or getFontSize()

The only thing the active app theme updates on a PillToggle is the PillTheme layer — geometry and labels are untouched. If you need to override colors without a full style, call applyTheme(MyPillTheme{}).


3Controls

SegmentToggle

A two-option segmented control drawn as a rounded rectangle split into two halves. The active segment is highlighted by an animated pill indicator. Inherits SegmentSettings (geometry, labels) and SegmentTheme (colors).

SegmentToggle — basic usage cpp
ml::SegmentToggle themeSwitch;
themeSwitch.setOffLabel("Light");  // left segment
themeSwitch.setOnLabel("Dark");    // right segment
themeSwitch.setPosition({200.f, 100.f});

themeSwitch.onToggled([](bool on) {
    applyTheme(on);
});

addComponent(themeSwitch);
SegmentToggle — full apply pattern cpp
struct MySegmentStyle : public ml::SegmentSettings,
                        public ml::SegmentTheme
{
    MySegmentStyle() {
        // SegmentSettings fields
        width       = 180.f;
        height      = 34.f;
        cornerRadius = 8.f;
        // SegmentTheme fields
        // (colors come from theme defaults)
    }
};

themeSwitch.applyStyle(MySegmentStyle{});

// Or apply layers separately:
themeSwitch.applySettings(MySegmentStyle{});  // geometry only
themeSwitch.applyTheme(MySegmentStyle{});     // colors only

Like PillToggle, the active theme only touches the SegmentTheme layer automatically. Call applySettings() explicitly whenever you need to update geometry.