Skip to content

Commit

Permalink
hooking up observers and clicking for ui node (bevyengine#14695)
Browse files Browse the repository at this point in the history
Makes the newly merged picking usable for UI elements. 

currently it both triggers the events, as well as sends them as throught
commands.trigger_targets. We should probably figure out if this is
needed for them all.

# Objective

Hooks up obserers and picking for a very simple example

## Solution

upstreamed the UI picking backend from bevy_mod_picking

## Testing

tested with the new example picking/simple_picking.rs


---

---------

Co-authored-by: Lixou <[email protected]>
Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Kristoffer Søholm <[email protected]>
  • Loading branch information
4 people authored Aug 15, 2024
1 parent 0ea4666 commit 6adf31b
Show file tree
Hide file tree
Showing 13 changed files with 455 additions and 66 deletions.
12 changes: 12 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3352,6 +3352,18 @@ description = "Demonstrates how to rotate the skybox and the environment map sim
category = "3D Rendering"
wasm = false

[[example]]
name = "simple_picking"
path = "examples/picking/simple_picking.rs"
doc-scrape-examples = true
required-features = ["bevy_picking"]

[package.metadata.example.simple_picking]
name = "Showcases simple picking events and usage"
description = "Demonstrates how to use picking events to spawn simple objects"
category = "Picking"
wasm = true

[profile.wasm-release]
inherits = "release"
opt-level = "z"
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ meshlet_processor = ["bevy_pbr?/meshlet_processor"]
bevy_dev_tools = ["dep:bevy_dev_tools"]

# Provides a picking functionality
bevy_picking = ["dep:bevy_picking"]
bevy_picking = ["dep:bevy_picking", "bevy_ui?/bevy_picking"]

# Enable support for the ios_simulator by downgrading some rendering capabilities
ios_simulator = ["bevy_pbr?/ios_simulator", "bevy_render?/ios_simulator"]
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_internal/src/default_plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ plugin_group! {
bevy_gizmos:::GizmoPlugin,
#[cfg(feature = "bevy_state")]
bevy_state::app:::StatesPlugin,
#[cfg(feature = "bevy_picking")]
bevy_picking:::DefaultPickingPlugins,
#[cfg(feature = "bevy_dev_tools")]
bevy_dev_tools:::DevToolsPlugin,
#[cfg(feature = "bevy_ci_testing")]
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_internal/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,7 @@ pub use crate::state::prelude::*;
#[doc(hidden)]
#[cfg(feature = "bevy_gltf")]
pub use crate::gltf::prelude::*;

#[doc(hidden)]
#[cfg(feature = "bevy_picking")]
pub use crate::picking::prelude::*;
3 changes: 3 additions & 0 deletions crates/bevy_picking/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ bevy_transform = { path = "../bevy_transform", version = "0.15.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" }
bevy_window = { path = "../bevy_window", version = "0.15.0-dev" }

bevy_time = { path = "../bevy_time", version = "0.15.0-dev" }
bevy_asset = { path = "../bevy_asset", version = "0.15.0-dev" }

uuid = { version = "1.1", features = ["v4"] }

[lints]
Expand Down
131 changes: 68 additions & 63 deletions crates/bevy_picking/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ pub struct Drop {
/// Generates pointer events from input and focus data
#[allow(clippy::too_many_arguments)]
pub fn pointer_events(
mut commands: Commands,
// Input
mut input_presses: EventReader<InputPress>,
mut input_moves: EventReader<InputMove>,
Expand Down Expand Up @@ -237,12 +238,14 @@ pub fn pointer_events(
.iter()
.flat_map(|h| h.iter().map(|(entity, data)| (*entity, data.to_owned())))
{
pointer_move.send(Pointer::new(
let event = Pointer::new(
pointer_id,
location.clone(),
hovered_entity,
Move { hit, delta },
));
);
commands.trigger_targets(event.clone(), event.target);
pointer_move.send(event);
}
}

Expand All @@ -264,12 +267,14 @@ pub fn pointer_events(
);
continue;
};
pointer_up.send(Pointer::new(
let event = Pointer::new(
press_event.pointer_id,
location,
hovered_entity,
Up { button, hit },
));
);
commands.trigger_targets(event.clone(), event.target);
pointer_up.send(event);
}
}
for (hovered_entity, hit) in hover_map
Expand All @@ -285,12 +290,14 @@ pub fn pointer_events(
);
continue;
};
pointer_down.send(Pointer::new(
let event = Pointer::new(
press_event.pointer_id,
location,
hovered_entity,
Down { button, hit },
));
);
commands.trigger_targets(event.clone(), event.target);
pointer_down.send(event);
}
}
}
Expand All @@ -313,12 +320,9 @@ pub fn pointer_events(
);
continue;
};
pointer_over.send(Pointer::new(
pointer_id,
location,
hovered_entity,
Over { hit },
));
let event = Pointer::new(pointer_id, location, hovered_entity, Over { hit });
commands.trigger_targets(event.clone(), event.target);
pointer_over.send(event);
}
}

