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 | |
| parent | ci: add caching, use mold for linking (diff) | |
| download | iced-builder-6a5a2b627cb8b588fe78463f218fd860fb78cd35.tar.gz | |
fix(iced_drop): support reactive rendering
| -rw-r--r-- | iced_drop/src/widget/droppable.rs | 48 | ||||
| -rw-r--r-- | src/main.rs | 6 | ||||
| -rw-r--r-- | src/panes/element_list.rs | 11 |
3 files changed, 50 insertions, 15 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, diff --git a/src/main.rs b/src/main.rs index 336378e..e566ed5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -350,7 +350,7 @@ impl App { } fn subscription(&self) -> iced::Subscription<Message> { - let hotkeys = keyboard::on_key_press(|key, modifiers| { + keyboard::on_key_press(|key, modifiers| { if modifiers.command() { match key.as_ref() { keyboard::Key::Character("o") => Some(Message::OpenFile), @@ -367,9 +367,7 @@ impl App { } else { None } - }); - - hotkeys + }) } fn view(&self) -> Element<'_, Message> { diff --git a/src/panes/element_list.rs b/src/panes/element_list.rs index a644083..10eea66 100644 --- a/src/panes/element_list.rs +++ b/src/panes/element_list.rs @@ -12,12 +12,11 @@ fn items_list_view(items: &[ElementName]) -> Element<'_, Message> { .width(Length::Fill); for item in items { - column = - column.push(droppable(text(item.clone().to_string())).on_drop( - move |point, rect| { - Message::DropNewElement(item.clone(), point, rect) - }, - )); + column = column.push( + droppable(text(item.clone().to_string())).on_drop(|point, rect| { + Message::DropNewElement(item.clone(), point, rect) + }), + ); } container(column) |
