1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use std::{
borrow::Cow,
rc::Rc,
};
use bytes::Bytes;
pub use mundy::{
AccentColor,
Srgba,
};
use torin::prelude::Size2D;
use crate::{
accessibility::id::AccessibilityId,
prelude::{
State,
consume_root_context,
},
user_event::UserEvent,
};
#[derive(Clone, Copy, PartialEq, Eq, Default, Debug, Hash)]
pub enum NavigationMode {
#[default]
NotKeyboard,
Keyboard,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum PreferredTheme {
#[default]
Light,
Dark,
}
/// Access point to different Freya-managed states such as the focused node,
/// root window size, navigation mode, and theme preference.
///
/// Retrieve it from any component with [`Platform::get`].
#[derive(Clone)]
pub struct Platform {
/// The [`AccessibilityId`] of the currently focused node.
pub focused_accessibility_id: State<AccessibilityId>,
/// The accessibility node data of the currently focused node.
pub focused_accessibility_node: State<accesskit::Node>,
/// The size of the root window.
pub root_size: State<Size2D>,
/// Rendering scale factor, the OS scale factor multiplied by the custom scale factor.
pub scale_factor: State<f64>,
/// Custom scale factor, change it with [`Platform::set_custom_scale_factor`].
pub custom_scale_factor: State<f64>,
/// The current [`NavigationMode`].
pub navigation_mode: State<NavigationMode>,
/// The OS-level [`PreferredTheme`].
pub preferred_theme: State<PreferredTheme>,
/// Whether the app currently has the OS-level focus.
pub is_app_focused: State<bool>,
/// The OS-level [`AccentColor`].
pub accent_color: State<AccentColor>,
/// Sender used to dispatch [`UserEvent`]s to the active renderer.
pub sender: Rc<dyn Fn(UserEvent)>,
}
impl Platform {
/// Retrieve the [`Platform`] from the root context.
#[track_caller]
pub fn get() -> Self {
consume_root_context()
}
/// Dispatch a [`UserEvent`] to the active renderer.
pub fn send(&self, event: UserEvent) {
(self.sender)(event)
}
/// Request the renderer to use a custom scale factor, multiplied with the
/// OS scale factor. The value might get clamped to a reasonable range.
pub fn set_custom_scale_factor(&self, custom_scale_factor: f64) {
self.send(UserEvent::SetCustomScaleFactor(custom_scale_factor));
}
/// Load a font at runtime, making it available under the given name in all windows.
///
/// # Example
///
/// ```rust,no_run
/// use freya_core::prelude::*;
///
/// fn load_rubik() {
/// let font = std::fs::read("./Rubik.ttf").expect("Failed to read the font file.");
/// Platform::get().load_font("Rubik", font);
/// }
/// ```
pub fn load_font(&self, font_name: impl Into<Cow<'static, str>>, font_data: impl Into<Bytes>) {
self.send(UserEvent::LoadFont {
font_name: font_name.into(),
font_data: font_data.into(),
});
}
}