spitfire_gui/
context.rs

1use crate::{interactions::GuiInteractionsEngine, prelude::GuiRenderer};
2#[cfg(target_arch = "wasm32")]
3use instant::Instant;
4use raui_core::{
5    application::Application,
6    layout::{CoordsMapping, CoordsMappingScaling, default_layout_engine::DefaultLayoutEngine},
7    make_widget,
8    widget::{
9        component::containers::content_box::content_box,
10        utils::{Color, Rect},
11    },
12};
13use raui_immediate::*;
14use spitfire_draw::prelude::*;
15use spitfire_fontdue::*;
16use spitfire_glow::prelude::*;
17#[cfg(not(target_arch = "wasm32"))]
18use std::time::Instant;
19
20pub struct GuiContext {
21    pub coords_map_scaling: CoordsMappingScaling,
22    pub texture_filtering: GlowTextureFiltering,
23    pub interactions: GuiInteractionsEngine,
24    application: Application,
25    text_renderer: TextRenderer<Color>,
26    immediate: ImmediateContext,
27    timer: Instant,
28    glyphs_texture: Option<Texture>,
29}
30
31impl Default for GuiContext {
32    fn default() -> Self {
33        Self {
34            coords_map_scaling: Default::default(),
35            texture_filtering: Default::default(),
36            interactions: Default::default(),
37            application: Default::default(),
38            text_renderer: Default::default(),
39            immediate: Default::default(),
40            timer: Instant::now(),
41            glyphs_texture: None,
42        }
43    }
44}
45
46impl GuiContext {
47    pub fn mark_dirty(&mut self) {
48        self.application.mark_dirty();
49    }
50
51    pub fn begin_frame(&self) {
52        ImmediateContext::activate(&self.immediate);
53        begin();
54    }
55
56    pub fn end_frame(
57        &mut self,
58        draw: &mut DrawContext,
59        graphics: &mut Graphics<Vertex>,
60        colored_shader: &ShaderRef,
61        textured_shader: &ShaderRef,
62        text_shader: &ShaderRef,
63    ) {
64        let widgets = end();
65        ImmediateContext::deactivate();
66        self.application
67            .apply(make_widget!(content_box).key("root").listed_slots(widgets));
68        let elapsed = std::mem::replace(&mut self.timer, Instant::now())
69            .elapsed()
70            .as_secs_f32();
71        self.timer = Instant::now();
72        self.application.animations_delta_time = elapsed;
73        let coords_mapping = CoordsMapping::new_scaling(
74            Rect {
75                left: 0.0,
76                right: graphics.main_camera.screen_size.x,
77                top: 0.0,
78                bottom: graphics.main_camera.screen_size.y,
79            },
80            self.coords_map_scaling,
81        );
82        if self.application.process() {
83            let mut layout_engine = DefaultLayoutEngine::<()>::default();
84            let _ = self.application.layout(&coords_mapping, &mut layout_engine);
85        }
86        self.interactions.maintain(&coords_mapping);
87        let _ = self.application.interact(&mut self.interactions);
88        self.application.consume_signals();
89        let mut renderer = GuiRenderer {
90            texture_filtering: self.texture_filtering,
91            draw,
92            graphics,
93            colored_shader,
94            textured_shader,
95            text_shader,
96        };
97        let _ = self.application.render(&coords_mapping, &mut renderer);
98        let [w, h, d] = self.text_renderer.atlas_size();
99        if let Some(texture) = self.glyphs_texture.as_mut() {
100            texture.upload(
101                w as _,
102                h as _,
103                d as _,
104                GlowTextureFormat::Monochromatic,
105                Some(self.text_renderer.image()),
106            );
107        } else {
108            self.glyphs_texture = graphics
109                .texture(
110                    w as _,
111                    h as _,
112                    d as _,
113                    GlowTextureFormat::Monochromatic,
114                    Some(self.text_renderer.image()),
115                )
116                .ok();
117        }
118    }
119}