Text¶
Header: winui/ui/text/Text.hpp. Spec: winui/ui/text/Text.hpp.
A non-interactive run of text, the label of every form.
A plain string draws in the style the theme's type ramp gives its role() (Body by default), in the theme's window text color. set_text_style(), set_color() and set_foreground() override them. The text can wrap (set_wrapping()), trim with an ellipsis (set_trimming()), align and justify (set_text_alignment()), and carry formatted runs and links (set_inlines()). With set_selection_enabled(), the user can select and copy it. Otherwise it takes no input or focus. In a spec tree it is built by ui::Text.
Example:
ui::Property<int> clicks{0};
window.set_content(ui::VerticalStack{
.spacing = 8,
.content = {
ui::Text{.text = "Settings", .role = ui::TextRole::Title},
ui::Text{.text = ui::bind(clicks, [](int n) { return std::format("Clicks: {}", n); }),
.wrapping = ui::TextWrapping::WrapWholeWords},
ui::Button{.text = "Click me", .on_click = [&] { ++clicks; }},
},
});
// Or imperatively, with formatted runs and a link:
auto stack = std::make_unique<ui::StackControl>(ui::Orientation::Vertical);
auto block = std::make_unique<ui::TextControl>();
block->set_inlines({
{.text = "Read the "},
{.text = "release notes", .on_click = [] { /* open them */ }},
ui::line_break(),
{.text = "before updating.", .weight = ui::FontWeight::Bold},
});
block->set_wrapping(ui::TextWrapping::WrapWholeWords);
block->set_selection_enabled(true);
ui::TextControl* observer = stack->add(std::move(block)); // the stack owns it now
ui::Text¶
A run of non-interactive text. Builds a ui::TextControl.
The text is a constant string, or a bind() so the label follows a Property. The font comes from the theme's type ramp through .role, such as TextRole::Caption or TextRole::Subtitle. .text_style sets a style for this label alone.
Example:
ui::Property<int> clicks{0};
ui::Control<ui::Text> status;
window.set_content(ui::VerticalStack{
.spacing = 8,
.content = {
ui::Text{ .text = "Appearance", .role = ui::TextRole::Subtitle },
ui::Text{ .text = ui::bind(clicks, [](int n) { return std::format("Clicks: {}", n); }) },
ui::Text{ .text = "A longer paragraph that wraps at the width the parent offers.",
.wrapping = ui::TextWrapping::Wrap,
.control = status },
},
});
Every field, in the order a designated initializer names them:
ui::Text{
.text, .inlines, .selection_enabled, .role, .text_style, .wrapping, .text_alignment,
.character_spacing, .selection_highlight_color, .foreground, .trimming, .style, .margin,
.width, .height, .min_width, .min_height, .max_width, .max_height, .horizontal_alignment,
.vertical_alignment, .visible, .tool_tip, .enabled, .accessibility,
.on_text_trimmed_changed, .on_pointer_entered, .on_pointer_exited, .on_got_focus,
.on_lost_focus, .on_key_down, .on_wheel, .control
}
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
text |
ui::Binding<std::string> |
The displayed string (UTF-8). Ignored when .inlines is set. |
|
inlines |
ui::Binding<std::vector<ui::Inline>> |
Runs with their own formatting, line breaks and links (ui/text/Inlines.hpp). When set, they are the content and .text is ignored. |
|
selection_enabled |
ui::Binding<bool> |
{false} |
The user can select the text with the pointer or keyboard and copy it. |
role |
ui::Binding<ui::TextRole> |
{ui::TextRole::Body} |
The step of the theme's type ramp the text uses, such as Caption or Subtitle. It follows a theme change. |
text_style |
ui::Binding<std::optional<ui::TextStyle>> |
A style for this label alone. When set, the theme's type ramp no longer applies to this label. | |
wrapping |
ui::Binding<ui::TextWrapping> |
{ui::TextWrapping::NoWrap} |
Whether the text breaks into lines at the width the parent offers. |
text_alignment |
ui::Binding<ui::TextAlignment> |
{ui::TextAlignment::Left} |
How each line sits between the left and right edges. |
character_spacing |
ui::Binding<int> |
{0} |
Extra space between characters, in thousandths of an em. |
selection_highlight_color |
ui::Binding<ui::Paint> |
The color behind selected text: a fixed color or a theme resource, which follows theme switches. Unset is the accent. | |
foreground |
ui::Binding<ui::Paint> |
The text color: a fixed color, or a theme resource re-read on a theme change. Unset uses the theme's text color. | |
trimming |
ui::Binding<ui::TextTrimming> |
{ui::TextTrimming::None} |
What shows when the text does not fit: all of it clipped, or an ellipsis (plain text only). |
on_text_trimmed_changed |
ui::Callback<void(bool)> |
Fires with the new state whenever layout starts or stops cutting the text off. Only with .trimming set. |
|
on_pointer_entered |
ui::Action |
The pointer moved onto the control. | |
on_pointer_exited |
ui::Action |
The pointer left the control. | |
on_got_focus |
ui::Action |
Keyboard focus arrived on the control, or on anything inside it, from outside it. A control with nothing focusable in it never gets focus, and never raises this. | |
on_lost_focus |
ui::Action |
Keyboard focus left the control and everything inside it. | |
on_key_down |
ui::Callback<ui::Handling(const ui::KeyEvent&)> |
A key pressed while focus is on the control or inside it, before the control's own handling; ui::Handled stops it there (Element::on_key_down()). | |
on_wheel |
ui::Callback<ui::Handling(const ui::PointerEvent&)> |
A wheel turn over the control, before the control scrolls; ui::Handled stops it there (Element::on_wheel()). | |
control |
ui::ControlOut<ui::Text> |
Out: the handle that receives the built control. |
Plus the common fields style, margin, width, height, min_width, min_height, max_width, max_height, horizontal_alignment, vertical_alignment, visible, tool_tip, enabled, accessibility every spec carries (conventions).
build¶
Consumes the spec and returns the built ui::TextControl; the caller owns it.
ui::TextControl¶
Derives from ui::Element.
A non-interactive run of text, the label of every form.
A plain string draws in the style the theme's type ramp gives its role() (Body by default), in the theme's window text color. set_text_style(), set_color() and set_foreground() override them. The text can wrap (set_wrapping()), trim with an ellipsis (set_trimming()), align and justify (set_text_alignment()), and carry formatted runs and links (set_inlines()). With set_selection_enabled(), the user can select and copy it. Otherwise it takes no input or focus. In a spec tree it is built by ui::Text.
Example:
ui::Property<int> clicks{0};
window.set_content(ui::VerticalStack{
.spacing = 8,
.content = {
ui::Text{.text = "Settings", .role = ui::TextRole::Title},
ui::Text{.text = ui::bind(clicks, [](int n) { return std::format("Clicks: {}", n); }),
.wrapping = ui::TextWrapping::WrapWholeWords},
ui::Button{.text = "Click me", .on_click = [&] { ++clicks; }},
},
});
// Or imperatively, with formatted runs and a link:
auto stack = std::make_unique<ui::StackControl>(ui::Orientation::Vertical);
auto block = std::make_unique<ui::TextControl>();
block->set_inlines({
{.text = "Read the "},
{.text = "release notes", .on_click = [] { /* open them */ }},
ui::line_break(),
{.text = "before updating.", .weight = ui::FontWeight::Bold},
});
block->set_wrapping(ui::TextWrapping::WrapWholeWords);
block->set_selection_enabled(true);
ui::TextControl* observer = stack->add(std::move(block)); // the stack owns it now
TextControl¶
An empty label.
TextControl¶
A label showing text (UTF-8) as one plain run.
text¶
The content as UTF-8; with inlines, their texts joined (line breaks as \n).
set_text¶
Replaces the content with one plain run, and drops any inlines and the selection.
inlines¶
The formatted runs; empty for plain text (the default, and after set_text()).
set_inlines¶
Replaces the content with formatted runs. text() becomes the runs' text joined. Clears the selection. An inline with on_click or navigate_uri is a link.
text_alignment¶
How each line sits between the left and right edges; Left by default.
set_text_alignment¶
Sets the line alignment.
character_spacing¶
Extra space between characters, in thousandths of an em; 0 by default.
set_character_spacing¶
Sets the extra space between characters, in thousandths of an em (TextStyle::character_spacing).
selection_enabled¶
Whether the user can select and copy the text; false by default. While true the block is focusable.
set_selection_enabled¶
Turns text selection on or off. While on, the user selects by dragging, double-clicking a word or triple-clicking a paragraph. Ctrl+A, Ctrl+C and a context menu with Copy and Select All act on the selection, and a click focuses the block. Turning it off clears the selection.
selection_highlight_color¶
The fixed color behind selected text; nullopt (the default) when unset or a theme resource is set. Unset is the accent.
selection_highlight_resource¶
The color behind selected text as a theme resource, or nullptr.
set_selection_highlight_color¶
Sets the fixed color behind selected text and clears a theme resource; nullopt goes back to the accent.
set_selection_highlight_color¶
Sets the color behind selected text to a theme resource, re-read under every theme, and clears a fixed one.
selection¶
The selection as [start, end) byte offsets into text() (inlines joined); {0, 0} when none.
select¶
Selects the byte range [start, end) of text(). The selection shows only while the block has focus and selection is enabled.
select_all¶
Selects the whole text, as Ctrl+A does.
selected_text¶
The selected part of the laid-out text; empty when nothing is selected or before the first measure.
text_style¶
The explicit style set by set_text_style(). Meaningful only once set_text_style() was called. Until then the theme's type ramp entry for role() is used.
set_text_style¶
Fixes the font, size, weight and alignment. From then on it takes precedence over role() and the theme's type ramp.
role¶
The role this label plays in the theme's type ramp; Body by default. The style is looked up in the current theme, so a plain TextControl follows the theme's own fonts, such as MS Sans Serif under Windows95 or Metro's Light and Semilight weights. set_text_style() always takes precedence.
set_role¶
Sets the type ramp role.
wrapping¶
Whether the text breaks into lines; NoWrap by default.
set_wrapping¶
Sets the wrapping mode. Anything but NoWrap wins over the wrapping of a style from set_text_style(). NoWrap, the default, leaves that style's own wrapping in charge. Text wraps only at a bounded width, and a horizontal StackControl offers an unbounded one.
color¶
The fixed text color, if any. Unset (the default) uses the theme's window text color, so a label without set_color() stays readable under a dark theme.
set_color¶
Fixes the text color and clears any set_foreground() resource. A fixed color does not follow a theme change.
set_foreground¶
Sets the text color to a theme resource, re-read whenever the text is drawn so it follows a theme change. Wins over set_color(); nullptr clears it.
trimming¶
What shows when the text does not fit the arranged box: all of it clipped (None, Clip), or as much as fits followed by an ellipsis, cut between characters or between words. Only the plain-text form trims (not inlines, selectable or justified text).
set_trimming¶
Sets the trimming mode.
is_text_trimmed¶
Whether the last arrange cut the text short.
on_text_trimmed_changed¶
Fires during arrange with the new is_text_trimmed() value whenever it changes. A typical use is a tooltip that shows the full text.
parallel_measure_safe¶
True: measuring reads only the text's own state, the measurer and the theme.
focusable¶
Focusable only while enabled with text selection on.
focused¶
Whether the block has keyboard focus (only ever true while focusable()).
handle_context_menu¶
Offers Copy / Select All while selection is enabled; returns false (no menu) otherwise.
cursor_at¶
A hand over a link, an I-beam over selectable text.
automation_role¶
Always AutomationRole::Text.
automation_name_fallback¶
The text, when no accessibility name is set.
automation_children¶
One node per link inline. Invoking a node follows its link.
measure_override¶
The text's size in DIPs in the resolved style, wrapped to available.width when wrapping.
arrange_override¶
Re-flows laid-out content to the arranged width and applies trimming (which may fire on_text_trimmed_changed()).
render_override¶
The text, or the laid-out runs with the selection highlight (while focused) and link underlines.
pointer_override¶
Selection drags and multi-clicks, and link clicks; ignored while disabled.
enabled_changed¶
is_enabled() flipped, through set_enabled() here or on an ancestor, or a move to another parent. Drop any press or hover state. The element is redrawn either way. No-op by default.
focus_changed¶
Tracks focus. The selection shows only while the block has focus.
key_override¶
Ctrl+A (select all) and Ctrl+C (copy), only while enabled with selection on.
draws_focus_ring¶
None: selectable text shows focus through its selection.
Enumerations¶
TextTrimming¶
What a TextControl shows when its text does not fit the arranged box.
| Value | |
|---|---|
None |
All of the text, clipped at the box (the default). |
CharacterEllipsis |
As much as fits, cut between characters, then an ellipsis. |
WordEllipsis |
As much as fits, cut between words, then an ellipsis. |
Clip |
All of the text, clipped at the box. |
Tests¶
tests/test_stack.cpp