Skip to content

Commit

Permalink
Mouse delta from DeviceEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
enomado committed May 20, 2022
1 parent b008b14 commit e401fa4
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 5 deletions.
4 changes: 4 additions & 0 deletions eframe/src/native/epi_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ impl EpiIntegration {
self.quit
}

pub fn on_mouse_delta(&mut self, delta: (f64, f64)) {
self.egui_winit.on_mouse_delta(delta);
}

pub fn on_event(&mut self, app: &mut dyn epi::App, event: &winit::event::WindowEvent<'_>) {
use winit::event::{ElementState, MouseButton, WindowEvent};

Expand Down
14 changes: 14 additions & 0 deletions eframe/src/native/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ pub fn run_glow(
winit::event::Event::RedrawEventsCleared if cfg!(windows) => redraw(),
winit::event::Event::RedrawRequested(_) if !cfg!(windows) => redraw(),

winit::event::Event::DeviceEvent {
device_id: _,
event: winit::event::DeviceEvent::MouseMotion { delta },
} => {
integration.on_mouse_delta(delta);
}

winit::event::Event::WindowEvent { event, .. } => {
match &event {
winit::event::WindowEvent::Focused(new_focused) => {
Expand Down Expand Up @@ -303,6 +310,13 @@ pub fn run_wgpu(
winit::event::Event::RedrawEventsCleared if cfg!(windows) => redraw(),
winit::event::Event::RedrawRequested(_) if !cfg!(windows) => redraw(),

winit::event::Event::DeviceEvent {
device_id: _,
event: winit::event::DeviceEvent::MouseMotion { delta },
} => {
integration.on_mouse_delta(delta);
}

winit::event::Event::WindowEvent { event, .. } => {
match &event {
winit::event::WindowEvent::Focused(new_focused) => {
Expand Down
15 changes: 11 additions & 4 deletions egui-winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#![allow(clippy::manual_range_contains)]

pub use egui;
use egui::Vec2;
pub use winit;

pub mod clipboard;
Expand Down Expand Up @@ -119,6 +120,13 @@ impl State {
self.egui_input.take()
}

pub fn on_mouse_delta(&mut self, delta: (f64, f64)) {
self.egui_input.events.push(egui::Event::MouseDelta(Vec2 {
x: delta.0 as f32,
y: delta.1 as f32,
}))
}

/// Call this when there is a new event.
///
/// The result can be found in [`Self::egui_input`] and be extracted with [`Self::take_egui_input`].
Expand Down Expand Up @@ -152,6 +160,7 @@ impl State {
}
WindowEvent::CursorMoved { position, .. } => {
self.on_cursor_moved(*position);

egui_ctx.is_using_pointer()
}
WindowEvent::CursorLeft { .. } => {
Expand Down Expand Up @@ -226,10 +235,8 @@ impl State {
};
false
}
_ => {
// dbg!(event);
false
}

_ => false,
}
}

Expand Down
5 changes: 5 additions & 0 deletions egui/src/data/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,11 @@ pub enum Event {
/// The mouse or touch moved to a new place.
PointerMoved(Pos2),

/// The mouse delta from winit::DeviceEvent. MouseDelta and PointerMoved can be emmited simultaneously.
/// If MouseDelta accumulated value is zero per frame, then `old_pos-new_pos` will be used as fallback.
/// For now it used in situations when we need delta but mouse pointer is on screen edge.
MouseDelta(Vec2),

/// A mouse button was pressed or released (or a touch started or stopped).
PointerButton {
/// Where is the pointer?
Expand Down
19 changes: 19 additions & 0 deletions egui/src/input_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,11 @@ pub struct PointerState {
/// How much the pointer moved compared to last frame, in points.
delta: Vec2,

/// How much the pointer moved despite on cursor location, window, in unspecified units.
/// Platform specific.
/// See `winit::event::DeviceEvent::MouseMotion`
motion: Vec2,

/// Current velocity of pointer.
velocity: Vec2,

Expand Down Expand Up @@ -490,6 +495,7 @@ impl Default for PointerState {
latest_pos: None,
interact_pos: None,
delta: Vec2::ZERO,
motion: Vec2::ZERO,
velocity: Vec2::ZERO,
pos_history: History::new(0..1000, 0.1),
down: Default::default(),
Expand All @@ -512,6 +518,7 @@ impl PointerState {

let old_pos = self.latest_pos;
self.interact_pos = self.latest_pos;
self.motion = Vec2::ZERO;

for event in &new.events {
match event {
Expand Down Expand Up @@ -597,6 +604,9 @@ impl PointerState {
self.latest_pos = None;
// NOTE: we do NOT clear `self.interact_pos` here. It will be cleared next frame.
}

Event::MouseDelta(delta) => self.motion += *delta,

_ => {}
}
}
Expand Down Expand Up @@ -636,6 +646,13 @@ impl PointerState {
self.delta
}

/// Mouse delta, in unspecified units. Works when mouse pointer in screen bounds.
/// Currently on winit only.
#[inline(always)]
pub fn motion(&self) -> Vec2 {
self.motion
}

/// Current velocity of pointer.
#[inline(always)]
pub fn velocity(&self) -> Vec2 {
Expand Down Expand Up @@ -889,6 +906,7 @@ impl PointerState {
latest_pos,
interact_pos,
delta,
motion,
velocity,
pos_history: _,
down,
Expand All @@ -903,6 +921,7 @@ impl PointerState {
ui.label(format!("latest_pos: {:?}", latest_pos));
ui.label(format!("interact_pos: {:?}", interact_pos));
ui.label(format!("delta: {:?}", delta));
ui.label(format!("motion: {:?}", motion));
ui.label(format!(
"velocity: [{:3.0} {:3.0}] points/sec",
velocity.x, velocity.y
Expand Down
18 changes: 18 additions & 0 deletions egui/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,24 @@ impl Response {
self.drag_released
}

/// Mouse dragged, nevertheless it's stuck on screen's edge or not.
pub fn motion_delta(&self) -> Vec2 {
#[cfg(target_family = "wasm")]
return self.drag_delta();

#[cfg(not(target_family = "wasm"))]
{
let res = self.ctx.input().pointer.motion();

if res == Vec2::ZERO {
// in a case of touchscreen or whatever
self.drag_delta()
} else {
res
}
}
}

/// If dragged, how many points were we dragged and in what direction?
pub fn drag_delta(&self) -> Vec2 {
if self.dragged() {
Expand Down
3 changes: 2 additions & 1 deletion egui/src/widgets/drag_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ impl<'a> Widget for DragValue<'a> {
} else if response.dragged() {
ui.output().cursor_icon = CursorIcon::ResizeHorizontal;

let mdelta = response.drag_delta();
let mdelta = response.motion_delta();

let delta_points = mdelta.x - mdelta.y; // Increase to the right and up

let speed = if is_slow_speed { speed / 10.0 } else { speed };
Expand Down

0 comments on commit e401fa4

Please sign in to comment.