Skip to content

Commit c7f607a

Browse files
fix: return current hit for DragDrop event (#21853)
# Objective - previously, the hit field in DragDrop event is the clone of the DragEnter one. - Fixes #21849. ## Solution - Describe the solution used to achieve the objective above. - use the hit from hover_map rather than the hit in state.dragging_over ## Testing - Did you test these changes? If so, how? - yes, tested this simple demo and examples/picking/debug_picking.rs and ui_drag_and_drop.rs on my mac. - Are there any parts that need more testing? - no, i think it's enough. - How can other people (reviewers) test your changes? Is there anything specific they need to know? - i pasted the code for testing at the bottom - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? - mac, but it doesnt matter --- ## Showcase https://github.com/user-attachments/assets/ff35a03d-00a0-41b8-952f-3f2e77530d5a https://github.com/user-attachments/assets/a7aa5172-f89c-4010-a153-b90171621204 <details> <summary>Click to view showcase</summary> ```rust use bevy::{ prelude::*, window::WindowMode, }; #[derive(Component)] struct Area; #[derive(Component)] struct ExampleButton; #[derive(Component)] struct GhostElement; #[derive(Component)] struct Element; const AREA_SIZE: f32 = 500.0; const BUTTON_SIZE: i32 = 50; const ELEMENT_SIZE: f32 = 25.0; #[bevy_main] pub fn main() -> AppExit { App::new() .add_plugins(( DefaultPlugins .set(WindowPlugin { primary_window: Some(Window { mode: WindowMode::BorderlessFullscreen(MonitorSelection::Primary), ..default() }), ..default() }), MeshPickingPlugin, )) .add_systems(Startup, setup) .run() } fn setup( mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>, mut materials: ResMut<Assets<ColorMaterial>>, ) { commands.spawn(Camera2d); commands.spawn(( Node { width: percent(100), height: percent(100), align_items: AlignItems::Center, justify_content: JustifyContent::Start, ..default() }, Pickable::IGNORE, )) .with_children(|parent| { parent.spawn(( ExampleButton, Button, Node { width: px(BUTTON_SIZE), height: px(BUTTON_SIZE), margin: UiRect::all(px(10)), border_radius: BorderRadius::MAX, ..default() }, BackgroundColor(Color::srgb(1.0, 0.0, 0.0)), )) .observe(|mut event: On<Pointer<DragStart>>, mut button_color: Single<&mut BackgroundColor, With<ExampleButton>>| { button_color.0 = Color::srgb(1.0, 0.5, 0.0); event.propagate(false); }) .observe(|mut event: On<Pointer<DragEnd>>, mut button_color: Single<&mut BackgroundColor, With<ExampleButton>>| { button_color.0 = Color::srgb(1.0, 0.0, 0.0); event.propagate(false); }); }); commands.spawn(( Area, Mesh2d(meshes.add(Rectangle::new(AREA_SIZE, AREA_SIZE))), MeshMaterial2d(materials.add(Color::srgb(0.1, 0.4, 0.1))), Transform::IDENTITY, )) .observe(on_enter) .observe(on_over) .observe(on_drop) .observe(on_leave); } fn on_enter( mut event: On<Pointer<DragEnter>>, button: Single<Entity, With<ExampleButton>>, mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>, mut materials: ResMut<Assets<ColorMaterial>>, ) { if event.dragged == *button { let Some(position) = event.hit.position else { return; }; commands.spawn(( GhostElement, Mesh2d(meshes.add(Circle::new(ELEMENT_SIZE))), MeshMaterial2d(materials.add(Color::srgba(1.0, 1.0, 0.6, 0.5))), Transform::from_translation(position), Pickable::IGNORE, )); event.propagate(false); } } fn on_over( mut event: On<Pointer<DragOver>>, button: Single<Entity, With<ExampleButton>>, mut ghost_element_transform: Single<&mut Transform, With<GhostElement>>, ) { if event.dragged == *button { let Some(position) = event.hit.position else { return; }; ghost_element_transform.translation = position; event.propagate(false); } } fn on_drop( mut event: On<Pointer<DragDrop>>, button: Single<Entity, With<ExampleButton>>, mut commands: Commands, ghost_element: Single<Entity, With<GhostElement>>, mut meshes: ResMut<Assets<Mesh>>, mut materials: ResMut<Assets<ColorMaterial>>, ) { if event.dropped == *button { println!("{:?}", event); commands.entity(*ghost_element).despawn(); let Some(position) = event.hit.position else { return; }; commands.spawn(( Element, Mesh2d(meshes.add(Circle::new(ELEMENT_SIZE))), MeshMaterial2d(materials.add(Color::srgb(1.0, 1.0, 0.6))), Transform::from_translation(position), Pickable::IGNORE, )); event.propagate(false); } } fn on_leave( mut event: On<Pointer<DragLeave>>, button: Single<Entity, With<ExampleButton>>, mut commands: Commands, ghost_element: Single<Entity, With<GhostElement>>, ) { if event.dragged == *button { commands.entity(*ghost_element).despawn(); event.propagate(false); } } ``` </details>
1 parent f21114a commit c7f607a

File tree

1 file changed

+1
-0
lines changed

1 file changed

+1
-0
lines changed

crates/bevy_picking/src/events.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,7 @@ pub fn pointer_events(
766766
.flat_map(|h| h.iter().map(|(entity, data)| (*entity, data.to_owned())))
767767
.filter(|(hovered_entity, _)| *hovered_entity != *drag_target)
768768
{
769+
*state.dragging_over.get_mut(&hovered_entity).unwrap() = hit.clone();
769770
let drag_over_event = Pointer::new(
770771
pointer_id,
771772
location.clone(),

0 commit comments

Comments
 (0)