raui_app/app/
immediate.rs1use 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}