Skip to content

Add winit phase to MouseWheel event #20438

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/bevy_input/src/mouse.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! The mouse input functionality.

use crate::{ButtonInput, ButtonState};
use crate::{touch::TouchPhase, ButtonInput, ButtonState};
use bevy_ecs::{
change_detection::DetectChangesMut,
entity::Entity,
Expand Down Expand Up @@ -160,6 +160,8 @@ pub struct MouseWheel {
pub y: f32,
/// Window that received the input.
pub window: Entity,
/// Phase of the wheel event.
pub phase: TouchPhase,
}

/// Updates the [`ButtonInput<MouseButton>`] resource with the latest [`MouseButtonInput`] events.
Expand Down
9 changes: 6 additions & 3 deletions crates/bevy_input/src/touch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,14 @@ pub enum ForceTouch {
reflect(Serialize, Deserialize)
)]
pub enum TouchPhase {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that feels weird to me is using the TouchPhase from touch.rs in mouse.rs. Open to suggestions if this is a concern.

/// A finger started to touch the touchscreen.
/// A finger started to touch the touchscreen or a wheel scroll started.
Started,
/// A finger moved over the touchscreen.
/// A finger moved over the touchscreen or touchpad scroll is in progress.
///
/// This can be used to detect whether a scroll action is taking place on a
/// mouse wheel or touchpad, because mouse wheel scrolls do not emit this event.
Moved,
/// A finger stopped touching the touchscreen.
/// A finger stopped touching the touchscreen or a wheel scroll finished.
Ended,
/// The system canceled the tracking of the finger.
///
Expand Down
7 changes: 5 additions & 2 deletions crates/bevy_picking/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
use core::{fmt::Debug, time::Duration};

use bevy_ecs::{prelude::*, query::QueryData, 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;
Expand Down Expand Up @@ -334,6 +334,8 @@ pub struct Scroll {
pub y: f32,
/// Information about the picking intersection.
pub hit: HitData,
/// `TouchPhase` of the scroll.
pub phase: TouchPhase,
}

/// An entry in the cache that drives the `pointer_events` system, storing additional data
Expand Down Expand Up @@ -776,7 +778,7 @@ pub fn pointer_events(
event_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()
Expand All @@ -791,6 +793,7 @@ pub fn pointer_events(
x,
y,
hit: hit.clone(),
phase,
},
);
commands.trigger_targets(scroll_event.clone(), hovered_entity);
Expand Down
10 changes: 8 additions & 2 deletions crates/bevy_picking/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,13 @@ pub fn mouse_pick_events(
pointer_events.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))
Expand All @@ -186,7 +192,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_events.write(PointerInput::new(PointerId::Mouse, location, action));
}
Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_picking/src/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//! driven by lower-level input devices and consumed by higher-level interaction systems.

use bevy_ecs::prelude::*;
use bevy_input::mouse::MouseScrollUnit;
use bevy_input::{mouse::MouseScrollUnit, touch::TouchPhase};
use bevy_math::Vec2;
use bevy_platform::collections::HashMap;
use bevy_reflect::prelude::*;
Expand Down Expand Up @@ -263,6 +263,8 @@ pub enum PointerAction {
x: f32,
/// The vertical scroll value.
y: f32,
/// The phase of the scroll.
phase: TouchPhase,
},
/// Cancel the pointer. Often used for touch events.
Cancel,
Expand Down
16 changes: 10 additions & 6 deletions crates/bevy_winit/src/converters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,22 @@ pub fn convert_mouse_button(mouse_button: winit::event::MouseButton) -> MouseBut
}
}

pub fn convert_touch_input_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,
}
}

pub fn convert_touch_input(
touch_input: winit::event::Touch,
location: winit::dpi::LogicalPosition<f64>,
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_input_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 {
Expand Down
7 changes: 5 additions & 2 deletions crates/bevy_winit/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ use bevy_window::{CursorOptions, PrimaryWindow, RawHandleWrapper};

use crate::{
accessibility::ACCESS_KIT_ADAPTERS,
converters, create_windows,
converters::{self, convert_touch_input_phase},
create_windows,
system::{create_monitors, CachedWindow, WinitWindowPressedKeys},
AppSendEvent, CreateMonitorParams, CreateWindowParams, EventLoopProxyWrapper,
RawWinitWindowEvent, UpdateMode, WinitSettings, WINIT_WINDOWS,
Expand Down Expand Up @@ -320,13 +321,14 @@ impl<T: BufferedEvent> ApplicationHandler<T> for WinitAppRunnerState<T> {
y: delta.y,
}));
}
WindowEvent::MouseWheel { delta, .. } => match delta {
WindowEvent::MouseWheel { delta, phase, .. } => match delta {
event::MouseScrollDelta::LineDelta(x, y) => {
self.bevy_window_events.send(MouseWheel {
unit: MouseScrollUnit::Line,
x,
y,
window,
phase: convert_touch_input_phase(phase),
});
}
event::MouseScrollDelta::PixelDelta(p) => {
Expand All @@ -335,6 +337,7 @@ impl<T: BufferedEvent> ApplicationHandler<T> for WinitAppRunnerState<T> {
x: p.x as f32,
y: p.y as f32,
window,
phase: convert_touch_input_phase(phase),
});
}
},
Expand Down
Loading