From 746b217767b04165393bea43883f5fe7a1bce92d Mon Sep 17 00:00:00 2001 From: Lictex Steaven Date: Mon, 26 Dec 2022 18:15:31 +0800 Subject: [PATCH 1/4] add button release events for drags --- crates/egui/src/context.rs | 8 +++---- crates/egui/src/input_state.rs | 40 +++++++++++++++++++++++----------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index dc4a479b79de..d94f9b790878 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -564,17 +564,17 @@ impl Context { } } } - PointerEvent::Released(click) => { + PointerEvent::Released { click, button } => { response.drag_released = response.dragged; response.dragged = false; if hovered && response.is_pointer_button_down_on { if let Some(click) = click { let clicked = hovered && response.is_pointer_button_down_on; - response.clicked[click.button as usize] = clicked; - response.double_clicked[click.button as usize] = + response.clicked[*button as usize] = clicked; + response.double_clicked[*button as usize] = clicked && click.is_double(); - response.triple_clicked[click.button as usize] = + response.triple_clicked[*button as usize] = clicked && click.is_triple(); } } diff --git a/crates/egui/src/input_state.rs b/crates/egui/src/input_state.rs index 050bcc3b318d..8fd645cb526a 100644 --- a/crates/egui/src/input_state.rs +++ b/crates/egui/src/input_state.rs @@ -447,7 +447,6 @@ impl InputState { #[derive(Clone, Debug, PartialEq)] pub(crate) struct Click { pub pos: Pos2, - pub button: PointerButton, /// 1 or 2 (double-click) or 3 (triple-click) pub count: u32, /// Allows you to check for e.g. shift-click @@ -471,7 +470,10 @@ pub(crate) enum PointerEvent { position: Pos2, button: PointerButton, }, - Released(Option), + Released { + click: Option, + button: PointerButton, + }, } impl PointerEvent { @@ -480,11 +482,11 @@ impl PointerEvent { } pub fn is_release(&self) -> bool { - matches!(self, PointerEvent::Released(_)) + matches!(self, PointerEvent::Released { .. }) } pub fn is_click(&self) -> bool { - matches!(self, PointerEvent::Released(Some(_click))) + matches!(self, PointerEvent::Released { click: Some(_), .. }) } } @@ -639,7 +641,6 @@ impl PointerState { Some(Click { pos, - button, count, modifiers, }) @@ -647,7 +648,8 @@ impl PointerState { None }; - self.pointer_events.push(PointerEvent::Released(click)); + self.pointer_events + .push(PointerEvent::Released { click, button }); self.press_origin = None; self.press_start_time = None; @@ -779,7 +781,7 @@ impl PointerState { 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)) + .any(|event| matches!(event, &PointerEvent::Released{button: b, ..} if button == b)) } /// Was the primary button released this frame? @@ -811,16 +813,28 @@ impl PointerState { /// Was the button given double clicked this frame? pub fn button_double_clicked(&self, button: PointerButton) -> bool { - self.pointer_events - .iter() - .any(|event| matches!(&event, PointerEvent::Released(Some(click)) if click.button == button && click.is_double())) + self.pointer_events.iter().any(|event| { + matches!( + &event, + PointerEvent::Released { + click: Some(click), + button: b, + } if *b == button && click.is_double() + ) + }) } /// Was the button given triple clicked this frame? pub fn button_triple_clicked(&self, button: PointerButton) -> bool { - self.pointer_events - .iter() - .any(|event| matches!(&event, PointerEvent::Released(Some(click)) if click.button == button && click.is_triple())) + self.pointer_events.iter().any(|event| { + matches!( + &event, + PointerEvent::Released { + click: Some(click), + button: b, + } if *b == button && click.is_triple() + ) + }) } /// Was the primary button clicked this frame? From 6fb36d7db61f3fba474ccf11e8d06c57957162f1 Mon Sep 17 00:00:00 2001 From: Lictex Steaven Date: Mon, 26 Dec 2022 19:02:28 +0800 Subject: [PATCH 2/4] add utility functions --- CHANGELOG.md | 3 +++ crates/egui/src/input_state.rs | 29 +++++++++++++++++------------ crates/egui/src/response.rs | 10 ++++++++++ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d59b8bfa25e0..a17c142db681 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG ## Unreleased ### Added ⭐ +* Add `Response::drag_started_by` and `Response::drag_released_by` for convenience, similar to `dragged` and `dragged_by`. +* Add `PointerState::*_pressed` to check if the given button was pressed in this frame. * `Event::Key` now has a `repeat` field that is set to `true` if the event was the result of a key-repeat ([#2435](https://github.com/emilk/egui/pull/2435)). * Add `Slider::drag_value_speed`, which lets you ask for finer precision when dragging the slider value rather than the actual slider. * Add `Memory::any_popup_open`, which returns true if any popup is currently open ([#2464](https://github.com/emilk/egui/pull/2464)). @@ -18,6 +20,7 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG * Improved the algorithm for picking the number of decimals to show when hovering values in the `Plot`. ### Fixed 🐛 +* Trigger `PointerEvent::Released` for drags ([#2094](https://github.com/emilk/egui/pull/2094)). * Expose `TextEdit`'s multiline flag to AccessKit ([#2448](https://github.com/emilk/egui/pull/2448)). * Don't render `\r` (Carriage Return) ([#2452](https://github.com/emilk/egui/pull/2452)). diff --git a/crates/egui/src/input_state.rs b/crates/egui/src/input_state.rs index 8fd645cb526a..92c6a32f7477 100644 --- a/crates/egui/src/input_state.rs +++ b/crates/egui/src/input_state.rs @@ -777,6 +777,13 @@ impl PointerState { self.pointer_events.iter().any(|event| event.is_release()) } + /// Was the button given pressed this frame? + pub fn button_pressed(&self, button: PointerButton) -> bool { + self.pointer_events + .iter() + .any(|event| matches!(event, &PointerEvent::Pressed{button: b, ..} if button == b)) + } + /// Was the button given released this frame? pub fn button_released(&self, button: PointerButton) -> bool { self.pointer_events @@ -784,6 +791,16 @@ impl PointerState { .any(|event| matches!(event, &PointerEvent::Released{button: b, ..} if button == b)) } + /// Was the primary button pressed this frame? + pub fn primary_pressed(&self) -> bool { + self.button_pressed(PointerButton::Primary) + } + + /// Was the secondary button pressed this frame? + pub fn secondary_pressed(&self) -> bool { + self.button_pressed(PointerButton::Secondary) + } + /// Was the primary button released this frame? pub fn primary_released(&self) -> bool { self.button_released(PointerButton::Primary) @@ -847,18 +864,6 @@ impl PointerState { 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. - // pub fn button_pressed(&self, button: PointerButton) -> bool { - // self.pointer_events.iter().any(|event| event.is_press()) - // } - - // /// Was this button released (`down -> !down`) this frame? - // pub fn button_released(&self, button: PointerButton) -> bool { - // self.pointer_events.iter().any(|event| event.is_release()) - // } - /// Is this button currently down? #[inline(always)] pub fn button_down(&self, button: PointerButton) -> bool { diff --git a/crates/egui/src/response.rs b/crates/egui/src/response.rs index 072f528059ac..28ab3fd55dda 100644 --- a/crates/egui/src/response.rs +++ b/crates/egui/src/response.rs @@ -278,11 +278,21 @@ impl Response { self.dragged && self.ctx.input().pointer.any_pressed() } + /// Did a drag on this widgets by the button begin this frame? + pub fn drag_started_by(&self, button: PointerButton) -> bool { + self.drag_started() && self.ctx.input().pointer.button_pressed(button) + } + /// The widget was being dragged, but now it has been released. pub fn drag_released(&self) -> bool { self.drag_released } + /// The widget was being dragged by the button, but now it has been released. + pub fn drag_released_by(&self, button: PointerButton) -> bool { + self.drag_released() && self.ctx.input().pointer.button_released(button) + } + /// If dragged, how many points were we dragged and in what direction? pub fn drag_delta(&self) -> Vec2 { if self.dragged() { From e53f103d47781406a0e9f500c9737d8a648081e0 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 24 Jan 2023 09:29:02 +0100 Subject: [PATCH 3/4] fix CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a17c142db681..2f76afa2f313 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG * Improved the algorithm for picking the number of decimals to show when hovering values in the `Plot`. ### Fixed 🐛 -* Trigger `PointerEvent::Released` for drags ([#2094](https://github.com/emilk/egui/pull/2094)). +* Trigger `PointerEvent::Released` for drags ([#2507](https://github.com/emilk/egui/pull/2507)). * Expose `TextEdit`'s multiline flag to AccessKit ([#2448](https://github.com/emilk/egui/pull/2448)). * Don't render `\r` (Carriage Return) ([#2452](https://github.com/emilk/egui/pull/2452)). From a4bd86a7b471a53733721593b2ccead2802de2d4 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 24 Jan 2023 09:29:09 +0100 Subject: [PATCH 4/4] fix CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f76afa2f313..0faf21e1cbe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,8 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG ## Unreleased ### Added ⭐ -* Add `Response::drag_started_by` and `Response::drag_released_by` for convenience, similar to `dragged` and `dragged_by`. -* Add `PointerState::*_pressed` to check if the given button was pressed in this frame. +* Add `Response::drag_started_by` and `Response::drag_released_by` for convenience, similar to `dragged` and `dragged_by` ([#2507](https://github.com/emilk/egui/pull/2507)). +* Add `PointerState::*_pressed` to check if the given button was pressed in this frame ([#2507](https://github.com/emilk/egui/pull/2507)). * `Event::Key` now has a `repeat` field that is set to `true` if the event was the result of a key-repeat ([#2435](https://github.com/emilk/egui/pull/2435)). * Add `Slider::drag_value_speed`, which lets you ask for finer precision when dragging the slider value rather than the actual slider. * Add `Memory::any_popup_open`, which returns true if any popup is currently open ([#2464](https://github.com/emilk/egui/pull/2464)).