web_sys_main_loop/input_handler/
mouse_state.rs

1// Copyright 2024 arongeo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/// The possible buttons that can be pressed on a mouse.
16#[derive(PartialEq, Eq)]
17pub enum MouseButton {
18    None,
19    Left,
20    Right,
21    Scroll,
22    Misc1,
23    Misc2,
24}
25
26/// Contains the state of the mouse
27/// in the current frame
28#[derive(Copy, Clone)]
29pub struct MouseState {
30    pub(crate) buttons_pressed: u8,
31    pub(crate) position: (i32, i32),
32    pub(crate) movement: (i32, i32),
33    pub(crate) offset: (i32, i32),
34}
35
36impl MouseState {
37    pub(crate) fn new() -> Self {
38        Self {
39            buttons_pressed: 0,
40            position: (0, 0),
41            movement: (0, 0),
42            offset: (0, 0),
43        }
44    }
45
46    /// Gets the currently pressed buttons on the mouse
47    pub fn get_pressed_buttons(&self) -> Option<Vec<MouseButton>> {
48        if self.buttons_pressed == 0 {
49            return None;
50        }
51
52        let mut iter_num = 0;
53        let mut buttons_pressed = self.buttons_pressed;
54        let mut buttons = Vec::new();
55
56        while iter_num < 5 {
57            if (buttons_pressed & (1 << iter_num)) == 1 {
58                buttons.push(match iter_num {
59                    0 => MouseButton::Left,
60                    1 => MouseButton::Right,
61                    2 => MouseButton::Scroll,
62                    3 => MouseButton::Misc1,
63                    4 => MouseButton::Misc2,
64                    _ => MouseButton::None,
65                });
66            }
67
68            buttons_pressed /= 2;
69            iter_num += 1;
70        }
71
72        return Some(buttons);
73    }
74
75    /// Gets the position (X, Y) of the cursor in the web_sys window
76    ///
77    /// [MDN Web Docs clientX property](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientX)
78    ///
79    /// [MDN Web Docs clientY property](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientY)
80    pub fn get_position(&self) -> (i32, i32) {
81        self.position
82    }
83
84    /// Gets the movement (X, Y) of the cursor between the
85    /// last mouse event and the current one.
86    ///
87    /// [MDN Web Docs movementX property](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX)
88    ///
89    /// [MDN Web Docs movementY property](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX)
90    pub fn get_movement(&self) -> (i32, i32) {
91        self.movement
92    }
93
94    /// Gets the offset (X, Y) between of the cursor between the
95    /// event which caused it and the padding edge of the
96    /// target node.
97    ///
98    /// [MDN Web Docs offsetX property](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/offsetX)
99    ///
100    /// [MDN Web Docs offsetY property](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/offsetY)
101    pub fn get_offset(&self) -> (i32, i32) {
102        self.offset
103    }
104
105    pub(crate) fn copy(&self) -> Self {
106        Self {
107            buttons_pressed: self.buttons_pressed,
108            position: self.position,
109            offset: self.offset,
110            movement: self.movement,
111        }
112    }
113}