From 66ae0ed7b92ebfc46c2118ccca09b176e1bb532a Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 26 Dec 2020 11:19:39 +0100 Subject: [PATCH] Add Id to Response --- CHANGELOG.md | 2 ++ egui/src/containers/area.rs | 13 +++++++------ egui/src/containers/panel.rs | 7 ++++--- egui/src/context.rs | 29 ++++++++++++++++------------- egui/src/demos/drag_and_drop.rs | 6 ++---- egui/src/types.rs | 8 +++++++- egui/src/ui.rs | 28 +++++++++++++--------------- egui/src/widgets/mod.rs | 6 +++--- 8 files changed, 54 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d45649d3..a7528e8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * You can now easily constrain Egui to a portion of the screen using `RawInput::screen_rect`. * You can now control the minimum and maixumum number of decimals to show in a `Slider` or `DragValue`. * Add `egui::math::Rot2`: rotation helper. +* `Response` now contains the `Id` of the widget it pertains to. ### Changed 🔧 @@ -44,6 +45,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Deprecated * `RawInput::screen_size` - use `RawInput::screen_rect` instead. * left/centered/right column functions on `Ui`. +* `ui.interact_hover` and `ui.hovered`. ## 0.5.0 - 2020-12-13 diff --git a/egui/src/containers/area.rs b/egui/src/containers/area.rs index 010c7311..7ef2f23d 100644 --- a/egui/src/containers/area.rs +++ b/egui/src/containers/area.rs @@ -172,10 +172,11 @@ impl Prepared { state.size = content_ui.min_rect().size(); - let interact_id = if movable { - Some(layer_id.id.with("move")) + let interact_id = layer_id.id.with("move"); + let sense = if movable { + Sense::click_and_drag() } else { - None + Sense::click() // allow clicks to bring to front }; let move_response = ctx.interact( @@ -184,16 +185,16 @@ impl Prepared { ctx.style().spacing.item_spacing, state.rect(), interact_id, - Sense::click_and_drag(), + sense, ); - if move_response.active { + if move_response.active && movable { state.pos += ctx.input().mouse.delta; } state.pos = ctx.constrain_window_rect(state.rect()).min; - if move_response.active + if (move_response.active || move_response.clicked) || mouse_pressed_on_area(ctx, layer_id) || !ctx.memory().areas.visible_last_frame(&layer_id) { diff --git a/egui/src/containers/panel.rs b/egui/src/containers/panel.rs index 639f2f39..e9e02a07 100644 --- a/egui/src/containers/panel.rs +++ b/egui/src/containers/panel.rs @@ -44,7 +44,7 @@ impl SidePanel { }); let panel_rect = panel_ui.min_rect(); - let response = panel_ui.interact_hover(panel_rect); + let response = panel_ui.interact(panel_rect, id, Sense::hover()); ctx.frame_state().allocate_left_panel(panel_rect); @@ -94,7 +94,7 @@ impl TopPanel { }); let panel_rect = panel_ui.min_rect(); - let response = panel_ui.interact_hover(panel_rect); + let response = panel_ui.interact(panel_rect, id, Sense::hover()); ctx.frame_state().allocate_top_panel(panel_rect); @@ -132,7 +132,8 @@ impl CentralPanel { }); let panel_rect = panel_ui.min_rect(); - let response = panel_ui.interact_hover(panel_rect); + let id = Id::new("central_panel"); + let response = panel_ui.interact(panel_rect, id, Sense::hover()); ctx.frame_state().allocate_central_panel(panel_rect); diff --git a/egui/src/context.rs b/egui/src/context.rs index 6399a667..8480e099 100644 --- a/egui/src/context.rs +++ b/egui/src/context.rs @@ -200,25 +200,24 @@ impl CtxRef { clip_rect: Rect, item_spacing: Vec2, rect: Rect, - id: Option, + id: Id, sense: Sense, ) -> Response { let interact_rect = rect.expand2((0.5 * item_spacing).min(Vec2::splat(5.0))); // make it easier to click let hovered = self.contains_mouse(layer_id, clip_rect, interact_rect); - let has_kb_focus = id.map(|id| self.memory().has_kb_focus(id)).unwrap_or(false); + let has_kb_focus = self.memory().has_kb_focus(id); // If the the focus is lost after the call to interact, // this will be `false`, so `TextEdit` also sets this manually. - let lost_kb_focus = id - .map(|id| self.memory().lost_kb_focus(id)) - .unwrap_or(false); + let lost_kb_focus = self.memory().lost_kb_focus(id); - if id.is_none() || sense == Sense::hover() || !layer_id.allow_interaction() { + if sense == Sense::hover() || !layer_id.allow_interaction() { // Not interested or allowed input: return Response { ctx: self.clone(), - sense, + id, rect, + sense, hovered, clicked: false, double_clicked: false, @@ -227,7 +226,6 @@ impl CtxRef { lost_kb_focus, }; } - let id = id.unwrap(); self.register_interaction_id(id, rect.min); @@ -243,8 +241,9 @@ impl CtxRef { if hovered { let mut response = Response { ctx: self.clone(), - sense, + id, rect, + sense, hovered: true, clicked: false, double_clicked: false, @@ -274,8 +273,9 @@ impl CtxRef { // miss Response { ctx: self.clone(), - sense, + id, rect, + sense, hovered, clicked: false, double_clicked: false, @@ -288,8 +288,9 @@ impl CtxRef { let clicked = hovered && active && self.input.mouse.could_be_click; Response { ctx: self.clone(), - sense, + id, rect, + sense, hovered, clicked, double_clicked: clicked && self.input.mouse.double_click, @@ -300,8 +301,9 @@ impl CtxRef { } else if self.input.mouse.down { Response { ctx: self.clone(), - sense, + id, rect, + sense, hovered: hovered && active, clicked: false, double_clicked: false, @@ -312,8 +314,9 @@ impl CtxRef { } else { Response { ctx: self.clone(), - sense, + id, rect, + sense, hovered, clicked: false, double_clicked: false, diff --git a/egui/src/demos/drag_and_drop.rs b/egui/src/demos/drag_and_drop.rs index 29d4fd02..59270a71 100644 --- a/egui/src/demos/drag_and_drop.rs +++ b/egui/src/demos/drag_and_drop.rs @@ -50,8 +50,8 @@ pub fn drop_target( let mut content_ui = ui.child_ui(inner_rect, *ui.layout()); let ret = body(&mut content_ui); let outer_rect = Rect::from_min_max(outer_rect_bounds.min, content_ui.min_rect().max + margin); - - let response = ui.interact_hover(outer_rect); + let (id, outer_rect) = ui.allocate_space(outer_rect.size()); + let response = ui.interact(outer_rect, id, Sense::hover()); let style = if is_being_dragged && can_accept_what_is_being_dragged && response.hovered { ui.style().visuals.widgets.active @@ -73,8 +73,6 @@ pub fn drop_target( }, ); - ui.allocate_space(outer_rect.size()); - (ret, response) } diff --git a/egui/src/types.rs b/egui/src/types.rs index 10754de5..794d5a64 100644 --- a/egui/src/types.rs +++ b/egui/src/types.rs @@ -1,4 +1,4 @@ -use crate::{math::Rect, CtxRef, Ui}; +use crate::{math::Rect, CtxRef, Id, Ui}; // ---------------------------------------------------------------------------- @@ -58,6 +58,9 @@ pub struct Response { pub ctx: CtxRef, // IN: + /// The `Id` of the widget/area this response pertains. + pub id: Id, + /// The area of the screen we are talking about pub rect: Rect, @@ -91,6 +94,7 @@ impl std::fmt::Debug for Response { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { ctx: _, + id, rect, sense, hovered, @@ -101,6 +105,7 @@ impl std::fmt::Debug for Response { lost_kb_focus, } = self; f.debug_struct("Response") + .field("id", id) .field("rect", rect) .field("sense", sense) .field("hovered", hovered) @@ -144,6 +149,7 @@ impl Response { assert!(self.ctx == other.ctx); Self { ctx: other.ctx, + id: self.id, rect: self.rect.union(other.rect), sense: self.sense.union(other.sense), hovered: self.hovered || other.hovered, diff --git a/egui/src/ui.rs b/egui/src/ui.rs index 258d4249..a61ad792 100644 --- a/egui/src/ui.rs +++ b/egui/src/ui.rs @@ -386,24 +386,19 @@ impl Ui { self.clip_rect(), self.style().spacing.item_spacing, rect, - Some(id), + id, sense, ) } + #[deprecated = "Use: interact(rect, id, Sense::hover())"] pub fn interact_hover(&self, rect: Rect) -> Response { - self.ctx().interact( - self.layer_id(), - self.clip_rect(), - self.style().spacing.item_spacing, - rect, - None, - Sense::hover(), - ) + self.interact(rect, self.auto_id_with("hover_rect"), Sense::hover()) } + #[deprecated = "Use: contains_mouse()"] pub fn hovered(&self, rect: Rect) -> bool { - self.interact_hover(rect).hovered + self.interact(rect, self.id, Sense::hover()).hovered } pub fn contains_mouse(&self, rect: Rect) -> bool { @@ -477,7 +472,8 @@ impl Ui { } } - let id = Id::new(self.next_auto_id); // TODO: increment counter here + self.next_auto_id = self.next_auto_id.wrapping_add(1); + let id = Id::new(self.next_auto_id); (id, rect) } @@ -499,15 +495,17 @@ impl Ui { ); self.region.expand_to_include_rect(inner_child_rect); - self.next_auto_id = self.next_auto_id.wrapping_add(1); inner_child_rect } - pub(crate) fn advance_cursor_after_rect(&mut self, rect: Rect) { + pub(crate) fn advance_cursor_after_rect(&mut self, rect: Rect) -> Id { let item_spacing = self.style().spacing.item_spacing; self.layout .advance_after_outer_rect(&mut self.region, rect, rect, item_spacing); self.region.expand_to_include_rect(rect); + + self.next_auto_id = self.next_auto_id.wrapping_add(1); + Id::new(self.next_auto_id) } pub(crate) fn cursor(&self) -> Pos2 { @@ -541,7 +539,7 @@ impl Ui { ); self.region.expand_to_include_rect(final_child_rect); - let response = self.interact_hover(final_child_rect); + let response = self.interact(final_child_rect, child_ui.id, Sense::hover()); (ret, response) } @@ -1029,7 +1027,7 @@ impl Ui { self.layout .advance_after_outer_rect(&mut self.region, rect, rect, item_spacing); self.region.expand_to_include_rect(rect); - (ret, self.interact_hover(rect)) + (ret, self.interact(rect, child_ui.id, Sense::hover())) } /// Temporarily split split an Ui into several columns. diff --git a/egui/src/widgets/mod.rs b/egui/src/widgets/mod.rs index 5aef35f8..0b5cd959 100644 --- a/egui/src/widgets/mod.rs +++ b/egui/src/widgets/mod.rs @@ -162,8 +162,8 @@ impl Widget for Label { assert!(!galley.rows.is_empty(), "Galleys are never empty"); let rect = galley.rows[0].rect().translate(vec2(pos.x, pos.y)); - ui.advance_cursor_after_rect(rect); - let mut total_response = ui.interact_hover(rect); + let id = ui.advance_cursor_after_rect(rect); + let mut total_response = ui.interact(rect, id, Sense::hover()); let mut y_translation = 0.0; if let Some(row) = galley.rows.get(1) { @@ -179,7 +179,7 @@ impl Widget for Label { row.y_max += y_translation; let rect = row.rect().translate(vec2(pos.x, pos.y)); ui.advance_cursor_after_rect(rect); - total_response |= ui.interact_hover(rect); + total_response |= ui.interact(rect, id, Sense::hover()); } self.paint_galley(ui, pos, galley);