Skip to main content

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