diff options
Diffstat (limited to '')
| -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) + } +} |
