1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-02 06:40:06 -04:00

Fix Response::interact and Ui:interact_with_hovered (#4013)

These broke in 0.26

* #3989
* #4006
This commit is contained in:
Emil Ernerfeldt
2024-02-10 10:48:00 +01:00
committed by GitHub
parent 808dc0103a
commit 5bf44f8850
4 changed files with 55 additions and 5 deletions

View File

@@ -234,7 +234,18 @@ impl WidgetRects {
/// Insert the given widget rect in the given layer.
pub fn insert(&mut self, layer_id: LayerId, widget_rect: WidgetRect) {
self.by_layer.entry(layer_id).or_default().push(widget_rect);
let layer_widgets = self.by_layer.entry(layer_id).or_default();
if let Some(last) = layer_widgets.last_mut() {
if last.id == widget_rect.id {
// e.g. calling `response.interact(…)` right after interacting.
last.sense |= widget_rect.sense;
last.rect = last.rect.union(widget_rect.rect);
return;
}
}
layer_widgets.push(widget_rect);
}
}
@@ -1089,7 +1100,19 @@ impl Context {
let clicked_elsewhere = res.clicked_elsewhere();
self.write(|ctx| {
let input = &ctx.viewports.entry(ctx.viewport_id()).or_default().input;
let viewport = ctx.viewports.entry(ctx.viewport_id()).or_default();
// We need to remember this widget.
// `widget_contains_pointer` also does this, but in case of e.g. `Response::interact`,
// that won't be called.
// We add all widgets here, even non-interactive ones,
// because we need this list not only for checking for blocking widgets,
// but also to know when we have reached the widget we are checking for cover.
viewport
.layer_rects_this_frame
.insert(layer_id, WidgetRect { id, rect, sense });
let input = &viewport.input;
let memory = &mut ctx.memory;
if sense.focusable {
@@ -2292,9 +2315,10 @@ impl Context {
let pointer_pos = viewport.input.pointer.interact_pos();
if let Some(pointer_pos) = pointer_pos {
if let Some(rects) = viewport.layer_rects_prev_frame.by_layer.get(&layer_id) {
// Iterate backwards, i.e. topmost widgets first.
for blocking in rects.iter().rev() {
if blocking.id == id {
// There are no earlier widgets before this one,
// We've checked all widgets there were added after this one last frame,
// which means there are no widgets covering us.
break;
}

View File

@@ -607,7 +607,7 @@ impl Response {
self.rect,
sense,
self.enabled,
self.hovered,
self.contains_pointer,
)
}

View File

@@ -85,3 +85,19 @@ impl Sense {
self.click || self.drag
}
}
impl std::ops::BitOr for Sense {
type Output = Self;
#[inline]
fn bitor(self, rhs: Self) -> Self {
self.union(rhs)
}
}
impl std::ops::BitOrAssign for Sense {
#[inline]
fn bitor_assign(&mut self, rhs: Self) {
*self = self.union(rhs);
}
}