Hopeful finished implementation of EventPump mouse_state()

- implemented tests using keyboard_state() as a template
- renamed some functions and structs in the process to better reflect
their use
- `EventPump` should now return a `MouseState` via `fn
mouse_state(&self) -> MouseState`. New functions added.
    - `fn is_mousebutton_pressed(&self, mousebutton: Mousebutton) ->
    bool`
    - `fn mousebuttons(&self) -> MousebuttonIterator`
    - `fn pressed_mousebuttons(&self) -> PressedMousebuttonIterator`
- Implemented `ToPrimitive` and `FromPrimitive` for struct `Mousebutton`
This commit is contained in:
Luke Jones
2016-11-18 21:48:54 +13:00
parent 0c8692c978
commit c696bc5a85
3 changed files with 141 additions and 26 deletions
+1 -2
View File
@@ -21,8 +21,7 @@ pub const SDL_SYSTEM_CURSOR_NO: SDL_SystemCursor = 10;
pub const SDL_SYSTEM_CURSOR_HAND: SDL_SystemCursor = 11;
pub const SDL_NUM_SYSTEM_CURSORS: SDL_SystemCursor = 12;
// #define SDL_BUTTON(X) (SDL_PRESSED<<(X-1))
// need to shift the SDL_BUTTON_LEFT over per above
pub const SDL_BUTTON_UNKNOWN: u8 = 0;
pub const SDL_BUTTON_LEFT : u8 = 1;
pub const SDL_BUTTON_MIDDLE : u8 = 2;
+12 -11
View File
@@ -23,7 +23,7 @@ use keyboard::Mod;
use sys::keycode::SDL_Keymod;
use keyboard::Keycode;
use mouse;
use mouse::{Mousecode, 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<Mousecode>,
mouse_btn: Option<Mousebutton>,
x: i32,
y: i32
},
@@ -518,7 +518,7 @@ pub enum Event {
timestamp: u32,
window_id: u32,
which: u32,
mouse_btn: Option<Mousecode>,
mouse_btn: Option<Mousebutton>,
x: i32,
y: i32
},
@@ -755,8 +755,9 @@ fn mk_keysym(scancode: Option<Scancode>,
}
}
fn mk_mousesym(mousecode: Option<Mousecode>) -> u8 {
mousecode.unwrap().to_ll().unwrap()
/// Helper function is only to unwrap a mousebutton to u8
fn mk_mousesym(mousebutton: Option<Mousebutton>) -> u8 {
mousebutton.unwrap().to_ll().unwrap()
}
// TODO: Remove this when from_utf8 is updated in Rust
@@ -1373,7 +1374,7 @@ impl Event {
timestamp: event.timestamp,
window_id: event.windowID,
which: event.which,
mouse_btn: mouse::Mousecode::from_ll(event.button),
mouse_btn: mouse::Mousebutton::from_ll(event.button),
x: event.x,
y: event.y
}
@@ -1385,7 +1386,7 @@ impl Event {
timestamp: event.timestamp,
window_id: event.windowID,
which: event.which,
mouse_btn: mouse::Mousecode::from_ll(event.button),
mouse_btn: mouse::Mousebutton::from_ll(event.button),
x: event.x,
y: event.y
}
@@ -1836,7 +1837,7 @@ mod test {
use super::WindowEventId;
use super::super::controller::{Button, Axis};
use super::super::joystick::{HatState};
use super::super::mouse::{Mouse, 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
@@ -1889,7 +1890,7 @@ mod test {
timestamp: 0,
window_id: 0,
which: 1,
mousestate: MouseState::from_state(1),
mousestate: MouseState::from_sdl_state(1),
x: 3,
y: 91,
xrel: -1,
@@ -1903,7 +1904,7 @@ mod test {
timestamp: 5634,
window_id: 2,
which: 0,
mouse_btn: Mouse::Left,
mouse_btn: Some(Mousebutton::Left),
x: 543,
y: 345,
};
@@ -1915,7 +1916,7 @@ mod test {
timestamp: 0,
window_id: 2,
which: 0,
mouse_btn: Mouse::Left,
mouse_btn: Some(Mousebutton::Left),
x: 543,
y: 345,
+128 -13
View File
@@ -127,7 +127,7 @@ impl MouseWheelDirection {
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum Mousecode {
pub enum Mousebutton {
Left = ll::SDL_BUTTON_LEFT as isize,
Middle = ll::SDL_BUTTON_MIDDLE as isize,
Right = ll::SDL_BUTTON_RIGHT as isize,
@@ -135,7 +135,7 @@ pub enum Mousecode {
X2 = ll::SDL_BUTTON_X2 as isize,
}
impl ToPrimitive for Mousecode {
impl ToPrimitive for Mousebutton {
#[inline]
fn to_i64(&self) -> Option<i64> {
Some(*self as i64)
@@ -152,15 +152,22 @@ impl ToPrimitive for Mousecode {
}
}
impl Mousecode {
impl FromPrimitive for Mousebutton {
#[inline]
pub fn from_ll(button: u8) -> Option<Mousecode> {
fn from_i64(n: i64) -> Option<Mousebutton> { Mousebutton::from_ll(n as u8) }
#[inline]
fn from_u64(n: u64) -> Option<Mousebutton> { Mousebutton::from_ll(n as u8) }
}
impl Mousebutton {
#[inline]
pub fn from_ll(button: u8) -> Option<Mousebutton> {
Some(match button {
ll::SDL_BUTTON_LEFT => Mousecode::Left,
ll::SDL_BUTTON_MIDDLE => Mousecode::Middle,
ll::SDL_BUTTON_RIGHT => Mousecode::Right,
ll::SDL_BUTTON_X1 => Mousecode::X1,
ll::SDL_BUTTON_X2 => Mousecode::X2,
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,
})
}
@@ -195,6 +202,114 @@ impl MouseState {
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<Mousebutton> {
/// e.mouse_state().pressed_mousebuttons().collect()
/// }
///
/// fn newly_pressed(old: &HashSet<Mousebutton>, new: &HashSet<Mousebutton>) -> HashSet<Mousebutton> {
/// 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<Mousebutton> {
while let Some((mousebutton, pressed)) = self.iter.next() {
if pressed { return Some(mousebutton) }
}
None
}
}
impl ::Sdl {
@@ -229,13 +344,13 @@ impl MouseUtil {
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_flags(raw), x as i32, y as i32);
return (MouseState::from_sdl_state(raw), x as i32, y as i32);
}
}
@@ -244,10 +359,10 @@ impl MouseUtil {
let mut y = 0;
unsafe {
let raw = ll::SDL_GetRelativeMouseState(&mut x, &mut y);
return (MouseState::from_flags(raw), x as i32, y as i32);
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); }
}