Expand All @@ -340,12 +344,9 @@ pub fn pointer_events(
);
continue;
};
pointer_out.send(Pointer::new(
pointer_id,
location,
hovered_entity,
Out { hit },
));
let event = Pointer::new(pointer_id, location, hovered_entity, Out { hit });
commands.trigger_targets(event.clone(), event.target);
pointer_out.send(event);
}
}
}
Expand All @@ -366,6 +367,11 @@ pub struct DragEntry {
/// Uses pointer events to determine when click and drag events occur.
#[allow(clippy::too_many_arguments)]
pub fn send_click_and_drag_events(
// for triggering observers
// - Pointer<Click>
// - Pointer<Drag>
// - Pointer<DragStart>
mut commands: Commands,
// Input
mut pointer_down: EventReader<Pointer<Down>>,
mut pointer_up: EventReader<Pointer<Up>>,
Expand All @@ -377,12 +383,9 @@ pub fn send_click_and_drag_events(
mut down_map: Local<
HashMap<(PointerId, PointerButton), HashMap<Entity, (Pointer<Down>, Instant)>>,
>,
// Output
// Outputs used for further processing
mut drag_map: ResMut<DragMap>,
mut pointer_click: EventWriter<Pointer<Click>>,
mut pointer_drag_start: EventWriter<Pointer<DragStart>>,
mut pointer_drag_end: EventWriter<Pointer<DragEnd>>,
mut pointer_drag: EventWriter<Pointer<Drag>>,
) {
let pointer_location = |pointer_id: PointerId| {
pointer_map
Expand Down Expand Up @@ -415,15 +418,16 @@ pub fn send_click_and_drag_events(
latest_pos: down.pointer_location.position,
},
);
pointer_drag_start.send(Pointer::new(
let event = Pointer::new(
pointer_id,
down.pointer_location.clone(),
down.target,
DragStart {
button,
hit: down.hit.clone(),
},
));
);
commands.trigger_targets(event, down.target);
}

for (dragged_entity, drag) in drag_list.iter_mut() {
Expand All @@ -433,12 +437,9 @@ pub fn send_click_and_drag_events(
delta: location.position - drag.latest_pos,
};
drag.latest_pos = location.position;
pointer_drag.send(Pointer::new(
pointer_id,
location.clone(),
*dragged_entity,
drag_event,
));
let target = *dragged_entity;
let event = Pointer::new(pointer_id, location.clone(), target, drag_event);
commands.trigger_targets(event, target);
}
}
}
Expand All @@ -458,7 +459,7 @@ pub fn send_click_and_drag_events(
.and_then(|down| down.get(&target))
{
let duration = now - *down_instant;
pointer_click.send(Pointer::new(
let event = Pointer::new(
pointer_id,
pointer_location,
target,
Expand All @@ -467,7 +468,8 @@ pub fn send_click_and_drag_events(
hit,
duration,
},
));
);
commands.trigger_targets(event, target);
}
}

