Flattened PointerAction::Pressed into Press and Release. (#17424)

Fixes #17397.
Also renamed all variants into present-tense.
## Migration Guide
- `PointerAction::Pressed` has been seperated into two variants,
`PointerAction::Press` and `PointerAction::Release`.
- `PointerAction::Moved` has been renamed to `PointerAction::Move`. 
- `PointerAction::Canceled` has been renamed to `PointerAction::Cancel`.
This commit is contained in:
AlephCubed 2025-01-19 14:51:57 -08:00 committed by GitHub
parent e66aef2d7a
commit 5d0e9cfb36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 156 additions and 165 deletions

View File

@ -50,9 +50,7 @@ use tracing::debug;
use crate::{ use crate::{
backend::{prelude::PointerLocation, HitData}, backend::{prelude::PointerLocation, HitData},
hover::{HoverMap, PreviousHoverMap}, hover::{HoverMap, PreviousHoverMap},
pointer::{ pointer::{Location, PointerAction, PointerButton, PointerId, PointerInput, PointerMap},
Location, PointerAction, PointerButton, PointerId, PointerInput, PointerMap, PressDirection,
},
}; };
/// Stores the common data needed for all pointer events. /// Stores the common data needed for all pointer events.
@ -538,13 +536,9 @@ pub fn pointer_events(
} in input_events.read().cloned() } in input_events.read().cloned()
{ {
match action { match action {
// Pressed Button PointerAction::Press(button) => {
PointerAction::Pressed { direction, button } => {
let state = pointer_state.get_mut(pointer_id, button); let state = pointer_state.get_mut(pointer_id, button);
// The sequence of events emitted depends on if this is a press or a release
match direction {
PressDirection::Pressed => {
// If it's a press, emit a Pressed event and mark the hovered entities as pressed // If it's a press, emit a Pressed event and mark the hovered entities as pressed
for (hovered_entity, hit) in hover_map for (hovered_entity, hit) in hover_map
.get(&pointer_id) .get(&pointer_id)
@ -568,7 +562,9 @@ pub fn pointer_events(
.insert(hovered_entity, (location.clone(), now, hit)); .insert(hovered_entity, (location.clone(), now, hit));
} }
} }
PressDirection::Released => { PointerAction::Release(button) => {
let state = pointer_state.get_mut(pointer_id, button);
// Emit Click and Up events on all the previously hovered entities. // Emit Click and Up events on all the previously hovered entities.
for (hovered_entity, hit) in previous_hover_map for (hovered_entity, hit) in previous_hover_map
.get(&pointer_id) .get(&pointer_id)
@ -576,8 +572,7 @@ pub fn pointer_events(
.flat_map(|h| h.iter().map(|(entity, data)| (*entity, data.clone()))) .flat_map(|h| h.iter().map(|(entity, data)| (*entity, data.clone())))
{ {
// If this pointer previously pressed the hovered entity, emit a Click event // If this pointer previously pressed the hovered entity, emit a Click event
if let Some((_, press_instant, _)) = state.pressing.get(&hovered_entity) if let Some((_, press_instant, _)) = state.pressing.get(&hovered_entity) {
{
let click_event = Pointer::new( let click_event = Pointer::new(
pointer_id, pointer_id,
location.clone(), location.clone(),
@ -656,10 +651,8 @@ pub fn pointer_events(
state.dragging.clear(); state.dragging.clear();
state.dragging_over.clear(); state.dragging_over.clear();
} }
}
}
// Moved // Moved
PointerAction::Moved { delta } => { PointerAction::Move { delta } => {
if delta == Vec2::ZERO { if delta == Vec2::ZERO {
continue; // If delta is zero, the following events will not be triggered. continue; // If delta is zero, the following events will not be triggered.
} }
@ -757,7 +750,7 @@ pub fn pointer_events(
} }
} }
// Canceled // Canceled
PointerAction::Canceled => { PointerAction::Cancel => {
// Emit a Cancel to the hovered entity. // Emit a Cancel to the hovered entity.
for (hovered_entity, hit) in hover_map for (hovered_entity, hit) in hover_map
.get(&pointer_id) .get(&pointer_id)

View File

@ -118,7 +118,7 @@ fn build_over_map(
let cancelled_pointers: HashSet<PointerId> = pointer_input let cancelled_pointers: HashSet<PointerId> = pointer_input
.read() .read()
.filter_map(|p| { .filter_map(|p| {
if let PointerAction::Canceled = p.action { if let PointerAction::Cancel = p.action {
Some(p.pointer_id) Some(p.pointer_id)
} else { } else {
None None

View File

@ -27,7 +27,6 @@ use tracing::debug;
use crate::pointer::{ use crate::pointer::{
Location, PointerAction, PointerButton, PointerId, PointerInput, PointerLocation, Location, PointerAction, PointerButton, PointerId, PointerInput, PointerLocation,
PressDirection,
}; };
use crate::PickSet; use crate::PickSet;
@ -128,7 +127,7 @@ pub fn mouse_pick_events(
pointer_events.send(PointerInput::new( pointer_events.send(PointerInput::new(
PointerId::Mouse, PointerId::Mouse,
location, location,
PointerAction::Moved { PointerAction::Move {
delta: event.position - *cursor_last, delta: event.position - *cursor_last,
}, },
)); ));
@ -151,15 +150,11 @@ pub fn mouse_pick_events(
MouseButton::Middle => PointerButton::Middle, MouseButton::Middle => PointerButton::Middle,
MouseButton::Other(_) | MouseButton::Back | MouseButton::Forward => continue, MouseButton::Other(_) | MouseButton::Back | MouseButton::Forward => continue,
}; };
let direction = match input.state { let action = match input.state {
ButtonState::Pressed => PressDirection::Pressed, ButtonState::Pressed => PointerAction::Press(button),
ButtonState::Released => PressDirection::Released, ButtonState::Released => PointerAction::Release(button),
}; };
pointer_events.send(PointerInput::new( pointer_events.send(PointerInput::new(PointerId::Mouse, location, action));
PointerId::Mouse,
location,
PointerAction::Pressed { direction, button },
));
} }
_ => {} _ => {}
} }
@ -197,10 +192,7 @@ pub fn touch_pick_events(
pointer_events.send(PointerInput::new( pointer_events.send(PointerInput::new(
pointer, pointer,
location, location,
PointerAction::Pressed { PointerAction::Press(PointerButton::Primary),
direction: PressDirection::Pressed,
button: PointerButton::Primary,
},
)); ));
touch_cache.insert(touch.id, *touch); touch_cache.insert(touch.id, *touch);
@ -214,7 +206,7 @@ pub fn touch_pick_events(
pointer_events.send(PointerInput::new( pointer_events.send(PointerInput::new(
pointer, pointer,
location, location,
PointerAction::Moved { PointerAction::Move {
delta: touch.position - last_touch.position, delta: touch.position - last_touch.position,
}, },
)); ));
@ -225,10 +217,7 @@ pub fn touch_pick_events(
pointer_events.send(PointerInput::new( pointer_events.send(PointerInput::new(
pointer, pointer,
location, location,
PointerAction::Pressed { PointerAction::Release(PointerButton::Primary),
direction: PressDirection::Released,
button: PointerButton::Primary,
},
)); ));
touch_cache.remove(&touch.id); touch_cache.remove(&touch.id);
} }
@ -236,7 +225,7 @@ pub fn touch_pick_events(
pointer_events.send(PointerInput::new( pointer_events.send(PointerInput::new(
pointer, pointer,
location, location,
PointerAction::Canceled, PointerAction::Cancel,
)); ));
touch_cache.remove(&touch.id); touch_cache.remove(&touch.id);
} }

View File

@ -239,23 +239,20 @@ impl Location {
} }
} }
/// Types of actions that can be taken by pointers. /// Event sent to drive a pointer.
#[derive(Debug, Clone, Copy, Reflect)] #[derive(Debug, Clone, Copy, Reflect)]
pub enum PointerAction { pub enum PointerAction {
/// A button has been pressed on the pointer. /// Causes the pointer to press a button.
Pressed { Press(PointerButton),
/// The press state, either pressed or released. /// Causes the pointer to release a button.
direction: PressDirection, Release(PointerButton),
/// The button that was pressed. /// Move the pointer.
button: PointerButton, Move {
},
/// The pointer has moved.
Moved {
/// How much the pointer moved from the previous position. /// How much the pointer moved from the previous position.
delta: Vec2, delta: Vec2,
}, },
/// The pointer has been canceled. The OS can cause this to happen to touch events. /// Cancel the pointer. Often used for touch events.
Canceled, Cancel,
} }
/// An input event effecting a pointer. /// An input event effecting a pointer.
@ -263,7 +260,7 @@ pub enum PointerAction {
pub struct PointerInput { pub struct PointerInput {
/// The id of the pointer. /// The id of the pointer.
pub pointer_id: PointerId, pub pointer_id: PointerId,
/// The location of the pointer. For [[`PointerAction::Moved`]], this is the location after the movement. /// The location of the pointer. For [`PointerAction::Move`], this is the location after the movement.
pub location: Location, pub location: Location,
/// The action that the event describes. /// The action that the event describes.
pub action: PointerAction, pub action: PointerAction,
@ -284,8 +281,8 @@ impl PointerInput {
/// Returns true if the `target_button` of this pointer was just pressed. /// Returns true if the `target_button` of this pointer was just pressed.
#[inline] #[inline]
pub fn button_just_pressed(&self, target_button: PointerButton) -> bool { pub fn button_just_pressed(&self, target_button: PointerButton) -> bool {
if let PointerAction::Pressed { direction, button } = self.action { if let PointerAction::Press(button) = self.action {
direction == PressDirection::Pressed && button == target_button button == target_button
} else { } else {
false false
} }
@ -294,8 +291,8 @@ impl PointerInput {
/// Returns true if the `target_button` of this pointer was just released. /// Returns true if the `target_button` of this pointer was just released.
#[inline] #[inline]
pub fn button_just_released(&self, target_button: PointerButton) -> bool { pub fn button_just_released(&self, target_button: PointerButton) -> bool {
if let PointerAction::Pressed { direction, button } = self.action { if let PointerAction::Release(button) = self.action {
direction == PressDirection::Released && button == target_button button == target_button
} else { } else {
false false
} }
@ -308,21 +305,33 @@ impl PointerInput {
) { ) {
for event in events.read() { for event in events.read() {
match event.action { match event.action {
PointerAction::Pressed { direction, button } => { PointerAction::Press(button) => {
pointers pointers
.iter_mut() .iter_mut()
.for_each(|(pointer_id, _, mut pointer)| { .for_each(|(pointer_id, _, mut pointer)| {
if *pointer_id == event.pointer_id { if *pointer_id == event.pointer_id {
let is_pressed = direction == PressDirection::Pressed;
match button { match button {
PointerButton::Primary => pointer.primary = is_pressed, PointerButton::Primary => pointer.primary = true,
PointerButton::Secondary => pointer.secondary = is_pressed, PointerButton::Secondary => pointer.secondary = true,
PointerButton::Middle => pointer.middle = is_pressed, PointerButton::Middle => pointer.middle = true,
} }
} }
}); });
} }
PointerAction::Moved { .. } => { PointerAction::Release(button) => {
pointers
.iter_mut()
.for_each(|(pointer_id, _, mut pointer)| {
if *pointer_id == event.pointer_id {
match button {
PointerButton::Primary => pointer.primary = false,
PointerButton::Secondary => pointer.secondary = false,
PointerButton::Middle => pointer.middle = false,
}
}
});
}
PointerAction::Move { .. } => {
pointers.iter_mut().for_each(|(id, mut pointer, _)| { pointers.iter_mut().for_each(|(id, mut pointer, _)| {
if *id == event.pointer_id { if *id == event.pointer_id {
pointer.location = Some(event.location.to_owned()); pointer.location = Some(event.location.to_owned());