Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Rikitav/Terminality/llms.txt

Use this file to discover all available pages before exploring further.

Interactive controls are focusable ControlBase subclasses that accept keyboard input and emit typed events. Terminality’s focus manager handles Tab-like navigation automatically when controls are placed inside layout containers. You do not wire up navigation manually — you configure the control’s behaviour through its properties and subscribe to its events.

Button

Button renders a labelled, clickable widget. It responds to Enter and Space when focused, visually toggles its pressed state, and fires the Clicked event on key-up. You can also trigger a click programmatically with Click().

Properties

Text
std::wstring
default:"L\"\""
The label rendered inside the button. Changing Text invalidates the measure pass, so the button resizes to fit its new content automatically.
PressedForegroundColor
Color
default:"Color::BLACK"
Foreground (text) color applied while the button is held down.
PressedBackgroundColor
Color
default:"Color::CYAN"
Background color applied while the button is held down.

Events

Clicked
Event<>
Fired when the user releases Enter or Space while the button is focused, or when Click() is called programmatically. Subscribe with +=.
button->Clicked += []() { /* handle click */ };

Methods

Click()
method
Programmatically activate the button: sets the pressed visual state, fires Clicked, and then clears the pressed state on the next OnKeyUp. Use this to trigger button behaviour from hotkeys or external logic.

Keyboard activation

The button intercepts InputKey::RETURN and InputKey::SPACE on OnKeyDown/OnKeyUp. It does not consume any other keys, so focus navigation through arrow keys works normally.

Example — status bar button with click handler

auto statusButton = init<Button>([](Button* btn)
{
    btn->Text                 = L"ESC - exit | /help | Chat: Tamerlan";
    btn->HorizontalAlignment  = HorizontalAlign::Stretch;
    btn->VerticalAlignment    = VerticalAlign::Top;

    btn->Clicked += []()
    {
        MessageBox::Show(L"Help", L"Help screen", MessageBoxButton::YesNoCancel);
    };
});
Give buttons a HorizontalAlignment of HorizontalAlign::Stretch inside a Star-sized column to fill available width. This makes keyboard-only interfaces feel more like traditional TUI forms.

TextBox

TextBox is a single- or multi-line text input. It manages an internal cursor position, handles character insertion and deletion, and fires TextChanged after every edit. It is the primary control for accepting free-form text from the user.

Properties

Text
std::wstring
default:"L\"\""
The current contents of the text box. You can read and write this property at any time. Writing to it moves the cursor to the end of the new string.
TextWrapping
TextWrap
default:"TextWrap::NoWrap"
How text that overflows the width is handled. Set to TextWrap::Wrap or TextWrap::WrapWholeWords to enable multi-line editing.
TextAlignment
TextAlign
default:"TextAlign::Left"
Horizontal alignment of the text within the control’s width.
AcceptsReturn
bool
default:"false"
When true, the Enter key inserts a newline character instead of being passed to the parent. Set to false for single-line inputs where Enter should trigger submission logic via OnHotkey.

Events

TextChanged
Event<>
Fired after every keystroke that modifies Text. Use this to implement live validation or character counters.

Example — chat input with Enter-to-send

This pattern is taken from MessangerTest in the test app. AcceptsReturn is false so Enter does not insert a newline, and OnHotkey intercepts InputKey::RETURN to submit the message.
inputGrid->AddChild(0, 2, init<TextBox>([&](TextBox* inputBox)
{
    inputBox->Text                = L"";
    inputBox->MaxSize             = Size(-1, 1);   // clamp to one row
    inputBox->HorizontalAlignment = HorizontalAlign::Stretch;
    inputBox->AcceptsReturn       = false;

    inputBox->OnHotkey(InputModifier::None, InputKey::RETURN, [&](ControlBase* self)
    {
        auto* tb = static_cast<TextBox*>(self);
        chatHistory_.push_back(MessageModel{ true, L"[now]", tb->Text });
        tb->Text = L"";   // clear after sending
    });
}));
OnHotkey is defined on ControlBase and is available on every control. It registers a key binding scoped to the control — the lambda receives a ControlBase* pointer to self, which you cast to the concrete type when needed.

CheckBox

CheckBox is a three-state toggle: unchecked (false), checked (true), and indeterminate (std::nullopt). It renders a label alongside a state indicator and fires distinct events for each state transition.

Properties

Text
std::wstring
default:"L\"\""
The label text displayed next to the checkbox indicator.
PressedForegroundColor
Color
default:"Color::BLACK"
Foreground color while the control is held down (key-press visual feedback).
PressedBackgroundColor
Color
default:"Color::CYAN"
Background color while the control is held down.

Events

Toggled
Event<std::optional<bool>>
Fired on every state change. The argument is the new value: true, false, or std::nullopt (indeterminate). This is the most general event — subscribe here if you need to handle all three states.
cb->Toggled += [](std::optional<bool> state)
{
    if (!state.has_value())
        // indeterminate
    else if (*state)
        // checked
    else
        // unchecked
};
Checked
Event<>
Fired when the state transitions specifically to true. Convenience event if you only care about the checked state.
Unchecked
Event<>
Fired when the state transitions specifically to false.

Methods

Toggle(std::optional<bool> value)
method
Programmatically set the checkbox state. Pass true, false, or std::nullopt for indeterminate. Fires the appropriate events just as a keyboard activation would.

Keyboard activation

CheckBox intercepts Enter and Space (InputKey::RETURN / InputKey::SPACE) on OnKeyDown/OnKeyUp, cycling through its states the same way a mouse click would.

Example

auto acceptBox = init<CheckBox>([](CheckBox* cb)
{
    cb->Text = L"Accept terms and conditions";

    cb->Checked += []()
    {
        // enable a submit button, etc.
    };

    cb->Unchecked += []()
    {
        // disable submit button
    };
});

// Force indeterminate state from parent logic
acceptBox->Toggle(std::nullopt);

ControlFocusKey bindingsPrimary eventState
ButtonYesEnter, SpaceClickedStateless
TextBoxYesAll printable keys, Backspace, arrowsTextChangedText wstring
CheckBoxYesEnter, SpaceToggled, Checked, Uncheckedoptional<bool>
All three controls inherit OnHotkey from ControlBase. This lets you attach key bindings that are only active when a specific control is focused, without polluting global hotkey handlers.
// Submit on Enter even though AcceptsReturn is false
textBox->OnHotkey(InputModifier::None, InputKey::RETURN, [](ControlBase* self)
{
    auto* tb = static_cast<TextBox*>(self);
    // process tb->Text
    tb->Text = L"";
});

// Ctrl+D to open a context menu on any focusable control
bubble->OnHotkey(InputModifier::None, InputKey::D, [](ControlBase* self)
{
    self->OpenContextMenu();
});

Build docs developers (and LLMs) love