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}