From b308eb7127ee7736cd3c5c52ed397d210205d144 Mon Sep 17 00:00:00 2001 From: GyulyVGC Date: Fri, 20 Sep 2024 14:56:29 +0200 Subject: [PATCH] migrating to iced 0.13 (use the new stack widget instead of modal) --- src/countries/country_utils.rs | 8 +- src/gui/components/modal.rs | 327 +++------------------------------ src/gui/sniffer.rs | 12 +- src/gui/styles/picklist.rs | 4 +- 4 files changed, 38 insertions(+), 313 deletions(-) diff --git a/src/countries/country_utils.rs b/src/countries/country_utils.rs index 19a42fbc..82d5dd7e 100644 --- a/src/countries/country_utils.rs +++ b/src/countries/country_utils.rs @@ -303,7 +303,7 @@ fn get_flag_from_country( flag } }))) - .style(svg_style) + .class(svg_style) .width(width) .height(width * 0.75); @@ -346,7 +346,7 @@ pub fn get_flag_tooltip( Position::FollowCursor, ) .snap_within_viewport(true) - .style(tooltip_style); + .class(tooltip_style); if width == FLAGS_WIDTH_SMALL { tooltip = tooltip.padding(3); @@ -371,7 +371,7 @@ pub fn get_computer_tooltip( (false, false, TrafficType::Unicast) => UNKNOWN, }, ))) - .style(SvgType::AdaptColor) + .class(SvgType::AdaptColor) .width(FLAGS_WIDTH_BIG) .height(FLAGS_WIDTH_BIG * 0.75); @@ -390,5 +390,5 @@ pub fn get_computer_tooltip( Position::FollowCursor, ) .snap_within_viewport(true) - .style(ContainerType::Tooltip) + .class(ContainerType::Tooltip) } diff --git a/src/gui/components/modal.rs b/src/gui/components/modal.rs index 3c6e2651..f29424ed 100644 --- a/src/gui/components/modal.rs +++ b/src/gui/components/modal.rs @@ -1,11 +1,9 @@ -use iced::advanced::layout::{self, Layout}; -use iced::advanced::overlay; -use iced::advanced::renderer; -use iced::advanced::widget::{self, Widget}; -use iced::advanced::{self, Clipboard, Shell}; use iced::alignment::{Alignment, Horizontal, Vertical}; -use iced::widget::{button, horizontal_space, Column, Container, Row, Space, Text}; -use iced::{event, mouse, Color, Element, Event, Font, Length, Point, Rectangle, Size, Vector}; +use iced::widget::{ + button, center, container, horizontal_space, mouse_area, opaque, stack, Column, Container, Row, + Space, Text, +}; +use iced::{Color, Element, Font, Length}; use crate::gui::components::button::button_hide; use crate::gui::styles::button::ButtonType; @@ -136,300 +134,31 @@ fn confirm_button_row( ) } -/// A widget that centers an overlay element over some base element -pub struct Modal<'a, Message, Theme, Renderer> { - base: Element<'a, Message, Theme, Renderer>, - overlay: Element<'a, Message, Theme, Renderer>, - on_blur: Option, -} - -impl<'a, Message, Theme, Renderer> Modal<'a, Message, Theme, Renderer> { - /// Returns a new [`Modal`] - pub fn new( - base: impl Into>, - modal: impl Into>, - ) -> Self { - Self { - base: base.into(), - overlay: modal.into(), - on_blur: None, - } - } - - /// Sets the message that will be produces when the background - /// of the [`Modal`] is pressed - pub fn on_blur(self, on_blur: Message) -> Self { - Self { - on_blur: Some(on_blur), - ..self - } - } -} - -impl<'a, Message, Theme, Renderer> Widget - for Modal<'a, Message, Theme, Renderer> -where - Renderer: advanced::Renderer, - Message: Clone, -{ - fn children(&self) -> Vec { - vec![ - widget::Tree::new(&self.base), - widget::Tree::new(&self.overlay), - ] - } - - fn diff(&self, tree: &mut widget::Tree) { - tree.diff_children(&[&self.base, &self.overlay]); - } - - fn size(&self) -> Size { - self.base.as_widget().size() - } - - fn layout( - &self, - tree: &mut widget::Tree, - renderer: &Renderer, - limits: &layout::Limits, - ) -> layout::Node { - self.base - .as_widget() - .layout(&mut tree.children[0], renderer, limits) - } - - fn on_event( - &mut self, - state: &mut widget::Tree, - event: Event, - layout: Layout<'_>, - cursor: mouse::Cursor, - renderer: &Renderer, - clipboard: &mut dyn Clipboard, - shell: &mut Shell<'_, Message>, - viewport: &Rectangle, - ) -> event::Status { - self.base.as_widget_mut().on_event( - &mut state.children[0], - event, - layout, - cursor, - renderer, - clipboard, - shell, - viewport, - ) - } - - fn draw( - &self, - state: &widget::Tree, - renderer: &mut Renderer, - theme: &Theme, - style: &renderer::Style, - layout: Layout<'_>, - cursor: mouse::Cursor, - viewport: &Rectangle, - ) { - self.base.as_widget().draw( - &state.children[0], - renderer, - theme, - style, - layout, - cursor, - viewport, - ); - } - - fn overlay<'b>( - &'b mut self, - state: &'b mut widget::Tree, - layout: Layout<'_>, - _renderer: &Renderer, - translation: Vector, - ) -> Option> { - Some(overlay::Element::new(Box::new(Overlay { - position: layout.position() + translation, - content: &mut self.overlay, - tree: &mut state.children[1], - size: layout.bounds().size(), - on_blur: self.on_blur.clone(), - }))) - } - - fn mouse_interaction( - &self, - state: &widget::Tree, - layout: Layout<'_>, - cursor: mouse::Cursor, - viewport: &Rectangle, - renderer: &Renderer, - ) -> mouse::Interaction { - self.base.as_widget().mouse_interaction( - &state.children[0], - layout, - cursor, - viewport, - renderer, - ) - } - - fn operate( - &self, - state: &mut widget::Tree, - layout: Layout<'_>, - renderer: &Renderer, - operation: &mut dyn widget::Operation, - ) { - self.base - .as_widget() - .operate(&mut state.children[0], layout, renderer, operation); - } -} - -struct Overlay<'a, 'b, Message, Theme, Renderer> { - position: Point, - content: &'b mut Element<'a, Message, Theme, Renderer>, - tree: &'b mut widget::Tree, - size: Size, - on_blur: Option, -} - -impl<'a, 'b, Message, Theme, Renderer> overlay::Overlay - for Overlay<'a, 'b, Message, Theme, Renderer> +pub fn new_modal<'a, Message, Theme, Renderer>( + base: impl Into>, + content: impl Into>, + on_blur: Message, +) -> Element<'a, Message, Theme, Renderer> where - Renderer: advanced::Renderer, - Message: Clone, + Message: Clone + 'a, { - fn layout(&mut self, renderer: &Renderer, _bounds: Size) -> layout::Node { - let limits = layout::Limits::new(Size::ZERO, self.size) - .width(Length::Fill) - .height(Length::Fill); - - let child = self - .content - .as_widget() - .layout(self.tree, renderer, &limits) - .align(Alignment::Center, Alignment::Center, limits.max()); - - layout::Node::with_children(self.size, vec![child]).move_to(self.position) - } - - fn on_event( - &mut self, - event: Event, - layout: Layout<'_>, - cursor: mouse::Cursor, - renderer: &Renderer, - clipboard: &mut dyn Clipboard, - shell: &mut Shell<'_, Message>, - ) -> event::Status { - let content_bounds = layout.children().next().unwrap().bounds(); - - if let Some(message) = self.on_blur.as_ref() { - if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) = &event { - if !cursor.is_over(content_bounds) { - shell.publish(message.clone()); - return event::Status::Captured; + stack![ + base.into(), + opaque( + mouse_area(center(opaque(content)).style(|_theme| { + container::Style { + background: Some( + Color { + a: 0.8, + ..Color::BLACK + } + .into(), + ), + ..container::Style::default() } - } - } - - self.content.as_widget_mut().on_event( - self.tree, - event, - layout.children().next().unwrap(), - cursor, - renderer, - clipboard, - shell, - &layout.bounds(), + })) + .on_press(on_blur) ) - } - - fn draw( - &self, - renderer: &mut Renderer, - theme: &Theme, - style: &renderer::Style, - layout: Layout<'_>, - cursor: mouse::Cursor, - ) { - renderer.fill_quad( - renderer::Quad { - bounds: layout.bounds(), - ..renderer::Quad::default() - }, - Color { - a: 0.80, - ..Color::BLACK - }, - ); - - self.content.as_widget().draw( - self.tree, - renderer, - theme, - style, - layout.children().next().unwrap(), - cursor, - &layout.bounds(), - ); - } - - fn operate( - &mut self, - layout: Layout<'_>, - renderer: &Renderer, - operation: &mut dyn widget::Operation, - ) { - self.content.as_widget().operate( - self.tree, - layout.children().next().unwrap(), - renderer, - operation, - ); - } - - fn mouse_interaction( - &self, - layout: Layout<'_>, - cursor: mouse::Cursor, - viewport: &Rectangle, - renderer: &Renderer, - ) -> mouse::Interaction { - self.content.as_widget().mouse_interaction( - self.tree, - layout.children().next().unwrap(), - cursor, - viewport, - renderer, - ) - } - - fn overlay<'c>( - &'c mut self, - layout: Layout<'_>, - renderer: &Renderer, - ) -> Option> { - self.content.as_widget_mut().overlay( - self.tree, - layout.children().next().unwrap(), - renderer, - Vector::ZERO, - ) - } -} - -impl<'a, Message, Theme, Renderer> From> - for Element<'a, Message, Theme, Renderer> -where - Theme: 'a, - Message: 'a + Clone, - Renderer: 'a + advanced::Renderer, -{ - fn from(modal: Modal<'a, Message, Theme, Renderer>) -> Self { - Element::new(modal) - } + ] + .into() } diff --git a/src/gui/sniffer.rs b/src/gui/sniffer.rs index a27d3f94..dc7eb0e4 100644 --- a/src/gui/sniffer.rs +++ b/src/gui/sniffer.rs @@ -20,7 +20,7 @@ use crate::chart::manage_chart_data::update_charts_data; use crate::configs::types::config_window::{ConfigWindow, ScaleAndCheck, ToPoint, ToSize}; use crate::gui::components::footer::footer; use crate::gui::components::header::header; -use crate::gui::components::modal::{get_clear_all_overlay, get_exit_overlay, Modal}; +use crate::gui::components::modal::{get_clear_all_overlay, get_exit_overlay, new_modal}; use crate::gui::components::types::my_modal::MyModal; use crate::gui::pages::connection_details_page::connection_details_page; use crate::gui::pages::initial_page::initial_page; @@ -568,9 +568,7 @@ impl Sniffer { SettingsPage::General => settings_general_page(self), }; - Modal::new(content, overlay) - .on_blur(Message::CloseSettings) - .into() + new_modal(content, overlay, Message::CloseSettings) } else { content.into() } @@ -584,9 +582,7 @@ impl Sniffer { MyModal::ConnectionDetails(key) => connection_details_page(self, key), }; - Modal::new(content, overlay) - .on_blur(Message::HideModal) - .into() + new_modal(content, overlay, Message::HideModal) } } } @@ -600,7 +596,7 @@ impl Sniffer { ]) } - pub fn theme(&self) -> Self::Theme { + pub fn theme(&self) -> StyleType { self.configs.lock().unwrap().settings.style } diff --git a/src/gui/styles/picklist.rs b/src/gui/styles/picklist.rs index 826921e5..d1087bb5 100644 --- a/src/gui/styles/picklist.rs +++ b/src/gui/styles/picklist.rs @@ -87,11 +87,11 @@ impl iced::overlay::menu::Catalog for StyleType { impl Catalog for StyleType { type Class<'a> = PicklistType; - fn default<'a>() -> Self::Class<'a> { + fn default<'a>() -> ::Class<'a> { Self::Class::default() } - fn style(&self, class: &Self::Class<'_>, status: Status) -> Style { + fn style(&self, class: &::Class<'_>, status: Status) -> Style { match status { Status::Active => class.active(self), Status::Hovered => class.hovered(self),