Skip to the content.

Core Concepts

App

The App class is the entry point of your application. It initializes the terminal, handles input events, and manages the main event loop.

#include "cpptui.hpp"
using namespace cpptui;

int main() {
    App app;
    auto root = std::make_shared<Vertical>();
    // ... add widgets to root ...
    app.run(root);
    return 0;
}

Threading

Background threads can update the UI without polling. Use post() to schedule widget modifications on the main thread:

App app;
auto label = std::make_shared<Label>("Waiting...");

std::thread worker([&]() {
    // Do work...
    app.post([&]() {
        label->set_text("Done!");  // Runs safely on the UI thread
    });
});
worker.detach();

app.run(root);

For advanced use where you manage your own synchronization, update() provides a lighter alternative:

label->set_text("Updated");  // Caller is responsible for thread safety
app.update();                 // Immediately wakes the event loop to redraw

Widget

Every visual element in cpp-tui inherits from the Widget class. Widgets have:

Layouts & Sizing Flow

Widgets in cpp-tui participate in a two-phase layout negotiation:

  1. Responsive and Size Constraint Resolution (update_responsive()):
    • Containers and widgets compute their size requests before layout.
    • If a container has auto_shrink = true, it recursively calculates its fixed size (fixed_width/fixed_height) based on the sum or maximum of its children’s fixed sizes plus container padding.
    • During auto-shrink size calculation, constraints are propagated: the computed size is clamped using the container’s own min_width/min_height and max_width/max_height.
    • If auto_shrink = false (the default), the container behaves flexibly and expands to fill the available space allocated by its parent.
  2. Actual Placement (layout()):
    • The parent container allocates actual positions (x, y) and dimensions (width, height) to its children.
    • Flexible Space Distribution (Multi-Pass Clamping): In layouts like Vertical, Horizontal, ScrollableVertical, and ScrollableHorizontal, remaining available space is dynamically distributed among flexible children. This is calculated using a multi-pass algorithm: space is initially split evenly, then children that violate their min_* or max_* constraints are clamped and settled, and the remaining space is redistributed among the remaining unsettled flex children.
    • Precedence (Min Wins): In case of conflicting constraints (e.g. min_width > max_width), the min constraint overrides the max constraint (matching standard CSS behavior).
    • Explicit Size Preservation: Containers respect child constraints; a child inside a container with an explicit fixed size will not be stretched to fill the container’s entire area. Additionally, a child’s cross-axis size is always clamped using its min and max constraints.

Theme

The Theme class manages the color palette of the application.

Events

Events are handled by the App and propagated to widgets.

Clipboard & History

Global default keybindings are available for text editing widgets (Input, TextArea, and selectable Label).