From fe6e1ce28fb6fd9b0d6bd6b6bc1b81cae95994ad Mon Sep 17 00:00:00 2001 From: Alejandro Perea Date: Thu, 5 May 2022 23:26:15 +0200 Subject: [PATCH] Add *_released & *_clicked PointerState methods (#1582) --- CHANGELOG.md | 2 +- egui/src/context.rs | 2 +- egui/src/input_state.rs | 46 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 873e337e3d7..440fa8fc630 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui-w ## Unreleased - +* Add `*_released` & `*_clicked` methods for `PointerState`. ## 0.18.1 - 2022-05-01 * Change `Shape::Callback` from `&dyn Any` to `&mut dyn Any` to support more backends. diff --git a/egui/src/context.rs b/egui/src/context.rs index e2609b4a86b..63e1a2407e6 100644 --- a/egui/src/context.rs +++ b/egui/src/context.rs @@ -375,7 +375,7 @@ impl Context { for pointer_event in &input.pointer.pointer_events { match pointer_event { PointerEvent::Moved(_) => {} - PointerEvent::Pressed(_) => { + PointerEvent::Pressed { .. } => { if hovered { if sense.click && memory.interaction.click_id.is_none() { // potential start of a click diff --git a/egui/src/input_state.rs b/egui/src/input_state.rs index 5d043fb0f4f..2ca5d38a17f 100644 --- a/egui/src/input_state.rs +++ b/egui/src/input_state.rs @@ -367,13 +367,16 @@ impl Click { #[derive(Clone, Debug, PartialEq)] pub(crate) enum PointerEvent { Moved(Pos2), - Pressed(Pos2), + Pressed { + position: Pos2, + button: PointerButton, + }, Released(Option), } impl PointerEvent { pub fn is_press(&self) -> bool { - matches!(self, PointerEvent::Pressed(_)) + matches!(self, PointerEvent::Pressed { .. }) } pub fn is_release(&self) -> bool { matches!(self, PointerEvent::Released(_)) @@ -509,7 +512,10 @@ impl PointerState { self.press_origin = Some(pos); self.press_start_time = Some(time); self.has_moved_too_much_for_a_click = false; - self.pointer_events.push(PointerEvent::Pressed(pos)); + self.pointer_events.push(PointerEvent::Pressed { + position: pos, + button, + }); } else { let clicked = self.could_any_button_be_click(); @@ -667,6 +673,23 @@ impl PointerState { self.pointer_events.iter().any(|event| event.is_release()) } + /// Was the button given released this frame? + pub fn button_released(&self, button: PointerButton) -> bool { + self.pointer_events + .iter() + .any(|event| matches!(event, &PointerEvent::Released(Some(Click{button: b, ..})) if button == b)) + } + + /// Was the primary button released this frame? + pub fn primary_released(&self) -> bool { + self.button_released(PointerButton::Primary) + } + + /// Was the secondary button released this frame? + pub fn secondary_released(&self) -> bool { + self.button_released(PointerButton::Secondary) + } + /// Is any pointer button currently down? pub fn any_down(&self) -> bool { self.down.iter().any(|&down| down) @@ -677,6 +700,23 @@ impl PointerState { self.pointer_events.iter().any(|event| event.is_click()) } + /// Was the button given clicked this frame? + pub fn button_clicked(&self, button: PointerButton) -> bool { + self.pointer_events + .iter() + .any(|event| matches!(event, &PointerEvent::Pressed { button: b, .. } if button == b)) + } + + /// Was the primary button clicked this frame? + pub fn primary_clicked(&self) -> bool { + self.button_clicked(PointerButton::Primary) + } + + /// Was the secondary button clicked this frame? + pub fn secondary_clicked(&self) -> bool { + self.button_clicked(PointerButton::Secondary) + } + // /// Was this button pressed (`!down -> down`) this frame? // /// This can sometimes return `true` even if `any_down() == false` // /// because a press can be shorted than one frame.