Add `Area::sense` and improve hit-testing of buttons in menus (#4234)
Previously, putting the cursor in the gap between two menu buttons would not hover any of the buttons, but the click-sensitive menu itself. Now the menu is no longer click-sensitive.
This commit is contained in:
parent
9cfaf8b961
commit
8a880d6d0f
|
|
@ -61,6 +61,7 @@ impl State {
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct Area {
|
pub struct Area {
|
||||||
pub(crate) id: Id,
|
pub(crate) id: Id,
|
||||||
|
sense: Option<Sense>,
|
||||||
movable: bool,
|
movable: bool,
|
||||||
interactable: bool,
|
interactable: bool,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
|
|
@ -78,6 +79,7 @@ impl Area {
|
||||||
pub fn new(id: Id) -> Self {
|
pub fn new(id: Id) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
|
sense: None,
|
||||||
movable: true,
|
movable: true,
|
||||||
interactable: true,
|
interactable: true,
|
||||||
constrain: false,
|
constrain: false,
|
||||||
|
|
@ -114,7 +116,7 @@ impl Area {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// moveable by dragging the area?
|
/// Moveable by dragging the area?
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn movable(mut self, movable: bool) -> Self {
|
pub fn movable(mut self, movable: bool) -> Self {
|
||||||
self.movable = movable;
|
self.movable = movable;
|
||||||
|
|
@ -139,6 +141,15 @@ impl Area {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Explicitly set a sense.
|
||||||
|
///
|
||||||
|
/// If not set, this will default to `Sense::drag()` if movable, `Sense::click()` if interactable, and `Sense::hover()` otherwise.
|
||||||
|
#[inline]
|
||||||
|
pub fn sense(mut self, sense: Sense) -> Self {
|
||||||
|
self.sense = Some(sense);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// `order(Order::Foreground)` for an Area that should always be on top
|
/// `order(Order::Foreground)` for an Area that should always be on top
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn order(mut self, order: Order) -> Self {
|
pub fn order(mut self, order: Order) -> Self {
|
||||||
|
|
@ -255,6 +266,7 @@ impl Area {
|
||||||
pub(crate) fn begin(self, ctx: &Context) -> Prepared {
|
pub(crate) fn begin(self, ctx: &Context) -> Prepared {
|
||||||
let Self {
|
let Self {
|
||||||
id,
|
id,
|
||||||
|
sense,
|
||||||
movable,
|
movable,
|
||||||
order,
|
order,
|
||||||
interactable,
|
interactable,
|
||||||
|
|
@ -299,13 +311,15 @@ impl Area {
|
||||||
// interact right away to prevent frame-delay
|
// interact right away to prevent frame-delay
|
||||||
let mut move_response = {
|
let mut move_response = {
|
||||||
let interact_id = layer_id.id.with("move");
|
let interact_id = layer_id.id.with("move");
|
||||||
let sense = if movable {
|
let sense = sense.unwrap_or_else(|| {
|
||||||
Sense::drag()
|
if movable {
|
||||||
} else if interactable {
|
Sense::drag()
|
||||||
Sense::click() // allow clicks to bring to front
|
} else if interactable {
|
||||||
} else {
|
Sense::click() // allow clicks to bring to front
|
||||||
Sense::hover()
|
} else {
|
||||||
};
|
Sense::hover()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let move_response = ctx.create_widget(WidgetRect {
|
let move_response = ctx.create_widget(WidgetRect {
|
||||||
id: interact_id,
|
id: interact_id,
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,8 @@ pub(crate) fn menu_ui<'c, R>(
|
||||||
.order(Order::Foreground)
|
.order(Order::Foreground)
|
||||||
.fixed_pos(pos)
|
.fixed_pos(pos)
|
||||||
.constrain_to(ctx.screen_rect())
|
.constrain_to(ctx.screen_rect())
|
||||||
.interactable(true);
|
.interactable(true)
|
||||||
|
.sense(Sense::hover());
|
||||||
|
|
||||||
let area_response = area.show(ctx, |ui| {
|
let area_response = area.show(ctx, |ui| {
|
||||||
set_menu_style(ui.style_mut());
|
set_menu_style(ui.style_mut());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue