1use bitflags::bitflags;
2use core::mem::{size_of, transmute};
3use static_assertions::const_assert_eq;
4
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8use crate::{Class, StateChange, ValueChange};
9
10#[derive(Clone, Copy, Debug)]
12pub struct Mouse;
13
14impl Class for Mouse {
15 type Input = MouseInput;
16 type Output = MouseOutput;
17
18 fn input(&self) -> Self::Input {
19 Self::Input::default()
20 }
21
22 fn output(&self) -> Self::Output {
23 Self::Output::default()
24 }
25}
26
27impl AsRef<str> for Mouse {
28 fn as_ref(&self) -> &str {
29 "mouse"
30 }
31}
32
33impl core::fmt::Display for Mouse {
34 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
35 f.write_str(self.as_ref())
36 }
37}
38
39bitflags! {
40 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
42 pub struct Buttons: u8 {
43 const Primary = 0x01;
47
48 const Secondary = 0x02;
52
53 const Tertiary = 0x04;
57 }
58}
59
60const_assert_eq!(size_of::<Buttons>(), 1);
61
62impl Default for Buttons {
63 fn default() -> Self {
64 Self::empty()
65 }
66}
67
68impl Buttons {
69 pub fn safe_from(raw: u8) -> Option<Self> {
71 Self::from_bits(raw)
72 }
73}
74
75impl From<Buttons> for u8 {
76 fn from(btns: Buttons) -> Self {
77 btns.bits()
78 }
79}
80
81code_enum! {
82 Button: u8 {
84 None = 0x00 => "none" | "0",
86
87 Primary = 0x01 => "primary" | "first" | "1",
91
92 Secondary = 0x02 => "secondary" | "second" | "2",
96
97 Tertiary = 0x03 => "tertiary" | "third" | "3",
101 }
102}
103
104impl From<Buttons> for Button {
105 fn from(mods: Buttons) -> Self {
106 let off = mods.bits().trailing_zeros() as u8;
107 if off < 3 {
108 Button::from(off + 1)
109 } else {
110 Button::None
111 }
112 }
113}
114
115impl From<Button> for Buttons {
116 fn from(key: Button) -> Self {
117 let code = key as u8;
118 Buttons::from_bits_retain(if code != 0 { 1 << (code - 1) } else { 0 })
119 }
120}
121
122impl Button {
123 pub fn safe_from(raw: u8) -> Option<Self> {
125 if raw <= 3 {
126 Some(From::from(raw))
127 } else {
128 None
129 }
130 }
131}
132
133impl Default for Button {
134 fn default() -> Self {
135 Self::None
136 }
137}
138
139serde_num! {
140 Buttons: u8, "a button mask";
141 Button: u8, "a numeric button code";
142}
143
144#[derive(Clone, Copy, Debug, Default)]
146#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
147#[repr(C, packed)]
148pub struct MouseInput {
149 #[cfg_attr(feature = "serde", serde(rename = "b"))]
151 button: Buttons,
152 #[cfg_attr(feature = "serde", serde(rename = "p"))]
154 pointer: (i16, i16),
155 #[cfg_attr(feature = "serde", serde(rename = "w"))]
157 wheel: i8,
158}
159
160const_assert_eq!(size_of::<MouseInput>(), 6);
161
162impl MouseInput {
163 pub fn mods(&self) -> Buttons {
165 self.button
166 }
167
168 pub fn count_pressed(&self) -> usize {
170 self.button.bits().count_ones() as _
171 }
172
173 pub fn pressed(&self) -> PressedButtons<'_> {
175 PressedButtons {
176 report: self,
177 element: 0,
178 }
179 }
180
181 pub fn change_buttons(&mut self, mask: Buttons, state: bool) {
183 if state {
184 self.button |= mask;
185 } else {
186 self.button &= !mask;
187 }
188 }
189
190 pub fn press_buttons(&mut self, mask: Buttons) {
192 self.change_buttons(mask, true);
193 }
194
195 pub fn release_buttons(&mut self, mask: Buttons) {
197 self.change_buttons(mask, false);
198 }
199
200 pub fn change_button(&mut self, code: Button, state: bool) {
202 self.change_buttons(code.into(), state);
203 }
204
205 pub fn press_button(&mut self, code: Button) {
207 self.change_button(code, true);
208 }
209
210 pub fn release_button(&mut self, code: Button) {
212 self.change_button(code, false);
213 }
214
215 pub fn pointer(&self) -> (i16, i16) {
217 self.pointer
218 }
219
220 pub fn set_pointer(&mut self, pointer: (i16, i16)) {
222 self.pointer = pointer;
223 }
224
225 pub fn change_pointer(&mut self, pointer: (i16, i16), relative: bool) {
227 if relative {
228 self.pointer = (self.pointer.0 + pointer.0, self.pointer.1 + pointer.1);
229 } else {
230 self.pointer = pointer;
231 }
232 }
233
234 pub fn wheel(&self) -> i8 {
236 self.wheel
237 }
238
239 pub fn set_wheel(&mut self, wheel: i8) {
241 self.wheel = wheel;
242 }
243
244 pub fn change_wheel(&mut self, wheel: i8, relative: bool) {
246 if relative {
247 self.wheel += wheel;
248 } else {
249 self.wheel = wheel;
250 }
251 }
252
253 pub fn change(&mut self, change: &MouseInputChange) {
255 match change {
256 MouseInputChange::Button(change) => self.change_button(**change, change.state()),
257 MouseInputChange::Pointer(change) => {
258 self.change_pointer(**change, change.is_relative())
259 }
260 MouseInputChange::Wheel(change) => self.change_wheel(**change, change.is_relative()),
261 }
262 }
263
264 pub fn diff<'i>(
268 &'i self,
269 other: &'i Self,
270 relative_pointer: bool,
271 relative_wheel: bool,
272 ) -> MouseInputChanges<'i> {
273 MouseInputChanges {
274 new: self,
275 old: other,
276 element: 0,
277 relative_pointer,
278 relative_wheel,
279 }
280 }
281}
282
283impl<'i> core::ops::Sub<&'i MouseInput> for &'i MouseInput {
284 type Output = MouseInputChanges<'i>;
285
286 fn sub(self, other: Self) -> Self::Output {
287 self.diff(other, false, false)
288 }
289}
290
291#[derive(Clone, Copy, Debug, PartialEq, Eq)]
293pub enum MouseInputChange {
294 Button(StateChange<Button>),
296 Pointer(ValueChange<(i16, i16)>),
298 Wheel(ValueChange<i8>),
300}
301
302pub struct MouseInputChanges<'i> {
304 new: &'i MouseInput,
305 old: &'i MouseInput,
306 element: u8,
307 relative_pointer: bool,
308 relative_wheel: bool,
309}
310
311impl<'i> Iterator for MouseInputChanges<'i> {
312 type Item = MouseInputChange;
313
314 fn next(&mut self) -> Option<Self::Item> {
315 loop {
316 if self.element < 8 {
317 let buttons = Buttons::from_bits_retain(1 << self.element);
319 self.element += 1;
320 if Buttons::empty() != ((self.new.button ^ self.old.button) & buttons) {
321 let button = Button::from(buttons);
322 let old_button = Button::from(self.old.button & buttons);
323 return Some(MouseInputChange::Button(StateChange::new(
324 button,
325 matches!(old_button, Button::None),
326 )));
327 }
328 } else if self.element < 9 {
329 self.element += 1;
331 if self.new.pointer.0 != self.old.pointer.0
332 || self.new.pointer.1 != self.old.pointer.1
333 {
334 return Some(MouseInputChange::Pointer(ValueChange::new(
335 if self.relative_pointer {
336 (
337 self.new.pointer.0 - self.old.pointer.0,
338 self.new.pointer.1 - self.old.pointer.1,
339 )
340 } else {
341 (self.new.pointer.0, self.new.pointer.1)
342 },
343 self.relative_pointer,
344 )));
345 }
346 } else if self.element < 10 {
347 self.element += 1;
348 if self.new.wheel != self.old.wheel {
349 return Some(MouseInputChange::Wheel(ValueChange::new(
350 if self.relative_wheel {
351 self.new.wheel - self.old.wheel
352 } else {
353 self.new.wheel
354 },
355 self.relative_wheel,
356 )));
357 }
358 } else {
359 return None;
360 }
361 }
362 }
363}
364
365impl Extend<StateChange<Buttons>> for MouseInput {
366 fn extend<T>(&mut self, iter: T)
367 where
368 T: IntoIterator<Item = StateChange<Buttons>>,
369 {
370 for StateChange { data, state } in iter {
371 self.change_buttons(data, state);
372 }
373 }
374}
375
376impl Extend<StateChange<Button>> for MouseInput {
377 fn extend<T>(&mut self, iter: T)
378 where
379 T: IntoIterator<Item = StateChange<Button>>,
380 {
381 for StateChange { data, state } in iter {
382 self.change_button(data, state);
383 }
384 }
385}
386
387impl Extend<ValueChange<(i16, i16)>> for MouseInput {
388 fn extend<T>(&mut self, iter: T)
389 where
390 T: IntoIterator<Item = ValueChange<(i16, i16)>>,
391 {
392 for ValueChange { data, relative } in iter {
393 self.change_pointer(data, relative);
394 }
395 }
396}
397
398impl Extend<(i16, i16)> for MouseInput {
399 fn extend<T>(&mut self, iter: T)
400 where
401 T: IntoIterator<Item = (i16, i16)>,
402 {
403 for data in iter {
404 self.set_pointer(data);
405 }
406 }
407}
408
409impl Extend<ValueChange<i8>> for MouseInput {
410 fn extend<T>(&mut self, iter: T)
411 where
412 T: IntoIterator<Item = ValueChange<i8>>,
413 {
414 for ValueChange { data, relative } in iter {
415 self.change_wheel(data, relative)
416 }
417 }
418}
419
420impl Extend<MouseInput> for MouseInput {
421 fn extend<T>(&mut self, iter: T)
422 where
423 T: IntoIterator<Item = MouseInput>,
424 {
425 for item in iter {
426 *self = item;
427 }
428 }
429}
430
431pub struct PressedButtons<'i> {
433 report: &'i MouseInput,
434 element: u8,
435}
436
437impl<'i> Iterator for PressedButtons<'i> {
438 type Item = Button;
439
440 fn next(&mut self) -> Option<Self::Item> {
441 while self.element < 8 {
442 let mask = Buttons::from_bits_retain(1u8 << self.element);
443 self.element += 1;
444 if self.report.button.contains(mask) {
445 return Some(mask.into());
446 }
447 }
448 None
449 }
450}
451
452#[derive(Clone, Copy, Debug, Default)]
454#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
455#[repr(C, packed)]
456pub struct MouseOutput {}
457
458const_assert_eq!(size_of::<MouseOutput>(), 0);
459
460raw_ref! {
461 Buttons;
462 Button;
463 MouseInput;
464 MouseOutput;
465}
466
467#[cfg(test)]
468mod test {
469 use super::*;
470
471 #[test]
472 fn button_mask_to_code() {
473 assert_eq!(Button::from(Buttons::default()), Button::None);
474 assert_eq!(Button::from(Buttons::empty()), Button::None);
475 assert_eq!(Button::from(Buttons::Primary), Button::Primary);
476 assert_eq!(Button::from(Buttons::Secondary), Button::Secondary);
477 assert_eq!(Button::from(Buttons::Tertiary), Button::Tertiary);
478 }
479
480 #[test]
481 fn button_code_to_mask() {
482 assert_eq!(Buttons::from(Button::None), Buttons::default());
483 assert_eq!(Buttons::from(Button::Primary), Buttons::Primary);
484 assert_eq!(Buttons::from(Button::Secondary), Buttons::Secondary);
485 assert_eq!(Buttons::from(Button::Tertiary), Buttons::Tertiary);
486 }
487
488 #[test]
489 fn mouse_input_diff() {
490 let mut old = MouseInput::default();
491
492 old.press_button(Button::Primary);
493 old.press_button(Button::Tertiary);
494 old.set_pointer((120, 450));
495 old.set_wheel(7);
496
497 let mut new = MouseInput::default();
498
499 new.press_button(Button::Tertiary);
500 new.press_button(Button::Secondary);
501 new.set_pointer((120, 150));
502 new.set_wheel(-1);
503
504 let mut changes = &new - &old;
505
506 assert_eq!(
507 changes.next(),
508 Some(MouseInputChange::Button(StateChange::release(
509 Button::Primary
510 )))
511 );
512 assert_eq!(
513 changes.next(),
514 Some(MouseInputChange::Button(StateChange::press(
515 Button::Secondary
516 )))
517 );
518 assert_eq!(
519 changes.next(),
520 Some(MouseInputChange::Pointer(ValueChange::new(
521 (120, 150),
522 false
523 )))
524 );
525 assert_eq!(
526 changes.next(),
527 Some(MouseInputChange::Wheel(ValueChange::new(-1, false)))
528 );
529 assert_eq!(changes.next(), None);
530
531 new.release_button(Button::Secondary);
532 new.set_wheel(7);
533
534 let mut changes = new.diff(&old, true, true);
535
536 assert_eq!(
537 changes.next(),
538 Some(MouseInputChange::Button(StateChange::release(
539 Button::Primary
540 )))
541 );
542 assert_eq!(
543 changes.next(),
544 Some(MouseInputChange::Pointer(ValueChange::new((0, -300), true)))
545 );
546 assert_eq!(changes.next(), None);
547 }
548}