Commit c7f607a
authored
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
1 file changed
+1
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
766 | 766 | | |
767 | 767 | | |
768 | 768 | | |
| 769 | + | |
769 | 770 | | |
770 | 771 | | |
771 | 772 | | |
| |||
0 commit comments