Modals: Add `UiKind::Modal`, and consume escape-key properly (#5414)

Small fixes/improvements to `Modal`

- Fixes #5413
This commit is contained in:
Antoine Beyeler 2024-12-03 11:46:37 +01:00 committed by GitHub
parent 8647b56b31
commit 3411aba768
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 3 deletions

View File

@ -1,5 +1,5 @@
use crate::{
Area, Color32, Context, Frame, Id, InnerResponse, Order, Response, Sense, Ui, UiBuilder,
Area, Color32, Context, Frame, Id, InnerResponse, Order, Response, Sense, Ui, UiBuilder, UiKind,
};
use emath::{Align2, Vec2};
@ -32,6 +32,7 @@ impl Modal {
/// - order: foreground
pub fn default_area(id: Id) -> Area {
Area::new(id)
.kind(UiKind::Modal)
.sense(Sense::hover())
.anchor(Align2::CENTER_CENTER, Vec2::ZERO)
.order(Order::Foreground)
@ -153,8 +154,12 @@ impl<T> ModalResponse<T> {
/// - this is the topmost modal, no popup is open and the escape key was pressed
pub fn should_close(&self) -> bool {
let ctx = &self.response.ctx;
let escape_clicked = ctx.input(|i| i.key_pressed(crate::Key::Escape));
// this is a closure so that `Esc` is consumed only if the modal is topmost
let escape_clicked =
|| ctx.input_mut(|i| i.consume_key(crate::Modifiers::NONE, crate::Key::Escape));
self.backdrop_response.clicked()
|| (self.is_top_modal && !self.any_popup_open && escape_clicked)
|| (self.is_top_modal && !self.any_popup_open && escape_clicked())
}
}

View File

@ -24,6 +24,9 @@ pub enum UiKind {
/// A bottom [`crate::TopBottomPanel`].
BottomPanel,
/// A modal [`crate::Modal`].
Modal,
/// A [`crate::Frame`].
Frame,
@ -82,6 +85,7 @@ impl UiKind {
Self::Window
| Self::Menu
| Self::Modal
| Self::Popup
| Self::Tooltip
| Self::Picker
@ -228,6 +232,12 @@ impl UiStack {
self.kind().map_or(false, |kind| kind.is_panel())
}
/// Is this [`crate::Ui`] an [`crate::Area`]?
#[inline]
pub fn is_area_ui(&self) -> bool {
self.kind().map_or(false, |kind| kind.is_area())
}
/// Is this a root [`crate::Ui`], i.e. created with [`crate::Ui::new()`]?
#[inline]
pub fn is_root_ui(&self) -> bool {