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

Text Components

ml::Text for display labels, TextInput for single-line editable fields, and TextArea for multi-line editing — all built on the RichTextBuffer engine with selection, scrolling, and theme integration.

interactive preview — click the fields to type
ml::Text
Hello, Malena!
A longer string with word-wrap enabled at 220 px — automatic line breaking at word boundaries.
TextInput — single-line
TextArea — multi-line
Introduction

Text Component Hierarchy

ClassPurposeKey feature
ml::TextDisplay label — non-editableWord wrap, full framework trait set (click, hover, drag, flags)
ml::TextInputSingle-line rich text inputHorizontal scrolling, selection, placeholder, readonly/error states
ml::TextAreaMulti-line rich text inputVertical scrolling via embedded ScrollPane, Enter = newline, Ctrl+Enter = submit

TextInput and TextArea both follow the Settings/Theme/Themeable pattern. ml::Text is a Graphic<sf::Text> — it extends the SFML text API directly.


1Graphics/Text

ml::Text

ml::Text wraps sf::Text inside Graphic<>, giving it click, hover, update subscriptions, flags, draggability, and setPosition()/getGlobalBounds(). It adds two layout helpers on top of the SFML API: setWordWrap() and setMaxWidth().

ml::Text — basic label cpp
ml::Text label;
label.setString("Hello, Malena!");
label.setCharacterSize(24);
label.setFillColor(sf::Color::White);
label.setPosition({50.f, 100.f});
addComponent(label);
ml::Text — word wrap cpp
ml::Text paragraph;
paragraph.setMaxWidth(300.f);   // break lines at 300 px
paragraph.setWordWrap(true);    // enable — call setString AFTER
paragraph.setString("A longer string that will wrap at 300 pixels "
                    "according to word boundaries.");
paragraph.setPosition({50.f, 150.f});
addComponent(paragraph);

The word-wrap layout is recomputed each time setString() is called while wordWrap is true. Call setMaxWidth() before enabling word wrap so the layout uses the correct width from the first setString() call.

TextWidth<M> is the manifest-attached variant (note the name — it is expected to be renamed to TextWith<M> in a future release):

ml::Text — with manifest cpp
class StatusLabel : public ml::TextWidth<UIManifest> {
public:
    void setError(bool err) {
        enableFlag(UIManifest::Flag::Error);
        setFillColor(err ? sf::Color(220, 60, 60) : sf::Color::White);
    }
};

2Graphics/Text

TextInput

A single-line editable field built on RichTextBuffer and RichTextRenderer. Content that overflows the visible width scrolls horizontally. Supports text selection (click-drag, double-click to select word, Ctrl+A), placeholder text, read-only mode, and an error visual state. Inherits TextInputSettings and TextInputTheme with automatic theme application via Themeable.

TextInput — basic usage cpp
ml::TextInput nameField;
nameField.setSize({300.f, 36.f});
nameField.setPosition({100.f, 150.f});
nameField.setPlaceholder("Enter your name...");

nameField.onChange([](const std::string& value) {
    validateName(value);
});

nameField.onSubmit([](const std::string& value) {
    submitForm(value);
});

addComponent(nameField);
TextInput — value and state API cpp
nameField.setValue("Alice");
std::string v = nameField.getValue();
nameField.clear();

nameField.setEnabled(false);   // no keyboard or click events
nameField.setReadOnly(true);   // text visible but not editable
nameField.setError(true);      // applies error visual state

bool dis = nameField.isEnabled();
bool ro  = nameField.isReadOnly();
bool err = nameField.hasError();
TextInput — selection API cpp
nameField.selectAll();
nameField.setSelection(0, 5);         // select characters 0–4
std::string sel = nameField.getSelectedText();

// Style the selected run
nameField.setSelectionColor(sf::Color(100, 120, 200));
nameField.setSelectionBold(true);
TextInput — font and size cpp
nameField.setFont(myFont);         // lvalue only — rvalue overload deleted
nameField.setCharacterSize(16);
unsigned sz = nameField.getCharacterSize();
sf::Vector2f size = nameField.getSize();
FlagStateMeaning
Flag::DISABLEDState::DISABLEDNo events, visually dimmed
Flag::READONLYVisible but not editable
State::FOCUSEDHas keyboard focus
State::ERRORValidation error highlighted
State::IDLEDefault

3Graphics/Text

TextArea

Extends TextInput with multi-line support. The canvas grows to fit the full content height and a ScrollPane is embedded internally to clip and scroll it. Enter inserts a newline. Ctrl+Enter fires the onSubmit callback. Mouse wheel and up/down arrow keys scroll the content. The scroll bar appearance is controlled through TextAreaTheme fields.

TextArea — basic usage cpp
ml::TextArea editor;
editor.setSize({600.f, 400.f});
editor.setPosition({40.f, 60.f});
editor.setPlaceholder("Start typing...");

editor.onChange([](const std::string& text) {
    markUnsaved();
});

editor.onSubmit([](const std::string& text) {
    sendMessage(text);
});

addComponent(editor);
TextArea — scroll bar styling cpp
editor.setScrollBarColor(sf::Color(100, 100, 160, 220));
editor.setScrollBarTrackColor(sf::Color(30, 30, 50, 180));
editor.setScrollBarWidth(8.f);

All TextInput methods apply to TextArea as well — setValue(), getValue(), clear(), setEnabled(), setReadOnly(), setError(), onChange(), onSubmit(), setFont(), and setCharacterSize().

TextArea — apply a style cpp
// applyStyle() requires a type that derives from both
// TextInputSettings and TextAreaTheme
struct EditorStyle : public ml::TextInputSettings,
                     public ml::TextAreaTheme
{
    EditorStyle() {
        // TextInputSettings fields
        // TextAreaTheme fields
        scrollBarWidth = 10.f;
    }
};

editor.applyStyle(EditorStyle{});

TextAreaWith<M> adds manifest flags and states on top of TextArea:

TextArea — manifest variant cpp
class LogView : public ml::TextAreaWith<AppManifest>
{
public:
    void appendLine(const std::string& line) {
        setValue(getValue() + line + "\n");
    }
};