Skip to content

Commit

Permalink
Add Response::contains_pointer (#3859)
Browse files Browse the repository at this point in the history
* Part of #3841
  • Loading branch information
emilk authored Jan 22, 2024
1 parent 894a534 commit 2d725d1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
15 changes: 14 additions & 1 deletion crates/egui/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ impl Response {

/// The pointer is hovering above this widget or the widget was clicked/tapped this frame.
///
/// Note that this is slightly different from checking `response.rect.contains(pointer_pos)`.
/// This will be `false` whenever some other widget is being dragged.
///
/// Note that this is slightly different from [`Self::contains_pointer`].
/// For one, the hover rectangle is slightly larger, by half of the current item spacing
/// (to make it easier to click things). But `hovered` also checks that no other area
/// is covering this response rectangle.
Expand All @@ -221,6 +223,17 @@ impl Response {
self.hovered
}

/// Returns true if the pointer is contained by the response rect.
///
/// In contrast to [`Self::hovered`], this can be `true` even if some other widget is being dragged.
/// This means it is useful for styling things like drag-and-drop targets.
///
/// In contrast to [`Self::hovered`], this is true even when dragging some other widget
/// onto this one.
pub fn contains_pointer(&self) -> bool {
self.ctx.rect_contains_pointer(self.layer_id, self.rect)
}

/// The widget is highlighted via a call to [`Self::highlight`] or [`Context::highlight_widget`].
#[doc(hidden)]
pub fn highlighted(&self) -> bool {
Expand Down
20 changes: 14 additions & 6 deletions crates/egui_demo_lib/src/demo/drag_and_drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,14 @@ pub fn drop_target<R>(
let outer_rect = Rect::from_min_max(outer_rect_bounds.min, content_ui.min_rect().max + margin);
let (rect, response) = ui.allocate_at_least(outer_rect.size(), Sense::hover());

let style = if is_being_dragged && can_accept_what_is_being_dragged && response.hovered() {
ui.visuals().widgets.active
} else {
ui.visuals().widgets.inactive
};
// NOTE: we use `response.contains_pointer` here instead of `hovered`, because
// `hovered` is always false when another widget is being dragged.
let style =
if is_being_dragged && can_accept_what_is_being_dragged && response.contains_pointer() {
ui.visuals().widgets.active
} else {
ui.visuals().widgets.inactive
};

let mut fill = style.bg_fill;
let mut stroke = style.bg_stroke;
Expand Down Expand Up @@ -149,7 +152,12 @@ impl super::View for DragAndDropDemo {
});

let is_being_dragged = ui.memory(|mem| mem.is_anything_being_dragged());
if is_being_dragged && can_accept_what_is_being_dragged && response.hovered() {
// NOTE: we use `response.contains_pointer` here instead of `hovered`, because
// `hovered` is always false when another widget is being dragged.
if is_being_dragged
&& can_accept_what_is_being_dragged
&& response.contains_pointer()
{
drop_col = Some(col_idx);
}
}
Expand Down

0 comments on commit 2d725d1

Please sign in to comment.