use crate::ConfigAction;
use crate::cast::Cast;
#[allow(unused)] use crate::event::Event;
use crate::event::ModifiersState;
use crate::geom::Vec2;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::cell::Ref;
use std::time::Duration;
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum EventConfigMsg {
HoverDelay(u32),
MenuDelay(u32),
TouchSelectDelay(u32),
KineticTimeout(u32),
KineticDecayMul(f32),
KineticDecaySub(f32),
KineticGrabSub(f32),
ScrollDistEm(f32),
PanDistThresh(f32),
DoubleClickDistThresh(f32),
MousePan(MousePan),
MouseTextPan(MousePan),
MouseWheelActions(bool),
MouseNavFocus(bool),
TouchNavFocus(bool),
ResetToDefault,
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct EventConfig {
#[cfg_attr(feature = "serde", serde(default = "defaults::hover_delay_ms"))]
pub hover_delay_ms: u32,
#[cfg_attr(feature = "serde", serde(default = "defaults::menu_delay_ms"))]
pub menu_delay_ms: u32,
#[cfg_attr(feature = "serde", serde(default = "defaults::touch_select_delay_ms"))]
pub touch_select_delay_ms: u32,
#[cfg_attr(feature = "serde", serde(default = "defaults::kinetic_timeout_ms"))]
pub kinetic_timeout_ms: u32,
#[cfg_attr(feature = "serde", serde(default = "defaults::kinetic_decay_mul"))]
pub kinetic_decay_mul: f32,
#[cfg_attr(feature = "serde", serde(default = "defaults::kinetic_decay_sub"))]
pub kinetic_decay_sub: f32,
#[cfg_attr(feature = "serde", serde(default = "defaults::kinetic_grab_sub"))]
pub kinetic_grab_sub: f32,
#[cfg_attr(feature = "serde", serde(default = "defaults::scroll_dist_em"))]
pub scroll_dist_em: f32,
#[cfg_attr(feature = "serde", serde(default = "defaults::pan_dist_thresh"))]
pub pan_dist_thresh: f32,
#[cfg_attr(
feature = "serde",
serde(default = "defaults::double_click_dist_thresh")
)]
pub double_click_dist_thresh: f32,
#[cfg_attr(feature = "serde", serde(default = "defaults::mouse_pan"))]
pub mouse_pan: MousePan,
#[cfg_attr(feature = "serde", serde(default = "defaults::mouse_text_pan"))]
pub mouse_text_pan: MousePan,
#[cfg_attr(feature = "serde", serde(default = "defaults::mouse_wheel_actions"))]
pub mouse_wheel_actions: bool,
#[cfg_attr(feature = "serde", serde(default = "defaults::mouse_nav_focus"))]
pub mouse_nav_focus: bool,
#[cfg_attr(feature = "serde", serde(default = "defaults::touch_nav_focus"))]
pub touch_nav_focus: bool,
}
impl Default for EventConfig {
fn default() -> Self {
EventConfig {
hover_delay_ms: defaults::hover_delay_ms(),
menu_delay_ms: defaults::menu_delay_ms(),
touch_select_delay_ms: defaults::touch_select_delay_ms(),
kinetic_timeout_ms: defaults::kinetic_timeout_ms(),
kinetic_decay_mul: defaults::kinetic_decay_mul(),
kinetic_decay_sub: defaults::kinetic_decay_sub(),
kinetic_grab_sub: defaults::kinetic_grab_sub(),
scroll_dist_em: defaults::scroll_dist_em(),
pan_dist_thresh: defaults::pan_dist_thresh(),
double_click_dist_thresh: defaults::double_click_dist_thresh(),
mouse_pan: defaults::mouse_pan(),
mouse_text_pan: defaults::mouse_text_pan(),
mouse_wheel_actions: defaults::mouse_wheel_actions(),
mouse_nav_focus: defaults::mouse_nav_focus(),
touch_nav_focus: defaults::touch_nav_focus(),
}
}
}
impl EventConfig {
pub(super) fn change_config(&mut self, msg: EventConfigMsg) -> ConfigAction {
match msg {
EventConfigMsg::HoverDelay(v) => self.hover_delay_ms = v,
EventConfigMsg::MenuDelay(v) => self.menu_delay_ms = v,
EventConfigMsg::TouchSelectDelay(v) => self.touch_select_delay_ms = v,
EventConfigMsg::KineticTimeout(v) => self.kinetic_timeout_ms = v,
EventConfigMsg::KineticDecayMul(v) => self.kinetic_decay_mul = v,
EventConfigMsg::KineticDecaySub(v) => self.kinetic_decay_sub = v,
EventConfigMsg::KineticGrabSub(v) => self.kinetic_grab_sub = v,
EventConfigMsg::ScrollDistEm(v) => self.scroll_dist_em = v,
EventConfigMsg::PanDistThresh(v) => self.pan_dist_thresh = v,
EventConfigMsg::DoubleClickDistThresh(v) => self.double_click_dist_thresh = v,
EventConfigMsg::MousePan(v) => self.mouse_pan = v,
EventConfigMsg::MouseTextPan(v) => self.mouse_text_pan = v,
EventConfigMsg::MouseWheelActions(v) => self.mouse_wheel_actions = v,
EventConfigMsg::MouseNavFocus(v) => self.mouse_nav_focus = v,
EventConfigMsg::TouchNavFocus(v) => self.touch_nav_focus = v,
EventConfigMsg::ResetToDefault => *self = EventConfig::default(),
}
ConfigAction::EVENT
}
}
#[derive(Clone, Debug)]
pub struct EventWindowConfig<'a>(pub(super) &'a super::WindowConfig);
impl<'a> EventWindowConfig<'a> {
#[inline]
pub fn base(&self) -> Ref<'_, EventConfig> {
Ref::map(self.0.config.borrow(), |c| &c.event)
}
#[inline]
pub fn hover_delay(&self) -> Duration {
Duration::from_millis(self.base().hover_delay_ms.cast())
}
#[inline]
pub fn menu_delay(&self) -> Duration {
Duration::from_millis(self.base().menu_delay_ms.cast())
}
#[inline]
pub fn touch_select_delay(&self) -> Duration {
Duration::from_millis(self.base().touch_select_delay_ms.cast())
}
#[inline]
pub fn kinetic_timeout(&self) -> Duration {
Duration::from_millis(self.base().kinetic_timeout_ms.cast())
}
#[inline]
pub fn kinetic_decay(&self) -> (f32, f32) {
(self.base().kinetic_decay_mul, self.0.kinetic_decay_sub)
}
#[inline]
pub fn kinetic_grab_sub(&self) -> f32 {
self.base().kinetic_grab_sub
}
pub fn scroll_distance(&self, lines: (f32, f32)) -> Vec2 {
let x = self.0.scroll_dist * lines.0;
let y = self.0.scroll_dist * lines.1;
Vec2(x, y)
}
#[inline]
pub fn pan_dist_thresh(&self) -> f32 {
self.0.pan_dist_thresh
}
#[inline]
pub(crate) fn double_click_dist_thresh(&self) -> f32 {
self.0.double_click_dist_thresh
}
#[inline]
pub fn mouse_wheel_actions(&self) -> bool {
self.base().mouse_wheel_actions
}
#[inline]
pub fn mouse_pan(&self) -> MousePan {
self.base().mouse_pan
}
#[inline]
pub fn mouse_text_pan(&self) -> MousePan {
self.base().mouse_text_pan
}
#[inline]
pub fn mouse_nav_focus(&self) -> bool {
self.0.nav_focus && self.base().mouse_nav_focus
}
#[inline]
pub fn touch_nav_focus(&self) -> bool {
self.0.nav_focus && self.base().touch_nav_focus
}
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum MousePan {
Never,
WithAlt,
WithCtrl,
Always,
}
impl MousePan {
pub fn is_enabled_with(self, modifiers: ModifiersState) -> bool {
match self {
MousePan::Never => false,
MousePan::WithAlt => modifiers.alt_key(),
MousePan::WithCtrl => modifiers.control_key(),
MousePan::Always => true,
}
}
}
mod defaults {
use super::MousePan;
pub fn hover_delay_ms() -> u32 {
1000
}
pub fn menu_delay_ms() -> u32 {
250
}
pub fn touch_select_delay_ms() -> u32 {
1000
}
pub fn kinetic_timeout_ms() -> u32 {
50
}
pub fn kinetic_decay_mul() -> f32 {
0.625
}
pub fn kinetic_decay_sub() -> f32 {
200.0
}
pub fn kinetic_grab_sub() -> f32 {
10000.0
}
pub fn scroll_dist_em() -> f32 {
4.5
}
pub fn pan_dist_thresh() -> f32 {
5.0
}
pub fn double_click_dist_thresh() -> f32 {
4.0
}
pub fn mouse_wheel_actions() -> bool {
true
}
pub fn mouse_pan() -> MousePan {
MousePan::Always
}
pub fn mouse_text_pan() -> MousePan {
#[cfg(target_os = "windows")]
{
MousePan::WithAlt
}
#[cfg(not(target_os = "windows"))]
{
MousePan::WithCtrl
}
}
pub fn mouse_nav_focus() -> bool {
true
}
pub fn touch_nav_focus() -> bool {
true
}
}