wa/
lib.rs

1// Copyright (c) 2023-present, Raphael Amorim.
2//
3// This source code is licensed under the MIT license found in the
4// LICENSE file in the root directory of this source tree.
5//
6// Originally retired from https://github.com/not-fl3/macroquad licensed under MIT
7// https://github.com/not-fl3/macroquad/blob/master/LICENSE-MIT
8// The code has suffered several changes like support to multiple windows, extension of windows
9// properties, menu support and etc.
10
11#![cfg(target_os = "macos")]
12
13pub mod app;
14pub mod conf;
15mod event;
16pub mod event_loop;
17pub mod native;
18mod resources;
19pub mod sync;
20pub use event::*;
21
22use once_cell::sync::OnceCell;
23use sync::FairMutex;
24
25macro_rules! unwrap_or_return {
26    ( $e:expr ) => {
27        match $e {
28            Some(x) => x,
29            None => return,
30        }
31    };
32}
33
34static NATIVE_DISPLAY: OnceCell<FairMutex<native::Handler>> = OnceCell::new();
35
36fn set_handler() {
37    let _ = NATIVE_DISPLAY.set(FairMutex::new(native::Handler::new()));
38}
39
40fn get_handler() -> &'static FairMutex<native::Handler> {
41    NATIVE_DISPLAY
42        .get()
43        .expect("Backend has not initialized NATIVE_DISPLAY yet.") //|| Mutex::new(Default::default()))
44}
45
46fn set_display(id: u16, display: native::NativeDisplayData) {
47    let handler: &FairMutex<native::Handler> = get_handler();
48    handler.lock().insert(id, display);
49}
50
51pub mod window {
52    use super::*;
53    pub fn order_quit(id: u16) {
54        let mut d = get_handler().lock();
55        if let Some(d) = d.get_mut(id) {
56            d.quit_ordered = true;
57        }
58    }
59    pub fn quit(id: u16) {
60        order_quit(id)
61    }
62    pub fn request_quit() {
63        App::confirm_quit()
64    }
65    pub fn cancel_quit(id: u16) {
66        let mut d = get_handler().lock();
67        if let Some(d) = d.get_mut(id) {
68            d.quit_requested = false;
69        }
70    }
71    pub fn set_cursor_grab(id: u16, grab: bool) {
72        let d = get_handler().lock();
73        if let Some(display) = d.get(id) {
74            let view = display.view;
75            unsafe {
76                if let Some(display) = native::macos::get_display_payload(&*view) {
77                    display.set_cursor_grab(grab);
78                }
79            }
80        }
81    }
82    /// Show or hide the mouse cursor
83    pub fn show_mouse(id: u16, shown: bool) {
84        let d = get_handler().lock();
85        let view = unwrap_or_return!(d.get(id)).view;
86        // drop view as soon we have it, if let Some() keeps locked until block drop
87        drop(d);
88
89        unsafe {
90            if let Some(display) = native::macos::get_display_payload(&*view) {
91                display.show_mouse(shown);
92            }
93        }
94    }
95
96    /// Show or hide the mouse cursor
97    pub fn set_window_title(id: u16, title: String, subtitle: String) {
98        let d = get_handler().lock();
99        let view = unwrap_or_return!(d.get(id)).view;
100        drop(d);
101        // drop view as soon we have it, if let Some() keeps locked until block drop
102
103        unsafe {
104            if let Some(display) = native::macos::get_display_payload(&*view) {
105                display.set_title(&title);
106                display.set_subtitle(&subtitle);
107            }
108        }
109    }
110
111    pub fn get_appearance() -> Appearance {
112        App::appearance()
113    }
114
115    /// Set the mouse cursor icon.
116    pub fn set_mouse_cursor(id: u16, cursor_icon: CursorIcon) {
117        let d = get_handler().lock();
118        let view = unwrap_or_return!(d.get(id)).view;
119        drop(d);
120        // drop view as soon we have it, if let Some() keeps locked until block drop
121
122        unsafe {
123            if let Some(display) = native::macos::get_display_payload(&*view) {
124                display.set_mouse_cursor(cursor_icon);
125            }
126        }
127    }
128
129    /// Set the application's window size.
130    pub fn set_window_size(id: u16, new_width: u32, new_height: u32) {
131        let d = get_handler().lock();
132        if let Some(display) = d.get(id) {
133            let view = display.view;
134            unsafe {
135                if let Some(display) = native::macos::get_display_payload(&*view) {
136                    display.set_window_size(new_width, new_height);
137                }
138            }
139        }
140    }
141
142    pub fn set_fullscreen(id: u16, fullscreen: bool) {
143        let d = get_handler().lock();
144        if let Some(display) = d.get(id) {
145            let view = display.view;
146            unsafe {
147                if let Some(display) = native::macos::get_display_payload(&*view) {
148                    display.set_fullscreen(fullscreen);
149                }
150            }
151        }
152    }
153    /// Get current OS clipboard value
154    pub fn clipboard_get(_id: u16) -> Option<String> {
155        // let mut d = get_handler().lock();
156        // if let Some(d) = d.get_mut(id) {
157        //     d.clipboard.get()
158        // } else {
159        Some(String::from(""))
160        // }
161    }
162    /// Save value to OS clipboard
163    pub fn clipboard_set(_id: u16, _data: &str) {
164        // let mut d = get_handler().lock();
165        // if let Some(d) = d.get_mut(id) {
166        //     d.clipboard.set(data)
167        // }
168    }
169}
170
171#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq)]
172pub enum CursorIcon {
173    Default,
174    Help,
175    Pointer,
176    Wait,
177    Crosshair,
178    Text,
179    Move,
180    NotAllowed,
181    EWResize,
182    NSResize,
183    NESWResize,
184    NWSEResize,
185}
186
187#[derive(Copy, Clone, PartialEq)]
188pub enum Target {
189    Game,
190    Application,
191}
192
193#[cfg(target_os = "macos")]
194pub type App = native::macos::App;
195#[cfg(target_os = "macos")]
196pub type Window = native::macos::Window;
197#[cfg(target_os = "macos")]
198pub type MenuItem = native::apple::menu::MenuItem;