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 }
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 }
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}