Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-core/src/windowing/mod.rs
1pub mod state;
2 
3mod system;
4 
5use std::rc::Rc;
6 
7use pathfinder_geometry::rect::RectF;
8pub use state::{State, StateEvent, WindowManager};
9pub use system::{CreateWindowingSystemError, System};
10 
11use crate::{
12 actions::StandardAction, platform::WindowContext, AppContext, AppContextRefMut, CursorInfo,
13 Event, Scene,
14};
15 
16/// Result of dispatching an event through the UI framework.
17#[derive(Debug, Clone, Copy, Default)]
18pub struct EventDispatchResult {
19 /// Whether the event was handled by the UI framework.
20 pub handled: bool,
21 /// Whether the soft keyboard should be shown (mobile WASM only).
22 pub soft_keyboard_requested: bool,
23}
24 
25pub(crate) type EventCallback = Box<dyn Fn(Event, &mut AppContext) -> EventDispatchResult>;
26pub(crate) type ResizeCallback = Box<dyn Fn(&dyn WindowContext, &mut AppContext)>;
27pub(crate) type StandardActionCallback = Box<dyn Fn(StandardAction, &mut AppContext)>;
28pub(crate) type ActiveCursorPositionCallback = Box<dyn Fn(&mut AppContext) -> Option<CursorInfo>>;
29pub(crate) type MoveCallback = Box<dyn Fn(RectF, &mut AppContext)>;
30pub(crate) type FrameCallback = Box<dyn Fn(&mut AppContext)>;
31pub(crate) type BuildSceneCallback = Box<dyn Fn(&dyn WindowContext, &mut AppContext) -> Rc<Scene>>;
32 
33/// A collection of callbacks that are used to update UI framework state in
34/// response to platform-level events.
35pub struct WindowCallbacks {
36 /// Dispatches a [`StandardAction`].
37 pub standard_action_callback: StandardActionCallback,
38 /// Dispatches an [`Event`].
39 pub event_callback: EventCallback,
40 /// Notifies the UI framework that the window was resized.
41 pub resize_callback: ResizeCallback,
42 /// Requests that the UI framework construct a scene to render.
43 pub build_scene_callback: BuildSceneCallback,
44 /// Notifies the UI framework that a frame was rendered.
45 pub frame_callback: FrameCallback,
46 /// Notifies the UI framework that a frame failed to draw.
47 pub draw_frame_error_callback: FrameCallback,
48 /// Notifies the UI framework that the window moved.
49 pub move_callback: MoveCallback,
50 /// Returns the current location of the text editing cursor, if an
51 /// editable text field is focused.
52 pub active_cursor_position_callback: ActiveCursorPositionCallback,
53}
54 
55/// A helper structure to simplify and standardize the act of making calls from
56/// platform code into platform-independent UI framework code.
57pub struct WindowCallbackDispatcher<'a> {
58 callbacks: &'a WindowCallbacks,
59 ctx: AppContextRefMut<'a>,
60}
61 
62impl<'a> WindowCallbackDispatcher<'a> {
63 pub(crate) fn new(callbacks: &'a WindowCallbacks, ctx: AppContextRefMut<'a>) -> Self {
64 Self { callbacks, ctx }
65 }
66 
67 pub fn dispatch_event(&mut self, event: Event) -> EventDispatchResult {
68 (self.callbacks.event_callback)(event, &mut self.ctx)
69 }
70 
71 pub fn window_resized(&mut self, window: &dyn WindowContext) {
72 (self.callbacks.resize_callback)(window, &mut self.ctx)
73 }
74 
75 pub fn frame_drawn(&mut self) {
76 (self.callbacks.frame_callback)(&mut self.ctx)
77 }
78 
79 #[cfg_attr(target_os = "macos", allow(dead_code))]
80 pub fn frame_failed_to_draw(&mut self) {
81 (self.callbacks.draw_frame_error_callback)(&mut self.ctx)
82 }
83 
84 pub fn get_active_cursor_position(&mut self) -> Option<CursorInfo> {
85 (self.callbacks.active_cursor_position_callback)(&mut self.ctx)
86 }
87 
88 pub fn window_moved(&mut self, bounds: RectF) {
89 (self.callbacks.move_callback)(bounds, &mut self.ctx)
90 }
91 
92 pub fn build_scene(&mut self, window: &dyn WindowContext) -> Rc<Scene> {
93 (self.callbacks.build_scene_callback)(window, &mut self.ctx)
94 }
95}
96 
97// Functions in WindowCallbackDispatcher that relate to application menus.
98//
99// This is marked as `allow(dead_code)` on Linux and wasm, as they do not
100// support application menus, so these never get called.
101// TODO(CORE-2691): implement native Windows OS app menus
102#[cfg_attr(
103 any(target_os = "linux", target_os = "windows", target_family = "wasm"),
104 allow(dead_code)
105)]
106impl WindowCallbackDispatcher<'_> {
107 pub fn dispatch_standard_action(&mut self, action: StandardAction) {
108 (self.callbacks.standard_action_callback)(action, &mut self.ctx)
109 }
110}
111