laid/elements/
text.rs

1use std::cell::RefCell;
2use std::rc::Rc;
3use crate::state::{StateValue, StateValueState};
4
5pub struct Text {
6    render_builder: Rc<RefCell<TextRenderBuilder>>,
7}
8
9impl Text {
10    pub fn new(value: Rc<RefCell<StateValue<String>>>) -> Self {
11        Self {
12            render_builder: Rc::new(RefCell::new(TextRenderBuilder::new(value))),
13        }
14    }
15}
16
17use miniquad::graphics as mg;
18use miniquad_text_rusttype as quad_text;
19struct TextRenderBuilder {
20    text_value: Rc<RefCell<StateValue<String>>>,
21    render: Option<TextRender>,
22}
23
24impl TextRenderBuilder {
25    pub fn new(text_value: Rc<RefCell<StateValue<String>>>) -> Self {
26        Self {
27            text_value,
28            render: None,
29        }
30    }
31
32    // pub fn update(&mut self, text_value: String) {
33    //     match self.render.as_mut() {
34    //         Some(render) => {
35    //             render.update(text_value);
36    //         }
37    //         None => {}
38    //     };
39    // }
40}
41
42impl crate::RawRender for TextRenderBuilder {
43    fn draw(&mut self, ctx: &mut mg::Context) {
44        if self.render.is_none() {
45            let system = quad_text::TextSystem::new(ctx);
46            let font = quad_text::FontTexture::new(
47                ctx,
48                &include_bytes!("../../assets/font.ttf")[..],
49                70,
50                quad_text::FontAtlas::ascii_character_list(),
51            )
52            .unwrap();
53            let text =
54                quad_text::TextDisplay::new(ctx, &system, Rc::new(font), &self.text_value.borrow().value);
55
56            self.render = Some(TextRender::new(system, text, self.text_value.clone()));
57        }
58
59        self.render.as_mut().unwrap().draw(ctx);
60    }
61}
62
63struct TextRender {
64    system: quad_text::TextSystem,
65    text: quad_text::TextDisplay<Rc<quad_text::FontTexture>>,
66    text_value: Rc<RefCell<StateValue<String>>>,
67}
68
69impl TextRender {
70    pub fn new(
71        system: quad_text::TextSystem,
72        text: quad_text::TextDisplay<Rc<quad_text::FontTexture>>,
73        text_value: Rc<RefCell<StateValue<String>>>,
74    ) -> Self {
75        Self {
76            system,
77            text,
78            text_value,
79        }
80    }
81
82    // pub fn update(&mut self, value: String) {
83    //     self.text_state = Some(value);
84    // }
85}
86
87impl crate::RawRender for TextRender {
88    fn draw(&mut self, ctx: &mut mg::Context) {
89        let text_value = self.text_value.borrow();
90        if text_value.state == StateValueState::New {
91            dbg!("updating text");
92            self.text.set_text(ctx, &text_value.value);
93        }
94
95        let (w, h) = ctx.screen_size();
96
97        let text_width = self.text.get_width();
98        #[rustfmt::skip]
99        let matrix:[[f32; 4]; 4] = glam::Mat4::from_cols_array(&[
100            2.0 / text_width, 0.0, 0.0, 0.0,
101            0.0, 2.0 * (w as f32) / (h as f32) / text_width, 0.0, 0.0,
102            0.0, 0.0, 1.0, 0.0,
103            -1.0, -1.0, 0.0, 1.0f32,
104        ]).to_cols_array_2d();
105        quad_text::draw(ctx, &self.text, &self.system, matrix, (1.0, 1.0, 0.0, 1.0));
106    }
107}
108
109impl crate::Element for Text {
110    fn render(&self) -> crate::Renderable {
111        crate::Renderable::RawRender(self.render_builder.clone())
112    }
113}