zng_wgt_input/keyboard.rs
1//! Keyboard events, [`on_key_down`](fn@on_key_down), [`on_key_up`](fn@on_key_up) and more.
2//!
3//! These events are low level and directly tied to a keyboard device.
4//! Before using them review the [`gesture`](super::gesture) properties, in particular
5//! the [`click_shortcut`](fn@super::gesture::click_shortcut) property.
6
7use zng_ext_input::keyboard::{KEY_INPUT_EVENT, KeyInputArgs, KeyState};
8use zng_wgt::prelude::*;
9
10event_property! {
11 /// Event fired when a keyboard key is pressed or released and the widget is enabled.
12 ///
13 /// # Route
14 ///
15 /// The event is raised in the [keyboard focused](crate::properties::is_focused)
16 /// widget and then each parent up to the root. If propagation stop
17 /// is requested the event is not notified further. If the widget is disabled or blocked the event is not notified.
18 ///
19 /// This route is also called *bubbling*.
20 ///
21 /// # Keys
22 ///
23 /// Any key press/release generates a key input event, including keys codes that don't map
24 /// to any virtual key, see [`KeyInputArgs`] for more details.
25 ///
26 /// For key combinations consider using a [`click_shortcut`] with a click handler.
27 ///
28 /// [`click_shortcut`]: fn@crate::gesture::click_shortcut
29 ///
30 /// # Underlying Event
31 ///
32 /// This event property uses the [`KEY_INPUT_EVENT`] that is included in the default app.
33 ///
34 /// [`KeyInputArgs`]: zng_ext_input::keyboard::KeyInputArgs
35 /// [`KEY_INPUT_EVENT`]: zng_ext_input::keyboard::KEY_INPUT_EVENT
36 #[property(EVENT)]
37 pub fn on_key_input<on_pre_key_input>(child: impl IntoUiNode, handler: Handler<KeyInputArgs>) -> UiNode {
38 const PRE: bool;
39 EventNodeBuilder::new(KEY_INPUT_EVENT)
40 .filter(|| {
41 let id = WIDGET.id();
42 move |args| args.target.contains_enabled(id)
43 })
44 .build::<PRE>(child, handler)
45 }
46
47 /// Event fired when a keyboard key is pressed or released and the widget is disabled.
48 ///
49 /// # Route
50 ///
51 /// The event is raised in the [keyboard focused](crate::properties::is_focused)
52 /// widget and then each parent up to the root. If propagation stop
53 /// is requested the event is not notified further. If the widget is enabled or blocked the event is not notified.
54 ///
55 /// This route is also called *bubbling*.
56 ///
57 /// # Keys
58 ///
59 /// Any key press/release generates a key input event, including keys that don't map
60 /// to any virtual key, see [`KeyInputArgs`] for more details.
61 ///
62 /// For key combinations consider using a [`click_shortcut`] with a click handler.
63 ///
64 /// [`click_shortcut`]: fn@crate::gesture::click_shortcut
65 ///
66 /// # Underlying Event
67 ///
68 /// This event property uses the [`KEY_INPUT_EVENT`] that is included in the default app.
69 ///
70 /// [`KeyInputArgs`]: zng_ext_input::keyboard::KeyInputArgs
71 /// [`KEY_INPUT_EVENT`]: zng_ext_input::keyboard::KEY_INPUT_EVENT
72 #[property(EVENT)]
73 pub fn on_disabled_key_input<on_pre_disabled_key_input>(child: impl IntoUiNode, handler: Handler<KeyInputArgs>) -> UiNode {
74 const PRE: bool;
75 EventNodeBuilder::new(KEY_INPUT_EVENT)
76 .filter(|| {
77 let id = WIDGET.id();
78 move |args| args.target.contains_disabled(id)
79 })
80 .build::<PRE>(child, handler)
81 }
82
83 /// Event fired when a keyboard key is pressed and the widget is enabled.
84 ///
85 /// # Route
86 ///
87 /// The event is raised in the [keyboard focused](crate::properties::is_focused)
88 /// widget and then each parent up to the root. If propagation stop
89 /// is requested the event is not notified further. If the widget is disabled or blocked the event is not notified.
90 ///
91 /// This route is also called *bubbling*.
92 ///
93 /// # Keys
94 ///
95 /// Any key press generates a key down event, including keys that don't map to any virtual key, see [`KeyInputArgs`]
96 /// for more details.
97 ///
98 /// For key combinations consider using a [`click_shortcut`] with a click handler.
99 ///
100 /// [`click_shortcut`]: fn@crate::gesture::click_shortcut
101 ///
102 /// # Underlying Event
103 ///
104 /// This event property uses the [`KEY_INPUT_EVENT`] that is included in the default app.
105 ///
106 /// [`KeyInputArgs`]: zng_ext_input::keyboard::KeyInputArgs
107 /// [`KEY_INPUT_EVENT`]: zng_ext_input::keyboard::KEY_INPUT_EVENT
108 #[property(EVENT)]
109 pub fn on_key_down<on_pre_key_down>(child: impl IntoUiNode, handler: Handler<KeyInputArgs>) -> UiNode {
110 const PRE: bool;
111 EventNodeBuilder::new(KEY_INPUT_EVENT)
112 .filter(|| {
113 let id = WIDGET.id();
114 move |args| args.state == KeyState::Pressed && args.target.contains_enabled(id)
115 })
116 .build::<PRE>(child, handler)
117 }
118
119 /// Event fired when a keyboard key is released and the widget is enabled.
120 ///
121 /// # Route
122 ///
123 /// The event is raised in the [keyboard focused](crate::properties::is_focused)
124 /// widget and then each parent up to the root. If propagation stop
125 /// is requested the event is not notified further. If the widget is disabled or blocked the event is not notified.
126 ///
127 /// This route is also called *bubbling*.
128 ///
129 /// # Keys
130 ///
131 /// Any key release generates a key up event, including keys that don't map to any virtual key, see [`KeyInputArgs`]
132 /// for more details.
133 /// For key combinations consider using a [`click_shortcut`] with a click handler.
134 ///
135 /// [`click_shortcut`]: fn@crate::gesture::click_shortcut
136 ///
137 /// # Underlying Event
138 ///
139 /// This event property uses the [`KEY_INPUT_EVENT`] that is included in the default app.
140 ///
141 /// [`KeyInputArgs`]: zng_ext_input::keyboard::KeyInputArgs
142 /// [`KEY_INPUT_EVENT`]: zng_ext_input::keyboard::KEY_INPUT_EVENT
143 #[property(EVENT)]
144 pub fn on_key_up<on_pre_key_up>(child: impl IntoUiNode, handler: Handler<KeyInputArgs>) -> UiNode {
145 const PRE: bool;
146 EventNodeBuilder::new(KEY_INPUT_EVENT)
147 .filter(|| {
148 let id = WIDGET.id();
149 move |args| args.state == KeyState::Released && args.target.contains_enabled(id)
150 })
151 .build::<PRE>(child, handler)
152 }
153}