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}