From e1c36f186f5de101c8482e42fc7e09c253437bf4 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Sat, 6 Jan 2024 17:17:04 +0000 Subject: [PATCH] Prevent layers under context menus from disappearing --- shalom/src/main.rs | 1 + shalom/src/widgets/blackhole_event.rs | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ shalom/src/widgets/context_menu.rs | 43 +++++++++++++++++++++++++++++++++---------- shalom/src/widgets/image_background.rs | 19 ++++++++----------- shalom/src/widgets/mod.rs | 1 + 5 files changed, 126 insertions(+), 21 deletions(-) create mode 100644 shalom/src/widgets/blackhole_event.rs diff --git a/shalom/src/main.rs b/shalom/src/main.rs index c826a2f..ca52e54 100644 --- a/shalom/src/main.rs +++ b/shalom/src/main.rs @@ -1,4 +1,5 @@ #![deny(clippy::pedantic)] +#![allow(clippy::struct_field_names)] mod config; mod context_menus; diff --git a/shalom/src/widgets/blackhole_event.rs b/shalom/src/widgets/blackhole_event.rs new file mode 100644 index 0000000..b70543e --- /dev/null +++ b/shalom/src/widgets/blackhole_event.rs @@ -0,0 +1,83 @@ +//! Prevents any events from reaching the inner element. + +use iced::{advanced::overlay, Vector}; + +pub fn blackhole_event(o: O) -> BlackholeEvent { + BlackholeEvent { overlay: o } +} + +pub struct BlackholeEvent { + overlay: O, +} + +impl overlay::Overlay + for BlackholeEvent> +{ + fn operate( + &mut self, + layout: iced::advanced::Layout<'_>, + renderer: &Renderer, + operation: &mut dyn iced::advanced::widget::Operation, + ) { + self.overlay.operate(layout, renderer, operation); + } + + fn on_event( + &mut self, + _event: iced::Event, + _layout: iced::advanced::Layout<'_>, + _cursor: iced::advanced::mouse::Cursor, + _renderer: &Renderer, + _clipboard: &mut dyn iced::advanced::Clipboard, + _shell: &mut iced::advanced::Shell<'_, Message>, + ) -> iced::event::Status { + iced::event::Status::Ignored + } + + fn mouse_interaction( + &self, + _layout: iced::advanced::Layout<'_>, + _cursor: iced::advanced::mouse::Cursor, + _viewport: &iced::Rectangle, + _renderer: &Renderer, + ) -> iced::advanced::mouse::Interaction { + iced::advanced::mouse::Interaction::Idle + } + + fn is_over( + &self, + _layout: iced::advanced::Layout<'_>, + _renderer: &Renderer, + _cursor_position: iced::Point, + ) -> bool { + false + } + + fn overlay<'a>( + &'a mut self, + layout: iced::advanced::Layout<'_>, + renderer: &Renderer, + ) -> Option> { + self.overlay.overlay(layout, renderer) + } + + fn layout( + &self, + renderer: &Renderer, + bounds: iced::Size, + _position: iced::Point, + ) -> iced::advanced::layout::Node { + self.overlay.layout(renderer, bounds, Vector::ZERO) + } + + fn draw( + &self, + renderer: &mut Renderer, + theme: &::Theme, + style: &iced::advanced::renderer::Style, + layout: iced::advanced::Layout<'_>, + cursor: iced::advanced::mouse::Cursor, + ) { + self.overlay.draw(renderer, theme, style, layout, cursor); + } +} diff --git a/shalom/src/widgets/context_menu.rs b/shalom/src/widgets/context_menu.rs index 70200b6..a43a8ee 100644 --- a/shalom/src/widgets/context_menu.rs +++ b/shalom/src/widgets/context_menu.rs @@ -21,6 +21,8 @@ use iced::{ }; use keyframe::{functions::EaseOutQuint, keyframes, AnimationSequence}; +use super::blackhole_event::blackhole_event; + pub struct ContextMenu<'a, M> { base: Element<'a, M, Renderer>, content: Element<'a, M, Renderer>, @@ -140,17 +142,38 @@ impl<'a, M: Clone> Widget for ContextMenu<'a, M> { &'b mut self, state: &'b mut Tree, layout: Layout<'_>, - _renderer: &Renderer, + renderer: &Renderer, ) -> Option> { - Some(overlay::Element::new( - layout.position(), - Box::new(Overlay { - content: &mut self.content, - tree: &mut state.children[1], - on_close: self.on_close.clone(), - state: state.state.downcast_mut::(), - }), - )) + let [ref mut base_tree, ref mut content_tree] = &mut state.children[..] else { + panic!(); + }; + + let mut group = overlay::Group::new(); + + if let Some(child) = self + .base + .as_widget_mut() + .overlay(base_tree, layout, renderer) + { + group = group.push(overlay::Element::new( + layout.position(), + Box::new(blackhole_event(child)), + )); + } + + Some( + group + .push(overlay::Element::new( + layout.position(), + Box::new(Overlay { + content: &mut self.content, + tree: content_tree, + on_close: self.on_close.clone(), + state: state.state.downcast_mut::(), + }), + )) + .into(), + ) } } diff --git a/shalom/src/widgets/image_background.rs b/shalom/src/widgets/image_background.rs index 9cf8dc7..e91a832 100644 --- a/shalom/src/widgets/image_background.rs +++ b/shalom/src/widgets/image_background.rs @@ -120,17 +120,14 @@ impl< layout: Layout<'_>, _renderer: &R, ) -> Option> { - Some( - overlay::Group::with_children(vec![overlay::Element::new( - layout.position(), - Box::new(Overlay { - el: &mut self.el, - tree: &mut state.children[0], - size: layout.bounds().size(), - }), - )]) - .overlay(), - ) + Some(overlay::Element::new( + layout.position(), + Box::new(Overlay { + el: &mut self.el, + tree: &mut state.children[0], + size: layout.bounds().size(), + }), + )) } } diff --git a/shalom/src/widgets/mod.rs b/shalom/src/widgets/mod.rs index e04b2f8..16d56e0 100644 --- a/shalom/src/widgets/mod.rs +++ b/shalom/src/widgets/mod.rs @@ -1,3 +1,4 @@ +pub mod blackhole_event; pub mod cards; pub mod colour_picker; pub mod context_menu; -- libgit2 1.7.2