blitz_traits/
shell.rs

1//! Abstraction over windowing / operating system ("shell") functionality
2
3use cursor_icon::CursorIcon;
4
5/// Type representing an error performing a clipboard operation
6// TODO: fill out with meaningful errors
7pub struct ClipboardError;
8
9/// Abstraction over windowing / operating system ("shell") functionality that allows a Blitz document
10/// to access that functionality without depending on a specific shell environment.
11pub trait ShellProvider {
12    fn request_redraw(&self) {}
13    fn set_cursor(&self, icon: CursorIcon) {
14        let _ = icon;
15    }
16    fn set_window_title(&self, title: String) {
17        let _ = title;
18    }
19    fn get_clipboard_text(&self) -> Result<String, ClipboardError> {
20        Err(ClipboardError)
21    }
22    fn set_clipboard_text(&self, text: String) -> Result<(), ClipboardError> {
23        let _ = text;
24        Err(ClipboardError)
25    }
26    fn open_file_dialog(
27        &self,
28        multiple: bool,
29        filter: Option<FileDialogFilter>,
30    ) -> Vec<std::path::PathBuf> {
31        let _ = multiple;
32        let _ = filter;
33        vec![]
34    }
35}
36
37pub struct DummyShellProvider;
38impl ShellProvider for DummyShellProvider {}
39
40/// The system color scheme (light and dark mode)
41#[derive(Default, Debug, Clone, Copy)]
42pub enum ColorScheme {
43    #[default]
44    Light,
45    Dark,
46}
47
48#[derive(Debug, Clone)]
49pub struct Viewport {
50    pub color_scheme: ColorScheme,
51    pub window_size: (u32, u32),
52    pub hidpi_scale: f32,
53    pub zoom: f32,
54}
55
56impl Default for Viewport {
57    fn default() -> Self {
58        Self {
59            window_size: (0, 0),
60            hidpi_scale: 1.0,
61            zoom: 1.0,
62            color_scheme: ColorScheme::Light,
63        }
64    }
65}
66
67impl Viewport {
68    pub fn new(
69        physical_width: u32,
70        physical_height: u32,
71        scale_factor: f32,
72        color_scheme: ColorScheme,
73    ) -> Self {
74        Self {
75            window_size: (physical_width, physical_height),
76            hidpi_scale: scale_factor,
77            zoom: 1.0,
78            color_scheme,
79        }
80    }
81
82    /// Total scaling, computed as `hidpi_scale_factor * zoom`
83    pub fn scale(&self) -> f32 {
84        self.hidpi_scale * self.zoom
85    }
86    /// Same as [`scale`](Self::scale) but `f64` instead of `f32`
87    pub fn scale_f64(&self) -> f64 {
88        self.scale() as f64
89    }
90
91    /// Set hidpi scale factor
92    pub fn set_hidpi_scale(&mut self, scale: f32) {
93        self.hidpi_scale = scale;
94    }
95
96    /// Get document zoom level
97    pub fn zoom(&self) -> f32 {
98        self.zoom
99    }
100
101    /// Set document zoom level (`1.0` is unzoomed)
102    pub fn set_zoom(&mut self, zoom: f32) {
103        self.zoom = zoom;
104    }
105
106    pub fn zoom_by(&mut self, zoom: f32) {
107        self.zoom += zoom;
108    }
109
110    pub fn zoom_mut(&mut self) -> &mut f32 {
111        &mut self.zoom
112    }
113}
114
115/// Filter provided by the dom for an file picker
116pub struct FileDialogFilter {
117    pub name: String,
118    pub extensions: Vec<String>,
119}