summaryrefslogtreecommitdiffstats
path: root/widget/src/overlay
diff options
context:
space:
mode:
Diffstat (limited to 'widget/src/overlay')
-rw-r--r--widget/src/overlay/menu.rs60
1 files changed, 42 insertions, 18 deletions
diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs
index b641e8f5..7907ef01 100644
--- a/widget/src/overlay/menu.rs
+++ b/widget/src/overlay/menu.rs
@@ -1,17 +1,17 @@
//! Build and show dropdown menus.
use crate::core::alignment;
use crate::core::border::{self, Border};
-use crate::core::event::{self, Event};
use crate::core::layout::{self, Layout};
use crate::core::mouse;
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,
+ Background, Clipboard, Color, Event, Length, Padding, Pixels, Point,
+ Rectangle, Size, Theme, Vector,
};
use crate::core::{Element, Shell, Widget};
use crate::scrollable::{self, Scrollable};
@@ -262,7 +262,7 @@ where
})
}
- fn on_event(
+ fn update(
&mut self,
event: Event,
layout: Layout<'_>,
@@ -270,13 +270,13 @@ where
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
- ) -> event::Status {
+ ) {
let bounds = layout.bounds();
- self.list.on_event(
+ self.list.update(
self.state, event, layout, cursor, renderer, clipboard, shell,
&bounds,
- )
+ );
}
fn mouse_interaction(
@@ -334,6 +334,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 +345,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,
@@ -374,9 +386,9 @@ where
layout::Node::new(size)
}
- fn on_event(
+ fn update(
&mut self,
- _state: &mut Tree,
+ tree: &mut Tree,
event: Event,
layout: Layout<'_>,
cursor: mouse::Cursor,
@@ -384,14 +396,14 @@ where
_clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
_viewport: &Rectangle,
- ) -> event::Status {
+ ) {
match event {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
if cursor.is_over(layout.bounds()) {
if let Some(index) = *self.hovered_option {
if let Some(option) = self.options.get(index) {
shell.publish((self.on_selected)(option.clone()));
- return event::Status::Captured;
+ shell.capture_event();
}
}
}
@@ -411,14 +423,18 @@ 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();
}
}
@@ -443,7 +459,7 @@ where
if let Some(index) = *self.hovered_option {
if let Some(option) = self.options.get(index) {
shell.publish((self.on_selected)(option.clone()));
- return event::Status::Captured;
+ shell.capture_event();
}
}
}
@@ -451,7 +467,15 @@ where
_ => {}
}
- event::Status::Ignored
+ let state = tree.state.downcast_mut::<ListState>();
+
+ if let Event::Window(window::Event::RedrawRequested(_now)) = event {
+ state.is_hovered = Some(cursor.is_over(layout.bounds()));
+ } else if state.is_hovered.is_some_and(|is_hovered| {
+ is_hovered != cursor.is_over(layout.bounds())
+ }) {
+ shell.request_redraw();
+ }
}
fn mouse_interaction(