Skip to main content

orbclient/
flags.rs

1#[cfg(not(feature = "std"))]
2use alloc::string::String;
3use core::fmt::Display;
4use core::fmt::Write;
5use core::str::FromStr;
6
7#[derive(Clone, Copy, Debug, PartialEq)]
8pub enum WindowFlag {
9    /// Asynchronous Event
10    Async,
11    /// Do not use. Reserved for background
12    Back,
13    /// Always on top, even taskbar
14    Front,
15    /// Hide the window
16    Hidden,
17    /// Hide window border, handle your own window dragging API
18    Borderless,
19    /// Maximize the window
20    Maximized,
21    /// Full screen the window
22    Fullscreen,
23    /// Window manager can resize the window
24    Resizable,
25    /// Window manager can enable window scaling
26    Scalable,
27    /// Apply blending with window behind (slower)
28    Transparent,
29    /// Cannot be closed, handle your own window close API
30    Unclosable,
31}
32
33#[derive(Debug, Default, Clone)]
34pub struct WindowFlags(String, usize);
35
36impl Display for WindowFlag {
37    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
38        match self {
39            WindowFlag::Async => write!(f, "a"),
40            WindowFlag::Back => write!(f, "b"),
41            WindowFlag::Front => write!(f, "f"),
42            WindowFlag::Hidden => write!(f, "h"),
43            WindowFlag::Borderless => write!(f, "l"),
44            WindowFlag::Maximized => write!(f, "m"),
45            WindowFlag::Fullscreen => write!(f, "M"),
46            WindowFlag::Resizable => write!(f, "r"),
47            WindowFlag::Scalable => write!(f, "s"),
48            WindowFlag::Transparent => write!(f, "t"),
49            WindowFlag::Unclosable => write!(f, "u"),
50        }
51    }
52}
53
54impl WindowFlags {
55    pub fn new(flags: String) -> Self {
56        Self(flags, 0)
57    }
58
59    pub fn reset(&mut self) {
60        self.1 = 0;
61    }
62
63    pub fn push(&mut self, flag: WindowFlag) {
64        let _ = write!(self.0, "{}", flag);
65    }
66}
67
68impl Display for WindowFlags {
69    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
70        write!(f, "{}", self.0)
71    }
72}
73
74impl Into<String> for WindowFlags {
75    fn into(self) -> String {
76        self.0
77    }
78}
79
80impl Iterator for WindowFlags {
81    type Item = WindowFlag;
82
83    fn next(&mut self) -> Option<Self::Item> {
84        let i = self.1;
85        if self.0.len() >= i {
86            return None;
87        }
88        self.1 += 1;
89        match self.0.as_bytes()[i] {
90            b'a' => Some(WindowFlag::Async),
91            b'b' => Some(WindowFlag::Back),
92            b'f' => Some(WindowFlag::Front),
93            b'h' => Some(WindowFlag::Hidden),
94            b'l' => Some(WindowFlag::Borderless),
95            b'm' => Some(WindowFlag::Maximized),
96            b'M' => Some(WindowFlag::Fullscreen),
97            b'r' => Some(WindowFlag::Resizable),
98            b's' => Some(WindowFlag::Scalable),
99            b't' => Some(WindowFlag::Transparent),
100            b'u' => Some(WindowFlag::Unclosable),
101            _ => None,
102        }
103    }
104}
105
106#[derive(Clone, Copy, Debug)]
107pub enum SurfaceFlag {}
108
109#[derive(Clone, Copy, Debug)]
110pub enum Mode {
111    Blend,     //Composite
112    Overwrite, //Replace
113}
114
115pub enum WindowDragKind {
116    None,
117    Move,
118    ResizeLeft,
119    ResizeRight,
120    ResizeBottom,
121    ResizeTop,
122}
123
124impl Display for WindowDragKind {
125    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
126        match self {
127            WindowDragKind::Move => write!(f, "M"),
128            WindowDragKind::ResizeLeft => write!(f, "L"),
129            WindowDragKind::ResizeRight => write!(f, "R"),
130            WindowDragKind::ResizeBottom => write!(f, "B"),
131            WindowDragKind::ResizeTop => write!(f, "T"),
132            WindowDragKind::None => write!(f, "0"),
133        }
134    }
135}
136
137impl WindowDragKind {
138    pub fn from_u8(val: i64) -> Option<Self> {
139        match val {
140            0 => Some(WindowDragKind::None),
141            1 => Some(WindowDragKind::Move),
142            2 => Some(WindowDragKind::ResizeLeft),
143            3 => Some(WindowDragKind::ResizeRight),
144            4 => Some(WindowDragKind::ResizeBottom),
145            5 => Some(WindowDragKind::ResizeTop),
146            _ => None,
147        }
148    }
149    pub fn to_u8(&self) -> i64 {
150        match self {
151            WindowDragKind::None => 0,
152            WindowDragKind::Move => 1,
153            WindowDragKind::ResizeLeft => 2,
154            WindowDragKind::ResizeRight => 3,
155            WindowDragKind::ResizeBottom => 4,
156            WindowDragKind::ResizeTop => 5,
157        }
158    }
159    #[allow(unused)]
160    pub(crate) fn to_orbital_cmd(&self) -> &'static [u8] {
161        match self {
162            WindowDragKind::None => b"D,0",
163            WindowDragKind::Move => b"D,M",
164            WindowDragKind::ResizeLeft => b"D,L",
165            WindowDragKind::ResizeRight => b"D,R",
166            WindowDragKind::ResizeBottom => b"D,B",
167            WindowDragKind::ResizeTop => b"D,T",
168        }
169    }
170}
171impl FromStr for WindowDragKind {
172    type Err = String;
173
174    fn from_str(s: &str) -> Result<Self, Self::Err> {
175        match s {
176            "" | "M" => Ok(WindowDragKind::Move),
177            "L" => Ok(WindowDragKind::ResizeLeft),
178            "R" => Ok(WindowDragKind::ResizeRight),
179            "B" => Ok(WindowDragKind::ResizeBottom),
180            "T" => Ok(WindowDragKind::ResizeTop),
181            _ => Err(s.into()),
182        }
183    }
184}
185
186/// A type of media that registered into clipboard or DND system.
187/// Text, File, Uri is designed for simple implementation.
188/// For programs that wants to send custom MIME, use Data.
189/// Cannot support multiple kind of data at the moment.
190#[derive(Clone, Copy, Debug)]
191pub enum MediaKind {
192    /// A regular text
193    Text,
194    /// A file path (can be multiple, \n separated)
195    File,
196    /// A URI path (HTTP or internal identifier)
197    Uri,
198    /// A data URI
199    Data,
200    /// Do not use
201    Any,
202}
203
204impl MediaKind {
205    pub fn from_i64(val: i64) -> Self {
206        match val {
207            1 => MediaKind::Text,
208            2 => MediaKind::File,
209            3 => MediaKind::Uri,
210            4 => MediaKind::Data,
211            _ => MediaKind::Any,
212        }
213    }
214    pub fn to_i64(&self) -> i64 {
215        match self {
216            MediaKind::Text => 1,
217            MediaKind::File => 2,
218            MediaKind::Uri => 3,
219            MediaKind::Data => 4,
220            MediaKind::Any => 1,
221        }
222    }
223    pub fn to_mime(&self, data: &str) -> String {
224        const DEFAULT_MIME: &str = "application/octet-stream";
225        match self {
226            MediaKind::Text => "text/plain".into(),
227            MediaKind::File => "text/uri-list".into(),
228            MediaKind::Uri => "text/x-uri".into(),
229            MediaKind::Data => {
230                if let Some(rest) = data.strip_prefix("data:") {
231                    if let Some((prefix, _)) = rest.split_once(&[';', ',', '\n']) {
232                        if prefix.len() < 100 {
233                            return prefix.into();
234                        }
235                    }
236                }
237                DEFAULT_MIME.into()
238            }
239            MediaKind::Any => DEFAULT_MIME.into(),
240        }
241    }
242}
243
244impl Display for MediaKind {
245    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
246        match self {
247            MediaKind::Text => write!(f, "t"),
248            MediaKind::File => write!(f, "f"),
249            MediaKind::Uri => write!(f, "u"),
250            MediaKind::Data => write!(f, "d"),
251            MediaKind::Any => write!(f, " "),
252        }
253    }
254}
255
256impl FromStr for MediaKind {
257    type Err = String;
258
259    fn from_str(s: &str) -> Result<Self, Self::Err> {
260        match s {
261            "t" => Ok(MediaKind::Text),
262            "f" => Ok(MediaKind::File),
263            "u" => Ok(MediaKind::Uri),
264            "d" => Ok(MediaKind::Data),
265            " " => Ok(MediaKind::Any),
266            _ => Err(s.into()),
267        }
268    }
269}
270
271#[derive(Clone, Copy, Debug)]
272pub enum ClipboardAction {
273    Copy,
274    Cut,
275    Paste,
276}
277
278impl ClipboardAction {
279    pub fn from_u8(val: u8) -> Option<Self> {
280        match val {
281            1 => Some(ClipboardAction::Copy),
282            2 => Some(ClipboardAction::Cut),
283            3 => Some(ClipboardAction::Paste),
284            _ => None,
285        }
286    }
287    pub fn to_u8(&self) -> u8 {
288        match self {
289            ClipboardAction::Copy => 1,
290            ClipboardAction::Cut => 2,
291            ClipboardAction::Paste => 3,
292        }
293    }
294}
295
296#[derive(Clone, Copy, Debug)]
297pub enum DragAction {
298    Copy,
299    Move,
300    Link,
301    None,
302}
303
304impl DragAction {
305    pub fn from_u8(val: u8) -> Option<Self> {
306        match val {
307            1 => Some(DragAction::Copy),
308            2 => Some(DragAction::Move),
309            4 => Some(DragAction::Link),
310            0 => Some(DragAction::None),
311            _ => None,
312        }
313    }
314    pub fn to_u8(&self) -> u8 {
315        match self {
316            DragAction::Copy => 1,
317            DragAction::Move => 2,
318            DragAction::Link => 4,
319            DragAction::None => 0,
320        }
321    }
322}