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

Selection Controls

Checkboxes, radio buttons, and dropdown selects — all with automatic layout helpers, group management, per-item enable/disable, and theme integration.

interactive preview
Checkbox / CheckboxGroup
Auto-save
Show grid
Enable tooltips
Disabled option
RadioButton / RadioGroup
Low
Medium
High
Select
1920 × 1080
1920 × 1080
2560 × 1440
3840 × 2160
Introduction

Selection Control Types

Malena provides five selection-related classes:

ClassPurposeVariant template
ml::CheckboxSingle toggleable checkbox with a square indicator and text labelCheckboxWith<M>
ml::CheckboxGroupSelf-contained group of checkboxes with automatic vertical layoutCheckboxGroupWith<M>
ml::RadioButtonSingle radio option with a circular indicator and text labelRadioButtonWith<M>
ml::RadioGroupSelf-contained group that enforces single-selection among its buttonsRadioGroupWith<M>
ml::SelectDropdown with rich per-item content — icons, descriptions, sub-stylesSelectWith<M>

All five follow the same Settings/Theme/Themeable layering. Pass applySettings(), applyTheme(), or applyStyle() a struct that derives from the appropriate base types.


1Controls

Checkbox

A toggleable square indicator with a text label. Inherits CheckboxSettings (box size, gap, label padding) and CheckboxTheme (colors, font). The active app theme is applied automatically. An optional font passed to the constructor overrides the themed font.

Checkbox — basic usage cpp
ml::Checkbox cb("Enable notifications");
cb.setPosition({100.f, 150.f});

cb.onClick([&cb] {
    bool checked = cb.isChecked();
    updateSetting("notifications", checked);
});

addComponent(cb);
Checkbox — state API cpp
cb.check();              // force checked
cb.uncheck();            // force unchecked
cb.toggle();             // flip current state
bool on = cb.isChecked();

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

cb.setLabel("Show FPS"); // change label text
FlagStateMeaning
Flag::CHECKEDState::CHECKEDCheckbox is checked
Flag::DISABLEDState::DISABLEDInteractions suppressed
State::IDLEDefault
State::HOVEREDMouse is over the checkbox

2Controls

CheckboxGroup

Manages a list of checkboxes with automatic vertical layout. Adding options via addOption() creates and owns a Checkbox internally — style changes propagate to all owned items automatically. You can also register external checkboxes via add().

CheckboxGroup — adding options cpp
ml::CheckboxGroup prefs;
prefs.addOption("Auto-save",       true);  // pre-checked
prefs.addOption("Show grid",       false);
prefs.addOption("Enable tooltips", true);
prefs.setPosition({100.f, 100.f});

prefs.onSelectionChanged([](const std::vector<std::string>& checked) {
    for (const auto& label : checked)
        std::cout << label << " is checked\n";
});

addComponent(prefs);
CheckboxGroup — query and control cpp
prefs.check(0);    // check item at index 0
prefs.uncheck(1);  // uncheck item at index 1
prefs.checkAll();
prefs.uncheckAll();

bool firstOn = prefs.isChecked(0);
auto labels  = prefs.getCheckedLabels();   // vector<string>
auto indices = prefs.getCheckedIndices();  // vector<size_t>

prefs.setOptionEnabled(2, false); // disable "Enable tooltips"

3Controls

RadioButton & RadioGroup

RadioButton is a standalone circular indicator. Use it when you need direct control. RadioGroup owns a set of buttons, enforces that only one can be selected at a time, and fires a single callback on change.

RadioButton — standalone cpp
ml::RadioButton opt("Option A");
opt.setPosition({100.f, 150.f});
opt.select();                  // force selected
bool sel = opt.isSelected();
opt.deselect();

opt.setEnabled(false);
opt.setLabel("Option A (locked)");
RadioGroup — typical usage cpp
ml::RadioGroup quality;
quality.addOption("Low");
quality.addOption("Medium");
quality.addOption("High");
quality.selectFirst(); // select "Low" by default
quality.setPosition({100.f, 100.f});

quality.onSelectionChanged([](const std::string& label, std::size_t index) {
    setGraphicsQuality(index);
});

addComponent(quality);
RadioGroup — query API cpp
quality.select(2);   // force "High" programmatically

std::string label = quality.getSelectedLabel();  // "High"
std::size_t idx   = quality.getSelectedIndex();  // 2
ml::RadioButton* btn = quality.getSelected();    // pointer (or nullptr)

quality.setOptionEnabled(0, false); // disable "Low"

4Controls

Select

A dropdown control with a trigger button and a floating panel. Each option has a label, a value, and an optional SelectOptionStyle that overrides colors, font, size, bold/italic, icon, and a secondary description line. Custom ml::Core components can also be used as option rows.

Select — basic options cpp
ml::Select resolution;
resolution.setPlaceholder("Choose resolution...");
resolution.setPosition({100.f, 100.f});

resolution.addOption("1920 × 1080", "1080p");
resolution.addOption("2560 × 1440", "1440p");
resolution.addOption("3840 × 2160", "4K");

resolution.onSelectionChanged([](const std::string& value, std::size_t index) {
    applyResolution(value);
});

addComponent(resolution);
Select — per-option styles and icons cpp
ml::SelectOptionStyle warnStyle;
warnStyle.color       = sf::Color(220, 80, 80);
warnStyle.description = "May reduce performance";

resolution.addOption("7680 × 4320", "8K", warnStyle);
Select — selection API cpp
resolution.selectIndex(1);           // select "1440p" by index
resolution.selectValue("4K");        // select by value string
resolution.clearSelection();         // deselect all

int   idx   = resolution.getSelectedIndex(); // -1 if none
std::string lbl = resolution.getSelectedLabel();
std::string val = resolution.getSelectedValue();

resolution.setOptionEnabled(2, false); // disable "4K"
resolution.setEnabled(false);          // disable the whole control

// Open / close the panel programmatically
resolution.open();
resolution.close();
bool open = resolution.isOpen();