egui-winit: Emulate mouse from touches (#791)
Additionally to emmiting egui::Event::Touch events, on_touch() now also emits egui::Event::PointerButton, egui::event::PointerMoved and egui::event::PointerGone facilitating UI usage on touchscreen devices. If there are multiple touches, only the first one will be translated into pointer events. This prevents situations with two pointers.
This commit is contained in:
parent
bd06dec653
commit
ca632c5e5d
1 changed files with 44 additions and 0 deletions
|
@ -106,7 +106,14 @@ pub struct State {
|
||||||
|
|
||||||
/// If `true`, mouse inputs will be treated as touches.
|
/// If `true`, mouse inputs will be treated as touches.
|
||||||
/// Useful for debugging touch support in egui.
|
/// Useful for debugging touch support in egui.
|
||||||
|
///
|
||||||
|
/// Creates duplicate touches, if real touch inputs are coming.
|
||||||
simulate_touch_screen: bool,
|
simulate_touch_screen: bool,
|
||||||
|
|
||||||
|
/// Is Some(…) when a touch is being translated to a pointer.
|
||||||
|
///
|
||||||
|
/// Only one touch will be interpreted as pointer at any time.
|
||||||
|
pointer_touch_id: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
|
@ -132,6 +139,7 @@ impl State {
|
||||||
screen_reader: screen_reader::ScreenReader::default(),
|
screen_reader: screen_reader::ScreenReader::default(),
|
||||||
|
|
||||||
simulate_touch_screen: false,
|
simulate_touch_screen: false,
|
||||||
|
pointer_touch_id: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,6 +358,7 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_touch(&mut self, touch: &winit::event::Touch) {
|
fn on_touch(&mut self, touch: &winit::event::Touch) {
|
||||||
|
// Emit touch event
|
||||||
self.egui_input.events.push(egui::Event::Touch {
|
self.egui_input.events.push(egui::Event::Touch {
|
||||||
device_id: egui::TouchDeviceId(egui::epaint::util::hash(touch.device_id)),
|
device_id: egui::TouchDeviceId(egui::epaint::util::hash(touch.device_id)),
|
||||||
id: egui::TouchId::from(touch.id),
|
id: egui::TouchId::from(touch.id),
|
||||||
|
@ -373,6 +382,41 @@ impl State {
|
||||||
None => 0_f32,
|
None => 0_f32,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
// If we're not yet tanslating a touch or we're translating this very
|
||||||
|
// touch …
|
||||||
|
if self.pointer_touch_id.is_none() || self.pointer_touch_id.unwrap() == touch.id {
|
||||||
|
// … emit PointerButton resp. PointerMoved events to emulate mouse
|
||||||
|
match touch.phase {
|
||||||
|
winit::event::TouchPhase::Started => {
|
||||||
|
self.pointer_touch_id = Some(touch.id);
|
||||||
|
// First move the pointer to the right location
|
||||||
|
self.on_cursor_moved(touch.location);
|
||||||
|
self.on_mouse_button_input(
|
||||||
|
winit::event::ElementState::Pressed,
|
||||||
|
winit::event::MouseButton::Left,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
winit::event::TouchPhase::Moved => {
|
||||||
|
self.on_cursor_moved(touch.location);
|
||||||
|
}
|
||||||
|
winit::event::TouchPhase::Ended => {
|
||||||
|
self.pointer_touch_id = None;
|
||||||
|
self.on_mouse_button_input(
|
||||||
|
winit::event::ElementState::Released,
|
||||||
|
winit::event::MouseButton::Left,
|
||||||
|
);
|
||||||
|
// The pointer should vanish completely to not get any
|
||||||
|
// hover effects
|
||||||
|
self.pointer_pos_in_points = None;
|
||||||
|
self.egui_input.events.push(egui::Event::PointerGone);
|
||||||
|
}
|
||||||
|
winit::event::TouchPhase::Cancelled => {
|
||||||
|
self.pointer_touch_id = None;
|
||||||
|
self.pointer_pos_in_points = None;
|
||||||
|
self.egui_input.events.push(egui::Event::PointerGone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_mouse_wheel(&mut self, delta: winit::event::MouseScrollDelta) {
|
fn on_mouse_wheel(&mut self, delta: winit::event::MouseScrollDelta) {
|
||||||
|
|
Loading…
Reference in a new issue