Skip to content

Commit df57850

Browse files
rename touchpad to gesture, and add new gestures (bevyengine#13660)
# Objective - With the recent winit update, touchpad specific events can also be triggered on mobile ## Solution - Rename them to gestures and add support for the new ones ## Testing - Tested on the mobile example on iOS https://github.com/bevyengine/bevy/assets/8672791/da4ed23f-ff0a-41b2-9dcd-726e8546bef2 ## Migration Guide - `TouchpadMagnify` has been renamed to `PinchGesture` - `TouchpadRotate` has been renamed to `RotationGesture ` --------- Co-authored-by: mike <ramirezmike2@gmail.com>
1 parent 58a0c13 commit df57850

File tree

9 files changed

+217
-67
lines changed

9 files changed

+217
-67
lines changed

crates/bevy_input/src/gestures.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//! Gestures functionality, from touchscreens and touchpads.
2+
3+
use bevy_ecs::event::Event;
4+
use bevy_math::Vec2;
5+
use bevy_reflect::Reflect;
6+
7+
#[cfg(feature = "serialize")]
8+
use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
9+
10+
/// Two-finger pinch gesture, often used for magnifications.
11+
///
12+
/// Positive delta values indicate magnification (zooming in) and
13+
/// negative delta values indicate shrinking (zooming out).
14+
///
15+
/// ## Platform-specific
16+
///
17+
/// - Only available on **`macOS`** and **`iOS`**.
18+
/// - On **`iOS`**, must be enabled first
19+
#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect)]
20+
#[reflect(Debug, PartialEq)]
21+
#[cfg_attr(
22+
feature = "serialize",
23+
derive(serde::Serialize, serde::Deserialize),
24+
reflect(Serialize, Deserialize)
25+
)]
26+
pub struct PinchGesture(pub f32);
27+
28+
/// Two-finger rotation gesture.
29+
///
30+
/// Positive delta values indicate rotation counterclockwise and
31+
/// negative delta values indicate rotation clockwise.
32+
///
33+
/// ## Platform-specific
34+
///
35+
/// - Only available on **`macOS`** and **`iOS`**.
36+
/// - On **`iOS`**, must be enabled first
37+
#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect)]
38+
#[reflect(Debug, PartialEq)]
39+
#[cfg_attr(
40+
feature = "serialize",
41+
derive(serde::Serialize, serde::Deserialize),
42+
reflect(Serialize, Deserialize)
43+
)]
44+
pub struct RotationGesture(pub f32);
45+
46+
/// Double tap gesture.
47+
///
48+
/// ## Platform-specific
49+
///
50+
/// - Only available on **`macOS`** and **`iOS`**.
51+
/// - On **`iOS`**, must be enabled first
52+
#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect)]
53+
#[reflect(Debug, PartialEq)]
54+
#[cfg_attr(
55+
feature = "serialize",
56+
derive(serde::Serialize, serde::Deserialize),
57+
reflect(Serialize, Deserialize)
58+
)]
59+
pub struct DoubleTapGesture;
60+
61+
/// Pan gesture.
62+
///
63+
/// ## Platform-specific
64+
///
65+
/// - On **`iOS`**, must be enabled first
66+
#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect)]
67+
#[reflect(Debug, PartialEq)]
68+
#[cfg_attr(
69+
feature = "serialize",
70+
derive(serde::Serialize, serde::Deserialize),
71+
reflect(Serialize, Deserialize)
72+
)]
73+
pub struct PanGesture(pub Vec2);

crates/bevy_input/src/lib.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ mod button_input;
1616
/// Common run conditions
1717
pub mod common_conditions;
1818
pub mod gamepad;
19+
pub mod gestures;
1920
pub mod keyboard;
2021
pub mod mouse;
2122
pub mod touch;
22-
pub mod touchpad;
2323

