ori_core/views/
text.rs

1use glam::Vec2;
2use ori_graphics::{Rect, TextSection};
3use ori_macro::Build;
4
5use crate::{BoxConstraints, Context, DrawContext, LayoutContext, Style, View};
6
7#[derive(Clone, Debug, Build)]
8pub struct Text {
9    #[prop]
10    text: String,
11}
12
13impl Default for Text {
14    fn default() -> Self {
15        Self {
16            text: String::new(),
17        }
18    }
19}
20
21impl Text {
22    pub fn new(text: impl Into<String>) -> Self {
23        Self { text: text.into() }
24    }
25
26    /// Set the text to display.
27    pub fn text(mut self, text: impl Into<String>) -> Self {
28        self.text = text.into();
29        self
30    }
31}
32
33impl View for Text {
34    type State = f32;
35
36    fn build(&self) -> Self::State {
37        0.0
38    }
39
40    fn style(&self) -> Style {
41        Style::new("text")
42    }
43
44    fn layout(&self, state: &mut Self::State, cx: &mut LayoutContext, bc: BoxConstraints) -> Vec2 {
45        let font_size = cx.style_range("font-size", 0.0..bc.max.y);
46        *state = font_size;
47
48        let bc = cx.style_constraints(bc);
49
50        let section = TextSection {
51            rect: Rect::min_size(Vec2::ZERO, bc.max),
52            scale: font_size,
53            h_align: cx.style("text-align"),
54            v_align: cx.style("text-valign"),
55            wrap: cx.style("text-wrap"),
56            text: self.text.clone(),
57            font: cx.style("font"),
58            color: cx.style("color"),
59        };
60
61        let bounds = cx.messure_text(&section).unwrap_or_default();
62        bc.constrain(bounds.size())
63    }
64
65    fn draw(&self, state: &mut Self::State, cx: &mut DrawContext) {
66        let section = TextSection {
67            rect: cx.rect().ceil(),
68            scale: *state,
69            h_align: cx.style("text-align"),
70            v_align: cx.style("text-valign"),
71            wrap: cx.style("text-wrap"),
72            text: self.text.clone(),
73            font: cx.style("font"),
74            color: cx.style("color"),
75        };
76
77        cx.draw(section);
78    }
79}