1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use crate::{app::SharedApp, Vertex};
use glutin::{event::Event, window::Window};
use raui_core::{
    application::{Application, ChangeNotifier},
    interactive::default_interactions_engine::DefaultInteractionsEngine,
    widget::utils::Color,
};
use raui_retained::{View, ViewState};
use spitfire_fontdue::TextRenderer;
use spitfire_glow::{
    app::{App, AppConfig, AppState},
    graphics::Graphics,
};

pub struct RetainedApp<T: ViewState> {
    shared: SharedApp,
    root: Option<View<T>>,
}

impl<T: ViewState> Default for RetainedApp<T> {
    fn default() -> Self {
        Self {
            shared: Default::default(),
            root: None,
        }
    }
}

impl<T: ViewState> RetainedApp<T> {
    pub fn simple(title: impl ToString, producer: impl FnMut(ChangeNotifier) -> View<T>) {
        App::<Vertex>::new(AppConfig::default().title(title)).run(Self::default().tree(producer));
    }

    pub fn simple_fullscreen(
        title: impl ToString,
        producer: impl FnMut(ChangeNotifier) -> View<T>,
    ) {
        App::<Vertex>::new(AppConfig::default().title(title).fullscreen(true))
            .run(Self::default().tree(producer));
    }

    pub fn redraw(
        mut self,
        f: impl FnMut(f32, &mut Graphics<Vertex>, &mut TextRenderer<Color>) + 'static,
    ) -> Self {
        self.shared.on_redraw = Some(Box::new(f));
        self
    }

    pub fn event(
        mut self,
        f: impl FnMut(&mut Application, Event<()>, &mut Window, &mut DefaultInteractionsEngine) -> bool
            + 'static,
    ) -> Self {
        self.shared.on_event = Some(Box::new(f));
        self
    }

    pub fn setup(mut self, mut f: impl FnMut(&mut Application)) -> Self {
        f(&mut self.shared.application);
        self
    }

    pub fn tree(mut self, mut producer: impl FnMut(ChangeNotifier) -> View<T>) -> Self {
        let root = producer(self.shared.application.notifier());
        self.shared.application.apply(root.component().key("root"));
        self.root = Some(root);
        self
    }
}

impl<T: ViewState> AppState<Vertex> for RetainedApp<T> {
    fn on_init(&mut self, graphics: &mut Graphics<Vertex>) {
        self.shared.init(graphics);
    }

    fn on_redraw(&mut self, graphics: &mut Graphics<Vertex>) {
        self.shared.redraw(graphics);
    }

    fn on_event(&mut self, event: Event<()>, window: &mut Window) -> bool {
        self.shared.event(event, window)
    }
}