Fix `Response::interact` and `Ui:interact_with_hovered` (#4013)
These broke in 0.26 * #3989 * #4006
This commit is contained in:
parent
808dc0103a
commit
5bf44f8850
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -607,7 +607,7 @@ impl Response {
|
|||
self.rect,
|
||||
sense,
|
||||
self.enabled,
|
||||
self.hovered,
|
||||
self.contains_pointer,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -357,6 +357,8 @@ pub struct InputTest {
|
|||
#[cfg_attr(feature = "serde", serde(skip))]
|
||||
history: [DeduplicatedHistory; 4],
|
||||
|
||||
late_interaction: bool,
|
||||
|
||||
show_hovers: bool,
|
||||
}
|
||||
|
||||
|
|
@ -394,6 +396,8 @@ impl super::View for InputTest {
|
|||
ui.checkbox(&mut self.show_hovers, "Show hover state");
|
||||
});
|
||||
|
||||
ui.checkbox(&mut self.late_interaction, "Use Response::interact");
|
||||
|
||||
ui.label("This tests how egui::Response reports events.\n\
|
||||
The different buttons are sensitive to different things.\n\
|
||||
Try interacting with them with any mouse button by clicking, double-clicking, triple-clicking, or dragging them.");
|
||||
|
|
@ -409,7 +413,13 @@ impl super::View for InputTest {
|
|||
.enumerate()
|
||||
{
|
||||
columns[i].push_id(i, |ui| {
|
||||
let response = ui.add(egui::Button::new(sense_name).sense(sense));
|
||||
let response = if self.late_interaction {
|
||||
let first_response =
|
||||
ui.add(egui::Button::new(sense_name).sense(egui::Sense::hover()));
|
||||
first_response.interact(sense)
|
||||
} else {
|
||||
ui.add(egui::Button::new(sense_name).sense(sense))
|
||||
};
|
||||
let info = response_summary(&response, self.show_hovers);
|
||||
self.history[i].add(info.trim().to_owned());
|
||||
self.history[i].ui(ui);
|
||||
|
|
|
|||
Loading…
Reference in New Issue