Skip to content

Commit

Permalink
Make find_widget_at_pos behavior more correct
Browse files Browse the repository at this point in the history
  • Loading branch information
Philipp-M committed Nov 23, 2024
1 parent b97a9e9 commit 133a1f0
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 31 deletions.
44 changes: 39 additions & 5 deletions masonry/src/widget/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,13 @@ pub trait Widget: AsAny + AsDynWidget {
ctx: QueryCtx<'c>,
pos: Point,
) -> Option<WidgetRef<'c, dyn Widget>> {
(WidgetRef {
widget: self.as_dyn(),
ctx,
})
.find_widget_at_pos(pos)
find_widget_at_pos(
&WidgetRef {
widget: self.as_dyn(),
ctx,
},
pos,
)
}

/// Get the (verbose) type name of the widget for debugging purposes.
Expand Down Expand Up @@ -327,6 +329,38 @@ pub trait Widget: AsAny + AsDynWidget {
}
}

pub(crate) fn find_widget_at_pos<'c>(
widget: &WidgetRef<'c, dyn Widget>,
pos: Point,
) -> Option<WidgetRef<'c, dyn Widget>> {
if widget.ctx.widget_state.bbox.contains(pos) {
let local_pos = widget.ctx().widget_state.window_transform.inverse() * pos;

if Some(false) == widget.ctx.clip_path().map(|clip| clip.contains(local_pos)) {
return None;
}

// Assumes `Self::children_ids` is in increasing "z-order", picking the last child in case
// of overlapping children.
for child_id in widget.children_ids().iter().rev() {
let child_ref = widget.ctx.get(*child_id);
if let Some(child) = child_ref.widget.find_widget_at_pos(child_ref.ctx, pos) {
return Some(child);
}
}
if !widget.ctx.is_stashed()
&& widget.ctx.accepts_pointer_interaction()
&& widget.ctx.size().to_rect().contains(local_pos)
{
Some(*widget)
} else {
None
}
} else {
None
}
}

/// Marker trait for Widgets whose parents can get a raw mutable reference to them.
///
/// "Raw mut" means using a mutable reference (eg `&mut MyWidget`) to the data
Expand Down
27 changes: 1 addition & 26 deletions masonry/src/widget/widget_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,32 +165,7 @@ impl<'w> WidgetRef<'w, dyn Widget> {
/// **pos** - the position in global coordinates (e.g. `(0,0)` is the top-left corner of the
/// window).
pub fn find_widget_at_pos(&self, pos: Point) -> Option<WidgetRef<'w, dyn Widget>> {
if self.ctx.widget_state.bbox.contains(pos) {
let local_pos = self.ctx().widget_state.window_transform.inverse() * pos;

if Some(false) == self.ctx.clip_path().map(|clip| clip.contains(local_pos)) {
return None;
}

// Assumes `Self::children_ids` is in increasing "z-order", picking the last child in case
// of overlapping children.
for child_id in self.children_ids().iter().rev() {
let child_ref = self.ctx.get(*child_id);
if let Some(child) = child_ref.widget.find_widget_at_pos(child_ref.ctx, pos) {
return Some(child);
}
}
if !self.ctx.is_stashed()
&& self.ctx.accepts_pointer_interaction()
&& self.ctx.size().to_rect().contains(local_pos)
{
Some(*self)
} else {
None
}
} else {
None
}
self.widget.find_widget_at_pos(self.ctx, pos)
}
}

Expand Down

0 comments on commit 133a1f0

Please sign in to comment.