Skip to main content

devela/ui/event/
window.rs

1// devela::ui::event::window
2//
3//! Defines [`EventWindow`].
4//
5
6use crate::{ConstInit, Event, EventKind};
7use crate::{Extent, Position};
8
9#[cfg(feature = "alloc")]
10use crate::String;
11
12#[doc = crate::_tags!(event interaction)]
13/// Events related to a window, viewport, or presentation surface.
14#[doc = crate::_doc_meta!{
15    location("ui/event"),
16    #[cfg(not(feature = "alloc"))]
17    test_size_of(EventWindow = 16|128; niche Option),
18    #[cfg(feature = "alloc")]
19    test_size_of(EventWindow = 24|192; niche Option),
20}]
21///
22/// Names and payloads are backend-agnostic and focus on
23/// stable cross-platform surface semantics.
24//
25// - https://docs.rs/sdl2/latest/sdl2/event/enum.WindowEvent.html
26// - https://docs.rs/crossterm/latest/crossterm/event/enum.Event.html
27#[non_exhaustive]
28#[derive(Clone, Debug, PartialEq, Eq, Hash)]
29pub enum EventWindow {
30    /* geometry */
31    /// The window or viewport size changed.
32    ///
33    /// Carries the new `[width, height]` when the backend provides it.
34    // NOTE in SDL: https://stackoverflow.com/a/55076700/940200
35    // SizeChanged(UiSize),
36    Resized(Option<Extent<u32, 2>>),
37    /// The window or viewport position changed.
38    ///
39    /// Carries the new `[x, y]` when available.
40    Moved(Option<Position<i32, 2>>),
41
42    /* focus*/
43    /// The window gained keyboard focus.
44    FocusGained,
45
46    /// The window lost keyboard focus.
47    FocusLost,
48
49    /* life cycle / visibility transitions */
50    /// The system or window manager requested that the window close.
51    CloseRequested,
52
53    /// The window became visible.
54    Shown,
55
56    /// The window became hidden.
57    Hidden,
58
59    /// The window needs its contents repainted.
60    RedrawRequested,
61
62    /// The window was minimized.
63    Minimized,
64
65    /// The window was maximized.
66    Maximized,
67
68    /// The window was restored to its normal state.
69    Restored,
70
71    /// The window entered fullscreen mode.
72    FullscreenEntered,
73
74    /// The window exited fullscreen mode.
75    FullscreenExited,
76
77    /* pointer enter/leave */
78    /// The pointer entered the window region.
79    Entered,
80
81    /// The pointer left the window region.
82    Left,
83
84    /* text / clipboard */
85    /// Text was pasted into the window.
86    #[cfg(feature = "alloc")]
87    #[cfg_attr(nightly_doc, doc(cfg(feature = "alloc")))]
88    Paste(String),
89}
90impl ConstInit for EventWindow {
91    const INIT: Self = Self::FocusLost;
92}
93impl From<EventWindow> for EventKind {
94    fn from(window_event: EventWindow) -> EventKind {
95        EventKind::Window(window_event)
96    }
97}
98impl From<EventWindow> for Event {
99    fn from(window_event: EventWindow) -> Event {
100        EventKind::from(window_event).into()
101    }
102}
103
104impl EventWindow {
105    /* geometry */
106
107    /// True if this event indicates a change in window size or position.
108    pub const fn is_geometry(&self) -> bool {
109        matches!(self, Self::Resized(_) | Self::Moved(_))
110    }
111
112    /// True if this is a resize event (with or without data).
113    pub const fn is_resize(&self) -> bool {
114        matches!(self, Self::Resized(_))
115    }
116    /// Returns some resize event, if that's the kind.
117    pub const fn resize_coord(&self) -> Option<Extent<u32, 2>> {
118        if let EventWindow::Resized(e) = self { *e } else { None }
119    }
120
121    /// True if this is a move event (with or without data).
122    pub const fn is_move(&self) -> bool {
123        matches!(self, Self::Moved(_))
124    }
125    /// Returns some move event, if that's the kind.
126    pub const fn move_coord(&self) -> Option<Position<i32, 2>> {
127        if let EventWindow::Moved(e) = self { *e } else { None }
128    }
129
130    /* focus */
131
132    /// True if this event indicates a change in keyboard focus.
133    pub const fn is_focus(&self) -> bool {
134        matches!(self, Self::FocusGained | Self::FocusLost)
135    }
136
137    /* life cycle / visibility */
138
139    /// True if this event indicates that the system wants the window to close.
140    pub const fn is_close(&self) -> bool {
141        matches!(self, Self::CloseRequested)
142    }
143
144    /// True if this event requests a redraw.
145    pub const fn is_redraw(&self) -> bool {
146        matches!(self, Self::RedrawRequested)
147    }
148
149    /// True if this event indicates window visibility or lifecycle transitions.
150    pub const fn is_visibility(&self) -> bool {
151        matches!(
152            self,
153            Self::Shown
154                | Self::Hidden
155                | Self::Minimized
156                | Self::Restored
157                | Self::Maximized
158                | Self::FullscreenEntered
159                | Self::FullscreenExited
160        )
161    }
162
163    /* pointer enter/leave */
164
165    /// True if the pointer crossed into or out of the window.
166    pub const fn is_pointer_crossing(&self) -> bool {
167        matches!(self, Self::Entered | Self::Left)
168    }
169
170    /* text / clipboard */
171
172    /// True if the event involves clipboard/text input.
173    #[cfg(feature = "alloc")]
174    pub const fn is_text_input(&self) -> bool {
175        matches!(self, Self::Paste(_))
176    }
177}