Skip to content

Commit 8435951

Browse files
authored
Add scroll functionality to bevy_picking (#17704)
# Objective `bevy_picking` currently does not support scroll events. ## Solution This pr adds a new event type for scroll, and updates the default input system for mouse pointers to read and emit this event. ## Testing - Did you test these changes? If so, how? - Are there any parts that need more testing? - How can other people (reviewers) test your changes? Is there anything specific they need to know? - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? I haven't tested these changes, if the reviewers can advise me how to do so I'd appreciate it!
1 parent 2660ddc commit 8435951

File tree

4 files changed

+66
-0
lines changed

4 files changed

+66
-0
lines changed

crates/bevy_picking/src/events.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
use core::{fmt::Debug, time::Duration};
4141

4242
use bevy_ecs::{prelude::*, query::QueryData, system::SystemParam, traversal::Traversal};
43+
use bevy_input::mouse::MouseScrollUnit;
4344
use bevy_math::Vec2;
4445
use bevy_platform_support::collections::HashMap;
4546
use bevy_platform_support::time::Instant;
@@ -285,6 +286,19 @@ pub struct DragEntry {
285286
pub latest_pos: Vec2,
286287
}
287288

289+
/// Fires while a pointer is scrolling over the `target` entity.
290+
#[derive(Clone, PartialEq, Debug, Reflect)]
291+
pub struct Scroll {
292+
/// The mouse scroll unit.
293+
pub unit: MouseScrollUnit,
294+
/// The horizontal scroll value.
295+
pub x: f32,
296+
/// The vertical scroll value.
297+
pub y: f32,
298+
/// Information about the picking intersection.
299+
pub hit: HitData,
300+
}
301+
288302
/// An entry in the cache that drives the `pointer_events` system, storing additional data
289303
/// about pointer button presses.
290304
#[derive(Debug, Clone, Default)]
@@ -346,6 +360,7 @@ pub struct PickingEventWriters<'w> {
346360
drag_leave_events: EventWriter<'w, Pointer<DragLeave>>,
347361
drag_over_events: EventWriter<'w, Pointer<DragOver>>,
348362
drag_start_events: EventWriter<'w, Pointer<DragStart>>,
363+
scroll_events: EventWriter<'w, Pointer<Scroll>>,
349364
move_events: EventWriter<'w, Pointer<Move>>,
350365
out_events: EventWriter<'w, Pointer<Out>>,
351366
over_events: EventWriter<'w, Pointer<Over>>,
@@ -750,6 +765,28 @@ pub fn pointer_events(
750765
event_writers.move_events.send(move_event);
751766
}
752767
}
768+
PointerAction::Scroll { x, y, unit } => {
769+
for (hovered_entity, hit) in hover_map
770+
.get(&pointer_id)
771+
.iter()
772+
.flat_map(|h| h.iter().map(|(entity, data)| (*entity, data.clone())))
773+
{
774+
// Emit Scroll events to the entities we are hovering
775+
let scroll_event = Pointer::new(
776+
pointer_id,
777+
location.clone(),
778+
hovered_entity,
779+
Scroll {
780+
unit,
781+
x,
782+
y,
783+
hit: hit.clone(),
784+
},
785+
);
786+
commands.trigger_targets(scroll_event.clone(), hovered_entity);
787+
event_writers.scroll_events.send(scroll_event);
788+
}
789+
}
753790
// Canceled
754791
PointerAction::Cancel => {
755792
// Emit a Cancel to the hovered entity.

crates/bevy_picking/src/input.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use bevy_app::prelude::*;
1515
use bevy_ecs::prelude::*;
1616
use bevy_input::{
17+
mouse::MouseWheel,
1718
prelude::*,
1819
touch::{TouchInput, TouchPhase},
1920
ButtonState,
@@ -156,6 +157,23 @@ pub fn mouse_pick_events(
156157
};
157158
pointer_events.send(PointerInput::new(PointerId::Mouse, location, action));
158159
}
160+
WindowEvent::MouseWheel(event) => {
161+
let MouseWheel { unit, x, y, window } = *event;
162+
163+
let location = Location {
164+
target: match RenderTarget::Window(WindowRef::Entity(window))
165+
.normalize(primary_window.get_single().ok())
166+
{
167+
Some(target) => target,
168+
None => continue,
169+
},
170+
position: *cursor_last,
171+
};
172+
173+
let action = PointerAction::Scroll { x, y, unit };
174+
175+
pointer_events.send(PointerInput::new(PointerId::Mouse, location, action));
176+
}
159177
_ => {}
160178
}
161179
}

crates/bevy_picking/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ impl Plugin for InteractionPlugin {
422422
.add_event::<Pointer<Out>>()
423423
.add_event::<Pointer<Over>>()
424424
.add_event::<Pointer<Released>>()
425+
.add_event::<Pointer<Scroll>>()
425426
.add_systems(
426427
PreUpdate,
427428
(generate_hovermap, update_interactions, pointer_events)

crates/bevy_picking/src/pointer.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//! driven by lower-level input devices and consumed by higher-level interaction systems.
1010
1111
use bevy_ecs::prelude::*;
12+
use bevy_input::mouse::MouseScrollUnit;
1213
use bevy_math::Vec2;
1314
use bevy_platform_support::collections::HashMap;
1415
use bevy_reflect::prelude::*;
@@ -251,6 +252,15 @@ pub enum PointerAction {
251252
/// How much the pointer moved from the previous position.
252253
delta: Vec2,
253254
},
255+
/// Scroll the pointer
256+
Scroll {
257+
/// The mouse scroll unit.
258+
unit: MouseScrollUnit,
259+
/// The horizontal scroll value.
260+
x: f32,
261+
/// The vertical scroll value.
262+
y: f32,
263+
},
254264
/// Cancel the pointer. Often used for touch events.
255265
Cancel,
256266
}

0 commit comments

Comments
 (0)