From 8df1858e5d25b49e9d4e79f631ba7322c3fc6bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=91=E5=AB=96233?= Date: Tue, 16 Jun 2026 23:35:59 +0800 Subject: [PATCH] feat(list_column): add drag and drop support to widget API --- src/widget/list/list_column.rs | 60 ++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/src/widget/list/list_column.rs b/src/widget/list/list_column.rs index 9e4204cc..b4640d34 100644 --- a/src/widget/list/list_column.rs +++ b/src/widget/list/list_column.rs @@ -3,7 +3,7 @@ use crate::widget::container::Catalog; use crate::widget::space::vertical; -use crate::widget::{button, column, container, divider, row}; +use crate::widget::{DndDestination, DndSource, button, column, container, divider, row}; use crate::{Apply, Element, theme}; use iced::{Length, Padding}; @@ -11,14 +11,23 @@ use iced::{Length, Padding}; pub struct ListButton<'a, Message> { content: Element<'a, Message>, on_press: Option, + dnd_source_builder: Option>>, + dnd_destination_builder: Option>>, selected: bool, } +/// Builds a DndSource, wrapping an element +pub type DndSourceBuilder<'a, Message> = dyn FnOnce(Element<'a, Message>) -> DndSource<'a, Message, Box>; +/// Builds a DndDestination, wrapping an element +pub type DndDestinationBuilder<'a, Message> = dyn FnOnce(Element<'a, Message>) -> DndDestination<'a, Message>; + /// Creates a [`ListButton`] with the given content. pub fn button<'a, Message>(content: impl Into>) -> ListButton<'a, Message> { ListButton { content: content.into(), on_press: None, + dnd_source_builder: None, + dnd_destination_builder: None, selected: false, } } @@ -38,6 +47,16 @@ impl<'a, Message: 'static> ListButton<'a, Message> { self.selected = selected; self } + + pub fn with_dnd_source(mut self, builder: Box>) -> Self { + self.dnd_source_builder = Some(builder); + self + } + + pub fn with_dnd_destination(mut self, builder: Box>) -> Self { + self.dnd_destination_builder = Some(builder); + self + } } pub enum ListItem<'a, Message> { @@ -175,19 +194,32 @@ impl<'a, Message: Clone + 'static> ListColumn<'a, Message> { content, on_press, selected, - }) => col.push( - content_row(content) - .apply(button::custom) - .padding(item_padding) - .width(Length::Fill) - .on_press_maybe(on_press) - .selected(selected) - .class(theme::Button::ListItem(get_radius( - radius_s, - i == 0, - i == last_index, - ))), - ), + dnd_source_builder, + dnd_destination_builder, + }) => { + let mut button: Element<'a, Message> = + content_row(content) + .apply(button::custom) + .padding(item_padding) + .width(Length::Fill) + .on_press_maybe(on_press) + .selected(selected) + .class(theme::Button::ListItem(get_radius( + radius_s, + i == 0, + i == last_index, + ))) + .into(); + if let Some(builder) = dnd_source_builder { + button = builder(button).into(); + } + + if let Some(builder) = dnd_destination_builder { + button = builder(button).into(); + } + + col.push(button) + }, }; }