notan_app/
backend.rs

1use crate::config::WindowConfig;
2use crate::{App, EventIterator};
3use downcast_rs::{impl_downcast, Downcast};
4use futures::prelude::*;
5use futures::Future;
6use notan_graphics::DeviceBackend;
7
8#[cfg(feature = "audio")]
9use notan_audio::AudioBackend;
10
11#[cfg(feature = "audio")]
12use std::cell::RefCell;
13
14#[cfg(feature = "audio")]
15use std::rc::Rc;
16
17/// Closure returned from the backend's initialize method
18pub type InitializeFn<S, R> = dyn FnOnce(App, S, R) -> Result<(), String>;
19
20/// Closure used to load files
21pub type LoadFileFn = Box<dyn Fn(String) -> Box<dyn Future<Output = Result<Vec<u8>, String>>>>;
22
23/// Represents the backend implementation
24pub trait Backend: Downcast {
25    /// Returns the window implementation
26    fn window(&mut self) -> &mut dyn WindowBackend;
27
28    /// Sets text to clipboard if the platform supports it
29    fn set_clipboard_text(&mut self, text: &str);
30
31    /// Returns an iterator that contains the backend events
32    fn events_iter(&mut self) -> EventIterator;
33
34    /// Closes the application
35    fn exit(&mut self);
36
37    /// Return the system timestamp
38    fn system_timestamp(&self) -> u64;
39
40    /// Open a link on a browser if the platform supports it
41    fn open_link(&self, url: &str, new_tab: bool);
42}
43
44impl_downcast!(Backend);
45
46/// Indicate to the backend if the frame was skipped or if it ended
47pub enum FrameState {
48    End,
49    Skip,
50}
51
52/// Backend initialization run
53pub trait BackendSystem: Backend {
54    /// Returns a closure where the backend is initialized and the application loops is managed
55    fn initialize<S, R>(&mut self, window: WindowConfig) -> Result<Box<InitializeFn<S, R>>, String>
56    where
57        Self: Backend,
58        S: 'static,
59        R: FnMut(&mut App, &mut S) -> Result<FrameState, String> + 'static;
60
61    /// Returns a function that load files
62    fn get_file_loader(&self) -> LoadFileFn {
63        Box::new(|path| Box::new(platter2::load_file(path).map_err(|e| e.to_string())))
64    }
65
66    /// Returns the graphics backend implementation
67    fn get_graphics_backend(&self) -> Box<dyn DeviceBackend>;
68
69    #[cfg(feature = "audio")]
70    /// Return the audio backend implementation
71    fn get_audio_backend(&self) -> Rc<RefCell<dyn AudioBackend>>;
72}
73
74/// Represent mouse cursor icon
75/// They are same as egui::CursorIcon because this is mostly to give support to egui
76#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Eq)]
77pub enum CursorIcon {
78    Default,
79    None,
80    ContextMenu,
81    Help,
82    PointingHand,
83    Progress,
84    Wait,
85    Cell,
86    Crosshair,
87    Text,
88    VerticalText,
89    Alias,
90    Copy,
91    Move,
92    NoDrop,
93    NotAllowed,
94    Grab,
95    Grabbing,
96    AllScroll,
97    ResizeHorizontal,
98    ResizeNeSw,
99    ResizeNwSe,
100    ResizeVertical,
101    ZoomIn,
102    ZoomOut,
103    ResizeEast,
104    ResizeSouthEast,
105    ResizeSouth,
106    ResizeSouthWest,
107    ResizeWest,
108    ResizeNorthWest,
109    ResizeNorth,
110    ResizeNorthEast,
111    ResizeColumn,
112    ResizeRow,
113}
114
115/// Represents a window
116pub trait WindowBackend {
117    /// Returns if the mouse is confined in the app
118    fn capture_cursor(&self) -> bool;
119
120    /// Returns the container size. Meaning the screen size on native
121    /// and the canvas's parent element size on `web`
122    fn container_size(&self) -> (i32, i32) {
123        self.screen_size()
124    }
125
126    /// Returns the current cursor icon
127    fn cursor(&self) -> CursorIcon;
128
129    /// Screen's DPI
130    fn dpi(&self) -> f64;
131
132    /// Window's height
133    fn height(&self) -> u32 {
134        self.size().1
135    }
136
137    // Returns the window id
138    fn id(&self) -> u64;
139
140    /// Returns true if window is drawn above others
141    fn is_always_on_top(&self) -> bool;
142
143    /// Returns true if the window is in fullscreen mode
144    fn is_fullscreen(&self) -> bool;
145
146    /// Returns true if the window has focus
147    fn is_focused(&self) -> bool;
148
149    /// Returns true if the lazy mode is enabled
150    fn lazy_loop(&self) -> bool;
151
152    /// Returns whether you can click through the window
153    fn mouse_passthrough(&mut self) -> bool;
154
155    /// Returns the window's position
156    fn position(&self) -> (i32, i32);
157
158    /// Request next frame
159    fn request_frame(&mut self);
160
161    /// Returns the screen's size
162    fn screen_size(&self) -> (i32, i32);
163
164    /// Set window to be drawn above others or not
165    fn set_always_on_top(&mut self, enabled: bool);
166
167    /// Confine the mouse on the app
168    fn set_capture_cursor(&mut self, capture: bool);
169
170    /// Sets the mouse cursor icon
171    fn set_cursor(&mut self, cursor: CursorIcon);
172
173    /// Sets the mouse cursor position
174    fn set_cursor_position(&mut self, x: f32, y: f32);
175
176    /// Enable or disable the fullscreen mode
177    fn set_fullscreen(&mut self, enabled: bool);
178
179    /// Enable or disable the lazy mode for the app's loop
180    fn set_lazy_loop(&mut self, lazy: bool);
181
182    /// Sets whether you can click through the window
183    fn set_mouse_passthrough(&mut self, pass_through: bool);
184
185    /// Sets the window's position
186    fn set_position(&mut self, x: i32, y: i32);
187
188    /// Sets the window's size
189    fn set_size(&mut self, width: u32, height: u32);
190
191    /// Hide or show the window
192    fn set_visible(&mut self, visible: bool);
193
194    /// Set the window's title
195    fn set_title(&mut self, title: &str);
196
197    /// Returns current windows title
198    fn title(&self) -> &str;
199
200    /// Returns the window's size
201    fn size(&self) -> (u32, u32);
202
203    /// Returns if the window is visible
204    fn visible(&self) -> bool;
205
206    /// Window's width
207    fn width(&self) -> u32 {
208        self.size().0
209    }
210
211    /// Use touch event as mouse events
212    fn set_touch_as_mouse(&mut self, enable: bool);
213
214    /// Returns if touch as mouse is enabled
215    fn touch_as_mouse(&self) -> bool;
216}