gedv/
mouse.rs

1use super::*;
2
3#[cfg(windows)]
4use windows::Win32::{Foundation::WPARAM, System::SystemServices::*};
5
6pub type ButtonState = KeyState;
7
8#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10pub enum MouseButton {
11    Left,
12    Right,
13    Middle,
14    Ex(u32),
15}
16
17impl MouseButton {
18    pub const EX_LEN: u32 = 29;
19
20    fn as_u32(&self) -> u32 {
21        match self {
22            Self::Left => 0x01,
23            Self::Right => 0x01 << 1,
24            Self::Middle => 0x01 << 2,
25            Self::Ex(x) => 0x01 << (x + 3),
26        }
27    }
28}
29
30impl std::fmt::Display for MouseButton {
31    #[inline]
32    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33        write!(f, "{:?}", self)
34    }
35}
36
37#[derive(Clone, Copy, PartialEq, Eq, Hash)]
38pub struct MouseButtons(u32);
39
40impl MouseButtons {
41    #[inline]
42    pub fn new() -> Self {
43        Self(0)
44    }
45
46    #[inline]
47    pub fn is_empty(&self) -> bool {
48        self.0 == 0
49    }
50
51    #[inline]
52    pub fn contains(&self, button: MouseButton) -> bool {
53        let button = button.as_u32();
54        self.0 & button == button
55    }
56
57    pub fn to_vec(&self) -> Vec<MouseButton> {
58        let mut v = vec![];
59        if self.contains(MouseButton::Left) {
60            v.push(MouseButton::Left);
61        }
62        if self.contains(MouseButton::Right) {
63            v.push(MouseButton::Right);
64        }
65        if self.contains(MouseButton::Middle) {
66            v.push(MouseButton::Middle);
67        }
68        for i in 0..MouseButton::EX_LEN {
69            if self.contains(MouseButton::Ex(i)) {
70                v.push(MouseButton::Ex(i));
71            }
72        }
73        v
74    }
75}
76
77impl Default for MouseButtons {
78    #[inline]
79    fn default() -> Self {
80        Self::new()
81    }
82}
83
84impl std::fmt::Debug for MouseButtons {
85    #[inline]
86    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87        let v = self.to_vec();
88        write!(f, "{:?}", v)
89    }
90}
91
92impl std::fmt::Display for MouseButtons {
93    #[inline]
94    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95        write!(f, "{:?}", self)
96    }
97}
98
99impl std::ops::BitOr for MouseButton {
100    type Output = MouseButtons;
101
102    #[inline]
103    fn bitor(self, rhs: Self) -> Self::Output {
104        MouseButtons(self.as_u32() | rhs.as_u32())
105    }
106}
107
108impl std::ops::BitOr<MouseButtons> for MouseButton {
109    type Output = MouseButtons;
110
111    #[inline]
112    fn bitor(self, rhs: MouseButtons) -> Self::Output {
113        MouseButtons(self.as_u32() | rhs.0)
114    }
115}
116
117impl std::ops::BitOr<MouseButton> for MouseButtons {
118    type Output = MouseButtons;
119
120    #[inline]
121    fn bitor(self, rhs: MouseButton) -> Self::Output {
122        MouseButtons(self.0 | rhs.as_u32())
123    }
124}
125
126impl std::ops::BitOrAssign for MouseButtons {
127    #[inline]
128    fn bitor_assign(&mut self, rhs: Self) {
129        self.0 |= rhs.0;
130    }
131}
132
133impl std::ops::BitOrAssign<MouseButton> for MouseButtons {
134    #[inline]
135    fn bitor_assign(&mut self, rhs: MouseButton) {
136        self.0 |= rhs.as_u32();
137    }
138}
139
140impl<const N: usize> From<[MouseButton; N]> for MouseButtons {
141    #[inline]
142    fn from(value: [MouseButton; N]) -> Self {
143        value.iter().fold(MouseButtons::new(), |r, b| r | *b)
144    }
145}
146
147impl<const N: usize> From<&[MouseButton; N]> for MouseButtons {
148    #[inline]
149    fn from(value: &[MouseButton; N]) -> Self {
150        value.iter().fold(MouseButtons::new(), |r, b| r | *b)
151    }
152}
153
154impl From<&[MouseButton]> for MouseButtons {
155    #[inline]
156    fn from(value: &[MouseButton]) -> Self {
157        value.iter().fold(MouseButtons::new(), |r, b| r | *b)
158    }
159}
160
161impl From<Vec<MouseButton>> for MouseButtons {
162    #[inline]
163    fn from(value: Vec<MouseButton>) -> Self {
164        value.iter().fold(MouseButtons::new(), |r, b| r | *b)
165    }
166}
167
168impl From<&Vec<MouseButton>> for MouseButtons {
169    #[inline]
170    fn from(value: &Vec<MouseButton>) -> Self {
171        value.iter().fold(MouseButtons::new(), |r, b| r | *b)
172    }
173}
174
175#[cfg(windows)]
176impl From<WPARAM> for MouseButtons {
177    fn from(value: WPARAM) -> Self {
178        let flags = MODIFIERKEYS_FLAGS(value.0 as u32);
179        let mut buttons = MouseButtons::new();
180        if flags.contains(MK_LBUTTON) {
181            buttons.0 |= MouseButton::Left.as_u32();
182        } else if flags.contains(MK_RBUTTON) {
183            buttons.0 |= MouseButton::Right.as_u32();
184        } else if flags.contains(MK_MBUTTON) {
185            buttons.0 |= MouseButton::Middle.as_u32();
186        } else if flags.contains(MK_XBUTTON1) {
187            buttons.0 |= MouseButton::Ex(0).as_u32();
188        } else if flags.contains(MK_XBUTTON2) {
189            buttons.0 |= MouseButton::Ex(1).as_u32();
190        }
191        buttons
192    }
193}
194
195#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
196#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
197pub enum MouseWheelAxis {
198    Vertical,
199    Horizontal,
200}
201
202#[cfg(test)]
203mod tests {
204    use super::*;
205
206    #[test]
207    fn mouse_buttons_contains() {
208        let btns = MouseButtons(MouseButton::Left.as_u32());
209        assert!(btns.contains(MouseButton::Left));
210        assert!(!btns.contains(MouseButton::Right));
211    }
212
213    #[test]
214    fn mouse_buttons_bitor() {
215        let btns = MouseButton::Left | MouseButton::Right;
216        assert!(btns.contains(MouseButton::Left));
217        assert!(btns.contains(MouseButton::Right));
218        assert!(!btns.contains(MouseButton::Middle));
219        assert!(!btns.contains(MouseButton::Ex(0)));
220        let btns = btns | MouseButton::Middle;
221        assert!(btns.contains(MouseButton::Left));
222        assert!(btns.contains(MouseButton::Right));
223        assert!(btns.contains(MouseButton::Middle));
224        assert!(!btns.contains(MouseButton::Ex(0)));
225    }
226
227    #[test]
228    fn array_to_mouse_buttons() {
229        let a = [MouseButton::Left, MouseButton::Right];
230        let btns = MouseButtons::from(a);
231        assert!(btns.contains(MouseButton::Left));
232        assert!(btns.contains(MouseButton::Right));
233        assert!(!btns.contains(MouseButton::Middle));
234        assert!(!btns.contains(MouseButton::Ex(0)));
235        let btns = MouseButtons::from(a.as_slice());
236        assert!(btns.contains(MouseButton::Left));
237        assert!(btns.contains(MouseButton::Right));
238        assert!(!btns.contains(MouseButton::Middle));
239        assert!(!btns.contains(MouseButton::Ex(0)));
240        let v = vec![MouseButton::Left, MouseButton::Right];
241        let btns = MouseButtons::from(v);
242        assert!(btns.contains(MouseButton::Left));
243        assert!(btns.contains(MouseButton::Right));
244        assert!(!btns.contains(MouseButton::Middle));
245        assert!(!btns.contains(MouseButton::Ex(0)));
246        let v = vec![MouseButton::Left, MouseButton::Right];
247        let btns = MouseButtons::from(&v);
248        assert!(btns.contains(MouseButton::Left));
249        assert!(btns.contains(MouseButton::Right));
250        assert!(!btns.contains(MouseButton::Middle));
251        assert!(!btns.contains(MouseButton::Ex(0)));
252    }
253}