diff options
| author | pml68 <contact@pml68.dev> | 2025-03-23 16:23:17 +0100 |
|---|---|---|
| committer | pml68 <contact@pml68.dev> | 2025-03-23 16:23:17 +0100 |
| commit | 6a5a2b627cb8b588fe78463f218fd860fb78cd35 (patch) | |
| tree | fb345030d03e99d0486e0abd77674c900b3dd58b /iced_drop/src/widget | |
| parent | ci: add caching, use mold for linking (diff) | |
| download | iced-builder-6a5a2b627cb8b588fe78463f218fd860fb78cd35.tar.gz | |
fix(iced_drop): support reactive rendering
Diffstat (limited to 'iced_drop/src/widget')
| -rw-r--r-- | iced_drop/src/widget/droppable.rs | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/iced_drop/src/widget/droppable.rs b/iced_drop/src/widget/droppable.rs index 163cbea..947cf5b 100644 --- a/iced_drop/src/widget/droppable.rs +++ b/iced_drop/src/widget/droppable.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use std::vec; use iced::advanced::widget::{Operation, Tree, Widget}; -use iced::advanced::{self, layout, mouse, overlay, renderer, Layout}; +use iced::advanced::{self, Layout, layout, mouse, overlay, renderer}; use iced::{Element, Point, Rectangle, Size, Vector}; /// An element that can be dragged and dropped on a [`DropZone`] @@ -28,6 +28,7 @@ pub struct Droppable< drag_center: bool, drag_size: Option<Size>, reset_delay: usize, + status: Option<Status>, } impl<'a, Message, Theme, Renderer> Droppable<'a, Message, Theme, Renderer> @@ -52,6 +53,7 @@ where drag_center: false, drag_size: None, reset_delay: 0, + status: None, } } @@ -293,6 +295,30 @@ where } } } + + let current_status = if cursor.is_over(layout.bounds()) { + if self.on_drop.is_none() { + Status::Disabled + } else { + let state = tree.state.downcast_ref::<State>(); + + if let Action::Drag(_, _) = state.action { + Status::Dragged + } else { + Status::Hovered + } + } + } else { + Status::Active + }; + + if let iced::Event::Window(iced::window::Event::RedrawRequested(_now)) = + event + { + self.status = Some(current_status); + } else if self.status.is_some_and(|status| status != current_status) { + shell.request_redraw(); + } } fn layout( @@ -395,18 +421,17 @@ where _translation: Vector, ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { let state: &mut State = tree.state.downcast_mut::<State>(); - let mut children = tree.children.iter_mut(); if self.drag_overlay { if let Action::Drag(_, _) = state.action { return Some(overlay::Element::new(Box::new(Overlay { content: &self.content, - tree: children.next().unwrap(), + tree: &mut tree.children[0], overlay_bounds: state.overlay_bounds, }))); } } self.content.as_widget_mut().overlay( - children.next().unwrap(), + &mut tree.children[0], layout, renderer, _translation, @@ -428,21 +453,25 @@ where _viewport, _renderer, ); + if child_interact != mouse::Interaction::default() { return child_interact; } let state = tree.state.downcast_ref::<State>(); - if self.on_drop.is_none() { + if self.on_drop.is_none() && cursor.is_over(layout.bounds()) { return mouse::Interaction::NotAllowed; } + if let Action::Drag(_, _) = state.action { return mouse::Interaction::Grabbing; } + if cursor.is_over(layout.bounds()) { return mouse::Interaction::Pointer; } + mouse::Interaction::default() } } @@ -469,6 +498,15 @@ pub struct State { } #[derive(Default, Clone, Copy, PartialEq, Debug)] +pub enum Status { + #[default] + Active, + Hovered, + Dragged, + Disabled, +} + +#[derive(Default, Clone, Copy, PartialEq, Debug)] pub enum Action { #[default] None, |
