Skip to main content

theframework/
thecontext.rs

1use crate::prelude::*;
2
3/// The cursor icon to display
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum TheCursorIcon {
6    Default,
7    Crosshair,
8    Hand,
9    Arrow,
10    Text,
11    Wait,
12    Help,
13    Progress,
14    NotAllowed,
15    ContextMenu,
16    Cell,
17    VerticalText,
18    Alias,
19    Copy,
20    NoDrop,
21    Grab,
22    Grabbing,
23    AllScroll,
24    ZoomIn,
25    ZoomOut,
26    EResize,
27    NResize,
28    NEResize,
29    NWResize,
30    SResize,
31    SEResize,
32    SWResize,
33    WResize,
34    EWResize,
35    NSResize,
36    NESWResize,
37    NWSEResize,
38    ColResize,
39    RowResize,
40}
41
42pub struct TheContext {
43    pub width: usize,
44    pub height: usize,
45    pub scale_factor: f32,
46
47    pub draw: TheDraw2D,
48    #[cfg(feature = "ui")]
49    pub ui: TheUIContext,
50
51    pub cursor_icon: TheCursorIcon,
52    pub cursor_changed: bool,
53    pub cursor_visible: bool,
54    pub cursor_visible_changed: bool,
55}
56
57impl TheContext {
58    pub fn new(width: usize, height: usize, scale_factor: f32) -> Self {
59        Self {
60            width,
61            height,
62            scale_factor,
63            draw: TheDraw2D::new(),
64            #[cfg(feature = "ui")]
65            ui: TheUIContext::new(),
66            cursor_icon: TheCursorIcon::Default,
67            cursor_changed: false,
68            cursor_visible: true,
69            cursor_visible_changed: false,
70        }
71    }
72
73    /// Set the cursor icon
74    pub fn set_cursor_icon(&mut self, icon: TheCursorIcon) {
75        if self.cursor_icon != icon {
76            self.cursor_icon = icon;
77            self.cursor_changed = true;
78        }
79    }
80
81    /// Get the current cursor icon
82    pub fn cursor_icon(&self) -> TheCursorIcon {
83        self.cursor_icon
84    }
85
86    /// Check if the cursor has changed
87    pub fn cursor_changed(&self) -> bool {
88        self.cursor_changed
89    }
90
91    /// Reset the cursor changed flag
92    pub fn reset_cursor_changed(&mut self) {
93        self.cursor_changed = false;
94    }
95
96    /// Set the cursor visibility
97    pub fn set_cursor_visible(&mut self, visible: bool) {
98        if self.cursor_visible != visible {
99            self.cursor_visible = visible;
100            self.cursor_visible_changed = true;
101        }
102    }
103
104    /// Get the current cursor visibility
105    pub fn cursor_visible(&self) -> bool {
106        self.cursor_visible
107    }
108
109    /// Check if the cursor visibility has changed
110    pub fn cursor_visible_changed(&self) -> bool {
111        self.cursor_visible_changed
112    }
113
114    /// Reset the cursor visibility changed flag
115    pub fn reset_cursor_visible_changed(&mut self) {
116        self.cursor_visible_changed = false;
117    }
118
119    /// Gets the current time in milliseconds.
120    pub fn get_time(&self) -> u128 {
121        let time;
122        #[cfg(not(target_arch = "wasm32"))]
123        {
124            use std::time::{SystemTime, UNIX_EPOCH};
125            let t = SystemTime::now()
126                .duration_since(UNIX_EPOCH)
127                .expect("Time went backwards");
128            time = t.as_millis();
129        }
130        #[cfg(target_arch = "wasm32")]
131        {
132            time = web_sys::window().unwrap().performance().unwrap().now() as u128;
133        }
134        time
135    }
136
137    #[cfg(feature = "i18n")]
138    pub fn load_system_fonts(&mut self, fonts: Vec<TheFontScript>) {
139        use std::fs::read;
140
141        use font_kit::{
142            family_name::FamilyName, handle::Handle, properties::Properties, source::SystemSource,
143        };
144
145        if fonts.is_empty() {
146            return;
147        }
148
149        let source = SystemSource::new();
150
151        for font in fonts {
152            for font_name in font.fonts() {
153                if let Ok(handle) = source.select_best_match(
154                    &[FamilyName::Title(font_name.to_string())],
155                    &Properties::new(),
156                ) {
157                    let buf = match handle {
158                        Handle::Memory { bytes, .. } => Some(bytes.to_vec()),
159                        Handle::Path { path, .. } => read(path).ok(),
160                    };
161
162                    if let Some(buf) = buf {
163                        self.draw.add_font_data(buf);
164
165                        break;
166                    }
167                }
168            }
169        }
170    }
171}