appy/components/
text.rs

1use crate::hooks::use_context;
2use crate::types::*;
3use appy::{derive_component, function_component, ComponentBuilder, SnakeFactory};
4use std::rc::Rc;
5
6/// Render text.
7///
8/// Renders text in the current [Blk](crate::components::Blk).
9///
10/// The alignment inside the `blk` can be speficied with the align and valign
11/// props.
12///
13/// In order to use custom fonts, first get a reference to the font using
14/// [`use_font_data`](crate::hooks::use_font_data).
15///
16/// Example:
17/// ```
18/// use appy::{*, hooks::*, components::*, types::*};
19///
20/// #[main_window]
21/// fn main()->Elements {
22///	    let font=use_font_data(||include_bytes!("../core/Roboto-Regular.ttf"));
23///
24///	    apx!{
25///		    <Text text="Hello World" font=font size=100/>
26///	    }
27/// }
28/// ```
29#[derive_component(ComponentBuilder, SnakeFactory)]
30pub struct Text {
31    color: u32,
32    text: String,
33    align: Align,
34    valign: VAlign,
35    font: Option<Rc<Font>>,
36    size: Dim,
37}
38
39impl Default for Text {
40    fn default() -> Self {
41        Self {
42            color: 0xffffff,
43            text: "<text>".to_string(),
44            align: Align::Center,
45            valign: VAlign::Middle,
46            children: vec![],
47            key: None,
48            font: Option::<Rc<Font>>::None,
49            size: Dim::Absolute(20.0),
50        }
51    }
52}
53
54#[function_component]
55fn _text(props: Text) -> Elements {
56    let app_context = use_context::<AppContext>();
57    let r = &app_context.rect;
58
59    let font = props.font.unwrap_or(app_context.default_font.clone());
60    let size = props.size.to_abs(app_context.rect.h);
61    let w = font.get_str_width(&props.text, size);
62
63    let x = match props.align {
64        Align::Left => r.x,
65        Align::Center => r.x + (r.w - w) / 2.0,
66        Align::Right => r.x + r.w - w,
67    };
68
69    let y = match props.valign {
70        VAlign::Top => r.y,
71        VAlign::Middle => r.y + (r.h - size) / 2.0,
72        VAlign::Bottom => r.y + r.h - size,
73    };
74
75    let mut tr = app_context.text_renderer.borrow_mut();
76    tr.draw(
77        &props.text,
78        x,
79        y,
80        &font,
81        size,
82        props.color,
83        app_context.pixel_ratio,
84    );
85
86    props.children
87}