iced_runtime/
dnd.rs

1//! Access the clipboard.
2
3use std::any::Any;
4
5use dnd::{DndDestinationRectangle, DndSurface};
6use iced_core::clipboard::DndSource;
7use window_clipboard::mime::{AllowedMimeTypes, AsMimeTypes};
8
9use crate::{oneshot, task, Action, Task};
10
11/// An action to be performed on the system.
12pub enum DndAction {
13    /// Register a Dnd destination.
14    RegisterDndDestination {
15        /// The surface to register.
16        surface: DndSurface,
17        /// The rectangles to register.
18        rectangles: Vec<DndDestinationRectangle>,
19    },
20    /// End a Dnd operation.
21    EndDnd,
22    /// Peek the current Dnd operation.
23    PeekDnd(
24        String,
25        oneshot::Sender<Option<(Vec<u8>, String)>>,
26        // Box<dyn Fn(Option<(Vec<u8>, String)>) -> T + Send + 'static>,
27    ),
28    /// Set the action of the Dnd operation.
29    SetAction(dnd::DndAction),
30}
31
32impl std::fmt::Debug for DndAction {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        match self {
35            Self::RegisterDndDestination {
36                surface,
37                rectangles,
38            } => f
39                .debug_struct("RegisterDndDestination")
40                .field("surface", surface)
41                .field("rectangles", rectangles)
42                .finish(),
43            Self::EndDnd => f.write_str("EndDnd"),
44            Self::PeekDnd(mime, _) => {
45                f.debug_struct("PeekDnd").field("mime", mime).finish()
46            }
47            Self::SetAction(a) => f.debug_tuple("SetAction").field(a).finish(),
48        }
49    }
50}
51
52/// Read the current contents of the Dnd operation.
53pub fn peek_dnd<T: AllowedMimeTypes>() -> Task<Option<T>> {
54    task::oneshot(|tx| {
55        Action::Dnd(DndAction::PeekDnd(
56            T::allowed()
57                .first()
58                .map_or_else(String::new, std::string::ToString::to_string),
59            tx,
60        ))
61    })
62    .map(|data| data.and_then(|data| T::try_from(data).ok()))
63}
64
65/// Register a Dnd destination.
66pub fn register_dnd_destination<Message>(
67    surface: DndSurface,
68    rectangles: Vec<DndDestinationRectangle>,
69) -> Task<Message> {
70    task::effect(Action::Dnd(DndAction::RegisterDndDestination {
71        surface,
72        rectangles,
73    }))
74}
75
76/// End a Dnd operation.
77pub fn end_dnd<Message>() -> Task<Message> {
78    task::effect(Action::Dnd(DndAction::EndDnd))
79}
80
81/// Set the action of the Dnd operation.
82pub fn set_action<Message>(a: dnd::DndAction) -> Task<Message> {
83    task::effect(Action::Dnd(DndAction::SetAction(a)))
84}