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!
This commit is contained in:
parent
2660ddc4c5
commit
84359514bd
@ -40,6 +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_math::Vec2;
|
||||
use bevy_platform_support::collections::HashMap;
|
||||
use bevy_platform_support::time::Instant;
|
||||
@ -285,6 +286,19 @@ pub struct DragEntry {
|
||||
pub latest_pos: Vec2,
|
||||
}
|
||||
|
||||
/// Fires while a pointer is scrolling over the `target` entity.
|
||||
#[derive(Clone, PartialEq, Debug, Reflect)]
|
||||
pub struct Scroll {
|
||||
/// The mouse scroll unit.
|
||||
pub unit: MouseScrollUnit,
|
||||
/// The horizontal scroll value.
|
||||
pub x: f32,
|
||||
/// The vertical scroll value.
|
||||
pub y: f32,
|
||||
/// Information about the picking intersection.
|
||||
pub hit: HitData,
|
||||
}
|
||||
|
||||
/// An entry in the cache that drives the `pointer_events` system, storing additional data
|
||||
/// about pointer button presses.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
@ -346,6 +360,7 @@ pub struct PickingEventWriters<'w> {
|
||||
drag_leave_events: EventWriter<'w, Pointer<DragLeave>>,
|
||||
drag_over_events: EventWriter<'w, Pointer<DragOver>>,
|
||||
drag_start_events: EventWriter<'w, Pointer<DragStart>>,
|
||||
scroll_events: EventWriter<'w, Pointer<Scroll>>,
|
||||
move_events: EventWriter<'w, Pointer<Move>>,
|
||||
out_events: EventWriter<'w, Pointer<Out>>,
|
||||
over_events: EventWriter<'w, Pointer<Over>>,
|
||||
@ -750,6 +765,28 @@ pub fn pointer_events(
|
||||
event_writers.move_events.send(move_event);
|
||||
}
|
||||
}
|
||||
PointerAction::Scroll { x, y, unit } => {
|
||||
for (hovered_entity, hit) in hover_map
|
||||
.get(&pointer_id)
|
||||
.iter()
|
||||
.flat_map(|h| h.iter().map(|(entity, data)| (*entity, data.clone())))
|
||||
{
|
||||
// Emit Scroll events to the entities we are hovering
|
||||
let scroll_event = Pointer::new(
|
||||
pointer_id,
|
||||
location.clone(),
|
||||
hovered_entity,
|
||||
Scroll {
|
||||
unit,
|
||||
x,
|
||||
y,
|
||||
hit: hit.clone(),
|
||||
},
|
||||
);
|
||||
commands.trigger_targets(scroll_event.clone(), hovered_entity);
|
||||
event_writers.scroll_events.send(scroll_event);
|
||||
}
|
||||
}
|
||||
// Canceled
|
||||
PointerAction::Cancel => {
|
||||
// Emit a Cancel to the hovered entity.
|
||||
|
@ -14,6 +14,7 @@
|
||||
use bevy_app::prelude::*;
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_input::{
|
||||
mouse::MouseWheel,
|
||||
prelude::*,
|
||||
touch::{TouchInput, TouchPhase},
|
||||
ButtonState,
|
||||
@ -156,6 +157,23 @@ pub fn mouse_pick_events(
|
||||
};
|
||||
pointer_events.send(PointerInput::new(PointerId::Mouse, location, action));
|
||||
}
|
||||
WindowEvent::MouseWheel(event) => {
|
||||
let MouseWheel { unit, x, y, window } = *event;
|
||||
|
||||
let location = Location {
|
||||
target: match RenderTarget::Window(WindowRef::Entity(window))
|
||||
.normalize(primary_window.get_single().ok())
|
||||
{
|
||||
Some(target) => target,
|
||||
None => continue,
|
||||
},
|
||||
position: *cursor_last,
|
||||
};
|
||||
|
||||
let action = PointerAction::Scroll { x, y, unit };
|
||||
|
||||
pointer_events.send(PointerInput::new(PointerId::Mouse, location, action));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -422,6 +422,7 @@ impl Plugin for InteractionPlugin {
|
||||
.add_event::<Pointer<Out>>()
|
||||
.add_event::<Pointer<Over>>()
|
||||
.add_event::<Pointer<Released>>()
|
||||
.add_event::<Pointer<Scroll>>()
|
||||
.add_systems(
|
||||
PreUpdate,
|
||||
(generate_hovermap, update_interactions, pointer_events)
|
||||
|
@ -9,6 +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_math::Vec2;
|
||||
use bevy_platform_support::collections::HashMap;
|
||||
use bevy_reflect::prelude::*;
|
||||
@ -251,6 +252,15 @@ pub enum PointerAction {
|
||||
/// How much the pointer moved from the previous position.
|
||||
delta: Vec2,
|
||||
},
|
||||
/// Scroll the pointer
|
||||
Scroll {
|
||||
/// The mouse scroll unit.
|
||||
unit: MouseScrollUnit,
|
||||
/// The horizontal scroll value.
|
||||
x: f32,
|
||||
/// The vertical scroll value.
|
||||
y: f32,
|
||||
},
|
||||
/// Cancel the pointer. Often used for touch events.
|
||||
Cancel,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user