sdl3/mouse/
relative.rs

1use crate::EventPump;
2
3use crate::sys;
4
5use super::{MouseButton, MouseButtonIterator, PressedMouseButtonIterator};
6
7#[derive(Copy, Clone, PartialEq)]
8pub struct RelativeMouseState {
9    mouse_state: u32,
10    x: f32,
11    y: f32,
12}
13
14impl RelativeMouseState {
15    #[doc(alias = "SDL_GetRelativeMouseState")]
16    pub fn new(_e: &EventPump) -> RelativeMouseState {
17        let mut x = 0.;
18        let mut y = 0.;
19        let mouse_state = unsafe {
20            // This call is the only difference between MouseState
21            sys::mouse::SDL_GetRelativeMouseState(&mut x, &mut y).0
22        };
23
24        RelativeMouseState { mouse_state, x, y }
25    }
26
27    pub fn from_sdl_state(state: u32) -> RelativeMouseState {
28        RelativeMouseState {
29            mouse_state: state,
30            x: 0.,
31            y: 0.,
32        }
33    }
34    pub fn to_sdl_state(&self) -> u32 {
35        self.mouse_state
36    }
37
38    fn button_mask(&self, button: i32) -> u32 {
39        1 << (button - 1)
40    }
41
42    /// Returns true if the left mouse button is pressed.
43    ///
44    /// # Example
45    /// ```no_run
46    /// use sdl3::mouse::MouseButton;
47    ///
48    /// fn is_a_pressed(e: &sdl3::EventPump) -> bool {
49    ///     e.mouse_state().left()
50    /// }
51    /// ```
52    pub fn left(&self) -> bool {
53        (self.mouse_state & self.button_mask(sys::mouse::SDL_BUTTON_LEFT)) != 0
54    }
55
56    /// Tests if the middle mouse button was pressed.
57    pub fn middle(&self) -> bool {
58        (self.mouse_state & self.button_mask(sys::mouse::SDL_BUTTON_MIDDLE)) != 0
59    }
60
61    /// Tests if the right mouse button was pressed.
62    pub fn right(&self) -> bool {
63        (self.mouse_state & self.button_mask(sys::mouse::SDL_BUTTON_RIGHT)) != 0
64    }
65
66    /// Tests if the X1 mouse button was pressed.
67    pub fn x1(&self) -> bool {
68        (self.mouse_state & self.button_mask(sys::mouse::SDL_BUTTON_X1)) != 0
69    }
70
71    /// Tests if the X2 mouse button was pressed.
72    pub fn x2(&self) -> bool {
73        (self.mouse_state & self.button_mask(sys::mouse::SDL_BUTTON_X2)) != 0
74    }
75
76    /// Returns the x coordinate of the state
77    pub fn x(&self) -> f32 {
78        self.x
79    }
80
81    /// Returns the y coordinate of the state
82    pub fn y(&self) -> f32 {
83        self.y
84    }
85
86    /// Returns true if the mouse button is pressed.
87    ///
88    /// # Example
89    /// ```no_run
90    /// use sdl3::mouse::MouseButton;
91    ///
92    /// fn is_left_pressed(e: &sdl3::EventPump) -> bool {
93    ///     e.mouse_state().is_mouse_button_pressed(MouseButton::Left)
94    /// }
95    /// ```
96    pub fn is_mouse_button_pressed(&self, mouse_button: MouseButton) -> bool {
97        let mask = 1 << ((mouse_button as u32) - 1);
98        self.mouse_state & mask != 0
99    }
100
101    /// Returns an iterator all mouse buttons with a boolean indicating if the scancode is pressed.
102    ///
103    /// # Example
104    /// ```no_run
105    /// use sdl3::mouse::MouseButton;
106    /// use std::collections::HashMap;
107    ///
108    /// fn mouse_button_set(e: &sdl3::EventPump) -> HashMap<MouseButton, bool> {
109    ///     e.mouse_state().mouse_buttons().collect()
110    /// }
111    ///
112    /// fn find_first_pressed(e: &sdl3::EventPump) -> bool {
113    ///     for (key,value) in mouse_button_set(e) {
114    ///         return value != false
115    ///     }
116    ///     false
117    /// }
118    ///
119    /// ```
120    pub fn mouse_buttons(&self) -> MouseButtonIterator<'_> {
121        MouseButtonIterator {
122            cur_button: 1,
123            mouse_state: &self.mouse_state,
124        }
125    }
126
127    /// Returns an iterator of pressed mouse buttons.
128    ///
129    /// # Example
130    /// ```no_run
131    /// use sdl3::mouse::MouseButton;
132    /// use std::collections::HashSet;
133    ///
134    /// fn pressed_mouse_button_set(e: &sdl3::EventPump) -> HashSet<MouseButton> {
135    ///     e.mouse_state().pressed_mouse_buttons().collect()
136    /// }
137    ///
138    /// fn newly_pressed(old: &HashSet<MouseButton>, new: &HashSet<MouseButton>) -> HashSet<MouseButton> {
139    ///     new - old
140    ///     // sugar for: new.difference(old).collect()
141    /// }
142    /// ```
143    pub fn pressed_mouse_buttons(&self) -> PressedMouseButtonIterator<'_> {
144        PressedMouseButtonIterator {
145            iter: self.mouse_buttons(),
146        }
147    }
148}