diff options
| author | Polesznyák Márk <contact@pml68.dev> | 2026-02-05 14:20:35 +0100 |
|---|---|---|
| committer | Polesznyák Márk <contact@pml68.dev> | 2026-02-05 14:21:32 +0100 |
| commit | 5eddb62f3cae4740680eaa81d448c3eeda88068a (patch) | |
| tree | f45e6b7afaa8ed3a2a5dea5e65685f83017c0eb7 /src/click.rs | |
| parent | chore: bump MSRV to match iced's (diff) | |
| download | iced_selection-5eddb62f3cae4740680eaa81d448c3eeda88068a.tar.gz | |
feat: make click interval for double & triple clicks customizable
Diffstat (limited to 'src/click.rs')
| -rw-r--r-- | src/click.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/click.rs b/src/click.rs new file mode 100644 index 0000000..83e6956 --- /dev/null +++ b/src/click.rs @@ -0,0 +1,87 @@ +use crate::core::Point; +use crate::core::mouse::Button; +use crate::core::time::{Duration, Instant}; + +/// A mouse click. +#[derive(Debug, Clone, Copy)] +pub struct Click { + kind: Kind, + button: Button, + position: Point, + time: Instant, + click_interval: Duration, +} + +/// The kind of mouse click. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Kind { + /// A single click + Single, + + /// A double click + Double, + + /// A triple click + Triple, +} + +impl Kind { + fn next(self) -> Kind { + match self { + Kind::Single => Kind::Double, + Kind::Double => Kind::Triple, + Kind::Triple => Kind::Double, + } + } +} + +impl Click { + /// Creates a new [`Click`] with the given position and previous last + /// [`Click`]. + pub fn new( + position: Point, + button: Button, + previous: Option<Click>, + click_interval: Option<Duration>, + ) -> Click { + let time = Instant::now(); + + let kind = if let Some(previous) = previous { + if previous.is_consecutive(position, time) + && button == previous.button + { + previous.kind.next() + } else { + Kind::Single + } + } else { + Kind::Single + }; + + Click { + kind, + button, + position, + time, + click_interval: click_interval + .unwrap_or(Duration::from_millis(300)), + } + } + + pub fn kind(&self) -> Kind { + self.kind + } + + fn is_consecutive(&self, new_position: Point, time: Instant) -> bool { + let duration = if time > self.time { + Some(time - self.time) + } else { + None + }; + + self.position.distance(new_position) < 6.0 + && duration + .map(|duration| duration <= self.click_interval) + .unwrap_or(false) + } +} |
