diff --git a/src/widget/popover.rs b/src/widget/popover.rs index 82a7c8ed..ae01d97b 100644 --- a/src/widget/popover.rs +++ b/src/widget/popover.rs @@ -38,6 +38,7 @@ pub struct Popover<'a, Message, Renderer> { // XXX Avoid refcell; improve iced overlay API? popup: Option>>, position: Position, + on_close: Option, } impl<'a, Message, Renderer> Popover<'a, Message, Renderer> { @@ -47,6 +48,7 @@ impl<'a, Message, Renderer> Popover<'a, Message, Renderer> { modal: false, popup: None, position: Position::Center, + on_close: None, } } @@ -56,6 +58,12 @@ impl<'a, Message, Renderer> Popover<'a, Message, Renderer> { self } + /// Emitted when the popup is closed. + pub fn on_close(mut self, on_close: Message) -> Self { + self.on_close = Some(on_close); + self + } + pub fn popup(mut self, popup: impl Into>) -> Self { self.popup = Some(RefCell::new(popup.into())); self @@ -69,7 +77,7 @@ impl<'a, Message, Renderer> Popover<'a, Message, Renderer> { // TODO More options for positioning similar to GdkPopup, xdg_popup } -impl<'a, Message, Renderer> Widget +impl<'a, Message: Clone, Renderer> Widget for Popover<'a, Message, Renderer> where Renderer: iced_core::Renderer, @@ -143,7 +151,14 @@ where ) { let state = tree.state.downcast_mut::(); + let was_open = state.is_open; state.is_open = cursor_position.is_over(layout.bounds()); + + if let Some(on_close) = self.on_close.clone() { + if was_open && !state.is_open { + shell.publish(on_close); + } + } } self.content.as_widget_mut().on_event( @@ -262,7 +277,7 @@ where impl<'a, Message, Renderer> From> for Element<'a, Message, crate::Theme, Renderer> where - Message: 'static, + Message: 'static + Clone, Renderer: iced_core::Renderer + 'static, { fn from(popover: Popover<'a, Message, Renderer>) -> Self { @@ -279,6 +294,7 @@ pub struct Overlay<'a, 'b, Message, Renderer> { impl<'a, 'b, Message, Renderer> overlay::Overlay for Overlay<'a, 'b, Message, Renderer> where + Message: Clone, Renderer: iced_core::Renderer, { fn layout(