Expand Down Expand Up @@ -501,19 +503,22 @@ pub fn send_click_and_drag_events(
button: press.button,
distance: drag.latest_pos - drag.start_pos,
};
pointer_drag_end.send(Pointer::new(
press.pointer_id,
location.clone(),
drag_target,
drag_end,
));
let event = Pointer::new(press.pointer_id, location.clone(), drag_target, drag_end);
commands.trigger_targets(event.clone(), event.target);
pointer_drag_end.send(event);
}
}
}

/// Uses pointer events to determine when drag-over events occur
#[allow(clippy::too_many_arguments)]
pub fn send_drag_over_events(
// uses this to trigger the following
// - Pointer<DragEnter>,
// - Pointer<DragOver>,
// - Pointer<DragLeave>,
// - Pointer<Drop>,
mut commands: Commands,
// Input
drag_map: Res<DragMap>,
mut pointer_over: EventReader<Pointer<Over>>,
Expand All @@ -522,12 +527,6 @@ pub fn send_drag_over_events(
mut pointer_drag_end: EventReader<Pointer<DragEnd>>,
// Local
mut drag_over_map: Local<HashMap<(PointerId, PointerButton), HashMap<Entity, HitData>>>,

// Output
mut pointer_drag_enter: EventWriter<Pointer<DragEnter>>,
mut pointer_drag_over: EventWriter<Pointer<DragOver>>,
mut pointer_drag_leave: EventWriter<Pointer<DragLeave>>,
mut pointer_drop: EventWriter<Pointer<Drop>>,
) {
// Fire PointerDragEnter events.
for Pointer {
Expand All @@ -548,17 +547,17 @@ pub fn send_drag_over_events(
{
let drag_entry = drag_over_map.entry((pointer_id, button)).or_default();
drag_entry.insert(target, hit.clone());
let event = DragEnter {
button,
dragged: *drag_target,
hit: hit.clone(),
};
pointer_drag_enter.send(Pointer::new(
let event = Pointer::new(
pointer_id,
pointer_location.clone(),
target,
event,
));
DragEnter {
button,
dragged: *drag_target,
hit: hit.clone(),
},
);
commands.trigger_targets(event, target);
}
}
}
Expand All @@ -580,7 +579,7 @@ pub fn send_drag_over_events(
|&&drag_target| target != drag_target, /* can't drag over itself */
)
{
pointer_drag_over.send(Pointer::new(
let event = Pointer::new(
pointer_id,
pointer_location.clone(),
target,
Expand All @@ -589,7 +588,8 @@ pub fn send_drag_over_events(
dragged: *drag_target,
hit: hit.clone(),
},
));
);
commands.trigger_targets(event, target);
}
}
}
Expand All @@ -598,7 +598,7 @@ pub fn send_drag_over_events(
for Pointer {
pointer_id,
pointer_location,
target,
target: drag_end_target,
event: DragEnd {
button,
distance: _,
Expand All @@ -609,26 +609,30 @@ pub fn send_drag_over_events(
continue;
};
for (dragged_over, hit) in drag_over_set.drain() {
pointer_drag_leave.send(Pointer::new(
let target = dragged_over;
let event = Pointer::new(
pointer_id,
pointer_location.clone(),
dragged_over,
DragLeave {
button,
dragged: target,
dragged: drag_end_target,
hit: hit.clone(),
},
));
pointer_drop.send(Pointer::new(
);
commands.trigger_targets(event, target);

let event = Pointer::new(
pointer_id,
pointer_location.clone(),
dragged_over,
target,
Drop {
button,
dropped: target,
hit: hit.clone(),
},
));
);
commands.trigger_targets(event, target);
}
}

Expand All @@ -651,7 +655,7 @@ pub fn send_drag_over_events(
continue;
};
for drag_target in drag_list.keys() {
pointer_drag_leave.send(Pointer::new(
let event = Pointer::new(
pointer_id,
pointer_location.clone(),
target,
Expand All @@ -660,7 +664,8 @@ pub fn send_drag_over_events(
dragged: *drag_target,
hit: hit.clone(),
},
));
);
commands.trigger_targets(event, target);
}
}
}
Expand Down
Loading

0 comments on commit 6adf31b

Please sign in to comment.