zng/
text.rs

1//! Text widget, properties and other types.
2//!
3//! The [`Text!`] widget implements text layout and rendering, it is also the base widget for
4//! [`SelectableText!`], [`TextInput!`] and [`label!`]. Text properties are largely contextual,
5//! you can set `text::font_size` in any widget to affect all text inside that widget.
6//!
7//! The `Text!` widget provides *simple* text rendering, that is all text is of the same style and
8//! different fonts are only used as fallback. You can implement *rich* text by combining multiple
9//! `Text!` and `Wrap!` panels, see the [`wrap`] module docs for an example. Some widgets also parse
10//! text and generate the rich text setup automatically, the [`Markdown!`] and [`AnsiText!`] widgets
11//! are examples of this.
12//!
13//! The example below declares two text widgets, one displays a text that requires multiple fonts to render,
14//! the other displays debug information about the first.
15//!
16//! ```
17//! use zng::prelude::*;
18//! # fn example() {
19//!
20//! let txt = "text ใƒ†ใ‚ญใ‚นใƒˆ ๐Ÿ“‹";
21//! let font_use = var(vec![]);
22//! # let _ =
23//! Stack! {
24//!     text::font_family = ["Segoe UI", "Yu Gothic UI", "Segoe Ui Emoji", "sans-serif"];
25//!     children = ui_vec![
26//!         Text! {
27//!             font_size = 1.5.em();
28//!             txt;
29//!             get_font_use = font_use.clone();
30//!         },
31//!         Text! {
32//!             font_size = 0.9.em();
33//!             txt = font_use.map(|u| {
34//!                 let mut r = Txt::from("");
35//!                 for (font, range) in u {
36//!                     use std::fmt::Write as _;
37//!                     writeln!(&mut r, "{} = {:?}", font.face().family_name(), &txt[range.clone()]).unwrap();
38//!                 }
39//!                 r.end_mut();
40//!                 r
41//!             });
42//!         },
43//!     ];
44//!     direction = StackDirection::top_to_bottom();
45//!     spacing = 15;
46//! }
47//! # ; }
48//! ```
49//!
50//! Note that the [`font_family`](fn@font_family) is set on the parent widget, both texts have the same
51//! font family value because of this, the [`font_size`](fn@font_size) on the other hand is set for
52//! each text widget and only affects that widget.
53//!
54//! # Rich Text
55//!
56//! Rich text is a sequence of `Text!` of different styles and other widgets such as `Image!` inside one or more layout panels,
57//! usually a `Wrap!` panel for paragraphs and a `Stack!` panel for the full text or page, if you only intent to present the text
58//! that is all you need, the inline layout will coordinate the flow of lines across multiple `Text!` widgets.
59//!
60//! To enable selection or editing in rich text you can enable the [`rich_text`] property on the panels. The outer panel will
61//! declare a rich text context that the inner `Text!` widgets will use to coordinate the caret position and selection across texts.
62//!
63//! ```
64//! use zng::prelude::*;
65//! # fn example() {
66//! # let _ =
67//! Wrap! {
68//!     text::rich_text = true;
69//!     text::txt_selectable = true;
70//!     children = ui_vec![
71//!         Text! {
72//!             txt = "red text";
73//!             font_color = colors::RED;
74//!         },
75//!         Text! {
76//!             txt = " green text";
77//!             font_color = colors::GREEN;
78//!         },
79//!         Text! {
80//!             txt = " blue text";
81//!             font_color = colors::BLUE;
82//!         },
83//!     ];
84//! }
85//! # ; }
86//! ```
87//!
88//! The example above declares a rich text with three different *text runs*, by enabling [`rich_text`] the wrap panel becomes
89//! a rich text context that all descendant texts will use to coordinate text operations. In this case the [`txt_selectable`]
90//! property enables text selection (and copy) for all descendants, without `rich_text` the descendant texts would allow
91//! selection only within each text.
92//!
93//! The [`rich_text`] property together with [`txt_editable`] is the base for rich text editor widgets, out of the box the descendant texts
94//! will coordinate the caret position and the focused text is edited by typing. A rich text editor needs to implement many other features,
95//! such as removing empty text widgets, inserting new styled texts, encoding all these texts into an unified representation for saving.
96//!
97//! To suppress the default behavior of component texts you can handle keyboard events in the preview track and stop propagation,
98//! same for mouse/touch events. The full text API crate provides the [`zng_wgt_text::cmd`] module that can be used to programmatically
99//! control the texts. The *active* component text is just the focused widget, that can be controlled using the [`zng::focus`] module.
100//!
101//! [`Text!`]: struct@Text
102//! [`SelectableText!`]: struct@crate::selectable::SelectableText
103//! [`TextInput!`]: struct@crate::text_input::TextInput
104//! [`label!`]: struct@crate::label::Label
105//! [`Markdown!`]: struct@crate::markdown::Markdown
106//! [`AnsiText!`]: struct@crate::ansi_text::AnsiText
107//! [`wrap`]: crate::wrap
108//! [`rich_text`]: fn@rich_text
109//! [`txt_selectable`]: fn@txt_selectable
110//! [`txt_editable`]: fn@txt_editable
111//!
112//! # Full API
113//!
114//! See [`zng_wgt_text`] for the full widget API.
115
116pub use zng_txt::*;
117
118pub use zng_wgt_text::{
119    AutoSelection, CaretShape, CaretStatus, ChangeStopArgs, ChangeStopCause, Em, FONT_COLOR_VAR, InteractiveCaretMode, LangMix,
120    LinesWrapCount, ParagraphMix, SelectionToolbarArgs, Strong, Text, TextOverflow, TxtParseValue, UnderlinePosition, UnderlineSkip,
121    accepts_enter, accepts_tab, auto_selection, caret_color, change_stop_delay, direction, font_aa, font_annotation, font_caps,
122    font_char_variant, font_cn_variant, font_color, font_common_lig, font_contextual_alt, font_discretionary_lig, font_ea_width,
123    font_family, font_features, font_historical_forms, font_historical_lig, font_jp_variant, font_kerning, font_num_fraction,
124    font_num_spacing, font_numeric, font_ornaments, font_palette, font_palette_colors, font_position, font_size, font_stretch, font_style,
125    font_style_set, font_stylistic, font_swash, font_synthesis, font_variations, font_weight, get_caret_index, get_caret_status,
126    get_chars_count, get_lines_len, get_lines_wrap_count, get_overflow, has_selection, hyphen_char, hyphens, ime_underline,
127    interactive_caret, interactive_caret_visual, is_line_overflown, is_overflown, is_parse_pending, justify_mode, lang, letter_spacing,
128    line_break, line_height, line_spacing, max_chars_count,
129    node::{TEXT, set_interactive_caret_spot},
130    obscure_txt, obscuring_char, on_change_stop, overline, overline_color, paragraph_spacing, rich_text, selection_color,
131    selection_toolbar, selection_toolbar_anchor, selection_toolbar_fn, strikethrough, strikethrough_color, tab_length, txt_align,
132    txt_editable, txt_overflow, txt_overflow_align, txt_selectable, txt_selectable_alt_only, underline, underline_color, underline_skip,
133    white_space, word_break, word_spacing,
134};
135
136/// Commands that controls the editable/selectable text.
137///
138/// Most of the normal text editing is controlled by keyboard events, these commands.
139///
140/// # Full API
141///
142/// See [`zng_wgt_text::cmd`] for the full API.
143pub mod cmd {
144    pub use zng_wgt_text::cmd::{EDIT_CMD, PARSE_CMD, SELECT_ALL_CMD, SELECT_CMD, TextEditOp, TextSelectOp};
145}