From ab6af8b64a963e7c18e0ce1dfb43c62cafb18bf0 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Mon, 15 Jan 2024 01:38:50 +0100 Subject: [PATCH] Create WidgetRect struct --- crates/egui/src/context.rs | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index 5a1579c9ab1b..e66f9820bbfc 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -112,6 +112,14 @@ impl ContextImpl { // ---------------------------------------------------------------------------- +/// Used to store each widgets [Id], [Rect] and [Sense] each frame. +/// Used to check for overlaps between widgets when handling events. +struct WidgetRect { + id: Id, + rect: Rect, + sense: Sense, +} + /// State stored per viewport #[derive(Default)] struct ViewportState { @@ -138,10 +146,10 @@ struct ViewportState { used: bool, /// Written to during the frame. - layer_rects_this_frame: HashMap>, + layer_rects_this_frame: HashMap>, /// Read - layer_rects_prev_frame: HashMap>, + layer_rects_prev_frame: HashMap>, /// State related to repaint scheduling. repaint: ViewportRepaintInfo, @@ -865,19 +873,29 @@ impl Context { .layer_rects_this_frame .entry(layer_id) .or_default() - .push((id, interact_rect, sense)); + .push(WidgetRect { + id, + rect: interact_rect, + sense, + }); if hovered { let pointer_pos = viewport.input.pointer.interact_pos(); if let Some(pointer_pos) = pointer_pos { if let Some(rects) = viewport.layer_rects_prev_frame.get(&layer_id) { - for &(prev_id, prev_rect, prev_sense) in rects.iter().rev() { + for &WidgetRect{ + id: prev_id, + rect: prev_rect, + sense: prev_sense, + } in rects.iter().rev() { if prev_id == id { break; // there is no other interactive widget covering us at the pointer position. } + // Check whether the previous widget was using a sense that conflicts with ours. + let has_conflicting_sense = (prev_sense.click && sense.click) + || (prev_sense.drag && sense.drag); if prev_rect.contains(pointer_pos) - && ((prev_sense.click && sense.click) - || (prev_sense.drag && sense.drag)) + && has_conflicting_sense { // Another interactive widget is covering us at the pointer position, // so we aren't hovered.