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 core::{fmt::Debug, time::Duration};
|
||||||
|
|
||||||
use bevy_ecs::{prelude::*, query::QueryData, system::SystemParam, traversal::Traversal};
|
use bevy_ecs::{prelude::*, query::QueryData, system::SystemParam, traversal::Traversal};
|
||||||
|
use bevy_input::mouse::MouseScrollUnit;
|
||||||
use bevy_math::Vec2;
|
use bevy_math::Vec2;
|
||||||
use bevy_platform_support::collections::HashMap;
|
use bevy_platform_support::collections::HashMap;
|
||||||
use bevy_platform_support::time::Instant;
|
use bevy_platform_support::time::Instant;
|
||||||
@ -285,6 +286,19 @@ pub struct DragEntry {
|
|||||||
pub latest_pos: Vec2,
|
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
|
/// An entry in the cache that drives the `pointer_events` system, storing additional data
|
||||||
/// about pointer button presses.
|
/// about pointer button presses.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
@ -346,6 +360,7 @@ pub struct PickingEventWriters<'w> {
|
|||||||
drag_leave_events: EventWriter<'w, Pointer<DragLeave>>,
|
drag_leave_events: EventWriter<'w, Pointer<DragLeave>>,
|
||||||
drag_over_events: EventWriter<'w, Pointer<DragOver>>,
|
drag_over_events: EventWriter<'w, Pointer<DragOver>>,
|
||||||
drag_start_events: EventWriter<'w, Pointer<DragStart>>,
|
drag_start_events: EventWriter<'w, Pointer<DragStart>>,
|
||||||
|
scroll_events: EventWriter<'w, Pointer<Scroll>>,
|
||||||
move_events: EventWriter<'w, Pointer<Move>>,
|
move_events: EventWriter<'w, Pointer<Move>>,
|
||||||
out_events: EventWriter<'w, Pointer<Out>>,
|
out_events: EventWriter<'w, Pointer<Out>>,
|
||||||
over_events: EventWriter<'w, Pointer<Over>>,
|
over_events: EventWriter<'w, Pointer<Over>>,
|
||||||
@ -750,6 +765,28 @@ pub fn pointer_events(
|
|||||||
event_writers.move_events.send(move_event);
|
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
|
// Canceled
|
||||||
PointerAction::Cancel => {
|
PointerAction::Cancel => {
|
||||||
// Emit a Cancel to the hovered entity.
|
// Emit a Cancel to the hovered entity.
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
use bevy_app::prelude::*;
|
use bevy_app::prelude::*;
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
use bevy_input::{
|
use bevy_input::{
|
||||||
|
mouse::MouseWheel,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
touch::{TouchInput, TouchPhase},
|
touch::{TouchInput, TouchPhase},
|
||||||
ButtonState,
|
ButtonState,
|
||||||
@ -156,6 +157,23 @@ pub fn mouse_pick_events(
|
|||||||
};
|
};
|
||||||
pointer_events.send(PointerInput::new(PointerId::Mouse, location, action));
|
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<Out>>()
|
||||||
.add_event::<Pointer<Over>>()
|
.add_event::<Pointer<Over>>()
|
||||||
.add_event::<Pointer<Released>>()
|
.add_event::<Pointer<Released>>()
|
||||||
|
.add_event::<Pointer<Scroll>>()
|
||||||
.add_systems(
|
.add_systems(
|
||||||
PreUpdate,
|
PreUpdate,
|
||||||
(generate_hovermap, update_interactions, pointer_events)
|
(generate_hovermap, update_interactions, pointer_events)
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
//! driven by lower-level input devices and consumed by higher-level interaction systems.
|
//! driven by lower-level input devices and consumed by higher-level interaction systems.
|
||||||
|
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
|
use bevy_input::mouse::MouseScrollUnit;
|
||||||
use bevy_math::Vec2;
|
use bevy_math::Vec2;
|
||||||
use bevy_platform_support::collections::HashMap;
|
use bevy_platform_support::collections::HashMap;
|
||||||
use bevy_reflect::prelude::*;
|
use bevy_reflect::prelude::*;
|
||||||
@ -251,6 +252,15 @@ pub enum PointerAction {
|
|||||||
/// How much the pointer moved from the previous position.
|
/// How much the pointer moved from the previous position.
|
||||||
delta: Vec2,
|
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 the pointer. Often used for touch events.
|
||||||
Cancel,
|
Cancel,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user