diff --git a/crates/bevy_input/src/mouse.rs b/crates/bevy_input/src/mouse.rs index 107121b7aa84e..902e0bf8a8f83 100644 --- a/crates/bevy_input/src/mouse.rs +++ b/crates/bevy_input/src/mouse.rs @@ -1,6 +1,6 @@ //! The mouse input functionality. -use crate::{ButtonInput, ButtonState}; +use crate::{touch::TouchPhase, ButtonInput, ButtonState}; #[cfg(feature = "bevy_reflect")] use bevy_ecs::prelude::ReflectMessage; use bevy_ecs::{ @@ -174,6 +174,10 @@ pub struct MouseWheel { pub y: f32, /// Window that received the input. pub window: Entity, + /// Touch phase of the input. + /// + /// When using a mouse, this will always be [`TouchPhase::Moved`]. + pub phase: TouchPhase, } /// Updates the [`ButtonInput`] resource with the latest [`MouseButtonInput`] events. diff --git a/crates/bevy_picking/src/events.rs b/crates/bevy_picking/src/events.rs index ffb9ce333a0ac..ee2cf133723f2 100644 --- a/crates/bevy_picking/src/events.rs +++ b/crates/bevy_picking/src/events.rs @@ -49,7 +49,7 @@ use bevy_ecs::{ system::SystemParam, traversal::Traversal, }; -use bevy_input::mouse::MouseScrollUnit; +use bevy_input::{mouse::MouseScrollUnit, touch::TouchPhase}; use bevy_math::Vec2; use bevy_platform::collections::HashMap; use bevy_platform::time::Instant; @@ -458,6 +458,10 @@ pub struct Scroll { pub y: f32, /// Information about the picking intersection. pub hit: HitData, + /// Touch phase of the input. + /// + /// When using a mouse, this will always be [`TouchPhase::Moved`]. + pub phase: TouchPhase, } /// An entry in the cache that drives the `pointer_events` system, storing additional data @@ -1141,7 +1145,7 @@ pub fn pointer_events( message_writers.move_events.write(move_event); } } - PointerAction::Scroll { x, y, unit } => { + PointerAction::Scroll { x, y, unit, phase } => { for (hovered_entity, hit) in hover_map .get(&pointer_id) .iter() @@ -1156,6 +1160,7 @@ pub fn pointer_events( x, y, hit: hit.clone(), + phase, }, hovered_entity, ); diff --git a/crates/bevy_picking/src/input.rs b/crates/bevy_picking/src/input.rs index efa634e05a40c..ae6dd8f8df3d3 100644 --- a/crates/bevy_picking/src/input.rs +++ b/crates/bevy_picking/src/input.rs @@ -173,7 +173,13 @@ pub fn mouse_pick_events( pointer_inputs.write(PointerInput::new(PointerId::Mouse, location, action)); } WindowEvent::MouseWheel(event) => { - let MouseWheel { unit, x, y, window } = *event; + let MouseWheel { + unit, + x, + y, + window, + phase, + } = *event; let location = Location { target: match RenderTarget::Window(WindowRef::Entity(window)) @@ -185,7 +191,7 @@ pub fn mouse_pick_events( position: *cursor_last, }; - let action = PointerAction::Scroll { x, y, unit }; + let action = PointerAction::Scroll { x, y, unit, phase }; pointer_inputs.write(PointerInput::new(PointerId::Mouse, location, action)); } diff --git a/crates/bevy_picking/src/pointer.rs b/crates/bevy_picking/src/pointer.rs index 1ef36a323346c..9e9decedef396 100644 --- a/crates/bevy_picking/src/pointer.rs +++ b/crates/bevy_picking/src/pointer.rs @@ -12,6 +12,7 @@ use bevy_camera::NormalizedRenderTarget; use bevy_camera::{Camera, RenderTarget}; use bevy_ecs::prelude::*; use bevy_input::mouse::MouseScrollUnit; +use bevy_input::touch::TouchPhase; use bevy_math::Vec2; use bevy_platform::collections::HashMap; use bevy_reflect::prelude::*; @@ -264,6 +265,10 @@ pub enum PointerAction { x: f32, /// The vertical scroll value. y: f32, + /// Touch phase of the input. + /// + /// When using a mouse, this will always be [`TouchPhase::Moved`]. + phase: TouchPhase, }, /// Cancel the pointer. Often used for touch events. Cancel, diff --git a/crates/bevy_winit/src/converters.rs b/crates/bevy_winit/src/converters.rs index 07f9d6e4af15b..5436147f68222 100644 --- a/crates/bevy_winit/src/converters.rs +++ b/crates/bevy_winit/src/converters.rs @@ -49,6 +49,16 @@ pub fn convert_mouse_button(mouse_button: winit::event::MouseButton) -> MouseBut } } +/// Converts a [`winit::event::TouchPhase`] to a Bevy [`TouchPhase`]. +pub fn convert_touch_phase(phase: winit::event::TouchPhase) -> TouchPhase { + match phase { + winit::event::TouchPhase::Started => TouchPhase::Started, + winit::event::TouchPhase::Moved => TouchPhase::Moved, + winit::event::TouchPhase::Ended => TouchPhase::Ended, + winit::event::TouchPhase::Cancelled => TouchPhase::Canceled, + } +} + /// Converts a [`winit::event::Touch`], [`winit::dpi::LogicalPosition`] and window [`Entity`] to a Bevy [`TouchInput`] pub fn convert_touch_input( touch_input: winit::event::Touch, @@ -56,12 +66,7 @@ pub fn convert_touch_input( window_entity: Entity, ) -> TouchInput { TouchInput { - phase: match touch_input.phase { - winit::event::TouchPhase::Started => TouchPhase::Started, - winit::event::TouchPhase::Moved => TouchPhase::Moved, - winit::event::TouchPhase::Ended => TouchPhase::Ended, - winit::event::TouchPhase::Cancelled => TouchPhase::Canceled, - }, + phase: convert_touch_phase(touch_input.phase), position: Vec2::new(location.x as f32, location.y as f32), window: window_entity, force: touch_input.force.map(|f| match f { diff --git a/crates/bevy_winit/src/state.rs b/crates/bevy_winit/src/state.rs index 916de3a236f1c..102beefa20b2f 100644 --- a/crates/bevy_winit/src/state.rs +++ b/crates/bevy_winit/src/state.rs @@ -39,7 +39,8 @@ use bevy_window::{CursorOptions, PrimaryWindow, RawHandleWrapper}; use crate::{ accessibility::ACCESS_KIT_ADAPTERS, - converters, create_windows, + converters::{self, convert_touch_phase}, + create_windows, system::{create_monitors, CachedWindow, WinitWindowPressedKeys}, AppSendEvent, CreateMonitorParams, CreateWindowParams, RawWinitWindowEvent, UpdateMode, WinitSettings, WinitUserEvent, WINIT_WINDOWS, @@ -336,24 +337,29 @@ impl ApplicationHandler for WinitAppRunnerState { y: delta.y, })); } - WindowEvent::MouseWheel { delta, .. } => match delta { - event::MouseScrollDelta::LineDelta(x, y) => { - self.bevy_window_events.send(MouseWheel { - unit: MouseScrollUnit::Line, - x, - y, - window, - }); - } - event::MouseScrollDelta::PixelDelta(p) => { - self.bevy_window_events.send(MouseWheel { - unit: MouseScrollUnit::Pixel, - x: p.x as f32, - y: p.y as f32, - window, - }); + WindowEvent::MouseWheel { delta, phase, .. } => { + let phase = convert_touch_phase(phase); + match delta { + event::MouseScrollDelta::LineDelta(x, y) => { + self.bevy_window_events.send(MouseWheel { + unit: MouseScrollUnit::Line, + x, + y, + window, + phase, + }); + } + event::MouseScrollDelta::PixelDelta(p) => { + self.bevy_window_events.send(MouseWheel { + unit: MouseScrollUnit::Pixel, + x: p.x as f32, + y: p.y as f32, + window, + phase, + }); + } } - }, + } WindowEvent::Touch(touch) => { let location = touch .location