Skip to main content

rmk_types/
mouse_button.rs

1//! Mouse button state and operations.
2//!
3//! This module handles mouse button combinations and states, supporting up to
4//! 8 mouse buttons.
5use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not};
6
7use bitfield_struct::bitfield;
8use postcard::experimental::max_size::MaxSize;
9
10/// Mouse buttons
11#[bitfield(u8, order = Lsb, defmt = cfg(feature = "defmt"))]
12#[derive(Eq, PartialEq, MaxSize)]
13pub struct MouseButtons {
14    #[bits(1)]
15    pub button1: bool, //left
16    #[bits(1)]
17    pub button2: bool, //right
18    #[bits(1)]
19    pub button3: bool, //middle
20    #[bits(1)]
21    pub button4: bool,
22    #[bits(1)]
23    pub button5: bool,
24    #[bits(1)]
25    pub button6: bool,
26    #[bits(1)]
27    pub button7: bool,
28    #[bits(1)]
29    pub button8: bool,
30}
31
32// u8 on the wire (postcard); named bools on serde-wasm-bindgen / serde_json (TS).
33crate::bitfield_named_serde!(MouseButtons, "MouseButtons", {
34    button1 = with_button1,
35    button2 = with_button2,
36    button3 = with_button3,
37    button4 = with_button4,
38    button5 = with_button5,
39    button6 = with_button6,
40    button7 = with_button7,
41    button8 = with_button8,
42});
43
44impl BitOr for MouseButtons {
45    type Output = Self;
46
47    fn bitor(self, rhs: Self) -> Self::Output {
48        Self::from_bits(self.into_bits() | rhs.into_bits())
49    }
50}
51impl BitAnd for MouseButtons {
52    type Output = Self;
53
54    fn bitand(self, rhs: Self) -> Self::Output {
55        Self::from_bits(self.into_bits() & rhs.into_bits())
56    }
57}
58impl Not for MouseButtons {
59    type Output = Self;
60
61    fn not(self) -> Self::Output {
62        Self::from_bits(!self.into_bits())
63    }
64}
65impl BitAndAssign for MouseButtons {
66    fn bitand_assign(&mut self, rhs: Self) {
67        *self = *self & rhs;
68    }
69}
70impl BitOrAssign for MouseButtons {
71    fn bitor_assign(&mut self, rhs: Self) {
72        *self = *self | rhs;
73    }
74}
75
76impl MouseButtons {
77    pub const BUTTON1: Self = Self::new().with_button1(true);
78    pub const BUTTON2: Self = Self::new().with_button2(true);
79    pub const BUTTON3: Self = Self::new().with_button3(true);
80    pub const BUTTON4: Self = Self::new().with_button4(true);
81    pub const BUTTON5: Self = Self::new().with_button5(true);
82    pub const BUTTON6: Self = Self::new().with_button6(true);
83    pub const BUTTON7: Self = Self::new().with_button7(true);
84    pub const BUTTON8: Self = Self::new().with_button8(true);
85
86    #[allow(clippy::too_many_arguments)]
87    pub const fn new_from(
88        button1: bool,
89        button2: bool,
90        button3: bool,
91        button4: bool,
92        button5: bool,
93        button6: bool,
94        button7: bool,
95        button8: bool,
96    ) -> Self {
97        Self::new()
98            .with_button1(button1)
99            .with_button2(button2)
100            .with_button3(button3)
101            .with_button4(button4)
102            .with_button5(button5)
103            .with_button6(button6)
104            .with_button7(button7)
105            .with_button8(button8)
106    }
107}