From 7ffc733434d2dc90b5287b68991a32d9f4480054 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Wed, 10 Jan 2024 23:21:13 +0000 Subject: [PATCH] Prevent recreating HeaderSearch, temporarily losing state --- shalom/src/magic/header_search.rs | 42 ++++++++++++++++++++++++++++++++++-------- shalom/src/pages/room.rs | 8 ++++++-- shalom/src/pages/room/listen.rs | 2 +- shalom/src/widgets/image_background.rs | 29 +++++++++++++++++++++++++++-- 4 files changed, 68 insertions(+), 13 deletions(-) diff --git a/shalom/src/magic/header_search.rs b/shalom/src/magic/header_search.rs index 3c6879c..e3412d7 100644 --- a/shalom/src/magic/header_search.rs +++ b/shalom/src/magic/header_search.rs @@ -6,11 +6,11 @@ use iced::{ layout::{Limits, Node}, mouse, renderer::{Quad, Style}, - widget::Tree, + widget::{tree::Tag, Tree}, Clipboard, Layout, Renderer as IRenderer, Shell, Widget, }, event::Status, - mouse::Cursor, + mouse::{Cursor, Interaction}, widget::{ text_input::{Appearance, Id}, Text, @@ -57,6 +57,7 @@ where } } +#[derive(Debug)] pub enum BoxSize { Fill, Min, @@ -283,12 +284,16 @@ where *state = std::mem::take(next_state); match &state { - State::Open => shell.publish((self.on_state_change)(true)), - State::Closed => shell.publish((self.on_state_change)(false)), + State::Open => { + shell.publish((self.on_state_change)(true)); + self.current_search_box_size = BoxSize::Fill; + } + State::Closed => { + shell.publish((self.on_state_change)(false)); + self.current_search_box_size = BoxSize::Min; + } State::Animate { .. } => {} } - - self.current_search_box_size = BoxSize::Fill; } shell.request_redraw(RedrawRequest::NextFrame); @@ -314,14 +319,35 @@ where } } + fn mouse_interaction( + &self, + state: &Tree, + layout: Layout<'_>, + cursor: Cursor, + viewport: &Rectangle, + renderer: &Renderer, + ) -> Interaction { + self.input.as_widget().mouse_interaction( + &state.children[0], + layout.children().nth(1).unwrap().children().nth(1).unwrap(), + cursor, + viewport, + renderer, + ) + } + fn state(&self) -> iced::advanced::widget::tree::State { - iced::advanced::widget::tree::State::Some(Box::new( + iced::advanced::widget::tree::State::new( if matches!(self.current_search_box_size, BoxSize::Fill) { State::Open } else { State::Closed }, - )) + ) + } + + fn tag(&self) -> Tag { + Tag::of::() } fn children(&self) -> Vec { diff --git a/shalom/src/pages/room.rs b/shalom/src/pages/room.rs index 0ad0cb3..406fc0c 100644 --- a/shalom/src/pages/room.rs +++ b/shalom/src/pages/room.rs @@ -7,7 +7,7 @@ use iced::{ advanced::graphics::core::Element, font::{Stretch, Weight}, theme, - widget::{container, row, text, Column}, + widget::{container, lazy, row, text, Column}, Color, Font, Length, Renderer, Subscription, }; @@ -69,7 +69,11 @@ impl Room { .style(theme::Text::Color(Color::WHITE)); let header = if let Page::Listen = self.current_page { - self.listen.header_magic(header).map(Message::Listen) + Element::from(lazy(self.room.name.as_ref(), move |_| { + self.listen + .header_magic(header.clone()) + .map(Message::Listen) + })) } else { Element::from(header) }; diff --git a/shalom/src/pages/room/listen.rs b/shalom/src/pages/room/listen.rs index 50afff7..be060e5 100644 --- a/shalom/src/pages/room/listen.rs +++ b/shalom/src/pages/room/listen.rs @@ -47,7 +47,7 @@ impl Listen { } } - pub fn header_magic<'a>(&'a self, text: Text<'a>) -> Element<'a, Message> { + pub fn header_magic<'a>(&self, text: Text<'a>) -> Element<'a, Message> { header_search( Message::OnSearchTerm, Message::OnSearchVisibleChange, diff --git a/shalom/src/widgets/image_background.rs b/shalom/src/widgets/image_background.rs index e91a832..13e65f5 100644 --- a/shalom/src/widgets/image_background.rs +++ b/shalom/src/widgets/image_background.rs @@ -4,11 +4,11 @@ use iced::{ layout::{Limits, Node}, overlay, renderer::Style, - widget::Tree, + widget::{Operation, Tree}, Clipboard, Layout, Shell, Widget, }, event::Status, - mouse::Cursor, + mouse::{Cursor, Interaction}, widget::image, Alignment, ContentFit, Element, Event, Length, Point, Rectangle, Size, Vector, }; @@ -193,6 +193,31 @@ impl<'a, 'b, M: Clone, R: iced::advanced::Renderer> overlay::Overlay &layout.bounds(), ) } + + fn mouse_interaction( + &self, + layout: Layout<'_>, + cursor: Cursor, + viewport: &Rectangle, + renderer: &R, + ) -> Interaction { + self.el.as_widget().mouse_interaction( + self.tree, + layout.children().next().unwrap(), + cursor, + viewport, + renderer, + ) + } + + fn operate(&mut self, layout: Layout<'_>, renderer: &R, operation: &mut dyn Operation) { + self.el.as_widget().operate( + self.tree, + layout.children().next().unwrap(), + renderer, + operation, + ); + } } impl<'a, M, R> From> for Element<'a, M, R> -- libgit2 1.7.2