2424
pub use axis::*;
2525
pub use button_input::*;
@@ -41,10 +41,10 @@ pub mod prelude {
4141
use bevy_app::prelude::*;
4242
use bevy_ecs::prelude::*;
4343
use bevy_reflect::Reflect;
44+
use gestures::*;
4445
use keyboard::{keyboard_input_system, KeyCode, KeyboardInput};
4546
use mouse::{mouse_button_input_system, MouseButton, MouseButtonInput, MouseMotion, MouseWheel};
4647
use touch::{touch_screen_input_system, TouchInput, Touches};
47-
use touchpad::{TouchpadMagnify, TouchpadRotate};
4848

4949
use gamepad::{
5050
gamepad_axis_event_system, gamepad_button_event_system, gamepad_connection_system,
@@ -77,8 +77,10 @@ impl Plugin for InputPlugin {
7777
.add_event::<MouseWheel>()
7878
.init_resource::<ButtonInput<MouseButton>>()
7979
.add_systems(PreUpdate, mouse_button_input_system.in_set(InputSystem))
80-
.add_event::<TouchpadMagnify>()
81-
.add_event::<TouchpadRotate>()
80+
.add_event::<PinchGesture>()
81+
.add_event::<RotationGesture>()
82+
.add_event::<DoubleTapGesture>()
83+
.add_event::<PanGesture>()
8284
// gamepad
8385
.add_event::<GamepadConnectionEvent>()
8486
.add_event::<GamepadButtonChangedEvent>()
@@ -114,8 +116,10 @@ impl Plugin for InputPlugin {
114116
app.register_type::<ButtonState>()
115117
.register_type::<KeyboardInput>()
116118
.register_type::<MouseButtonInput>()
117-
.register_type::<TouchpadMagnify>()
118-
.register_type::<TouchpadRotate>()
119+
.register_type::<PinchGesture>()
120+
.register_type::<RotationGesture>()
121+
.register_type::<DoubleTapGesture>()
122+
.register_type::<PanGesture>()
119123
.register_type::<TouchInput>()
120124
.register_type::<GamepadEvent>()
121125
.register_type::<GamepadButtonInput>()

crates/bevy_input/src/touchpad.rs

Lines changed: 0 additions & 41 deletions
This file was deleted.

crates/bevy_window/src/window.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,33 @@ pub struct Window {
281281
/// [`wgpu::SurfaceConfiguration::desired_maximum_frame_latency`]:
282282
/// https://docs.rs/wgpu/latest/wgpu/type.SurfaceConfiguration.html#structfield.desired_maximum_frame_latency
283283
pub desired_maximum_frame_latency: Option<NonZeroU32>,
284+
/// Sets whether this window recognizes [`PinchGesture`]
285+
///
286+
/// ## Platform-specific
287+
///
288+
/// - Only used on iOS.
289+
/// - On macOS, they are recognized by default and can't be disabled.
290+
pub recognize_pinch_gesture: bool,
291+
/// Sets whether this window recognizes [`RotationGesture`]
292+
///
293+
/// ## Platform-specific
294+
///
295+
/// - Only used on iOS.
296+
/// - On macOS, they are recognized by default and can't be disabled.
297+
pub recognize_rotation_gesture: bool,
298+
/// Sets whether this window recognizes [`DoubleTapGesture`]
299+
///
300+
/// ## Platform-specific
301+
///
302+
/// - Only used on iOS.
303+
/// - On macOS, they are recognized by default and can't be disabled.
304+
pub recognize_doubletap_gesture: bool,
305+
/// Sets whether this window recognizes [`PanGesture`], with a number of fingers between the first value and the last.
306+
///
307+
/// ## Platform-specific
308+
///
309+
/// - Only used on iOS.
310+
pub recognize_pan_gesture: Option<(u8, u8)>,
284311
}
285312

286313
impl Default for Window {
@@ -311,6 +338,10 @@ impl Default for Window {
311338
visible: true,
312339
skip_taskbar: false,
313340
desired_maximum_frame_latency: None,
341+
recognize_pinch_gesture: false,
342+
recognize_rotation_gesture: false,
343+
recognize_doubletap_gesture: false,
344+
recognize_pan_gesture: None,
314345
}
315346
}
316347
}

crates/bevy_winit/src/state.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use bevy_ecs::prelude::*;
77
use bevy_ecs::system::SystemState;
88
use bevy_ecs::world::FromWorld;
99
use bevy_input::{
10+
gestures::*,
1011
mouse::{MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel},
11-
touchpad::{TouchpadMagnify, TouchpadRotate},
1212
};
1313
use bevy_log::{error, trace, warn};
1414
use bevy_math::{ivec2, DVec2, Vec2};
@@ -264,10 +264,19 @@ impl<T: Event> ApplicationHandler<T> for WinitAppRunnerState<T> {
264264
});
265265
}
266266
WindowEvent::PinchGesture { delta, .. } => {
267-
self.winit_events.send(TouchpadMagnify(delta as f32));
267+
self.winit_events.send(PinchGesture(delta as f32));
268268
}
269269
WindowEvent::RotationGesture { delta, .. } => {
270-
self.winit_events.send(TouchpadRotate(delta));
270+
self.winit_events.send(RotationGesture(delta));
271+
}
272+
WindowEvent::DoubleTapGesture { .. } => {
273+
self.winit_events.send(DoubleTapGesture);
274+
}
275+
WindowEvent::PanGesture { delta, .. } => {
276+
self.winit_events.send(PanGesture(Vec2 {
277+
x: delta.x,
278+
y: delta.y,
279+
}));
271280
}
272281
WindowEvent::MouseWheel { delta, .. } => match delta {
273282
event::MouseScrollDelta::LineDelta(x, y) => {
@@ -674,10 +683,16 @@ impl<T: Event> WinitAppRunnerState<T> {
674683
WinitEvent::MouseWheel(e) => {
675684
world.send_event(e);
676685
}
677-
WinitEvent::TouchpadMagnify(e) => {
686+
WinitEvent::PinchGesture(e) => {
687+
world.send_event(e);
688+
}
689+
WinitEvent::RotationGesture(e) => {
690+
world.send_event(e);
691+
}
692+
WinitEvent::DoubleTapGesture(e) => {
678693
world.send_event(e);
679694
}
680-
WinitEvent::TouchpadRotate(e) => {
695+
WinitEvent::PanGesture(e) => {
681696
world.send_event(e);
682697
}
683698
WinitEvent::TouchInput(e) => {

crates/bevy_winit/src/system.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use winit::dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
1616
use winit::event_loop::ActiveEventLoop;
1717

1818
use bevy_ecs::query::With;
19+
#[cfg(target_os = "ios")]
20+
use winit::platform::ios::WindowExtIOS;
1921
#[cfg(target_arch = "wasm32")]
2022
use winit::platform::web::WindowExtWebSys;
2123

@@ -97,6 +99,19 @@ pub fn create_windows<F: QueryFilter + 'static>(
9799
style.set_property("height", "100%").unwrap();
98100
}
99101
}
102+
103+
#[cfg(target_os = "ios")]
104+
{
105+
winit_window.recognize_pinch_gesture(window.recognize_pinch_gesture);
106+
winit_window.recognize_rotation_gesture(window.recognize_rotation_gesture);
107+
winit_window.recognize_doubletap_gesture(window.recognize_doubletap_gesture);
108+
if let Some((min, max)) = window.recognize_pan_gesture {
109+
winit_window.recognize_pan_gesture(true, min, max);
110+
} else {
111+
winit_window.recognize_pan_gesture(false, 0, 0);
112+
}
113+
}
114+
100115
window_created_events.send(WindowCreated { window: entity });
101116
}
102117
}
@@ -360,6 +375,31 @@ pub(crate) fn changed_windows(
360375
winit_window.set_visible(window.visible);
361376
}
362377

378+
#[cfg(target_os = "ios")]
379+
{
380+
if window.recognize_pinch_gesture != cache.window.recognize_pinch_gesture {
381+
winit_window.recognize_pinch_gesture(window.recognize_pinch_gesture);
382+
}
383+
if window.recognize_rotation_gesture != cache.window.recognize_rotation_gesture {
384+
winit_window.recognize_rotation_gesture(window.recognize_rotation_gesture);
385+
}
386+
if window.recognize_doubletap_gesture != cache.window.recognize_doubletap_gesture {
387+
winit_window.recognize_doubletap_gesture(window.recognize_doubletap_gesture);
388+
}
389+
if window.recognize_pan_gesture != cache.window.recognize_pan_gesture {
390+
match (
391+
window.recognize_pan_gesture,
392+
cache.window.recognize_pan_gesture,
393+
) {
394+
(Some(_), Some(_)) => {
395+
warn!("Bevy currently doesn't support modifying PanGesture number of fingers recognition. Please disable it before re-enabling it with the new number of fingers");
396+
}
397+
(Some((min, max)), _) => winit_window.recognize_pan_gesture(true, min, max),
398+
_ => winit_window.recognize_pan_gesture(false, 0, 0),
399+
}
400+
}
401+
}
402+
363403
cache.window = window.clone();
364404
}
365405
}

crates/bevy_winit/src/winit_event.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use bevy_ecs::prelude::*;
55
use bevy_input::keyboard::KeyboardInput;
66
use bevy_input::touch::TouchInput;
77
use bevy_input::{
8+
gestures::*,
89
mouse::{MouseButtonInput, MouseMotion, MouseWheel},
9-
touchpad::{TouchpadMagnify, TouchpadRotate},
1010
};
1111
use bevy_reflect::Reflect;
1212
#[cfg(feature = "serialize")]
@@ -55,8 +55,10 @@ pub enum WinitEvent {
5555
MouseMotion(MouseMotion),
5656
MouseWheel(MouseWheel),
5757

58-
TouchpadMagnify(TouchpadMagnify),
59-
TouchpadRotate(TouchpadRotate),
58+
PinchGesture(PinchGesture),
59+
RotationGesture(RotationGesture),
60+
DoubleTapGesture(DoubleTapGesture),
61+
PanGesture(PanGesture),
6062

6163
TouchInput(TouchInput),
6264

@@ -168,14 +170,24 @@ impl From<MouseWheel> for WinitEvent {
168170
Self::MouseWheel(e)
169171
}
170172
}
171-
impl From<TouchpadMagnify> for WinitEvent {
172-
fn from(e: TouchpadMagnify) -> Self {
173-
Self::TouchpadMagnify(e)
173+
impl From<PinchGesture> for WinitEvent {
174+
fn from(e: PinchGesture) -> Self {
175+
Self::PinchGesture(e)
174176
}
175177
}
176-
impl From<TouchpadRotate> for WinitEvent {
177-
fn from(e: TouchpadRotate) -> Self {
178-
Self::TouchpadRotate(e)
178+
impl From<RotationGesture> for WinitEvent {
179+
fn from(e: RotationGesture) -> Self {
180+
Self::RotationGesture(e)
181+
}
182+
}
183+
impl From<DoubleTapGesture> for WinitEvent {
184+
fn from(e: DoubleTapGesture) -> Self {
185+
Self::DoubleTapGesture(e)
186+
}
187+
}
188+
impl From<PanGesture> for WinitEvent {
189+
fn from(e: PanGesture) -> Self {
190+
Self::PanGesture(e)
179191
}
180192
}
181193
impl From<TouchInput> for WinitEvent {

0 commit comments

Comments
 (0)