bevy_window/
event.rs

1#![allow(deprecated)]
2use std::path::PathBuf;
3
4use bevy_ecs::entity::Entity;
5use bevy_ecs::event::Event;
6use bevy_math::{IVec2, Vec2};
7use bevy_reflect::Reflect;
8use smol_str::SmolStr;
9
10#[cfg(feature = "serialize")]
11use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
12
13use crate::WindowTheme;
14
15/// A window event that is sent whenever a window's logical size has changed.
16#[derive(Event, Debug, Clone, PartialEq, Reflect)]
17#[reflect(Debug, PartialEq)]
18#[cfg_attr(
19    feature = "serialize",
20    derive(serde::Serialize, serde::Deserialize),
21    reflect(Serialize, Deserialize)
22)]
23pub struct WindowResized {
24    /// Window that has changed.
25    pub window: Entity,
26    /// The new logical width of the window.
27    pub width: f32,
28    /// The new logical height of the window.
29    pub height: f32,
30}
31
32/// An event that indicates all of the application's windows should be redrawn,
33/// even if their control flow is set to `Wait` and there have been no window events.
34#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
35#[reflect(Debug, PartialEq)]
36#[cfg_attr(
37    feature = "serialize",
38    derive(serde::Serialize, serde::Deserialize),
39    reflect(Serialize, Deserialize)
40)]
41pub struct RequestRedraw;
42
43/// An event that is sent whenever a new window is created.
44///
45/// To create a new window, spawn an entity with a [`crate::Window`] on it.
46#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
47#[reflect(Debug, PartialEq)]
48#[cfg_attr(
49    feature = "serialize",
50    derive(serde::Serialize, serde::Deserialize),
51    reflect(Serialize, Deserialize)
52)]
53pub struct WindowCreated {
54    /// Window that has been created.
55    pub window: Entity,
56}
57
58/// An event that is sent whenever the operating systems requests that a window
59/// be closed. This will be sent when the close button of the window is pressed.
60///
61/// If the default [`WindowPlugin`] is used, these events are handled
62/// by closing the corresponding [`Window`].
63/// To disable this behavior, set `close_when_requested` on the [`WindowPlugin`]
64/// to `false`.
65///
66/// [`WindowPlugin`]: crate::WindowPlugin
67/// [`Window`]: crate::Window
68#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
69#[reflect(Debug, PartialEq)]
70#[cfg_attr(
71    feature = "serialize",
72    derive(serde::Serialize, serde::Deserialize),
73    reflect(Serialize, Deserialize)
74)]
75pub struct WindowCloseRequested {
76    /// Window to close.
77    pub window: Entity,
78}
79
80/// An event that is sent whenever a window is closed. This will be sent when
81/// the window entity loses its [`Window`](crate::window::Window) component or is despawned.
82#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
83#[reflect(Debug, PartialEq)]
84#[cfg_attr(
85    feature = "serialize",
86    derive(serde::Serialize, serde::Deserialize),
87    reflect(Serialize, Deserialize)
88)]
89pub struct WindowClosed {
90    /// Window that has been closed.
91    ///
92    /// Note that this entity probably no longer exists
93    /// by the time this event is received.
94    pub window: Entity,
95}
96
97/// An event that is sent whenever a window is closing. This will be sent when
98/// after a [`WindowCloseRequested`] event is received and the window is in the process of closing.
99#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
100#[reflect(Debug, PartialEq)]
101#[cfg_attr(
102    feature = "serialize",
103    derive(serde::Serialize, serde::Deserialize),
104    reflect(Serialize, Deserialize)
105)]
106pub struct WindowClosing {
107    /// Window that has been requested to close and is the process of closing.
108    pub window: Entity,
109}
110
111/// An event that is sent whenever a window is destroyed by the underlying window system.
112///
113/// Note that if your application only has a single window, this event may be your last chance to
114/// persist state before the application terminates.
115#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
116#[reflect(Debug, PartialEq)]
117#[cfg_attr(
118    feature = "serialize",
119    derive(serde::Serialize, serde::Deserialize),
120    reflect(Serialize, Deserialize)
121)]
122pub struct WindowDestroyed {
123    /// Window that has been destroyed.
124    ///
125    /// Note that this entity probably no longer exists
126    /// by the time this event is received.
127    pub window: Entity,
128}
129
130/// An event reporting that the mouse cursor has moved inside a window.
131///
132/// The event is sent only if the cursor is over one of the application's windows.
133/// It is the translated version of [`WindowEvent::CursorMoved`] from the `winit` crate with the addition of `delta`.
134///
135/// Not to be confused with the `MouseMotion` event from `bevy_input`.
136///
137/// Because the range of data is limited by the window area and it may have been transformed by the OS to implement certain effects like acceleration,
138/// you should not use it for non-cursor-like behaviour such as 3D camera control. Please see `MouseMotion` instead.
139///
140/// [`WindowEvent::CursorMoved`]: https://docs.rs/winit/latest/winit/event/enum.WindowEvent.html#variant.CursorMoved
141#[derive(Event, Debug, Clone, PartialEq, Reflect)]
142#[reflect(Debug, PartialEq)]
143#[cfg_attr(
144    feature = "serialize",
145    derive(serde::Serialize, serde::Deserialize),
146    reflect(Serialize, Deserialize)
147)]
148pub struct CursorMoved {
149    /// Window that the cursor moved inside.
150    pub window: Entity,
151    /// The cursor position in logical pixels.
152    pub position: Vec2,
153    /// The change in the position of the cursor since the last event was sent.
154    /// This value is `None` if the cursor was outside the window area during the last frame.
155    //
156    // Because the range of this data is limited by the display area and it may have been
157    //  transformed by the OS to implement effects such as cursor acceleration, it should
158    // not be used to implement non-cursor-like interactions such as 3D camera control.
159    pub delta: Option<Vec2>,
160}
161
162/// An event that is sent whenever the user's cursor enters a window.
163#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
164#[reflect(Debug, PartialEq)]
165#[cfg_attr(
166    feature = "serialize",
167    derive(serde::Serialize, serde::Deserialize),
168    reflect(Serialize, Deserialize)
169)]
170pub struct CursorEntered {
171    /// Window that the cursor entered.
172    pub window: Entity,
173}
174
175/// An event that is sent whenever the user's cursor leaves a window.
176#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
177#[reflect(Debug, PartialEq)]
178#[cfg_attr(
179    feature = "serialize",
180    derive(serde::Serialize, serde::Deserialize),
181    reflect(Serialize, Deserialize)
182)]
183pub struct CursorLeft {
184    /// Window that the cursor left.
185    pub window: Entity,
186}
187
188/// An event that is sent whenever a window receives a character from the OS or underlying system.
189#[deprecated(since = "0.14.0", note = "Use `KeyboardInput` instead.")]
190#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
191#[reflect(Debug, PartialEq)]
192#[cfg_attr(
193    feature = "serialize",
194    derive(serde::Serialize, serde::Deserialize),
195    reflect(Serialize, Deserialize)
196)]
197pub struct ReceivedCharacter {
198    /// Window that received the character.
199    pub window: Entity,
200    /// Received character.
201    pub char: SmolStr,
202}
203
204/// A Input Method Editor event.
205///
206/// This event is the translated version of the `WindowEvent::Ime` from the `winit` crate.
207///
208/// It is only sent if IME was enabled on the window with [`Window::ime_enabled`](crate::window::Window::ime_enabled).
209#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
210#[reflect(Debug, PartialEq)]
211#[cfg_attr(
212    feature = "serialize",
213    derive(serde::Serialize, serde::Deserialize),
214    reflect(Serialize, Deserialize)
215)]
216pub enum Ime {
217    /// Notifies when a new composing text should be set at the cursor position.
218    Preedit {
219        /// Window that received the event.
220        window: Entity,
221        /// Current value.
222        value: String,
223        /// Cursor begin and end position.
224        ///
225        /// `None` indicated the cursor should be hidden
226        cursor: Option<(usize, usize)>,
227    },
228    /// Notifies when text should be inserted into the editor widget.
229    Commit {
230        /// Window that received the event.
231        window: Entity,
232        /// Input string
233        value: String,
234    },
235    /// Notifies when the IME was enabled.
236    ///
237    /// After this event, you will receive events `Ime::Preedit` and `Ime::Commit`,
238    /// and stop receiving events [`ReceivedCharacter`].
239    Enabled {
240        /// Window that received the event.
241        window: Entity,
242    },
243    /// Notifies when the IME was disabled.
244    Disabled {
245        /// Window that received the event.
246        window: Entity,
247    },
248}
249
250/// An event that indicates a window has received or lost focus.
251#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
252#[reflect(Debug, PartialEq)]
253#[cfg_attr(
254    feature = "serialize",
255    derive(serde::Serialize, serde::Deserialize),
256    reflect(Serialize, Deserialize)
257)]
258pub struct WindowFocused {
259    /// Window that changed focus.
260    pub window: Entity,
261    /// Whether it was focused (true) or lost focused (false).
262    pub focused: bool,
263}
264
265/// The window has been occluded (completely hidden from view).
266///
267/// This is different to window visibility as it depends on
268/// whether the window is closed, minimised, set invisible,
269/// or fully occluded by another window.
270///
271/// It is the translated version of [`WindowEvent::Occluded`] from the `winit` crate.
272///
273/// [`WindowEvent::Occluded`]: https://docs.rs/winit/latest/winit/event/enum.WindowEvent.html#variant.Occluded
274#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
275#[reflect(Debug, PartialEq)]
276#[cfg_attr(
277    feature = "serialize",
278    derive(serde::Serialize, serde::Deserialize),
279    reflect(Serialize, Deserialize)
280)]
281pub struct WindowOccluded {
282    /// Window that changed occluded state.
283    pub window: Entity,
284    /// Whether it was occluded (true) or not occluded (false).
285    pub occluded: bool,
286}
287
288/// An event that indicates a window's scale factor has changed.
289#[derive(Event, Debug, Clone, PartialEq, Reflect)]
290#[reflect(Debug, PartialEq)]
291#[cfg_attr(
292    feature = "serialize",
293    derive(serde::Serialize, serde::Deserialize),
294    reflect(Serialize, Deserialize)
295)]
296pub struct WindowScaleFactorChanged {
297    /// Window that had its scale factor changed.
298    pub window: Entity,
299    /// The new scale factor.
300    pub scale_factor: f64,
301}
302
303/// An event that indicates a window's OS-reported scale factor has changed.
304#[derive(Event, Debug, Clone, PartialEq, Reflect)]
305#[reflect(Debug, PartialEq)]
306#[cfg_attr(
307    feature = "serialize",
308    derive(serde::Serialize, serde::Deserialize),
309    reflect(Serialize, Deserialize)
310)]
311pub struct WindowBackendScaleFactorChanged {
312    /// Window that had its scale factor changed by the backend.
313    pub window: Entity,
314    /// The new scale factor.
315    pub scale_factor: f64,
316}
317
318/// Events related to files being dragged and dropped on a window.
319#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
320#[reflect(Debug, PartialEq)]
321#[cfg_attr(
322    feature = "serialize",
323    derive(serde::Serialize, serde::Deserialize),
324    reflect(Serialize, Deserialize)
325)]
326pub enum FileDragAndDrop {
327    /// File is being dropped into a window.
328    DroppedFile {
329        /// Window the file was dropped into.
330        window: Entity,
331        /// Path to the file that was dropped in.
332        path_buf: PathBuf,
333    },
334
335    /// File is currently being hovered over a window.
336    HoveredFile {
337        /// Window a file is possibly going to be dropped into.
338        window: Entity,
339        /// Path to the file that might be dropped in.
340        path_buf: PathBuf,
341    },
342
343    /// File hovering was canceled.
344    HoveredFileCanceled {
345        /// Window that had a canceled file drop.
346        window: Entity,
347    },
348}
349
350/// An event that is sent when a window is repositioned in physical pixels.
351#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
352#[reflect(Debug, PartialEq)]
353#[cfg_attr(
354    feature = "serialize",
355    derive(serde::Serialize, serde::Deserialize),
356    reflect(Serialize, Deserialize)
357)]
358pub struct WindowMoved {
359    /// Window that moved.
360    pub window: Entity,
361    /// Where the window moved to in physical pixels.
362    pub position: IVec2,
363}
364
365/// An event sent when the system theme changes for a window.
366///
367/// This event is only sent when the window is relying on the system theme to control its appearance.
368/// i.e. It is only sent when [`Window::window_theme`](crate::window::Window::window_theme) is `None` and the system theme changes.
369#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
370#[reflect(Debug, PartialEq)]
371#[cfg_attr(
372    feature = "serialize",
373    derive(serde::Serialize, serde::Deserialize),
374    reflect(Serialize, Deserialize)
375)]
376pub struct WindowThemeChanged {
377    /// Window for which the system theme has changed.
378    pub window: Entity,
379    /// The new system theme.
380    pub theme: WindowTheme,
381}
382
383/// Application lifetime events
384#[derive(Event, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
385#[reflect(Debug, PartialEq)]
386#[cfg_attr(
387    feature = "serialize",
388    derive(serde::Serialize, serde::Deserialize),
389    reflect(Serialize, Deserialize)
390)]
391pub enum AppLifecycle {
392    /// The application is not started yet.
393    Idle,
394    /// The application is running.
395    Running,
396    /// The application is going to be suspended.
397    /// Applications have one frame to react to this event before being paused in the background.
398    WillSuspend,
399    /// The application was suspended.
400    Suspended,
401    /// The application is going to be resumed.
402    /// Applications have one extra frame to react to this event before being fully resumed.
403    WillResume,
404}
405
406impl AppLifecycle {
407    /// Return `true` if the app can be updated.
408    #[inline]
409    pub fn is_active(&self) -> bool {
410        match self {
411            Self::Idle | Self::Suspended => false,
412            Self::Running | Self::WillSuspend | Self::WillResume => true,
413        }
414    }
415}