1use crate::ConfigAction;
9use crate::cast::Cast;
10#[allow(unused)] use crate::event::Event;
11use crate::event::ModifiersState;
12use crate::geom::Vec2;
13#[cfg(feature = "serde")]
14use serde::{Deserialize, Serialize};
15use std::cell::Ref;
16use std::time::Duration;
17
18#[derive(Clone, Debug)]
20#[non_exhaustive]
21pub enum EventConfigMsg {
22 HoverDelay(u32),
23 MenuDelay(u32),
24 TouchSelectDelay(u32),
25 KineticTimeout(u32),
26 KineticDecayMul(f32),
27 KineticDecaySub(f32),
28 KineticGrabSub(f32),
29 ScrollDistEm(f32),
30 PanDistThresh(f32),
31 DoubleClickDistThresh(f32),
32 MousePan(MousePan),
33 MouseTextPan(MousePan),
34 MouseWheelActions(bool),
35 MouseNavFocus(bool),
36 TouchNavFocus(bool),
37 ResetToDefault,
39}
40
41#[derive(Clone, Debug, PartialEq)]
60#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
61pub struct EventConfig {
62 #[cfg_attr(feature = "serde", serde(default = "defaults::hover_delay_ms"))]
63 pub hover_delay_ms: u32,
64
65 #[cfg_attr(feature = "serde", serde(default = "defaults::menu_delay_ms"))]
66 pub menu_delay_ms: u32,
67
68 #[cfg_attr(feature = "serde", serde(default = "defaults::touch_select_delay_ms"))]
69 pub touch_select_delay_ms: u32,
70
71 #[cfg_attr(feature = "serde", serde(default = "defaults::kinetic_timeout_ms"))]
72 pub kinetic_timeout_ms: u32,
73
74 #[cfg_attr(feature = "serde", serde(default = "defaults::kinetic_decay_mul"))]
75 pub kinetic_decay_mul: f32,
76
77 #[cfg_attr(feature = "serde", serde(default = "defaults::kinetic_decay_sub"))]
78 pub kinetic_decay_sub: f32,
79
80 #[cfg_attr(feature = "serde", serde(default = "defaults::kinetic_grab_sub"))]
81 pub kinetic_grab_sub: f32,
82
83 #[cfg_attr(feature = "serde", serde(default = "defaults::scroll_dist_em"))]
84 pub scroll_dist_em: f32,
85
86 #[cfg_attr(feature = "serde", serde(default = "defaults::pan_dist_thresh"))]
87 pub pan_dist_thresh: f32,
88
89 #[cfg_attr(
90 feature = "serde",
91 serde(default = "defaults::double_click_dist_thresh")
92 )]
93 pub double_click_dist_thresh: f32,
94
95 #[cfg_attr(feature = "serde", serde(default = "defaults::mouse_pan"))]
96 pub mouse_pan: MousePan,
97 #[cfg_attr(feature = "serde", serde(default = "defaults::mouse_text_pan"))]
98 pub mouse_text_pan: MousePan,
99
100 #[cfg_attr(feature = "serde", serde(default = "defaults::mouse_wheel_actions"))]
101 pub mouse_wheel_actions: bool,
102
103 #[cfg_attr(feature = "serde", serde(default = "defaults::mouse_nav_focus"))]
104 pub mouse_nav_focus: bool,
105 #[cfg_attr(feature = "serde", serde(default = "defaults::touch_nav_focus"))]
106 pub touch_nav_focus: bool,
107}
108
109impl Default for EventConfig {
110 fn default() -> Self {
111 EventConfig {
112 hover_delay_ms: defaults::hover_delay_ms(),
113 menu_delay_ms: defaults::menu_delay_ms(),
114 touch_select_delay_ms: defaults::touch_select_delay_ms(),
115 kinetic_timeout_ms: defaults::kinetic_timeout_ms(),
116 kinetic_decay_mul: defaults::kinetic_decay_mul(),
117 kinetic_decay_sub: defaults::kinetic_decay_sub(),
118 kinetic_grab_sub: defaults::kinetic_grab_sub(),
119 scroll_dist_em: defaults::scroll_dist_em(),
120 pan_dist_thresh: defaults::pan_dist_thresh(),
121 double_click_dist_thresh: defaults::double_click_dist_thresh(),
122 mouse_pan: defaults::mouse_pan(),
123 mouse_text_pan: defaults::mouse_text_pan(),
124 mouse_wheel_actions: defaults::mouse_wheel_actions(),
125 mouse_nav_focus: defaults::mouse_nav_focus(),
126 touch_nav_focus: defaults::touch_nav_focus(),
127 }
128 }
129}
130
131impl EventConfig {
132 pub(super) fn change_config(&mut self, msg: EventConfigMsg) -> ConfigAction {
133 match msg {
134 EventConfigMsg::HoverDelay(v) => self.hover_delay_ms = v,
135 EventConfigMsg::MenuDelay(v) => self.menu_delay_ms = v,
136 EventConfigMsg::TouchSelectDelay(v) => self.touch_select_delay_ms = v,
137 EventConfigMsg::KineticTimeout(v) => self.kinetic_timeout_ms = v,
138 EventConfigMsg::KineticDecayMul(v) => self.kinetic_decay_mul = v,
139 EventConfigMsg::KineticDecaySub(v) => self.kinetic_decay_sub = v,
140 EventConfigMsg::KineticGrabSub(v) => self.kinetic_grab_sub = v,
141 EventConfigMsg::ScrollDistEm(v) => self.scroll_dist_em = v,
142 EventConfigMsg::PanDistThresh(v) => self.pan_dist_thresh = v,
143 EventConfigMsg::DoubleClickDistThresh(v) => self.double_click_dist_thresh = v,
144 EventConfigMsg::MousePan(v) => self.mouse_pan = v,
145 EventConfigMsg::MouseTextPan(v) => self.mouse_text_pan = v,
146 EventConfigMsg::MouseWheelActions(v) => self.mouse_wheel_actions = v,
147 EventConfigMsg::MouseNavFocus(v) => self.mouse_nav_focus = v,
148 EventConfigMsg::TouchNavFocus(v) => self.touch_nav_focus = v,
149 EventConfigMsg::ResetToDefault => *self = EventConfig::default(),
150 }
151
152 ConfigAction::EVENT
153 }
154}
155
156#[derive(Clone, Debug)]
161pub struct EventWindowConfig<'a>(pub(super) &'a super::WindowConfig);
162
163impl<'a> EventWindowConfig<'a> {
164 #[inline]
166 pub fn base(&self) -> Ref<'_, EventConfig> {
167 Ref::map(self.0.config.borrow(), |c| &c.event)
168 }
169
170 #[inline]
172 pub fn hover_delay(&self) -> Duration {
173 Duration::from_millis(self.base().hover_delay_ms.cast())
174 }
175
176 #[inline]
178 pub fn menu_delay(&self) -> Duration {
179 Duration::from_millis(self.base().menu_delay_ms.cast())
180 }
181
182 #[inline]
184 pub fn touch_select_delay(&self) -> Duration {
185 Duration::from_millis(self.base().touch_select_delay_ms.cast())
186 }
187
188 #[inline]
194 pub fn kinetic_timeout(&self) -> Duration {
195 Duration::from_millis(self.base().kinetic_timeout_ms.cast())
196 }
197
198 #[inline]
209 pub fn kinetic_decay(&self) -> (f32, f32) {
210 (self.base().kinetic_decay_mul, self.0.kinetic_decay_sub)
211 }
212
213 #[inline]
220 pub fn kinetic_grab_sub(&self) -> f32 {
221 self.base().kinetic_grab_sub
222 }
223
224 pub fn scroll_distance(&self, lines: (f32, f32)) -> Vec2 {
228 let x = self.0.scroll_dist * lines.0;
229 let y = self.0.scroll_dist * lines.1;
230 Vec2(x, y)
231 }
232
233 #[inline]
241 pub fn pan_dist_thresh(&self) -> f32 {
242 self.0.pan_dist_thresh
243 }
244
245 #[inline]
254 pub(crate) fn double_click_dist_thresh(&self) -> f32 {
255 self.0.double_click_dist_thresh
256 }
257
258 #[inline]
260 pub fn mouse_wheel_actions(&self) -> bool {
261 self.base().mouse_wheel_actions
262 }
263
264 #[inline]
266 pub fn mouse_pan(&self) -> MousePan {
267 self.base().mouse_pan
268 }
269
270 #[inline]
272 pub fn mouse_text_pan(&self) -> MousePan {
273 self.base().mouse_text_pan
274 }
275
276 #[inline]
278 pub fn mouse_nav_focus(&self) -> bool {
279 self.0.nav_focus && self.base().mouse_nav_focus
280 }
281
282 #[inline]
284 pub fn touch_nav_focus(&self) -> bool {
285 self.0.nav_focus && self.base().touch_nav_focus
286 }
287}
288
289#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
298#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
299#[repr(u8)]
300pub enum MousePan {
301 Never,
303 WithAlt,
305 WithCtrl,
307 Always,
309}
310
311impl MousePan {
312 pub fn is_enabled_with(self, modifiers: ModifiersState) -> bool {
314 match self {
315 MousePan::Never => false,
316 MousePan::WithAlt => modifiers.alt_key(),
317 MousePan::WithCtrl => modifiers.control_key(),
318 MousePan::Always => true,
319 }
320 }
321}
322
323mod defaults {
324 use super::MousePan;
325
326 pub fn hover_delay_ms() -> u32 {
327 1000
328 }
329 pub fn menu_delay_ms() -> u32 {
330 250
331 }
332 pub fn touch_select_delay_ms() -> u32 {
333 1000
334 }
335 pub fn kinetic_timeout_ms() -> u32 {
336 50
337 }
338 pub fn kinetic_decay_mul() -> f32 {
339 0.625
340 }
341 pub fn kinetic_decay_sub() -> f32 {
342 200.0
343 }
344 pub fn kinetic_grab_sub() -> f32 {
345 10000.0
346 }
347 pub fn scroll_dist_em() -> f32 {
348 4.5
349 }
350 pub fn pan_dist_thresh() -> f32 {
351 5.0
352 }
353 pub fn double_click_dist_thresh() -> f32 {
354 4.0
355 }
356 pub fn mouse_wheel_actions() -> bool {
357 true
358 }
359 pub fn mouse_pan() -> MousePan {
360 MousePan::Always
361 }
362 pub fn mouse_text_pan() -> MousePan {
363 #[cfg(target_os = "windows")]
364 {
365 MousePan::WithAlt
366 }
367 #[cfg(not(target_os = "windows"))]
368 {
369 MousePan::WithCtrl
370 }
371 }
372 pub fn mouse_nav_focus() -> bool {
373 true
374 }
375 pub fn touch_nav_focus() -> bool {
376 true
377 }
378}