mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 04:40:03 -04:00
Add response container helpers
This commit is contained in:
@@ -909,7 +909,7 @@ impl InputState {
|
|||||||
/// to trigger a secondary click (context menu).
|
/// to trigger a secondary click (context menu).
|
||||||
///
|
///
|
||||||
/// Returns `true` only on one frame.
|
/// Returns `true` only on one frame.
|
||||||
pub(crate) fn is_long_touch(&self) -> bool {
|
pub fn is_long_touch(&self) -> bool {
|
||||||
self.any_touches() && self.pointer.is_long_press()
|
self.any_touches() && self.pointer.is_long_press()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1481,7 +1481,7 @@ impl PointerState {
|
|||||||
/// to trigger a secondary click (context menu).
|
/// to trigger a secondary click (context menu).
|
||||||
///
|
///
|
||||||
/// Returns `true` only on one frame.
|
/// Returns `true` only on one frame.
|
||||||
pub(crate) fn is_long_press(&self) -> bool {
|
pub fn is_long_press(&self) -> bool {
|
||||||
self.started_decidedly_dragging
|
self.started_decidedly_dragging
|
||||||
&& !self.has_moved_too_much_for_a_click
|
&& !self.has_moved_too_much_for_a_click
|
||||||
&& self.button_down(PointerButton::Primary)
|
&& self.button_down(PointerButton::Primary)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use std::{any::Any, sync::Arc};
|
use std::{any::Any, sync::Arc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Context, CursorIcon, Id, LayerId, PointerButton, Popup, PopupKind, Sense, Tooltip, Ui,
|
emath::{Align, Pos2, Rect, Vec2}, pass_state, Context, CursorIcon, Id, LayerId, PointerButton, Popup, PopupKind, Sense,
|
||||||
WidgetRect, WidgetText,
|
Tooltip, Ui,
|
||||||
emath::{Align, Pos2, Rect, Vec2},
|
WidgetRect,
|
||||||
pass_state,
|
WidgetText,
|
||||||
};
|
};
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -282,13 +282,34 @@ impl Response {
|
|||||||
/// This means it is useful for styling things like drag-and-drop targets.
|
/// This means it is useful for styling things like drag-and-drop targets.
|
||||||
/// `contains_pointer` can also be `true` for disabled widgets.
|
/// `contains_pointer` can also be `true` for disabled widgets.
|
||||||
///
|
///
|
||||||
/// This is slightly different from [`Ui::rect_contains_pointer`] and [`Context::rect_contains_pointer`], in that
|
/// This is slightly different from [`Response::container_contains_pointer`],
|
||||||
/// [`Self::contains_pointer`] also checks that no other widget is covering this response rectangle.
|
/// [`Ui::rect_contains_pointer`] and [`Context::rect_contains_pointer`], in that
|
||||||
|
/// [`Response::contains_pointer`] also checks that no other widget is covering this response rectangle.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn contains_pointer(&self) -> bool {
|
pub fn contains_pointer(&self) -> bool {
|
||||||
self.flags.contains(Flags::CONTAINS_POINTER)
|
self.flags.contains(Flags::CONTAINS_POINTER)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Is this response or any child widgets hovered?
|
||||||
|
///
|
||||||
|
/// Will return false if some other area is covering the given layer, or if anything is being
|
||||||
|
/// dragged.
|
||||||
|
///
|
||||||
|
/// This calls [`Context::rect_contains_pointer`]. See also [`Response::hovered`].
|
||||||
|
pub fn container_hovered(&self) -> bool {
|
||||||
|
self.ctx.dragged_id().is_none() && self.container_contains_pointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Does this response or any child widgets contain the mouse pointer?
|
||||||
|
///
|
||||||
|
/// Will return false if some other area is covering the given layer.
|
||||||
|
///
|
||||||
|
/// This calls [`Context::rect_contains_pointer`]. See also [`Response::contains_pointer`].
|
||||||
|
pub fn container_contains_pointer(&self) -> bool {
|
||||||
|
self.ctx
|
||||||
|
.rect_contains_pointer(self.layer_id, self.interact_rect)
|
||||||
|
}
|
||||||
|
|
||||||
/// The widget is highlighted via a call to [`Self::highlight`] or [`Context::highlight_widget`].
|
/// The widget is highlighted via a call to [`Self::highlight`] or [`Context::highlight_widget`].
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -1006,6 +1027,47 @@ impl Response {
|
|||||||
intrinsic_size: None,
|
intrinsic_size: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calls [`Self::union`] with all widgets on the same layer fully contained within this
|
||||||
|
/// response's rect.
|
||||||
|
///
|
||||||
|
/// Note that this is an expensive call if there are many widgets on the same layer.
|
||||||
|
/// Consider using [`Response::container_clicked`] or [`Response::container_secondary_clicked`]
|
||||||
|
/// which are optimized.
|
||||||
|
///
|
||||||
|
/// This is useful if you e.g. want to sense right clicks on some [`Ui`] that contains
|
||||||
|
/// widgets that also sense for clicks.
|
||||||
|
pub fn union_children(&self) -> Self {
|
||||||
|
let child_widgets = self.ctx.pass_state(|pass| {
|
||||||
|
pass.widgets
|
||||||
|
.get_layer(self.layer_id)
|
||||||
|
.filter(|r| self.rect.contains_rect(r.rect))
|
||||||
|
.copied()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
});
|
||||||
|
let mut result = self.clone();
|
||||||
|
for widget in child_widgets {
|
||||||
|
let child_response = self.ctx.get_response(widget);
|
||||||
|
result = result.union(child_response);
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Optimized version of `response.union_children().clicked()`.
|
||||||
|
pub fn container_clicked(&self) -> bool {
|
||||||
|
self.container_contains_pointer()
|
||||||
|
&& self.ctx.input(|i| i.pointer.primary_clicked())
|
||||||
|
&& self.union_children().clicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Optimized version of `response.union_children().secondary_clicked()`.
|
||||||
|
pub fn container_secondary_clicked(&self) -> bool {
|
||||||
|
self.container_contains_pointer()
|
||||||
|
&& self
|
||||||
|
.ctx
|
||||||
|
.input(|i| i.pointer.secondary_clicked() || i.is_long_touch())
|
||||||
|
&& self.union_children().secondary_clicked()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Response {
|
impl Response {
|
||||||
|
|||||||
Reference in New Issue
Block a user