telar_ui_core/
rich_text.rs1use std::rc::Rc;
2use std::sync::Arc;
3
4use geometry_core::Rect;
5use layout_core::{LayoutError, LayoutStyle};
6use platform_core::Event;
7use renderer_core::{TextRun, TextStyle};
8use ui_tree::{Component, EventResult, RenderNode};
9
10use crate::impl_leaf_widget;
11use crate::layout_leaf::LayoutLeaf;
12
13pub struct RichText {
18 runs: Rc<dyn Fn() -> Vec<TextRun>>,
19 base: Rc<dyn Fn() -> TextStyle>,
20 leaf: LayoutLeaf,
21}
22
23impl RichText {
24 pub fn auto(
27 runs_fn: impl Fn() -> Vec<TextRun> + 'static,
28 layout_style: LayoutStyle,
29 base_fn: impl Fn() -> TextStyle + 'static,
30 ) -> Result<Self, LayoutError> {
31 let runs: Rc<dyn Fn() -> Vec<TextRun>> = Rc::new(runs_fn);
32 let base: Rc<dyn Fn() -> TextStyle> = Rc::new(base_fn);
33
34 let measure_runs = Rc::clone(&runs);
35 let measure_base = Rc::clone(&base);
36 let measure = Box::new(move |max_width: f32| {
37 renderer_text::measure_rich_text(&(measure_runs)(), max_width, &(measure_base)())
38 });
39
40 let (node, rect) =
41 crate::context::new_measured_leaf(layout_style.align_self_stretch(), measure)?;
42 Ok(Self {
43 runs,
44 base,
45 leaf: LayoutLeaf { node, rect },
46 })
47 }
48}
49
50impl Component for RichText {
51 fn view(&self) -> RenderNode {
52 let r = self.leaf.rect.get();
53 let runs: Arc<[TextRun]> = Arc::from((self.runs)());
54 let base = (self.base)();
55 self.leaf.at_layout_position(RenderNode::rich_text(
56 runs,
57 Rect {
58 x: 0.0,
59 y: 0.0,
60 width: r.width,
61 height: r.height,
62 },
63 base,
64 ))
65 }
66
67 fn on_event(&mut self, _event: &Event) -> EventResult {
68 EventResult::Ignored
69 }
70
71 fn debug_name(&self) -> &'static str {
72 "RichText"
73 }
74}
75
76impl_leaf_widget!(RichText);