raui_app/app/
immediate.rs

1use crate::{Vertex, app::SharedApp, interactions::AppInteractionsEngine};
2use glutin::{event::Event, window::Window};
3use raui_core::{
4    application::Application,
5    interactive::default_interactions_engine::DefaultInteractionsEngine,
6    layout::CoordsMappingScaling,
7    make_widget,
8    tester::{AppCycleFrameRunner, AppCycleTester},
9    widget::{component::containers::content_box::content_box, utils::Color},
10};
11use raui_immediate::{ImmediateContext, make_widgets};
12use spitfire_fontdue::TextRenderer;
13use spitfire_glow::{
14    app::{App, AppConfig, AppControl, AppState},
15    graphics::Graphics,
16};
17
18#[derive(Default)]
19pub struct ImmediateApp {
20    shared: SharedApp,
21}
22
23impl ImmediateApp {
24    pub fn simple(title: impl ToString, callback: impl FnMut(&mut AppControl) + 'static) {
25        App::<Vertex>::new(AppConfig::default().title(title)).run(Self::default().update(callback));
26    }
27
28    pub fn simple_scaled(
29        title: impl ToString,
30        scaling: CoordsMappingScaling,
31        callback: impl FnMut(&mut AppControl) + 'static,
32    ) {
33        App::<Vertex>::new(AppConfig::default().title(title)).run(
34            Self::default()
35                .coords_mapping_scaling(scaling)
36                .update(callback),
37        );
38    }
39
40    pub fn simple_fullscreen(
41        title: impl ToString,
42        callback: impl FnMut(&mut AppControl) + 'static,
43    ) {
44        App::<Vertex>::new(AppConfig::default().title(title).fullscreen(true))
45            .run(Self::default().update(callback));
46    }
47
48    pub fn simple_fullscreen_scaled(
49        title: impl ToString,
50        scaling: CoordsMappingScaling,
51        callback: impl FnMut(&mut AppControl) + 'static,
52    ) {
53        App::<Vertex>::new(AppConfig::default().title(title).fullscreen(true)).run(
54            Self::default()
55                .coords_mapping_scaling(scaling)
56                .update(callback),
57        );
58    }
59
60    pub fn test_frame<F: FnMut()>(f: F) -> ImmediateAppCycleFrameRunner<F> {
61        ImmediateAppCycleFrameRunner(f)
62    }
63
64    pub fn update(mut self, callback: impl FnMut(&mut AppControl) + 'static) -> Self {
65        let mut callback = Box::new(callback);
66        let context = ImmediateContext::default();
67        self.shared.on_update = Some(Box::new(move |application, control| {
68            raui_immediate::reset();
69            let widgets = make_widgets(&context, || {
70                callback(control);
71            });
72            application.apply(make_widget!(content_box).listed_slots(widgets));
73        }));
74        self
75    }
76
77    pub fn redraw(
78        mut self,
79        f: impl FnMut(f32, &mut Graphics<Vertex>, &mut TextRenderer<Color>, &mut AppControl) + 'static,
80    ) -> Self {
81        self.shared.on_redraw = Some(Box::new(f));
82        self
83    }
84
85    pub fn event(
86        mut self,
87        f: impl FnMut(&mut Application, Event<()>, &mut Window, &mut DefaultInteractionsEngine) -> bool
88        + 'static,
89    ) -> Self {
90        self.shared.on_event = Some(Box::new(f));
91        self
92    }
93
94    pub fn setup(mut self, mut f: impl FnMut(&mut Application)) -> Self {
95        f(&mut self.shared.application);
96        self
97    }
98
99    pub fn setup_interactions(mut self, mut f: impl FnMut(&mut AppInteractionsEngine)) -> Self {
100        f(&mut self.shared.interactions);
101        self
102    }
103
104    pub fn coords_mapping_scaling(mut self, value: CoordsMappingScaling) -> Self {
105        self.shared.coords_mapping_scaling = value;
106        self
107    }
108}
109
110impl AppState<Vertex> for ImmediateApp {
111    fn on_init(&mut self, graphics: &mut Graphics<Vertex>, _: &mut AppControl) {
112        self.shared.init(graphics);
113    }
114
115    fn on_redraw(&mut self, graphics: &mut Graphics<Vertex>, control: &mut AppControl) {
116        self.shared.redraw(graphics, control);
117    }
118
119    fn on_event(&mut self, event: Event<()>, window: &mut Window) -> bool {
120        self.shared.event(event, window)
121    }
122}
123
124pub struct ImmediateAppCycleFrameRunner<F: FnMut()>(F);
125
126impl<F: FnMut()> AppCycleFrameRunner<ImmediateContext> for ImmediateAppCycleFrameRunner<F> {
127    fn run_frame(mut self, tester: &mut AppCycleTester<ImmediateContext>) {
128        raui_immediate::reset();
129        let widgets = make_widgets(&tester.user_data, || {
130            (self.0)();
131        });
132        tester
133            .application
134            .apply(make_widget!(content_box).listed_slots(widgets));
135    }
136}