fix(popover): add modal property for dialogs

Fixes quirks with the context drawer and dialogs
This commit is contained in:
Michael Aaron Murphy 2024-04-11 20:44:58 +02:00 committed by Michael Murphy
parent c6ab6cfe23
commit 2bfdc09a43
2 changed files with 16 additions and 6 deletions

View file

@ -745,7 +745,7 @@ impl<App: Application> ApplicationExt for App {
// Show any current dialog on top and centered over the view content // Show any current dialog on top and centered over the view content
// We have to use a popover even without a dialog to keep the tree from changing // We have to use a popover even without a dialog to keep the tree from changing
let mut popover = popover(view_column); let mut popover = popover(view_column).modal(true);
if let Some(dialog) = self.dialog() { if let Some(dialog) = self.dialog() {
popover = popover.popup(dialog.map(Message::App)); popover = popover.popup(dialog.map(Message::App));
} }

View file

@ -34,6 +34,7 @@ pub enum Position {
#[must_use] #[must_use]
pub struct Popover<'a, Message, Renderer> { pub struct Popover<'a, Message, Renderer> {
content: Element<'a, Message, crate::Theme, Renderer>, content: Element<'a, Message, crate::Theme, Renderer>,
modal: bool,
// XXX Avoid refcell; improve iced overlay API? // XXX Avoid refcell; improve iced overlay API?
popup: Option<RefCell<Element<'a, Message, crate::Theme, Renderer>>>, popup: Option<RefCell<Element<'a, Message, crate::Theme, Renderer>>>,
position: Position, position: Position,
@ -43,11 +44,18 @@ impl<'a, Message, Renderer> Popover<'a, Message, Renderer> {
pub fn new(content: impl Into<Element<'a, Message, crate::Theme, Renderer>>) -> Self { pub fn new(content: impl Into<Element<'a, Message, crate::Theme, Renderer>>) -> Self {
Self { Self {
content: content.into(), content: content.into(),
modal: false,
popup: None, popup: None,
position: Position::Center, position: Position::Center,
} }
} }
/// A modal popup interrupts user inputs and demands action.
pub fn modal(mut self, modal: bool) -> Self {
self.modal = modal;
self
}
pub fn popup(mut self, popup: impl Into<Element<'a, Message, crate::Theme, Renderer>>) -> Self { pub fn popup(mut self, popup: impl Into<Element<'a, Message, crate::Theme, Renderer>>) -> Self {
self.popup = Some(RefCell::new(popup.into())); self.popup = Some(RefCell::new(popup.into()));
self self
@ -127,11 +135,13 @@ where
shell: &mut Shell<'_, Message>, shell: &mut Shell<'_, Message>,
viewport: &Rectangle, viewport: &Rectangle,
) -> event::Status { ) -> event::Status {
if matches!( if !self.modal
event, && matches!(
Event::Mouse(mouse::Event::ButtonPressed(_)) event,
| Event::Touch(touch::Event::FingerPressed { .. }) Event::Mouse(mouse::Event::ButtonPressed(_))
) { | Event::Touch(touch::Event::FingerPressed { .. })
)
{
let state = tree.state.downcast_mut::<State>(); let state = tree.state.downcast_mut::<State>();
state.is_open = cursor_position.is_over(layout.bounds()); state.is_open = cursor_position.is_over(layout.bounds());
} }