ori_core/event/
event.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use std::any::Any;

use crate::{command::Command, view::ViewId, window::WindowId};

use super::{
    IsKey, KeyPressed, KeyReleased, PointerLeft, PointerMoved, PointerPressed, PointerReleased,
    PointerScrolled, WindowCloseRequested, WindowMaximized, WindowResized, WindowScaled,
};

/// A request to focus a view.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct RequestFocus(pub WindowId, pub ViewId);

/// A request to focus the next view in the focus chain.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct RequestFocusNext(pub WindowId);

/// A request to focus the previous view in the focus chain.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct RequestFocusPrev(pub WindowId);

/// A target for focus.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum FocusTarget {
    /// Focus should be given to the next view in the focus chain.
    Next,

    /// Focus should be given to the previous view in the focus chain.
    Prev,

    /// Focus should be given to a specific view.
    View(ViewId),
}

/// An event that can be sent to a view.
#[derive(Debug)]
#[non_exhaustive]
pub enum Event {
    /// The window was resized.
    WindowResized(WindowResized),

    /// The window was scaled.
    WindowScaled(WindowScaled),

    /// The window was maximized.
    WindowMaximized(WindowMaximized),

    /// The window requested to be close.
    WindowCloseRequested(WindowCloseRequested),

    /// A pointer moved.
    PointerMoved(PointerMoved),

    /// A pointer left the window.
    PointerLeft(PointerLeft),

    /// A pointer button was pressed.
    PointerPressed(PointerPressed),

    /// A pointer button was released.
    PointerReleased(PointerReleased),

    /// A pointer was scrolled.
    PointerScrolled(PointerScrolled),

    /// A keyboard key was pressed.
    KeyPressed(KeyPressed),

    /// A keyboard key was released.
    KeyReleased(KeyReleased),

    /// All views need to be laid out.
    ForceLayout,

    /// Focus should be switched to next view in the focus chain.
    FocusNext,

    /// Focus should be switched to previous view in the focus chain.
    FocusPrev,

    /// Focus is wanted by another view.
    ///
    /// A view receiving this event should give up focus.
    FocusWanted,

    /// Focus given to either a specific target.
    FocusGiven(FocusTarget),

    /// An animation frame has passed.
    Animate(f32),

    /// A command was sent.
    Command(Command),

    /// Event sent when something has changed and the view should be given a chance to update.
    Notify,
}

impl Event {
    /// Check if the event is a command of a specific type.
    pub fn is_cmd<T: Any>(&self) -> bool {
        match self {
            Event::Command(cmd) => cmd.is::<T>(),
            _ => false,
        }
    }

    /// Try to get the command as a specific type.
    ///
    /// Returns `None` if the event is not a command or if the command is not of the specified type.
    pub fn cmd<T: Any>(&self) -> Option<&T> {
        match self {
            Event::Command(cmd) => cmd.get(),
            _ => None,
        }
    }

    /// Check if the event represents a key press of a specific key.
    pub fn is_key_pressed(&self, key: impl IsKey) -> bool {
        match self {
            Event::KeyPressed(pressed) => pressed.is_key(key),
            _ => false,
        }
    }

    /// Check if the event represents a key release of a specific key.
    pub fn is_key_released(&self, key: impl IsKey) -> bool {
        match self {
            Event::KeyReleased(released) => released.is_key(key),
            _ => false,
        }
    }

    /// Check if the event wants to take focus.
    ///
    /// This is true for `FocusNext`, `FocusPrev`, and `FocusWanted`.
    #[rustfmt::skip]
    pub fn wants_focus(&self) -> bool {
        matches!(self, Event::FocusNext | Event::FocusPrev | Event::FocusWanted)
    }
}