zng_view_api/
drag_drop.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//! Drag&drop types.

use std::{fmt, path::PathBuf};

use zng_txt::Txt;

use crate::ipc::IpcBytes;

use bitflags::bitflags;

/// Drag&drop data payload.
#[derive(Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum DragDropData {
    /// Text encoded data.
    ///
    /// This can be HTML or JSON for example.
    Text {
        /// MIME type of the data.
        ///
        /// Plain text is `"text/plain"`.
        format: Txt,
        /// Data.
        data: Txt,
    },
    /// File or directory path.
    Path(PathBuf),
    /// Binary encoded data.
    ///
    /// This can be an image for example.
    Binary {
        /// MIME type of the data.
        format: Txt,
        /// Data.
        data: IpcBytes,
    },
}
impl fmt::Debug for DragDropData {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Text { format, data } => write!(f, "Text {{ format: {:?}, data: {} bytes }}", format, data.len()),
            Self::Path(data) => write!(f, "Path({})", data.display()),
            Self::Binary { format, data } => write!(f, "Binary {{ format: {:?}, data: {} bytes }}", format, data.len()),
        }
    }
}

#[cfg(feature = "var")]
zng_var::impl_from_and_into_var! {
    fn from(plain: Txt) -> DragDropData {
        DragDropData::Text {
            format: "text/plain".into(),
            data: plain,
        }
    }

    fn from(plain: String) -> DragDropData {
        Txt::from(plain).into()
    }

    fn from(plain: &'static str) -> DragDropData {
        Txt::from(plain).into()
    }

    fn from(path: PathBuf) -> DragDropData {
        DragDropData::Path(path)
    }
}

bitflags! {
    /// Drag&drop drop effect on the data source.
    #[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct DragDropEffect: u8 {
        /// Indicates that the dragged data will be copied from its present location to the drop location.
        const COPY = 0b001;
        /// Indicates that the dragged data will be moved from its present location to the drop location.
        const MOVE = 0b010;
        /// Indicates that some form of relationship or connection will be created between the source and drop locations.
        const LINK = 0b100;
    }
}
impl DragDropEffect {
    /// Count effects flagged.
    pub fn len(&self) -> u8 {
        [DragDropEffect::COPY, DragDropEffect::MOVE, DragDropEffect::LINK]
            .into_iter()
            .filter(|&f| self.contains(f))
            .count() as u8
    }
}

/// Error for drag start or cancel error.
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum DragDropError {
    /// View-process implementer does not support any of the provided data types.
    NotSupported,
    /// Cannot start dragging.
    CannotStart(Txt),
}
impl fmt::Display for DragDropError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            DragDropError::NotSupported => write!(f, "not supported"),
            DragDropError::CannotStart(txt) => write!(f, "cannot start, {txt}"),
        }
    }
}
impl std::error::Error for DragDropError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        None
    }
}