zng_view_api/config.rs
1//! System config types.
2
3use std::{fmt, time::Duration};
4
5use serde::{Deserialize, Serialize};
6
7use zng_txt::Txt;
8use zng_unit::{Dip, DipSize, Rgba};
9
10/// System settings needed for implementing double/triple clicks.
11#[derive(Debug, Clone, Copy, Serialize, PartialEq, Eq, Deserialize)]
12pub struct MultiClickConfig {
13 /// Maximum time interval between clicks.
14 ///
15 /// Only repeated clicks within this time interval can count as double-clicks.
16 pub time: Duration,
17
18 /// Maximum (x, y) distance in pixels.
19 ///
20 /// Only repeated clicks that are within this distance of the first click can count as double-clicks.
21 pub area: DipSize,
22}
23impl Default for MultiClickConfig {
24 /// `500ms` and `4, 4`.
25 fn default() -> Self {
26 Self {
27 time: Duration::from_millis(500),
28 area: DipSize::splat(Dip::new(4)),
29 }
30 }
31}
32
33/// System settings needed to implementing touch gestures.
34#[derive(Debug, Clone, Copy, Serialize, PartialEq, Eq, Deserialize)]
35pub struct TouchConfig {
36 /// Maximum (x, y) distance between a touch start and end that generates a touch click.
37 ///
38 /// Area can be disregarded if the touch is not ambiguous. This usually defines the initial lag
39 /// for a single finger drag gesture.
40 pub tap_area: DipSize,
41
42 /// Maximum (x, y) distance that a subsequent touch click is linked with the previous one as a double click.
43 ///
44 /// Area can be disregarded if the touch is not ambiguous.
45 pub double_tap_area: DipSize,
46
47 /// Maximum time between start and end in the `tap_area` that generates a touch click.
48 ///
49 /// Time can be disregarded if the touch is not ambiguous. This usually defines the *long press* delay.
50 pub tap_max_time: Duration,
51
52 /// Maximum time between taps that generates a double click.
53 pub double_tap_max_time: Duration,
54
55 /// Minimum velocity that can be considered a fling gesture, in dip per seconds.
56 pub min_fling_velocity: Dip,
57
58 /// Fling velocity ceiling, in dip per seconds.
59 pub max_fling_velocity: Dip,
60}
61impl Default for TouchConfig {
62 fn default() -> Self {
63 Self {
64 tap_area: DipSize::splat(Dip::new(8)),
65 double_tap_area: DipSize::splat(Dip::new(28)),
66 tap_max_time: Duration::from_millis(500),
67 double_tap_max_time: Duration::from_millis(500),
68 min_fling_velocity: Dip::new(50),
69 max_fling_velocity: Dip::new(8000),
70 }
71 }
72}
73
74/// System settings that define the key pressed repeat.
75#[derive(Debug, Clone, Copy, Serialize, PartialEq, Eq, Deserialize)]
76pub struct KeyRepeatConfig {
77 /// Delay before repeat starts.
78 pub start_delay: Duration,
79 /// Delay before each repeat event after the first.
80 pub interval: Duration,
81}
82impl Default for KeyRepeatConfig {
83 /// 600ms, 100ms.
84 fn default() -> Self {
85 Self {
86 start_delay: Duration::from_millis(600),
87 interval: Duration::from_millis(100),
88 }
89 }
90}
91
92/// System settings that control animations.
93#[derive(Debug, Clone, Copy, Serialize, PartialEq, Eq, Deserialize)]
94pub struct AnimationsConfig {
95 /// If animation are enabled.
96 ///
97 /// People with photo-sensitive epilepsy usually disable animations system wide.
98 pub enabled: bool,
99
100 /// Interval of the caret blink animation.
101 ///
102 /// This is the duration the cursor stays visible.
103 pub caret_blink_interval: Duration,
104 /// Duration after which the blink animation stops.
105 pub caret_blink_timeout: Duration,
106}
107impl Default for AnimationsConfig {
108 /// true, 530ms, 5s.
109 fn default() -> Self {
110 Self {
111 enabled: true,
112 caret_blink_interval: Duration::from_millis(530),
113 caret_blink_timeout: Duration::from_secs(5),
114 }
115 }
116}
117
118/// System settings that define the locale.
119#[derive(Debug, Clone, Serialize, PartialEq, Eq, Deserialize, Default)]
120pub struct LocaleConfig {
121 /// BCP-47 language tags, if the locale can be obtained.
122 pub langs: Vec<Txt>,
123}
124
125/// Text anti-aliasing.
126#[derive(Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
127pub enum FontAntiAliasing {
128 /// Uses the operating system configuration.
129 #[default]
130 Default,
131 /// Sub-pixel anti-aliasing if a fast implementation is available, otherwise uses `Alpha`.
132 Subpixel,
133 /// Alpha blending anti-aliasing.
134 Alpha,
135 /// Disable anti-aliasing.
136 Mono,
137}
138impl fmt::Debug for FontAntiAliasing {
139 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140 if f.alternate() {
141 write!(f, "FontAntiAliasing::")?;
142 }
143 match self {
144 FontAntiAliasing::Default => write!(f, "Default"),
145 FontAntiAliasing::Subpixel => write!(f, "Subpixel"),
146 FontAntiAliasing::Alpha => write!(f, "Alpha"),
147 FontAntiAliasing::Mono => write!(f, "Mono"),
148 }
149 }
150}
151
152/// Color scheme preference.
153#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
154pub enum ColorScheme {
155 /// Dark text, light background.
156 Light,
157
158 /// Light text, dark background.
159 Dark,
160}
161impl Default for ColorScheme {
162 /// Light.
163 fn default() -> Self {
164 ColorScheme::Light
165 }
166}
167
168/// System colors and color scheme.
169#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
170pub struct ColorsConfig {
171 /// Color scheme (light/dark) preference.
172 pub scheme: ColorScheme,
173 /// Accent color.
174 ///
175 /// Accent color preference.
176 ///
177 /// Expect a saturated color that contrasts with the text color.
178 pub accent: Rgba,
179}
180impl Default for ColorsConfig {
181 fn default() -> Self {
182 Self {
183 scheme: Default::default(),
184 accent: Rgba::new(10, 10, 200, 255),
185 }
186 }
187}
188
189#[cfg(feature = "var")]
190zng_var::impl_from_and_into_var! {
191 fn from(some: ColorScheme) -> Option<ColorScheme>;
192}
193
194/// Window chrome (decorations) preference.
195#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
196pub struct ChromeConfig {
197 /// Window manager prefers that the window renders a custom chrome.
198 ///
199 /// This is also called "Client-Side Decorations", it is `true` in GNOME+Wayland.
200 pub prefer_custom: bool,
201
202 /// If the Window manager provides a chrome.
203 ///
204 /// When this is `false` the view-process implementation may provide just a very basic fallback chrome,
205 /// if the app-process still requests system chrome.
206 pub provided: bool,
207}
208impl ChromeConfig {
209 /// If system prefers custom and does not provide chrome.
210 ///
211 /// Note that a chromeless window is not forbidden if this is `true`.
212 pub fn needs_custom(&self) -> bool {
213 self.prefer_custom && !self.provided
214 }
215}
216impl Default for ChromeConfig {
217 fn default() -> Self {
218 Self {
219 prefer_custom: false,
220 provided: true,
221 }
222 }
223}