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