ailloli_ui_core/event/keyboard.rs
1//! Platform-neutral keyboard keys, modifiers, and event payloads.
2
3use crate::Point;
4
5/// Modifier keys held during a keyboard or pointer event.
6///
7/// # Examples
8///
9/// ```
10/// use ailloli_ui_core::event::Modifiers;
11/// let modifiers = Modifiers { ctrl: true, ..Modifiers::default() };
12/// assert!(modifiers.ctrl);
13/// ```
14#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
15pub struct Modifiers {
16 /// `true` while a Control modifier is active.
17 pub ctrl: bool,
18 /// `true` while an Alt/Option modifier is active.
19 pub alt: bool,
20 /// `true` while a Shift modifier is active.
21 pub shift: bool,
22 /// `true` while a platform Meta/Command/Windows modifier is active.
23 pub meta: bool,
24}
25
26/// Press or release phase of a key event.
27///
28/// Possible values are [`KeyState::Pressed`] and [`KeyState::Released`].
29///
30/// # Examples
31///
32/// ```
33/// use ailloli_ui_core::event::KeyState;
34/// assert_ne!(KeyState::Pressed, KeyState::Released);
35/// ```
36#[derive(Debug, Clone, Copy, PartialEq, Eq)]
37pub enum KeyState {
38 /// The key transitioned to the down state.
39 Pressed,
40 /// The key transitioned to the up state.
41 Released,
42}
43
44/// Well-known keys with stable names (arrows, editing keys, function keys).
45///
46/// # Examples
47///
48/// ```
49/// use ailloli_ui_core::event::NamedKey;
50/// assert_eq!(NamedKey::F(12), NamedKey::F(12));
51/// assert_eq!(NamedKey::Other("MediaPlay".into()), NamedKey::Other("MediaPlay".into()));
52/// ```
53#[derive(Debug, Clone, PartialEq, Eq)]
54pub enum NamedKey {
55 /// Backspace editing key.
56 Backspace,
57 /// Forward-delete editing key.
58 Delete,
59 /// Enter or Return activation key.
60 Enter,
61 /// Tab navigation or text key.
62 Tab,
63 /// Space key when represented as a named key.
64 Space,
65 /// Left arrow navigation key.
66 ArrowLeft,
67 /// Right arrow navigation key.
68 ArrowRight,
69 /// Up arrow navigation key.
70 ArrowUp,
71 /// Down arrow navigation key.
72 ArrowDown,
73 /// Home navigation key.
74 Home,
75 /// End navigation key.
76 End,
77 /// Page-up navigation key.
78 PageUp,
79 /// Page-down navigation key.
80 PageDown,
81 /// Escape/cancel key.
82 Escape,
83 /// Insert editing key.
84 Insert,
85 /// Function key number supplied by the provider.
86 ///
87 /// The conventional range is `1..=12`, but this type does not enforce it.
88 F(u8),
89 /// Key not mapped to a known variant.
90 Other(String),
91}
92
93/// Platform-neutral key representation.
94///
95/// Mapping from `winit` logical/physical keys is performed in `ailloli_ui_winit`.
96///
97/// # Examples
98///
99/// ```
100/// use ailloli_ui_core::event::{Key, NamedKey};
101/// let key = Key::Named(NamedKey::Enter);
102/// assert!(matches!(key, Key::Named(NamedKey::Enter)));
103/// ```
104#[derive(Debug, Clone, PartialEq, Eq)]
105pub enum Key {
106 /// Named special key.
107 Named(NamedKey),
108 /// Printable Unicode string (usually one character).
109 Character(String),
110 /// Dead key accent, if any.
111 Dead(Option<String>),
112 /// Key could not be identified.
113 Unidentified,
114}
115
116/// Keyboard input event in logical coordinates.
117///
118/// # Examples
119///
120/// ```
121/// use ailloli_ui_core::event::{Key, KeyEvent, KeyState, Modifiers};
122/// let event = KeyEvent {
123/// state: KeyState::Pressed,
124/// key: Key::Character("a".into()),
125/// modifiers: Modifiers::default(),
126/// repeat: false,
127/// pointer_pos: None,
128/// text: Some("a".into()),
129/// };
130/// assert_eq!(event.text.as_deref(), Some("a"));
131/// ```
132#[derive(Debug, Clone, PartialEq)]
133pub struct KeyEvent {
134 /// Press or release transition.
135 pub state: KeyState,
136 /// Provider-normalized logical key.
137 pub key: Key,
138 /// Modifier snapshot observed with this transition.
139 pub modifiers: Modifiers,
140 /// `true` when the OS reports auto-repeat.
141 pub repeat: bool,
142 /// Cursor position in logical window coordinates at event time, if known.
143 pub pointer_pos: Option<Point>,
144 /// Committed or composed text from the platform, when provided.
145 ///
146 /// `None` means no text payload was supplied; `Some("")` preserves an
147 /// explicitly supplied empty payload.
148 pub text: Option<String>,
149}