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.

Visual controls render content but do not accept keyboard focus or fire interaction events. Use them to display information, decorate sections of your layout, and provide feedback on ongoing operations. Each control described here is a direct subclass of ControlBase and participates fully in the layout system — you can set Margin, HorizontalAlignment, VerticalAlignment, and MaxSize on any of them.

Label

Label renders a std::wstring inside its arranged rectangle. It supports three text-wrapping modes and three alignment modes, making it suitable for everything from a single-line prompt prefix to a multi-line message body.

Constructors

Label();                        // empty text, default alignment
Label(std::wstring& text);      // initialize with an existing string

Properties

Text
std::wstring
default:"L\"\""
The string to render. Assigning a new value invalidates the measure pass so the control resizes automatically.
TextWrapping
TextWrap
default:"TextWrap::NoWrap"
Controls how text that is wider than the available width is handled.
ValueBehaviour
TextWrap::NoWrapText is clipped at the right edge. No line breaks are inserted.
TextWrap::WrapLine breaks are inserted at any character boundary when the line would overflow.
TextWrap::WrapWholeWordsLine breaks are inserted only at word boundaries, preserving whole words.
TextAlignment
TextAlign
default:"TextAlign::Left"
Horizontal alignment of each line of text within the label’s width.
ValueBehaviour
TextAlign::LeftText starts at the left edge (default).
TextAlign::CenterEach line is centred.
TextAlign::RightEach line is right-aligned.
TextAlign::JustifySpaces between words are stretched to fill the full width.

Events

TextChanged
Event<>
Fired by OnPropertyChanged whenever the Text property is assigned a new value. Subscribe with +=.

Example

// Simple prompt prefix
auto label = init<Label>([](Label* l)
{
    l->Text            = L"Rikitav@Tamerlan> ";
    l->HorizontalAlignment = HorizontalAlign::Left;
});

// Multi-line status area
auto status = init<Label>([](Label* l)
{
    l->Text         = L"Press ESC to exit. Use arrow keys to navigate.";
    l->TextWrapping = TextWrap::WrapWholeWords;
    l->TextAlignment = TextAlign::Center;
});

// React to text changes
label->TextChanged += []() { /* refresh dependent state */ };

Border

Border wraps exactly one child control in a box drawn with box-drawing characters. It supports an optional header caption rendered inside the top edge of the box, making it easy to create labelled panels.

Constructors

Border();                                       // no child
Border(std::unique_ptr<ControlBase> content);   // with initial child

Properties

Content
unique_ptr<ControlBase>
default:"nullptr"
The single child displayed inside the border. The border reserves one cell of padding on each side so the child has a clean inner area.
HeaderText
std::wstring
default:"L\"\""
Text drawn into the top edge of the border box. When non-empty it appears inset into the top horizontal line of the rectangle.
BorderColor
Color
default:"Color::DARK_GRAY"
Color of the border lines when the control does not have focus.
FocusedBorderColor
Color
default:"Color::CYAN"
Color of the border lines when the control or one of its descendants has focus.
BorderThickness
Thickness
default:"Thickness::Single"
Inset applied to the content area. The default Thickness::Single reserves one cell on every side for the border lines.
Style
BorderStyle (function pointer)
default:"nullptr"
Optional custom glyph function. The signature is wchar_t (*)(RectanglePos). When nullptr, the default box-drawing style is used. Use RectanglePos values (LeftTopCorner, RightBottomCorner, TopHorizontalLine, etc.) to return different glyphs per position.

Example — labelled chat panel

This is drawn directly from the MessangerTest in the test app:
AddChild(0, 0, init<Border>([&](Border* chatBorder)
{
    chatBorder->Margin     = Thickness(0, 1, 0, 0);
    chatBorder->HeaderText = L"Chat: Tamerlan";

    chatBorder->Content = init<ItemsControl<MessageModel>>([&](auto* list)
    {
        list->SetItemsSource(&chatHistory_);
        list->Scrollable     = true;
        list->AutoScrollToEnd = true;
        list->SetItemTemplate([](const MessageModel& item) -> std::unique_ptr<ControlBase>
        {
            return init<Label>([&](Label* l)
            {
                l->Text = item.Timestamp + L" " + item.Text;
            });
        });
    });
}));
Border forwards focus to its Content child. The FocusedBorderColor activates as soon as any descendant receives focus, giving the user a clear visual indicator of the active panel.

ProgressBar

ProgressBar renders a horizontal bar that fills proportionally based on Value relative to [Minimum, Maximum]. It is stateless with respect to animation — you drive the value from a DispatchTimer tick or any other source.

Properties

Value
float
default:"0.0f"
The current progress value. Must be between Minimum and Maximum. Assigning a value outside this range clamps the visual fill but does not throw.
Minimum
float
default:"0.0f"
The value that corresponds to an empty bar.
Maximum
float
default:"100.0f"
The value that corresponds to a completely full bar.
BarColor
Color
default:"Color::GREEN"
Color of the filled portion of the bar.
TrackColor
Color
default:"Color::DARK_GRAY"
Color of the unfilled background portion of the bar.

Example — animated progress from a dispatch timer

This pattern is taken from the MessangerTest test app:
auto progress = init<ProgressBar>([](ProgressBar* bar)
{
    bar->Margin               = Thickness(1, 0, 1, 0);
    bar->HorizontalAlignment  = HorizontalAlign::Stretch;
    bar->VerticalAlignment    = VerticalAlign::Top;

    // Advance at 10 units per second, wrapping back to Minimum at the top
    DispatchTimer::Current().TickEvent += [bar](float dt)
    {
        float current = bar->Value.Get();
        current += dt * 10.0f;

        if (current > bar->Maximum.Get())
            current = bar->Minimum.Get();

        bar->Value = current;
    };
});
DispatchTimer::Current().TickEvent delivers a float dt (delta-time in seconds) on every UI tick. Multiply by a rate constant to produce smooth, frame-rate-independent animation.

Spinner

Spinner is a single-cell animated indicator that cycles through a sequence of frames driven by the DispatchTimer. It is self-animating — you do not need to write any update code. Drop it anywhere you want to signal that a background operation is in progress.

Properties

Frames
std::vector<std::wstring>
default:"{ L\"-\", L\"\\\\\", L\"|\", L\"/\" }"
The sequence of strings cycled through during animation. Each element is rendered in turn. Replace this vector to use custom glyphs, Unicode spinners, or multi-character frames.

Example

// Default spinner — renders the classic ASCII rotation
auto spinner = init<Spinner>([](Spinner* s)
{
    s->Margin = Thickness(1, 0, 1, 0);
});

// Unicode braille spinner
auto brailleSpinner = init<Spinner>([](Spinner* s)
{
    s->Frames = { L"⠋", L"⠙", L"⠹", L"⠸", L"⠼", L"⠴", L"⠦", L"⠧", L"⠇", L"⠏" };
});
Spinner connects to DispatchTimer in its constructor and disconnects when destroyed. You do not need to start or stop it manually — the animation runs for as long as the control exists in the visual tree.
ControlFocusableAnimatedChild content
LabelNoNoText string
BorderVia childNoOne ControlBase
ProgressBarNoNo (value-driven)None
SpinnerNoYes (self-driven)None

Build docs developers (and LLMs) love