1use crate::{Event, Input, Motion};
4
5#[derive(Copy, Clone, Deserialize, Serialize, PartialEq, Eq, Ord, PartialOrd, Hash, Debug)]
7pub enum MouseButton {
8 Unknown,
10 Left,
12 Right,
14 Middle,
16 X1,
18 X2,
20 Button6,
22 Button7,
24 Button8,
26}
27
28impl From<u32> for MouseButton {
29 fn from(n: u32) -> MouseButton {
30 match n {
31 0 => MouseButton::Unknown,
32 1 => MouseButton::Left,
33 2 => MouseButton::Right,
34 3 => MouseButton::Middle,
35 4 => MouseButton::X1,
36 5 => MouseButton::X2,
37 6 => MouseButton::Button6,
38 7 => MouseButton::Button7,
39 8 => MouseButton::Button8,
40 _ => MouseButton::Unknown,
41 }
42 }
43}
44
45impl From<MouseButton> for u32 {
46 fn from(button: MouseButton) -> u32 {
47 match button {
48 MouseButton::Unknown => 0,
49 MouseButton::Left => 1,
50 MouseButton::Right => 2,
51 MouseButton::Middle => 3,
52 MouseButton::X1 => 4,
53 MouseButton::X2 => 5,
54 MouseButton::Button6 => 6,
55 MouseButton::Button7 => 7,
56 MouseButton::Button8 => 8,
57 }
58 }
59}
60
61#[cfg(test)]
62mod mouse_button_tests {
63 use super::*;
64
65 #[test]
66 fn test_mouse_button_primitives() {
67 for i in 0u32..9 {
68 let button: MouseButton = i.into();
69 let j: u32 = button.into();
70 assert_eq!(i, j);
71 }
72 }
73}
74
75pub trait MouseCursorEvent: Sized {
77 fn from_pos(pos: [f64; 2], old_event: &Self) -> Option<Self>;
81 fn mouse_cursor<U, F>(&self, f: F) -> Option<U>
83 where
84 F: FnMut([f64; 2]) -> U;
85 fn mouse_cursor_args(&self) -> Option<[f64; 2]> {
87 self.mouse_cursor(|pos| pos)
88 }
89}
90
91impl MouseCursorEvent for Event {
92 fn from_pos(pos: [f64; 2], old_event: &Self) -> Option<Self> {
93 let timestamp = if let Event::Input(_, x) = old_event {
94 *x
95 } else {
96 None
97 };
98 Some(Event::Input(
99 Input::Move(Motion::MouseCursor(pos)),
100 timestamp,
101 ))
102 }
103
104 fn mouse_cursor<U, F>(&self, mut f: F) -> Option<U>
105 where
106 F: FnMut([f64; 2]) -> U,
107 {
108 match *self {
109 Event::Input(Input::Move(Motion::MouseCursor(pos)), _) => Some(f(pos)),
110 _ => None,
111 }
112 }
113}
114
115pub trait MouseRelativeEvent: Sized {
119 fn from_pos(x: [f64; 2], old_event: &Self) -> Option<Self>;
123 fn mouse_relative<U, F>(&self, f: F) -> Option<U>
125 where
126 F: FnMut([f64; 2]) -> U;
127 fn mouse_relative_args(&self) -> Option<[f64; 2]> {
129 self.mouse_relative(|pos| pos)
130 }
131}
132
133impl MouseRelativeEvent for Event {
134 fn from_pos(pos: [f64; 2], old_event: &Self) -> Option<Self> {
135 let timestamp = if let Event::Input(_, x) = old_event {
136 *x
137 } else {
138 None
139 };
140 Some(Event::Input(
141 Input::Move(Motion::MouseRelative(pos)),
142 timestamp,
143 ))
144 }
145
146 fn mouse_relative<U, F>(&self, mut f: F) -> Option<U>
147 where
148 F: FnMut([f64; 2]) -> U,
149 {
150 match *self {
151 Event::Input(Input::Move(Motion::MouseRelative(pos)), _) => Some(f(pos)),
152 _ => None,
153 }
154 }
155}
156
157pub trait MouseScrollEvent: Sized {
159 fn from_pos(pos: [f64; 2], old_event: &Self) -> Option<Self>;
163 fn mouse_scroll<U, F>(&self, f: F) -> Option<U>
165 where
166 F: FnMut([f64; 2]) -> U;
167 fn mouse_scroll_args(&self) -> Option<[f64; 2]> {
169 self.mouse_scroll(|pos| pos)
170 }
171}
172
173impl MouseScrollEvent for Event {
174 fn from_pos(pos: [f64; 2], old_event: &Self) -> Option<Self> {
175 let timestamp = if let Event::Input(_, x) = old_event {
176 *x
177 } else {
178 None
179 };
180 Some(Event::Input(
181 Input::Move(Motion::MouseScroll(pos)),
182 timestamp,
183 ))
184 }
185
186 fn mouse_scroll<U, F>(&self, mut f: F) -> Option<U>
187 where
188 F: FnMut([f64; 2]) -> U,
189 {
190 match *self {
191 Event::Input(Input::Move(Motion::MouseScroll(pos)), _) => Some(f(pos)),
192 _ => None,
193 }
194 }
195}
196
197#[cfg(test)]
198mod mouse_event_tests {
199 use super::*;
200
201 #[test]
202 fn test_input_mouse_cursor() {
203 use super::super::Motion;
204
205 let e: Event = Motion::MouseCursor([0.0, 0.0]).into();
206 let a: Option<Event> = MouseCursorEvent::from_pos([1.0, 0.0], &e);
207 let b: Option<Event> = a
208 .clone()
209 .unwrap()
210 .mouse_cursor(|pos| MouseCursorEvent::from_pos(pos, a.as_ref().unwrap()))
211 .unwrap();
212 assert_eq!(a, b);
213 }
214
215 #[test]
216 fn test_input_mouse_relative() {
217 use super::super::Motion;
218
219 let e: Event = Motion::MouseRelative([0.0, 0.0]).into();
220 let a: Option<Event> = MouseRelativeEvent::from_pos([1.0, 0.0], &e);
221 let b: Option<Event> = a
222 .clone()
223 .unwrap()
224 .mouse_relative(|pos| MouseRelativeEvent::from_pos(pos, a.as_ref().unwrap()))
225 .unwrap();
226 assert_eq!(a, b);
227 }
228
229 #[test]
230 fn test_input_mouse_scroll() {
231 use super::super::Motion;
232
233 let e: Event = Motion::MouseScroll([0.0, 0.0]).into();
234 let a: Option<Event> = MouseScrollEvent::from_pos([1.0, 0.0], &e);
235 let b: Option<Event> = a
236 .clone()
237 .unwrap()
238 .mouse_scroll(|pos| MouseScrollEvent::from_pos(pos, a.as_ref().unwrap()))
239 .unwrap();
240 assert_eq!(a, b);
241 }
242}