zng_view_api/
drag_drop.rs

1//! Drag&drop types.
2
3use std::{fmt, path::PathBuf};
4
5use zng_txt::Txt;
6
7use crate::ipc::IpcBytes;
8
9use bitflags::bitflags;
10
11/// Drag&drop data payload.
12#[derive(Clone, PartialEq, serde::Serialize, serde::Deserialize)]
13pub enum DragDropData {
14    /// Text encoded data.
15    ///
16    /// This can be HTML or JSON for example.
17    Text {
18        /// MIME type of the data.
19        ///
20        /// Plain text is `"text/plain"`.
21        format: Txt,
22        /// Data.
23        data: Txt,
24    },
25    /// File or directory path.
26    Path(PathBuf),
27    /// Binary encoded data.
28    ///
29    /// This can be an image for example.
30    Binary {
31        /// MIME type of the data.
32        format: Txt,
33        /// Data.
34        data: IpcBytes,
35    },
36}
37impl fmt::Debug for DragDropData {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        match self {
40            Self::Text { format, data } => write!(f, "Text {{ format: {:?}, data: {} bytes }}", format, data.len()),
41            Self::Path(data) => write!(f, "Path({})", data.display()),
42            Self::Binary { format, data } => write!(f, "Binary {{ format: {:?}, data: {} bytes }}", format, data.len()),
43        }
44    }
45}
46
47#[cfg(feature = "var")]
48zng_var::impl_from_and_into_var! {
49    fn from(plain: Txt) -> DragDropData {
50        DragDropData::Text {
51            format: "text/plain".into(),
52            data: plain,
53        }
54    }
55
56    fn from(plain: String) -> DragDropData {
57        Txt::from(plain).into()
58    }
59
60    fn from(plain: &'static str) -> DragDropData {
61        Txt::from(plain).into()
62    }
63
64    fn from(path: PathBuf) -> DragDropData {
65        DragDropData::Path(path)
66    }
67}
68
69bitflags! {
70    /// Drag&drop drop effect on the data source.
71    #[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
72    pub struct DragDropEffect: u8 {
73        /// Indicates that the dragged data will be copied from its present location to the drop location.
74        const COPY = 0b001;
75        /// Indicates that the dragged data will be moved from its present location to the drop location.
76        const MOVE = 0b010;
77        /// Indicates that some form of relationship or connection will be created between the source and drop locations.
78        const LINK = 0b100;
79    }
80}
81impl DragDropEffect {
82    /// Count effects flagged.
83    pub fn len(&self) -> u8 {
84        [DragDropEffect::COPY, DragDropEffect::MOVE, DragDropEffect::LINK]
85            .into_iter()
86            .filter(|&f| self.contains(f))
87            .count() as u8
88    }
89}
90
91/// Error for drag start or cancel error.
92#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
93pub enum DragDropError {
94    /// View-process implementer does not support any of the provided data types.
95    NotSupported,
96    /// Cannot start dragging.
97    CannotStart(Txt),
98}
99impl fmt::Display for DragDropError {
100    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101        match self {
102            DragDropError::NotSupported => write!(f, "not supported"),
103            DragDropError::CannotStart(txt) => write!(f, "cannot start, {txt}"),
104        }
105    }
106}
107impl std::error::Error for DragDropError {
108    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
109        None
110    }
111}