test.rs

  1use super::CursorStyle;
  2use crate::{AnyAction, ClipboardItem};
  3use parking_lot::Mutex;
  4use pathfinder_geometry::vector::Vector2F;
  5use std::{
  6    any::Any,
  7    cell::RefCell,
  8    path::{Path, PathBuf},
  9    rc::Rc,
 10    sync::Arc,
 11};
 12
 13pub struct Platform {
 14    dispatcher: Arc<dyn super::Dispatcher>,
 15    fonts: Arc<dyn super::FontSystem>,
 16    current_clipboard_item: Mutex<Option<ClipboardItem>>,
 17    cursor: Mutex<CursorStyle>,
 18}
 19
 20#[derive(Default)]
 21pub struct ForegroundPlatform {
 22    last_prompt_for_new_path_args: RefCell<Option<(PathBuf, Box<dyn FnOnce(Option<PathBuf>)>)>>,
 23}
 24
 25struct Dispatcher;
 26
 27pub struct Window {
 28    size: Vector2F,
 29    scale_factor: f32,
 30    current_scene: Option<crate::Scene>,
 31    event_handlers: Vec<Box<dyn FnMut(super::Event)>>,
 32    resize_handlers: Vec<Box<dyn FnMut(&mut dyn super::WindowContext)>>,
 33    close_handlers: Vec<Box<dyn FnOnce()>>,
 34    pub(crate) last_prompt: RefCell<Option<Box<dyn FnOnce(usize)>>>,
 35}
 36
 37impl ForegroundPlatform {
 38    pub(crate) fn simulate_new_path_selection(
 39        &self,
 40        result: impl FnOnce(PathBuf) -> Option<PathBuf>,
 41    ) {
 42        let (dir_path, callback) = self
 43            .last_prompt_for_new_path_args
 44            .take()
 45            .expect("prompt_for_new_path was not called");
 46        callback(result(dir_path));
 47    }
 48
 49    pub(crate) fn did_prompt_for_new_path(&self) -> bool {
 50        self.last_prompt_for_new_path_args.borrow().is_some()
 51    }
 52}
 53
 54impl super::ForegroundPlatform for ForegroundPlatform {
 55    fn on_become_active(&self, _: Box<dyn FnMut()>) {}
 56
 57    fn on_resign_active(&self, _: Box<dyn FnMut()>) {}
 58
 59    fn on_event(&self, _: Box<dyn FnMut(crate::Event) -> bool>) {}
 60
 61    fn on_open_files(&self, _: Box<dyn FnMut(Vec<std::path::PathBuf>)>) {}
 62
 63    fn run(&self, _on_finish_launching: Box<dyn FnOnce() -> ()>) {
 64        unimplemented!()
 65    }
 66
 67    fn on_menu_command(&self, _: Box<dyn FnMut(&dyn AnyAction)>) {}
 68
 69    fn set_menus(&self, _: Vec<crate::Menu>) {}
 70
 71    fn prompt_for_paths(
 72        &self,
 73        _: super::PathPromptOptions,
 74        _: Box<dyn FnOnce(Option<Vec<std::path::PathBuf>>)>,
 75    ) {
 76    }
 77
 78    fn prompt_for_new_path(&self, path: &Path, f: Box<dyn FnOnce(Option<std::path::PathBuf>)>) {
 79        *self.last_prompt_for_new_path_args.borrow_mut() = Some((path.to_path_buf(), f));
 80    }
 81}
 82
 83impl Platform {
 84    fn new() -> Self {
 85        Self {
 86            dispatcher: Arc::new(Dispatcher),
 87            fonts: Arc::new(super::current::FontSystem::new()),
 88            current_clipboard_item: Default::default(),
 89            cursor: Mutex::new(CursorStyle::Arrow),
 90        }
 91    }
 92}
 93
 94impl super::Platform for Platform {
 95    fn dispatcher(&self) -> Arc<dyn super::Dispatcher> {
 96        self.dispatcher.clone()
 97    }
 98
 99    fn fonts(&self) -> std::sync::Arc<dyn super::FontSystem> {
100        self.fonts.clone()
101    }
102
103    fn activate(&self, _ignoring_other_apps: bool) {}
104
105    fn open_window(
106        &self,
107        _: usize,
108        options: super::WindowOptions,
109        _executor: Rc<super::executor::Foreground>,
110    ) -> Box<dyn super::Window> {
111        Box::new(Window::new(options.bounds.size()))
112    }
113
114    fn key_window_id(&self) -> Option<usize> {
115        None
116    }
117
118    fn quit(&self) {}
119
120    fn write_to_clipboard(&self, item: ClipboardItem) {
121        *self.current_clipboard_item.lock() = Some(item);
122    }
123
124    fn read_from_clipboard(&self) -> Option<ClipboardItem> {
125        self.current_clipboard_item.lock().clone()
126    }
127
128    fn open_url(&self, _: &str) {}
129
130    fn write_credentials(&self, _: &str, _: &str, _: &[u8]) {}
131
132    fn read_credentials(&self, _: &str) -> Option<(String, Vec<u8>)> {
133        None
134    }
135
136    fn set_cursor_style(&self, style: CursorStyle) {
137        *self.cursor.lock() = style;
138    }
139}
140
141impl Window {
142    fn new(size: Vector2F) -> Self {
143        Self {
144            size,
145            event_handlers: Vec::new(),
146            resize_handlers: Vec::new(),
147            close_handlers: Vec::new(),
148            scale_factor: 1.0,
149            current_scene: None,
150            last_prompt: RefCell::new(None),
151        }
152    }
153}
154
155impl super::Dispatcher for Dispatcher {
156    fn is_main_thread(&self) -> bool {
157        true
158    }
159
160    fn run_on_main_thread(&self, task: async_task::Runnable) {
161        task.run();
162    }
163}
164
165impl super::WindowContext for Window {
166    fn size(&self) -> Vector2F {
167        self.size
168    }
169
170    fn scale_factor(&self) -> f32 {
171        self.scale_factor
172    }
173
174    fn titlebar_height(&self) -> f32 {
175        24.
176    }
177
178    fn present_scene(&mut self, scene: crate::Scene) {
179        self.current_scene = Some(scene);
180    }
181}
182
183impl super::Window for Window {
184    fn as_any_mut(&mut self) -> &mut dyn Any {
185        self
186    }
187
188    fn on_event(&mut self, callback: Box<dyn FnMut(crate::Event)>) {
189        self.event_handlers.push(callback);
190    }
191
192    fn on_resize(&mut self, callback: Box<dyn FnMut(&mut dyn super::WindowContext)>) {
193        self.resize_handlers.push(callback);
194    }
195
196    fn on_close(&mut self, callback: Box<dyn FnOnce()>) {
197        self.close_handlers.push(callback);
198    }
199
200    fn prompt(&self, _: crate::PromptLevel, _: &str, _: &[&str], f: Box<dyn FnOnce(usize)>) {
201        self.last_prompt.replace(Some(f));
202    }
203}
204
205pub fn platform() -> Platform {
206    Platform::new()
207}
208
209pub fn foreground_platform() -> ForegroundPlatform {
210    ForegroundPlatform::default()
211}