mirror of
https://github.com/encounter/rust-sdl2.git
synced 2026-07-10 21:18:41 -07:00
Merge pull request #559 from Luke-Nukem/master
For review: implementing `mouse_state()`
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 185 KiB |
@@ -0,0 +1,55 @@
|
||||
extern crate sdl2;
|
||||
use std::path::Path;
|
||||
|
||||
use sdl2::event::Event;
|
||||
use sdl2::keyboard::Keycode;
|
||||
use sdl2::rect::Rect;
|
||||
use sdl2::rect::Point;
|
||||
use std::time::Duration;
|
||||
|
||||
fn main() {
|
||||
let sdl_context = sdl2::init().unwrap();
|
||||
let video_subsystem = sdl_context.video().unwrap();
|
||||
|
||||
let window = video_subsystem.window("SDL2", 640, 480)
|
||||
.position_centered().build().unwrap();
|
||||
|
||||
let mut renderer = window.renderer()
|
||||
.accelerated().build().unwrap();
|
||||
|
||||
renderer.set_draw_color(sdl2::pixels::Color::RGBA(0,0,0,255));
|
||||
|
||||
let mut timer = sdl_context.timer().unwrap();
|
||||
|
||||
let mut event_pump = sdl_context.event_pump().unwrap();
|
||||
|
||||
let temp_surface = sdl2::surface::Surface::load_bmp(Path::new("assets/animate.bmp")).unwrap();
|
||||
let texture = renderer.create_texture_from_surface(&temp_surface).unwrap();
|
||||
let texture_query = texture.query();
|
||||
|
||||
let mut center = Point::new(320,240);
|
||||
let mut source_rect = Rect::new(0, 0, 128, 82);
|
||||
let mut dest_rect = Rect::new(0,0, 128, 82);
|
||||
dest_rect.center_on(center);
|
||||
|
||||
let mut running = true;
|
||||
while running {
|
||||
for event in event_pump.poll_iter() {
|
||||
match event {
|
||||
Event::Quit {..} | Event::KeyDown {keycode: Some(Keycode::Escape), ..} => {
|
||||
running = false;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let ticks = timer.ticks();
|
||||
|
||||
source_rect.set_x((128 * ((ticks / 100) % 6) ) as i32);
|
||||
renderer.clear();
|
||||
renderer.copy_ex(&texture, Some(source_rect), Some(dest_rect), 10.0, None, true, false);
|
||||
renderer.present();
|
||||
|
||||
std::thread::sleep(Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
extern crate sdl2;
|
||||
|
||||
use sdl2::event::Event;
|
||||
use sdl2::mouse::MouseButton;
|
||||
use std::collections::HashSet;
|
||||
use std::time::Duration;
|
||||
|
||||
pub fn main() {
|
||||
let sdl_context = sdl2::init().unwrap();
|
||||
let video_subsystem = sdl_context.video().unwrap();
|
||||
|
||||
let _window = video_subsystem.window("Mouse", 800, 600)
|
||||
.position_centered()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let mut events = sdl_context.event_pump().unwrap();
|
||||
|
||||
let mut prev_buttons = HashSet::new();
|
||||
|
||||
'running: loop {
|
||||
for event in events.poll_iter() {
|
||||
match event {
|
||||
Event::Quit {..} => break 'running,
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
// get a mouse state
|
||||
let state = events.mouse_state();
|
||||
|
||||
// Create a set of pressed Keys.
|
||||
let buttons = state.pressed_mouse_buttons().collect();
|
||||
|
||||
// Get the difference between the new and old sets.
|
||||
let new_buttons = &buttons - &prev_buttons;
|
||||
let old_buttons = &prev_buttons - &buttons;
|
||||
|
||||
if !new_buttons.is_empty() || !old_buttons.is_empty() {
|
||||
println!("X = {:?}, Y = {:?} : {:?} -> {:?}", state.x(), state.y(), new_buttons, old_buttons);
|
||||
}
|
||||
|
||||
prev_buttons = buttons;
|
||||
|
||||
std::thread::sleep(Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
extern crate sdl2;
|
||||
|
||||
use sdl2::event::Event;
|
||||
use sdl2::mouse::MouseButton;
|
||||
use std::time::Duration;
|
||||
|
||||
pub fn main() {
|
||||
let sdl_context = sdl2::init().unwrap();
|
||||
let video_subsystem = sdl_context.video().unwrap();
|
||||
|
||||
let _window = video_subsystem.window("Mouse", 800, 600)
|
||||
.position_centered()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let mut events = sdl_context.event_pump().unwrap();
|
||||
|
||||
let mut state = events.relative_mouse_state();
|
||||
let mut old_x = 0;
|
||||
let mut old_y = 0;
|
||||
|
||||
'running: loop {
|
||||
for event in events.poll_iter() {
|
||||
match event {
|
||||
Event::Quit {..} => break 'running,
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
// get a mouse state using mouse_state() so as not to call
|
||||
// relative_mouse_state() twice and get a false position reading
|
||||
if events.mouse_state().is_mouse_button_pressed(MouseButton::Left) {
|
||||
state = events.relative_mouse_state();
|
||||
println!("Relative - X = {:?}, Y = {:?}", state.x(), state.y());
|
||||
}
|
||||
|
||||
std::thread::sleep(Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
+11
-11
@@ -22,17 +22,17 @@ pub const SDL_SYSTEM_CURSOR_HAND: SDL_SystemCursor = 11;
|
||||
pub const SDL_NUM_SYSTEM_CURSORS: SDL_SystemCursor = 12;
|
||||
|
||||
|
||||
|
||||
pub const SDL_BUTTON_LEFT: u8 = 1;
|
||||
pub const SDL_BUTTON_MIDDLE: u8 = 2;
|
||||
pub const SDL_BUTTON_RIGHT: u8 = 3;
|
||||
pub const SDL_BUTTON_X1: u8 = 4;
|
||||
pub const SDL_BUTTON_X2: u8 = 5;
|
||||
pub const SDL_BUTTON_LMASK: u32 = 0x01;
|
||||
pub const SDL_BUTTON_MMASK: u32 = 0x02;
|
||||
pub const SDL_BUTTON_RMASK: u32 = 0x04;
|
||||
pub const SDL_BUTTON_X1MASK: u32 = 0x08;
|
||||
pub const SDL_BUTTON_X2MASK: u32 = 0x10;
|
||||
pub const SDL_BUTTON_UNKNOWN: u8 = 0;
|
||||
pub const SDL_BUTTON_LEFT : u8 = 1;
|
||||
pub const SDL_BUTTON_MIDDLE : u8 = 2;
|
||||
pub const SDL_BUTTON_RIGHT : u8 = 3;
|
||||
pub const SDL_BUTTON_X1 : u8 = 4;
|
||||
pub const SDL_BUTTON_X2 : u8 = 5;
|
||||
pub const SDL_BUTTON_LMASK : u32 = 0x01;
|
||||
pub const SDL_BUTTON_MMASK : u32 = 0x02;
|
||||
pub const SDL_BUTTON_RMASK : u32 = 0x04;
|
||||
pub const SDL_BUTTON_X1MASK : u32 = 0x08;
|
||||
pub const SDL_BUTTON_X2MASK : u32 = 0x10;
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
+31
-16
@@ -23,7 +23,7 @@ use keyboard::Mod;
|
||||
use sys::keycode::SDL_Keymod;
|
||||
use keyboard::Keycode;
|
||||
use mouse;
|
||||
use mouse::{Mouse, MouseState, MouseWheelDirection};
|
||||
use mouse::{MouseButton, MouseState, MouseWheelDirection};
|
||||
use keyboard::Scancode;
|
||||
use get_error;
|
||||
|
||||
@@ -456,7 +456,7 @@ pub enum Event {
|
||||
AppDidEnterForeground { timestamp: u32 },
|
||||
|
||||
Window {
|
||||
timestamp: u32 ,
|
||||
timestamp: u32,
|
||||
window_id: u32,
|
||||
win_event_id: WindowEventId,
|
||||
data1: i32,
|
||||
@@ -465,7 +465,7 @@ pub enum Event {
|
||||
// TODO: SysWMEvent
|
||||
|
||||
KeyDown {
|
||||
timestamp: u32 ,
|
||||
timestamp: u32,
|
||||
window_id: u32,
|
||||
keycode: Option<Keycode>,
|
||||
scancode: Option<Scancode>,
|
||||
@@ -473,7 +473,7 @@ pub enum Event {
|
||||
repeat: bool
|
||||
},
|
||||
KeyUp {
|
||||
timestamp: u32 ,
|
||||
timestamp: u32,
|
||||
window_id: u32,
|
||||
keycode: Option<Keycode>,
|
||||
scancode: Option<Scancode>,
|
||||
@@ -510,7 +510,7 @@ pub enum Event {
|
||||
timestamp: u32,
|
||||
window_id: u32,
|
||||
which: u32,
|
||||
mouse_btn: Mouse,
|
||||
mouse_btn: Option<MouseButton>,
|
||||
x: i32,
|
||||
y: i32
|
||||
},
|
||||
@@ -518,7 +518,7 @@ pub enum Event {
|
||||
timestamp: u32,
|
||||
window_id: u32,
|
||||
which: u32,
|
||||
mouse_btn: Mouse,
|
||||
mouse_btn: Option<MouseButton>,
|
||||
x: i32,
|
||||
y: i32
|
||||
},
|
||||
@@ -755,6 +755,11 @@ fn mk_keysym(scancode: Option<Scancode>,
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function is only to unwrap a mouse_button to u8
|
||||
fn mk_mouse_button(mouse_button: Option<MouseButton>) -> u8 {
|
||||
mouse_button.unwrap().to_ll().unwrap()
|
||||
}
|
||||
|
||||
// TODO: Remove this when from_utf8 is updated in Rust
|
||||
// This would honestly be nice if it took &self instead of self,
|
||||
// but Event::User's raw pointers kind of removes that possibility.
|
||||
@@ -870,7 +875,7 @@ impl Event {
|
||||
xrel,
|
||||
yrel
|
||||
} => {
|
||||
let state = mousestate.to_flags();
|
||||
let state = mousestate.to_sdl_state();
|
||||
let event = ll::SDL_MouseMotionEvent {
|
||||
type_: ll::SDL_MOUSEMOTION,
|
||||
timestamp: timestamp,
|
||||
@@ -896,7 +901,7 @@ impl Event {
|
||||
x,
|
||||
y
|
||||
} => {
|
||||
let button = mouse_btn.to_ll();
|
||||
let button = mk_mouse_button(mouse_btn);
|
||||
let event = ll::SDL_MouseButtonEvent {
|
||||
type_: ll::SDL_MOUSEBUTTONDOWN,
|
||||
timestamp: timestamp,
|
||||
@@ -922,7 +927,7 @@ impl Event {
|
||||
x,
|
||||
y
|
||||
} => {
|
||||
let button = mouse_btn.to_ll();
|
||||
let button = mk_mouse_button(mouse_btn);
|
||||
let event = ll::SDL_MouseButtonEvent {
|
||||
type_: ll::SDL_MOUSEBUTTONUP,
|
||||
timestamp: timestamp,
|
||||
@@ -1355,7 +1360,7 @@ impl Event {
|
||||
timestamp: event.timestamp,
|
||||
window_id: event.windowID,
|
||||
which: event.which,
|
||||
mousestate: mouse::MouseState::from_flags(event.state),
|
||||
mousestate: mouse::MouseState::from_sdl_state(event.state),
|
||||
x: event.x,
|
||||
y: event.y,
|
||||
xrel: event.xrel,
|
||||
@@ -1369,7 +1374,7 @@ impl Event {
|
||||
timestamp: event.timestamp,
|
||||
window_id: event.windowID,
|
||||
which: event.which,
|
||||
mouse_btn: mouse::Mouse::from_ll(event.button),
|
||||
mouse_btn: mouse::MouseButton::from_ll(event.button),
|
||||
x: event.x,
|
||||
y: event.y
|
||||
}
|
||||
@@ -1381,7 +1386,7 @@ impl Event {
|
||||
timestamp: event.timestamp,
|
||||
window_id: event.windowID,
|
||||
which: event.which,
|
||||
mouse_btn: mouse::Mouse::from_ll(event.button),
|
||||
mouse_btn: mouse::MouseButton::from_ll(event.button),
|
||||
x: event.x,
|
||||
y: event.y
|
||||
}
|
||||
@@ -1784,6 +1789,16 @@ impl ::EventPump {
|
||||
pub fn keyboard_state(&self) -> ::keyboard::KeyboardState {
|
||||
::keyboard::KeyboardState::new(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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()`.
|
||||
@@ -1827,7 +1842,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
|
||||
@@ -1880,7 +1895,7 @@ mod test {
|
||||
timestamp: 0,
|
||||
window_id: 0,
|
||||
which: 1,
|
||||
mousestate: MouseState::from_flags(1),
|
||||
mousestate: MouseState::from_sdl_state(1),
|
||||
x: 3,
|
||||
y: 91,
|
||||
xrel: -1,
|
||||
@@ -1894,7 +1909,7 @@ mod test {
|
||||
timestamp: 5634,
|
||||
window_id: 2,
|
||||
which: 0,
|
||||
mouse_btn: Mouse::Left,
|
||||
mouse_btn: Some(MouseButton::Left),
|
||||
x: 543,
|
||||
y: 345,
|
||||
};
|
||||
@@ -1906,7 +1921,7 @@ mod test {
|
||||
timestamp: 0,
|
||||
window_id: 2,
|
||||
which: 0,
|
||||
mouse_btn: Mouse::Left,
|
||||
mouse_btn: Some(MouseButton::Left),
|
||||
x: 543,
|
||||
y: 345,
|
||||
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
use num::{ToPrimitive, FromPrimitive};
|
||||
use std::ptr;
|
||||
|
||||
use get_error;
|
||||
use surface::SurfaceRef;
|
||||
use video;
|
||||
use EventPump;
|
||||
|
||||
use sys::mouse as ll;
|
||||
|
||||
mod relative;
|
||||
pub use self::relative::RelativeMouseState;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
||||
#[repr(u32)]
|
||||
pub enum SystemCursor {
|
||||
@@ -124,84 +129,219 @@ impl MouseWheelDirection {
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
||||
pub enum Mouse {
|
||||
Left,
|
||||
Middle,
|
||||
Right,
|
||||
X1,
|
||||
X2,
|
||||
Unknown(u8)
|
||||
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 Mouse {
|
||||
impl ToPrimitive for MouseButton {
|
||||
#[inline]
|
||||
pub fn from_ll(button: u8) -> Mouse {
|
||||
match button {
|
||||
1 => Mouse::Left,
|
||||
2 => Mouse::Middle,
|
||||
3 => Mouse::Right,
|
||||
4 => Mouse::X1,
|
||||
5 => Mouse::X2,
|
||||
_ => Mouse::Unknown(button)
|
||||
}
|
||||
fn to_i64(&self) -> Option<i64> {
|
||||
Some(*self as i64)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_u64(&self) -> Option<u64> {
|
||||
Some(*self as u64)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_isize(&self) -> Option<isize> {
|
||||
Some(*self as isize)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromPrimitive for MouseButton {
|
||||
#[inline]
|
||||
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 => 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) -> u8 {
|
||||
match *self {
|
||||
Mouse::Left => 1,
|
||||
Mouse::Middle => 2,
|
||||
Mouse::Right => 3,
|
||||
Mouse::X1 => 4,
|
||||
Mouse::X2 => 5,
|
||||
Mouse::Unknown(button) => button,
|
||||
}
|
||||
pub fn to_ll(&self) -> Option<u8> {
|
||||
Some(*self as u8)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct MouseState {
|
||||
flags: u32
|
||||
mouse_state: u32,
|
||||
x: i32,
|
||||
y: i32
|
||||
}
|
||||
|
||||
impl MouseState {
|
||||
/// Tests if a mouse button was pressed.
|
||||
pub fn button(&self, button: Mouse) -> bool {
|
||||
match button {
|
||||
Mouse::Left => self.left(),
|
||||
Mouse::Middle => self.middle(),
|
||||
Mouse::Right => self.right(),
|
||||
Mouse::X1 => self.x1(),
|
||||
Mouse::X2 => self.x2(),
|
||||
Mouse::Unknown(x) => {
|
||||
assert!(x <= 32);
|
||||
let mask = 1 << ((x as u32) - 1);
|
||||
(self.flags & mask) != 0
|
||||
}
|
||||
pub fn new(_e: &EventPump) -> MouseState {
|
||||
let mut x = 0;
|
||||
let mut y = 0;
|
||||
let mouse_state: u32 = unsafe {
|
||||
ll::SDL_GetMouseState(&mut x, &mut y)
|
||||
};
|
||||
|
||||
MouseState {
|
||||
mouse_state: mouse_state,
|
||||
x: x as i32,
|
||||
y: y as i32
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests if the left mouse button was pressed.
|
||||
pub fn left(&self) -> bool { (self.flags & ll::SDL_BUTTON_LMASK) != 0 }
|
||||
|
||||
/// Tests if the middle mouse button was pressed.
|
||||
pub fn middle(&self) -> bool { (self.flags & ll::SDL_BUTTON_MMASK) != 0 }
|
||||
|
||||
/// Tests if the right mouse button was pressed.
|
||||
pub fn right(&self) -> bool { (self.flags & ll::SDL_BUTTON_RMASK) != 0 }
|
||||
|
||||
/// Tests if the X1 mouse button was pressed.
|
||||
pub fn x1(&self) -> bool { (self.flags & ll::SDL_BUTTON_X1MASK) != 0 }
|
||||
|
||||
/// Tests if the X2 mouse button was pressed.
|
||||
pub fn x2(&self) -> bool { (self.flags & ll::SDL_BUTTON_X2MASK) != 0 }
|
||||
|
||||
pub fn from_flags(flags: u32) -> MouseState {
|
||||
MouseState { flags: flags }
|
||||
pub fn from_sdl_state(state: u32) -> MouseState {
|
||||
MouseState { mouse_state : state, x: 0, y: 0 }
|
||||
}
|
||||
pub fn to_sdl_state(&self) -> u32 {
|
||||
self.mouse_state
|
||||
}
|
||||
|
||||
pub fn to_flags(&self) -> u32 {
|
||||
self.flags
|
||||
/// 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 the x coordinate of the state
|
||||
pub fn x(&self) -> i32 { self.x }
|
||||
|
||||
/// Returns the y coordinate of the state
|
||||
pub fn y(&self) -> i32 { self.y }
|
||||
|
||||
/// Returns true if the mouse button is pressed.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// use sdl2::mouse::MouseButton;
|
||||
///
|
||||
/// fn is_left_pressed(e: &sdl2::EventPump) -> bool {
|
||||
/// e.mouse_state().is_mouse_button_pressed(MouseButton::Left)
|
||||
/// }
|
||||
/// ```
|
||||
pub fn is_mouse_button_pressed(&self, mouse_button: MouseButton) -> bool {
|
||||
let mask = 1 << ((mouse_button as u32)-1);
|
||||
self.mouse_state & mask != 0
|
||||
}
|
||||
|
||||
/// Returns an iterator all mouse buttons with a boolean indicating if the scancode is pressed.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// use sdl2::mouse::MouseButton;
|
||||
/// use std::collections::HashMap;
|
||||
///
|
||||
/// fn mouse_button_set(e: &sdl2::EventPump) -> HashMap<MouseButton, bool> {
|
||||
/// e.mouse_state().mouse_buttons().collect()
|
||||
/// }
|
||||
///
|
||||
/// fn find_first_pressed(e: &sdl2::EventPump) -> bool {
|
||||
/// for (key,value) in mouse_button_set(e) {
|
||||
/// return value != false
|
||||
/// }
|
||||
/// false
|
||||
/// }
|
||||
///
|
||||
/// ```
|
||||
pub fn mouse_buttons(&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_mouse_button_set(e: &sdl2::EventPump) -> HashSet<MouseButton> {
|
||||
/// e.mouse_state().pressed_mouse_buttons().collect()
|
||||
/// }
|
||||
///
|
||||
/// fn newly_pressed(old: &HashSet<MouseButton>, new: &HashSet<MouseButton>) -> HashSet<MouseButton> {
|
||||
/// new - old
|
||||
/// // sugar for: new.difference(old).collect()
|
||||
/// }
|
||||
/// ```
|
||||
pub fn pressed_mouse_buttons(&self) -> PressedMouseButtonIterator {
|
||||
PressedMouseButtonIterator {
|
||||
iter: self.mouse_buttons()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 +1 {
|
||||
let index = self.index;
|
||||
self.index += 1;
|
||||
|
||||
if let Some(mouse_button) = FromPrimitive::from_usize(index) {
|
||||
let mask = 1 << ((mouse_button as u32)-1);
|
||||
let pressed = self.mouse_state & mask != 0;
|
||||
|
||||
Some((mouse_button, 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((mouse_button, pressed)) = self.iter.next() {
|
||||
if pressed { return Some(mouse_button) }
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,24 +378,6 @@ impl MouseUtil {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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_flags(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); }
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
use EventPump;
|
||||
|
||||
use sys::mouse as ll;
|
||||
|
||||
use super::{MouseButton, MouseButtonIterator, PressedMouseButtonIterator};
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct RelativeMouseState {
|
||||
mouse_state: u32,
|
||||
x: i32,
|
||||
y: i32
|
||||
}
|
||||
|
||||
impl RelativeMouseState {
|
||||
pub fn new(_e: &EventPump) -> RelativeMouseState {
|
||||
let mut x = 0;
|
||||
let mut y = 0;
|
||||
let mouse_state = unsafe {
|
||||
// This call is the only difference between MouseState
|
||||
ll::SDL_GetRelativeMouseState(&mut x, &mut y)
|
||||
};
|
||||
|
||||
RelativeMouseState {
|
||||
mouse_state: mouse_state,
|
||||
x: x as i32,
|
||||
y: y as i32
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_sdl_state(state: u32) -> RelativeMouseState {
|
||||
RelativeMouseState { mouse_state : state, x: 0, y: 0 }
|
||||
}
|
||||
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 the x coordinate of the state
|
||||
pub fn x(&self) -> i32 { self.x }
|
||||
|
||||
/// Returns the y coordinate of the state
|
||||
pub fn y(&self) -> i32 { self.y }
|
||||
|
||||
/// Returns true if the mouse button is pressed.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// use sdl2::mouse::MouseButton;
|
||||
///
|
||||
/// fn is_left_pressed(e: &sdl2::EventPump) -> bool {
|
||||
/// e.mouse_state().is_mouse_button_pressed(MouseButton::Left)
|
||||
/// }
|
||||
/// ```
|
||||
pub fn is_mouse_button_pressed(&self, mouse_button: MouseButton) -> bool {
|
||||
let mask = 1 << ((mouse_button as u32)-1);
|
||||
self.mouse_state & mask != 0
|
||||
}
|
||||
|
||||
/// Returns an iterator all mouse buttons with a boolean indicating if the scancode is pressed.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// use sdl2::mouse::MouseButton;
|
||||
/// use std::collections::HashMap;
|
||||
///
|
||||
/// fn mouse_button_set(e: &sdl2::EventPump) -> HashMap<MouseButton, bool> {
|
||||
/// e.mouse_state().mouse_buttons().collect()
|
||||
/// }
|
||||
///
|
||||
/// fn find_first_pressed(e: &sdl2::EventPump) -> bool {
|
||||
/// for (key,value) in mouse_button_set(e) {
|
||||
/// return value != false
|
||||
/// }
|
||||
/// false
|
||||
/// }
|
||||
///
|
||||
/// ```
|
||||
pub fn mouse_buttons(&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_mouse_button_set(e: &sdl2::EventPump) -> HashSet<MouseButton> {
|
||||
/// e.mouse_state().pressed_mouse_buttons().collect()
|
||||
/// }
|
||||
///
|
||||
/// fn newly_pressed(old: &HashSet<MouseButton>, new: &HashSet<MouseButton>) -> HashSet<MouseButton> {
|
||||
/// new - old
|
||||
/// // sugar for: new.difference(old).collect()
|
||||
/// }
|
||||
/// ```
|
||||
pub fn pressed_mouse_buttons(&self) -> PressedMouseButtonIterator {
|
||||
PressedMouseButtonIterator {
|
||||
iter: self.mouse_buttons()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user