Merge pull request #559 from Luke-Nukem/master

For review: implementing `mouse_state()`
This commit is contained in:
Tony Aldridge
2016-11-21 09:37:52 +00:00
committed by GitHub
8 changed files with 511 additions and 104 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

+55
View File
@@ -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));
}
}
+47
View File
@@ -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));
}
}
+39
View File
@@ -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
View File
@@ -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
View File
@@ -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,
+199 -77
View File
@@ -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); }
}
+129
View File
@@ -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()
}
}
}