pix_engine/gui/
mouse.rs

1//! Mouse state management.
2
3use crate::prelude::*;
4use std::{
5    collections::{HashMap, HashSet},
6    time::{Duration, Instant},
7};
8
9/// Keep track of mouse position and clicks between frames.
10#[derive(Default, Debug, Clone, PartialEq, Eq)]
11pub(crate) struct MouseState {
12    pub(crate) pos: Point<i32>,
13    pub(crate) xrel: i32,
14    pub(crate) yrel: i32,
15    pub(crate) pressed: HashSet<Mouse>,
16    pub(crate) clicked: HashSet<Mouse>,
17    pub(crate) last_clicked: HashMap<Mouse, Instant>,
18    pub(crate) last_dbl_clicked: HashMap<Mouse, Instant>,
19}
20
21impl MouseState {
22    /// Whether any [Mouse] buttons are pressed.
23    #[inline]
24    #[must_use]
25    pub(crate) fn is_pressed(&self) -> bool {
26        !self.pressed.is_empty()
27    }
28
29    /// Whether a [Mouse] buttons was clicked.
30    #[inline]
31    #[must_use]
32    pub(crate) fn was_clicked(&self, btn: Mouse) -> bool {
33        self.clicked.contains(&btn)
34    }
35
36    /// Whether a [Mouse] buttons was double clicked.
37    #[inline]
38    #[must_use]
39    pub(crate) fn was_dbl_clicked(&self, btn: Mouse) -> bool {
40        match (self.last_dbl_clicked(btn), self.last_clicked(btn)) {
41            (Some(dbl), Some(clicked)) => {
42                dbl >= clicked && (*dbl - *clicked) < Duration::from_millis(500)
43            }
44            _ => false,
45        }
46    }
47
48    /// Returns if a specific [Mouse] button is currently being held.
49    #[inline]
50    #[must_use]
51    pub(crate) fn is_down(&self, btn: Mouse) -> bool {
52        self.pressed.contains(&btn)
53    }
54
55    /// Store a pressed [Mouse] button.
56    #[inline]
57    pub(crate) fn press(&mut self, btn: Mouse) {
58        self.pressed.insert(btn);
59    }
60
61    /// Returns a list of the current mouse buttons pressed this frame.
62    #[inline]
63    pub(crate) const fn pressed(&self) -> &HashSet<Mouse> {
64        &self.pressed
65    }
66
67    /// Store mouse wheel motion.
68    #[inline]
69    pub(crate) fn wheel(&mut self, x: i32, y: i32) {
70        self.xrel = x;
71        self.yrel = y;
72    }
73
74    /// Remove a pressed [Mouse] button.
75    #[inline]
76    pub(crate) fn release(&mut self, btn: Mouse) {
77        self.pressed.remove(&btn);
78    }
79
80    /// Store last time a [Mouse] button was clicked.
81    #[inline]
82    pub(crate) fn click(&mut self, btn: Mouse, time: Instant) {
83        self.clicked.insert(btn);
84        self.last_clicked.insert(btn, time);
85    }
86
87    /// Store last time a [Mouse] button was double clicked.
88    #[inline]
89    pub(crate) fn dbl_click(&mut self, btn: Mouse, time: Instant) {
90        self.last_dbl_clicked.insert(btn, time);
91    }
92
93    /// Returns last time a [Mouse] button was clicked.
94    #[inline]
95    pub(crate) fn last_clicked(&self, btn: Mouse) -> Option<&Instant> {
96        self.last_clicked.get(&btn)
97    }
98
99    /// Returns last time a [Mouse] button was double-clicked.
100    #[inline]
101    pub(crate) fn last_dbl_clicked(&self, btn: Mouse) -> Option<&Instant> {
102        self.last_dbl_clicked.get(&btn)
103    }
104}