use std::any::Any;
use dnd::{DndDestinationRectangle, DndSurface};
use iced_core::clipboard::DndSource;
use window_clipboard::mime::{AllowedMimeTypes, AsMimeTypes};
use crate::{oneshot, task, Action, Task};
pub enum DndAction {
RegisterDndDestination {
surface: DndSurface,
rectangles: Vec<DndDestinationRectangle>,
},
StartDnd {
internal: bool,
source_surface: Option<DndSource>,
icon_surface: Option<Box<dyn Any + Send>>,
content: Box<dyn AsMimeTypes + Send + 'static>,
actions: dnd::DndAction,
},
EndDnd,
PeekDnd(
String,
oneshot::Sender<Option<(Vec<u8>, String)>>,
),
SetAction(dnd::DndAction),
}
impl std::fmt::Debug for DndAction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::RegisterDndDestination {
surface,
rectangles,
} => f
.debug_struct("RegisterDndDestination")
.field("surface", surface)
.field("rectangles", rectangles)
.finish(),
Self::StartDnd {
internal,
source_surface,
icon_surface,
content: _,
actions,
} => f
.debug_struct("StartDnd")
.field("internal", internal)
.field("source_surface", source_surface)
.field("icon_surface", icon_surface)
.field("actions", actions)
.finish(),
Self::EndDnd => f.write_str("EndDnd"),
Self::PeekDnd(mime, _) => {
f.debug_struct("PeekDnd").field("mime", mime).finish()
}
Self::SetAction(a) => f.debug_tuple("SetAction").field(a).finish(),
}
}
}
pub fn peek_dnd<T: AllowedMimeTypes>() -> Task<Option<T>> {
task::oneshot(|tx| {
Action::Dnd(DndAction::PeekDnd(
T::allowed()
.first()
.map_or_else(String::new, std::string::ToString::to_string),
tx,
))
})
.map(|data| data.and_then(|data| T::try_from(data).ok()))
}
pub fn register_dnd_destination<Message>(
surface: DndSurface,
rectangles: Vec<DndDestinationRectangle>,
) -> Task<Message> {
task::effect(Action::Dnd(DndAction::RegisterDndDestination {
surface,
rectangles,
}))
}
pub fn start_dnd<Message>(
internal: bool,
source_surface: Option<DndSource>,
icon_surface: Option<Box<dyn Any + Send>>,
content: Box<dyn AsMimeTypes + Send + 'static>,
actions: dnd::DndAction,
) -> Task<Message> {
task::effect(Action::Dnd(DndAction::StartDnd {
internal,
source_surface,
icon_surface,
content,
actions,
}))
}
pub fn end_dnd<Message>() -> Task<Message> {
task::effect(Action::Dnd(DndAction::EndDnd))
}
pub fn set_action<Message>(a: dnd::DndAction) -> Task<Message> {
task::effect(Action::Dnd(DndAction::SetAction(a)))
}