Express scroll deltas as either line or pixel deltas

Depending on the platform and device, scroll deltas may either
be represented as pixel deltas specifying the amount
in pixels to scroll or they may be expressed in 'lines' or 'chunks'
for low resolution devices (eg. a traditional mouse wheel).

Pixel deltas are currently available on OS X. X11 currently
supports only integer line deltas, though pixel deltas
are available via XInput2. Windows supports fractional
line deltas.
This commit is contained in:
Robert Knight 2015-06-12 15:32:11 +01:00
parent a0e29d9410
commit f0bab95c4d
5 changed files with 33 additions and 8 deletions

View file

@ -17,7 +17,7 @@ fn main() { println!("This example requires glutin to be compiled with the `wind
#[cfg(feature = "window")] #[cfg(feature = "window")]
fn main() { fn main() {
let mut window = glutin::Window::new().unwrap(); let window = glutin::Window::new().unwrap();
window.set_title("A fantastic window!"); window.set_title("A fantastic window!");
unsafe { window.make_current() }; unsafe { window.make_current() };

View file

@ -275,7 +275,11 @@ impl<'a> Iterator for PollEventsIterator<'a> {
self.window.delegate.state.pending_events.lock().unwrap().extend(events.into_iter()); self.window.delegate.state.pending_events.lock().unwrap().extend(events.into_iter());
event event
}, },
NSScrollWheel => { Some(MouseWheel(event.scrollingDeltaX() as f64, event.scrollingDeltaY() as f64)) }, NSScrollWheel => {
use events::MouseScrollDelta::PixelDelta;
let delta = PixelDelta(event.scrollingDeltaX() as f32, event.scrollingDeltaY() as f32);
Some(MouseWheel(delta))
},
_ => { None }, _ => { None },
}; };

View file

@ -112,12 +112,13 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT,
winapi::WM_MOUSEWHEEL => { winapi::WM_MOUSEWHEEL => {
use events::Event::MouseWheel; use events::Event::MouseWheel;
use events::MouseScrollDelta::LineDelta;
let value = (wparam >> 16) as i16; let value = (wparam >> 16) as i16;
let value = value as i32; let value = value as i32;
let value = value as f64 / winapi::WHEEL_DELTA as f64; let value = value as f32 / winapi::WHEEL_DELTA as f32;
send_event(window, MouseWheel(0.0, value)); send_event(window, MouseWheel(LineDelta(0.0, value)));
0 0
}, },

View file

@ -219,6 +219,7 @@ impl<'a> Iterator for PollEventsIterator<'a> {
use events::Event::{MouseInput, MouseWheel}; use events::Event::{MouseInput, MouseWheel};
use events::ElementState::{Pressed, Released}; use events::ElementState::{Pressed, Released};
use events::MouseButton::{Left, Right, Middle}; use events::MouseButton::{Left, Right, Middle};
use events::MouseScrollDelta::{LineDelta};
let event: &ffi::XButtonEvent = unsafe { mem::transmute(&xev) }; let event: &ffi::XButtonEvent = unsafe { mem::transmute(&xev) };
@ -229,11 +230,13 @@ impl<'a> Iterator for PollEventsIterator<'a> {
ffi::Button2 => Some(Middle), ffi::Button2 => Some(Middle),
ffi::Button3 => Some(Right), ffi::Button3 => Some(Right),
ffi::Button4 => { ffi::Button4 => {
self.window.pending_events.lock().unwrap().push_back(MouseWheel(0.0, 1.0)); let delta = LineDelta(0.0, 1.0);
self.window.pending_events.lock().unwrap().push_back(MouseWheel(delta));
None None
} }
ffi::Button5 => { ffi::Button5 => {
self.window.pending_events.lock().unwrap().push_back(MouseWheel(0.0, -1.0)); let delta = LineDelta(0.0, -1.0);
self.window.pending_events.lock().unwrap().push_back(MouseWheel(delta));
None None
} }
_ => None _ => None

View file

@ -25,11 +25,11 @@ pub enum Event {
/// The parameter are the (x,y) coords in pixels relative to the top-left corner of the window. /// The parameter are the (x,y) coords in pixels relative to the top-left corner of the window.
MouseMoved((i32, i32)), MouseMoved((i32, i32)),
/// Returns the horizontal and vertical mouse scrolling. /// A mouse wheel or touchpad scroll occurred. Depending on whether the
/// ///
/// A positive value indicates that the wheel was rotated forward, away from the user; /// A positive value indicates that the wheel was rotated forward, away from the user;
/// a negative value indicates that the wheel was rotated backward, toward the user. /// a negative value indicates that the wheel was rotated backward, toward the user.
MouseWheel(f64, f64), MouseWheel(MouseScrollDelta),
/// An event from the mouse has been received. /// An event from the mouse has been received.
MouseInput(ElementState, MouseButton), MouseInput(ElementState, MouseButton),
@ -57,6 +57,23 @@ pub enum MouseButton {
Other(u8), Other(u8),
} }
#[derive(Debug, Clone, Copy)]
pub enum MouseScrollDelta {
/// Amount in lines or rows to scroll in the horizontal
/// and vertical directions.
///
/// Positive values indicate movement forward
/// (away from the user) or righwards.
LineDelta(f32, f32),
/// Amount in pixels to scroll in the horizontal and
/// vertical direction.
///
/// Scroll events are expressed as a PixelDelta if
/// supported by the device (eg. a touchpad) and
/// platform.
PixelDelta(f32, f32)
}
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
pub enum VirtualKeyCode { pub enum VirtualKeyCode {
/// The '1' key over the letters. /// The '1' key over the letters.