From 2295e440e04e25af218cdbac242524302824c3b4 Mon Sep 17 00:00:00 2001 From: Luke Jones Date: Sat, 19 Nov 2016 08:18:43 +1300 Subject: [PATCH] Further changes: - `MouseState` now contains the x,y coordinates - removal of `mousestate()` from `MouseUtil`, `MouseState` contains x,y by default now - `RelativeMouseState` is a new struct and function set which is exactly the same as `MouseState`, except if calls (raw sdl)`SDL_GetRelativeMouseState` on construction - removal of `relative_mouse_state()` from `MouseUtil`, see above. - move mouse functionality in to `/sdl2/mouse/`, split `RelativeMouseState` in to own file; the main reason for this is to make tests easier to write/work with - add additional tests for button iterators - add `EventPump::relative_mouse_state()` to complement `mouse_state()` --- src/sdl2/event.rs | 31 ++-- src/sdl2/mouse.rs | 385 ---------------------------------------------- 2 files changed, 18 insertions(+), 398 deletions(-) delete mode 100644 src/sdl2/mouse.rs diff --git a/src/sdl2/event.rs b/src/sdl2/event.rs index 8164784c..82b31b3e 100644 --- a/src/sdl2/event.rs +++ b/src/sdl2/event.rs @@ -23,7 +23,7 @@ use keyboard::Mod; use sys::keycode::SDL_Keymod; use keyboard::Keycode; use mouse; -use mouse::{Mousebutton, MouseState, MouseWheelDirection}; +use mouse::{MouseButton, MouseState, MouseWheelDirection}; use keyboard::Scancode; use get_error; @@ -510,7 +510,7 @@ pub enum Event { timestamp: u32, window_id: u32, which: u32, - mouse_btn: Option, + mouse_btn: Option, x: i32, y: i32 }, @@ -518,7 +518,7 @@ pub enum Event { timestamp: u32, window_id: u32, which: u32, - mouse_btn: Option, + mouse_btn: Option, x: i32, y: i32 }, @@ -755,9 +755,9 @@ fn mk_keysym(scancode: Option, } } -/// Helper function is only to unwrap a mousebutton to u8 -fn mk_mousesym(mousebutton: Option) -> u8 { - mousebutton.unwrap().to_ll().unwrap() +/// Helper function is only to unwrap a mouse_button to u8 +fn mk_mouse_button(mouse_button: Option) -> u8 { + mouse_button.unwrap().to_ll().unwrap() } // TODO: Remove this when from_utf8 is updated in Rust @@ -901,7 +901,7 @@ impl Event { x, y } => { - let button = mk_mousesym(mouse_btn); + let button = mk_mouse_button(mouse_btn); let event = ll::SDL_MouseButtonEvent { type_: ll::SDL_MOUSEBUTTONDOWN, timestamp: timestamp, @@ -927,7 +927,7 @@ impl Event { x, y } => { - let button = mk_mousesym(mouse_btn); + let button = mk_mouse_button(mouse_btn); let event = ll::SDL_MouseButtonEvent { type_: ll::SDL_MOUSEBUTTONUP, timestamp: timestamp, @@ -1374,7 +1374,7 @@ impl Event { timestamp: event.timestamp, window_id: event.windowID, which: event.which, - mouse_btn: mouse::Mousebutton::from_ll(event.button), + mouse_btn: mouse::MouseButton::from_ll(event.button), x: event.x, y: event.y } @@ -1386,7 +1386,7 @@ impl Event { timestamp: event.timestamp, window_id: event.windowID, which: event.which, - mouse_btn: mouse::Mousebutton::from_ll(event.button), + mouse_btn: mouse::MouseButton::from_ll(event.button), x: event.x, y: event.y } @@ -1794,6 +1794,11 @@ impl ::EventPump { pub fn mouse_state(&self) -> ::mouse::MouseState { ::mouse::MouseState::new(self) } + + #[inline] + pub fn relative_mouse_state(&self) -> ::mouse::RelativeMouseState { + ::mouse::RelativeMouseState::new(self) + } } /// An iterator that calls `EventPump::poll_event()`. @@ -1837,7 +1842,7 @@ mod test { use super::WindowEventId; use super::super::controller::{Button, Axis}; use super::super::joystick::{HatState}; - use super::super::mouse::{Mousebutton, MouseState, MouseWheelDirection}; + use super::super::mouse::{MouseButton, MouseState, MouseWheelDirection}; use super::super::keyboard::{Keycode, Scancode, Mod}; // Tests a round-trip conversion from an Event type to @@ -1904,7 +1909,7 @@ mod test { timestamp: 5634, window_id: 2, which: 0, - mouse_btn: Some(Mousebutton::Left), + mouse_btn: Some(MouseButton::Left), x: 543, y: 345, }; @@ -1916,7 +1921,7 @@ mod test { timestamp: 0, window_id: 2, which: 0, - mouse_btn: Some(Mousebutton::Left), + mouse_btn: Some(MouseButton::Left), x: 543, y: 345, diff --git a/src/sdl2/mouse.rs b/src/sdl2/mouse.rs deleted file mode 100644 index fdb2262d..00000000 --- a/src/sdl2/mouse.rs +++ /dev/null @@ -1,385 +0,0 @@ -use num::{ToPrimitive, FromPrimitive}; -use std::ptr; - -use get_error; -use surface::SurfaceRef; -use video; -// -use EventPump; - -use sys::mouse as ll; - -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -#[repr(u32)] -pub enum SystemCursor { - Arrow = ll::SDL_SYSTEM_CURSOR_ARROW, - IBeam = ll::SDL_SYSTEM_CURSOR_IBEAM, - Wait = ll::SDL_SYSTEM_CURSOR_WAIT, - Crosshair = ll::SDL_SYSTEM_CURSOR_CROSSHAIR, - WaitArrow = ll::SDL_SYSTEM_CURSOR_WAITARROW, - SizeNWSE = ll::SDL_SYSTEM_CURSOR_SIZENWSE, - SizeNESW = ll::SDL_SYSTEM_CURSOR_SIZENESW, - SizeWE = ll::SDL_SYSTEM_CURSOR_SIZEWE, - SizeNS = ll::SDL_SYSTEM_CURSOR_SIZENS, - SizeAll = ll::SDL_SYSTEM_CURSOR_SIZEALL, - No = ll::SDL_SYSTEM_CURSOR_NO, - Hand = ll::SDL_SYSTEM_CURSOR_HAND, -} - -pub struct Cursor { - raw: *mut ll::SDL_Cursor -} - -impl Drop for Cursor { - #[inline] - fn drop(&mut self) { - unsafe { ll::SDL_FreeCursor(self.raw) }; - } -} - -impl Cursor { - pub fn new(data: &[u8], mask: &[u8], width: i32, height: i32, hot_x: i32, hot_y: i32) -> Result { - unsafe { - let raw = ll::SDL_CreateCursor(data.as_ptr(), - mask.as_ptr(), - width as i32, height as i32, - hot_x as i32, hot_y as i32); - - if raw == ptr::null_mut() { - Err(get_error()) - } else { - Ok(Cursor{ raw: raw }) - } - } - } - - // TODO: figure out how to pass Surface in here correctly - pub fn from_surface>(surface: S, hot_x: i32, hot_y: i32) -> Result { - unsafe { - let raw = ll::SDL_CreateColorCursor(surface.as_ref().raw(), hot_x, hot_y); - - if raw == ptr::null_mut() { - Err(get_error()) - } else { - Ok(Cursor{ raw: raw }) - } - } - } - - pub fn from_system(cursor: SystemCursor) -> Result { - unsafe { - let raw = ll::SDL_CreateSystemCursor(cursor as u32); - - if raw == ptr::null_mut() { - Err(get_error()) - } else { - Ok(Cursor{ raw: raw }) - } - } - } - - pub fn set(&self) { - unsafe { ll::SDL_SetCursor(self.raw); } - } -} - -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -pub enum MouseWheelDirection { - Normal, - Flipped, - Unknown(u32), -} - -// 0 and 1 are not fixed values in the SDL source code. This value is defined as an enum which is then cast to a Uint32. -// The enum in C is defined as such: - -/** - * \brief Scroll direction types for the Scroll event - */ -//typedef enum -//{ -// SDL_MOUSEWHEEL_NORMAL, /**< The scroll direction is normal */ -// SDL_MOUSEWHEEL_FLIPPED /**< The scroll direction is flipped / natural */ -//} SDL_MouseWheelDirection; - -// Since no value is given in the enum definition these values are auto assigned by the C compiler starting at 0. -// Normally I would prefer to use the enum rather than hard code what it is implied to represent however -// the mouse wheel direction value could be described equally as well by a bool, so I don't think changes -// to this enum in the C source code are going to be a problem. - -impl MouseWheelDirection { - #[inline] - pub fn from_ll(direction: u32) -> MouseWheelDirection { - match direction { - 0 => MouseWheelDirection::Normal, - 1 => MouseWheelDirection::Flipped, - _ => MouseWheelDirection::Unknown(direction), - } - } - #[inline] - pub fn to_ll(&self) -> u32 { - match *self { - MouseWheelDirection::Normal => 0, - MouseWheelDirection::Flipped => 1, - MouseWheelDirection::Unknown(direction) => direction, - } - } -} - -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -pub enum Mousebutton { - Left = ll::SDL_BUTTON_LEFT as isize, - Middle = ll::SDL_BUTTON_MIDDLE as isize, - Right = ll::SDL_BUTTON_RIGHT as isize, - X1 = ll::SDL_BUTTON_X1 as isize, - X2 = ll::SDL_BUTTON_X2 as isize, -} - -impl ToPrimitive for Mousebutton { - #[inline] - fn to_i64(&self) -> Option { - Some(*self as i64) - } - - #[inline] - fn to_u64(&self) -> Option { - Some(*self as u64) - } - - #[inline] - fn to_isize(&self) -> Option { - Some(*self as isize) - } -} - -impl FromPrimitive for Mousebutton { - #[inline] - fn from_i64(n: i64) -> Option { Mousebutton::from_ll(n as u8) } - #[inline] - fn from_u64(n: u64) -> Option { Mousebutton::from_ll(n as u8) } -} - -impl Mousebutton { - #[inline] - pub fn from_ll(button: u8) -> Option { - Some(match button { - ll::SDL_BUTTON_LEFT => Mousebutton::Left, - ll::SDL_BUTTON_MIDDLE => Mousebutton::Middle, - ll::SDL_BUTTON_RIGHT => Mousebutton::Right, - ll::SDL_BUTTON_X1 => Mousebutton::X1, - ll::SDL_BUTTON_X2 => Mousebutton::X2, - _ => return None, - }) - } - #[inline] - pub fn to_ll(&self) -> Option { - Some(*self as u8) - } - -} - -#[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct MouseState { - mouse_state: u32, -} - -impl MouseState { - pub fn new(_e: &EventPump) -> MouseState { - let mouse_state: u32 = unsafe { - let mut x = 0; - let mut y = 0; - ll::SDL_GetMouseState(&mut x, &mut y) - }; - - MouseState { - mouse_state: mouse_state - } - } - - pub fn from_sdl_state(state: u32) -> MouseState { - MouseState { mouse_state : state } - } - pub fn to_sdl_state(&self) -> u32 { - self.mouse_state - } - - /// Returns true if the left mouse button is pressed. - /// - /// # Example - /// ```no_run - /// use sdl2::mouse::Mousebutton; - /// - /// fn is_a_pressed(e: &sdl2::EventPump) -> bool { - /// e.mouse_state().left() - /// } - pub fn left(&self) -> bool { (self.mouse_state & ll::SDL_BUTTON_LMASK) != 0 } - - /// Tests if the middle mouse button was pressed. - pub fn middle(&self) -> bool { (self.mouse_state & ll::SDL_BUTTON_MMASK) != 0 } - - /// Tests if the right mouse button was pressed. - pub fn right(&self) -> bool { (self.mouse_state & ll::SDL_BUTTON_RMASK) != 0 } - - /// Tests if the X1 mouse button was pressed. - pub fn x1(&self) -> bool { (self.mouse_state & ll::SDL_BUTTON_X1MASK) != 0 } - - /// Tests if the X2 mouse button was pressed. - pub fn x2(&self) -> bool { (self.mouse_state & ll::SDL_BUTTON_X2MASK) != 0 } - - /// Returns true if the mouse button is pressed. - /// - /// # Example - /// ```no_run - /// use sdl2::mouse::Mousebutton; - /// - /// fn is_a_pressed(e: &sdl2::EventPump) -> bool { - /// e.mouse_state().is_mousebutton_pressed(Mousebutton::Left) - /// } - /// ``` - pub fn is_mousebutton_pressed(&self, mousebutton: Mousebutton) -> bool { - self.mouse_state<<((mousebutton as u32)-1) != 0 - } - - /// Returns an iterator all scancodes with a boolean indicating if the scancode is pressed. - pub fn mousebuttons(&self) -> MousebuttonIterator { - MousebuttonIterator { - index: 0, - mouse_state: &self.mouse_state - } - } - - /// Returns an iterator of pressed mouse buttons. - /// - /// # Example - /// ```no_run - /// use sdl2::mouse::Mousebutton; - /// use std::collections::HashSet; - /// - /// fn pressed_mousebutton_set(e: &sdl2::EventPump) -> HashSet { - /// e.mouse_state().pressed_mousebuttons().collect() - /// } - /// - /// fn newly_pressed(old: &HashSet, new: &HashSet) -> HashSet { - /// new - old - /// // sugar for: new.difference(old).collect() - /// } - /// ``` - pub fn pressed_mousebuttons(&self) -> PressedMousebuttonIterator { - PressedMousebuttonIterator { - iter: self.mousebuttons() - } - } -} - -pub struct MousebuttonIterator<'a> { - index: usize, - mouse_state: &'a u32 -} - -impl<'a> Iterator for MousebuttonIterator<'a> { - type Item = (Mousebutton, bool); - - fn next(&mut self) -> Option<(Mousebutton, bool)> { - if self.index < Mousebutton::X2 as usize { - let index = self.index; - self.index += 1; - - if let Some(mousebutton) = FromPrimitive::from_usize(index) { - let pressed = self.mouse_state&(Mousebutton::Middle as u32) != 0; - - Some((mousebutton, pressed)) - } else { - self.next() - } - } else { - None - } - } -} - -pub struct PressedMousebuttonIterator<'a> { - iter: MousebuttonIterator<'a> -} - -impl<'a> Iterator for PressedMousebuttonIterator<'a> { - type Item = Mousebutton; - - fn next(&mut self) -> Option { - while let Some((mousebutton, pressed)) = self.iter.next() { - if pressed { return Some(mousebutton) } - } - None - } -} - -impl ::Sdl { - #[inline] - pub fn mouse(&self) -> MouseUtil { - MouseUtil { - _sdldrop: self.sdldrop() - } - } -} - -/// Mouse utility functions. Access with `Sdl::mouse()`. -/// -/// ```no_run -/// let sdl_context = sdl2::init().unwrap(); -/// -/// // Hide the cursor -/// sdl_context.mouse().show_cursor(false); -/// ``` -pub struct MouseUtil { - _sdldrop: ::std::rc::Rc<::SdlDrop> -} - -impl MouseUtil { - /// Gets the id of the window which currently has mouse focus. - pub fn focused_window_id(&self) -> Option { - let raw = unsafe { ll::SDL_GetMouseFocus() }; - if raw == ptr::null_mut() { - None - } else { - let id = unsafe { ::sys::video::SDL_GetWindowID(raw) }; - Some(id) - } - } - - pub fn mouse_state(&self) -> (MouseState, i32, i32) { - let mut x = 0; - let mut y = 0; - unsafe { - let raw = ll::SDL_GetMouseState(&mut x, &mut y); - return (MouseState::from_sdl_state(raw), x as i32, y as i32); - } - } - - pub fn relative_mouse_state(&self) -> (MouseState, i32, i32) { - let mut x = 0; - let mut y = 0; - unsafe { - let raw = ll::SDL_GetRelativeMouseState(&mut x, &mut y); - return (MouseState::from_sdl_state(raw), x as i32, y as i32); - } - } - - pub fn warp_mouse_in_window(&self, window: &video::WindowRef, x: i32, y: i32) { - unsafe { ll::SDL_WarpMouseInWindow(window.raw(), x, y); } - } - - pub fn set_relative_mouse_mode(&self, on: bool) { - unsafe { ll::SDL_SetRelativeMouseMode(on as i32); } - } - - pub fn relative_mouse_mode(&self) -> bool { - unsafe { ll::SDL_GetRelativeMouseMode() == 1 } - } - - pub fn is_cursor_showing(&self) -> bool { - unsafe { ll::SDL_ShowCursor(::sys::SDL_QUERY) == 1 } - } - - pub fn show_cursor(&self, show: bool) { - unsafe { ll::SDL_ShowCursor(show as i32); } - } -}