diff options
author | 2024-10-23 20:04:13 +0200 | |
---|---|---|
committer | 2024-11-05 23:52:57 +0100 | |
commit | 908af3fed72131d21d7c7ffbc503c9b1e8a65144 (patch) | |
tree | c4a929417ae835ef65646e0b0d983c6a23a0b55d /widget/src/overlay | |
parent | fdf046daff5e9196713d2513cd1b654cfc122d80 (diff) | |
download | iced-908af3fed72131d21d7c7ffbc503c9b1e8a65144.tar.gz iced-908af3fed72131d21d7c7ffbc503c9b1e8a65144.tar.bz2 iced-908af3fed72131d21d7c7ffbc503c9b1e8a65144.zip |
Implement `reactive-rendering` for `menu`
Diffstat (limited to 'widget/src/overlay')
-rw-r--r-- | widget/src/overlay/menu.rs | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index b641e8f5..e79bd3da 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -8,7 +8,8 @@ use crate::core::overlay; use crate::core::renderer; use crate::core::text::{self, Text}; use crate::core::touch; -use crate::core::widget::Tree; +use crate::core::widget::tree::{self, Tree}; +use crate::core::window; use crate::core::{ Background, Clipboard, Color, Length, Padding, Pixels, Point, Rectangle, Size, Theme, Vector, @@ -334,6 +335,10 @@ where class: &'a <Theme as Catalog>::Class<'b>, } +struct ListState { + is_hovered: Option<bool>, +} + impl<'a, 'b, T, Message, Theme, Renderer> Widget<Message, Theme, Renderer> for List<'a, 'b, T, Message, Theme, Renderer> where @@ -341,6 +346,14 @@ where Theme: Catalog, Renderer: text::Renderer, { + fn tag(&self) -> tree::Tag { + tree::Tag::of::<Option<bool>>() + } + + fn state(&self) -> tree::State { + tree::State::new(ListState { is_hovered: None }) + } + fn size(&self) -> Size<Length> { Size { width: Length::Fill, @@ -376,7 +389,7 @@ where fn on_event( &mut self, - _state: &mut Tree, + tree: &mut Tree, event: Event, layout: Layout<'_>, cursor: mouse::Cursor, @@ -411,14 +424,20 @@ where let new_hovered_option = (cursor_position.y / option_height) as usize; - if let Some(on_option_hovered) = self.on_option_hovered { - if *self.hovered_option != Some(new_hovered_option) { - if let Some(option) = - self.options.get(new_hovered_option) + if *self.hovered_option != Some(new_hovered_option) { + if let Some(option) = + self.options.get(new_hovered_option) + { + if let Some(on_option_hovered) = + self.on_option_hovered { shell .publish(on_option_hovered(option.clone())); } + + shell.request_redraw( + window::RedrawRequest::NextFrame, + ); } } @@ -451,6 +470,18 @@ where _ => {} } + let state = tree.state.downcast_mut::<ListState>(); + + if state.is_hovered.is_some_and(|is_hovered| { + is_hovered != cursor.is_over(layout.bounds()) + }) { + shell.request_redraw(window::RedrawRequest::NextFrame); + } + + if let Event::Window(window::Event::RedrawRequested(_now)) = event { + state.is_hovered = Some(cursor.is_over(layout.bounds())); + } + event::Status::Ignored } |