1use crate::Action;
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 MousePan(MousePan),
32 MouseTextPan(MousePan),
33 MouseWheelActions(bool),
34 MouseNavFocus(bool),
35 TouchNavFocus(bool),
36 ResetToDefault,
38}
39
40#[derive(Clone, Debug, PartialEq)]
58#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
59pub struct EventConfig {
60 #[cfg_attr(feature = "serde", serde(default = "defaults::hover_delay_ms"))]
61 pub hover_delay_ms: u32,
62
63 #[cfg_attr(feature = "serde", serde(default = "defaults::menu_delay_ms"))]
64 pub menu_delay_ms: u32,
65
66 #[cfg_attr(feature = "serde", serde(default = "defaults::touch_select_delay_ms"))]
67 pub touch_select_delay_ms: u32,
68
69 #[cfg_attr(feature = "serde", serde(default = "defaults::kinetic_timeout_ms"))]
70 pub kinetic_timeout_ms: u32,
71
72 #[cfg_attr(feature = "serde", serde(default = "defaults::kinetic_decay_mul"))]
73 pub kinetic_decay_mul: f32,
74
75 #[cfg_attr(feature = "serde", serde(default = "defaults::kinetic_decay_sub"))]
76 pub kinetic_decay_sub: f32,
77
78 #[cfg_attr(feature = "serde", serde(default = "defaults::kinetic_grab_sub"))]
79 pub kinetic_grab_sub: f32,
80
81 #[cfg_attr(feature = "serde", serde(default = "defaults::scroll_dist_em"))]
82 pub scroll_dist_em: f32,
83
84 #[cfg_attr(feature = "serde", serde(default = "defaults::pan_dist_thresh"))]
85 pub pan_dist_thresh: f32,
86
87 #[cfg_attr(feature = "serde", serde(default = "defaults::mouse_pan"))]
88 pub mouse_pan: MousePan,
89 #[cfg_attr(feature = "serde", serde(default = "defaults::mouse_text_pan"))]
90 pub mouse_text_pan: MousePan,
91
92 #[cfg_attr(feature = "serde", serde(default = "defaults::mouse_wheel_actions"))]
93 pub mouse_wheel_actions: bool,
94
95 #[cfg_attr(feature = "serde", serde(default = "defaults::mouse_nav_focus"))]
96 pub mouse_nav_focus: bool,
97 #[cfg_attr(feature = "serde", serde(default = "defaults::touch_nav_focus"))]
98 pub touch_nav_focus: bool,
99}
100
101impl Default for EventConfig {
102 fn default() -> Self {
103 EventConfig {
104 hover_delay_ms: defaults::hover_delay_ms(),
105 menu_delay_ms: defaults::menu_delay_ms(),
106 touch_select_delay_ms: defaults::touch_select_delay_ms(),
107 kinetic_timeout_ms: defaults::kinetic_timeout_ms(),
108 kinetic_decay_mul: defaults::kinetic_decay_mul(),
109 kinetic_decay_sub: defaults::kinetic_decay_sub(),
110 kinetic_grab_sub: defaults::kinetic_grab_sub(),
111 scroll_dist_em: defaults::scroll_dist_em(),
112 pan_dist_thresh: defaults::pan_dist_thresh(),
113 mouse_pan: defaults::mouse_pan(),
114 mouse_text_pan: defaults::mouse_text_pan(),
115 mouse_wheel_actions: defaults::mouse_wheel_actions(),
116 mouse_nav_focus: defaults::mouse_nav_focus(),
117 touch_nav_focus: defaults::touch_nav_focus(),
118 }
119 }
120}
121
122impl EventConfig {
123 pub(super) fn change_config(&mut self, msg: EventConfigMsg) -> Action {
124 match msg {
125 EventConfigMsg::HoverDelay(v) => self.hover_delay_ms = v,
126 EventConfigMsg::MenuDelay(v) => self.menu_delay_ms = v,
127 EventConfigMsg::TouchSelectDelay(v) => self.touch_select_delay_ms = v,
128 EventConfigMsg::KineticTimeout(v) => self.kinetic_timeout_ms = v,
129 EventConfigMsg::KineticDecayMul(v) => self.kinetic_decay_mul = v,
130 EventConfigMsg::KineticDecaySub(v) => self.kinetic_decay_sub = v,
131 EventConfigMsg::KineticGrabSub(v) => self.kinetic_grab_sub = v,
132 EventConfigMsg::ScrollDistEm(v) => self.scroll_dist_em = v,
133 EventConfigMsg::PanDistThresh(v) => self.pan_dist_thresh = v,
134 EventConfigMsg::MousePan(v) => self.mouse_pan = v,
135 EventConfigMsg::MouseTextPan(v) => self.mouse_text_pan = v,
136 EventConfigMsg::MouseWheelActions(v) => self.mouse_wheel_actions = v,
137 EventConfigMsg::MouseNavFocus(v) => self.mouse_nav_focus = v,
138 EventConfigMsg::TouchNavFocus(v) => self.touch_nav_focus = v,
139 EventConfigMsg::ResetToDefault => *self = EventConfig::default(),
140 }
141
142 Action::EVENT_CONFIG
143 }
144}
145
146#[derive(Clone, Debug)]
151pub struct EventWindowConfig<'a>(pub(super) &'a super::WindowConfig);
152
153impl<'a> EventWindowConfig<'a> {
154 #[inline]
156 pub fn base(&self) -> Ref<'_, EventConfig> {
157 Ref::map(self.0.config.borrow(), |c| &c.event)
158 }
159
160 #[inline]
162 pub fn hover_delay(&self) -> Duration {
163 Duration::from_millis(self.base().hover_delay_ms.cast())
164 }
165
166 #[inline]
168 pub fn menu_delay(&self) -> Duration {
169 Duration::from_millis(self.base().menu_delay_ms.cast())
170 }
171
172 #[inline]
174 pub fn touch_select_delay(&self) -> Duration {
175 Duration::from_millis(self.base().touch_select_delay_ms.cast())
176 }
177
178 #[inline]
184 pub fn kinetic_timeout(&self) -> Duration {
185 Duration::from_millis(self.base().kinetic_timeout_ms.cast())
186 }
187
188 #[inline]
199 pub fn kinetic_decay(&self) -> (f32, f32) {
200 (self.base().kinetic_decay_mul, self.0.kinetic_decay_sub)
201 }
202
203 #[inline]
210 pub fn kinetic_grab_sub(&self) -> f32 {
211 self.base().kinetic_grab_sub
212 }
213
214 pub fn scroll_distance(&self, lines: (f32, f32)) -> Vec2 {
218 let x = self.0.scroll_dist * lines.0;
219 let y = self.0.scroll_dist * lines.1;
220 Vec2(x, y)
221 }
222
223 #[inline]
231 pub fn pan_dist_thresh(&self) -> f32 {
232 self.0.pan_dist_thresh
233 }
234
235 #[inline]
237 pub fn mouse_wheel_actions(&self) -> bool {
238 self.base().mouse_wheel_actions
239 }
240
241 #[inline]
243 pub fn mouse_pan(&self) -> MousePan {
244 self.base().mouse_pan
245 }
246
247 #[inline]
249 pub fn mouse_text_pan(&self) -> MousePan {
250 self.base().mouse_text_pan
251 }
252
253 #[inline]
255 pub fn mouse_nav_focus(&self) -> bool {
256 self.0.nav_focus && self.base().mouse_nav_focus
257 }
258
259 #[inline]
261 pub fn touch_nav_focus(&self) -> bool {
262 self.0.nav_focus && self.base().touch_nav_focus
263 }
264}
265
266#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
275#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
276#[repr(u8)]
277pub enum MousePan {
278 Never,
280 WithAlt,
282 WithCtrl,
284 Always,
286}
287
288impl MousePan {
289 pub fn is_enabled_with(self, modifiers: ModifiersState) -> bool {
291 match self {
292 MousePan::Never => false,
293 MousePan::WithAlt => modifiers.alt_key(),
294 MousePan::WithCtrl => modifiers.control_key(),
295 MousePan::Always => true,
296 }
297 }
298}
299
300mod defaults {
301 use super::MousePan;
302
303 pub fn hover_delay_ms() -> u32 {
304 1000
305 }
306 pub fn menu_delay_ms() -> u32 {
307 250
308 }
309 pub fn touch_select_delay_ms() -> u32 {
310 1000
311 }
312 pub fn kinetic_timeout_ms() -> u32 {
313 50
314 }
315 pub fn kinetic_decay_mul() -> f32 {
316 0.625
317 }
318 pub fn kinetic_decay_sub() -> f32 {
319 200.0
320 }
321 pub fn kinetic_grab_sub() -> f32 {
322 10000.0
323 }
324 pub fn scroll_dist_em() -> f32 {
325 4.5
326 }
327 pub fn pan_dist_thresh() -> f32 {
328 5.0
329 }
330 pub fn mouse_wheel_actions() -> bool {
331 true
332 }
333 pub fn mouse_pan() -> MousePan {
334 MousePan::Always
335 }
336 pub fn mouse_text_pan() -> MousePan {
337 #[cfg(target_os = "windows")]
338 {
339 MousePan::WithAlt
340 }
341 #[cfg(not(target_os = "windows"))]
342 {
343 MousePan::WithCtrl
344 }
345 }
346 pub fn mouse_nav_focus() -> bool {
347 true
348 }
349 pub fn touch_nav_focus() -> bool {
350 true
351 }
352}