diff --git a/CHANGELOG.md b/CHANGELOG.md index cfeb82592..2cca3d125 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. ## Unreleased +### Changed + + - **Breaking:** The internal key code for the keys left, right, home and end + has changed. This was undocumented, but if one was handling this in the + `FocusScope` event, these keys will now be ignored. Use the `Keys.LeftArrow` + and other code exposed in the `Keys` namespace instead + ### Added - Colors names can now be accessed through the `Colors` namespace @@ -10,6 +17,8 @@ All notable changes to this project will be documented in this file. - `TouchArea` gained a `mouse-cursor` property to change the mouse cursor - C++: Added version macros - Optimize some property access by doing more constant propagation + - More special keyboard key codes are provided in the `FocusScope`, and + special keys are handled ### Fixed diff --git a/docs/builtin_elements.md b/docs/builtin_elements.md index 4847e511a..e0995c84c 100644 --- a/docs/builtin_elements.md +++ b/docs/builtin_elements.md @@ -458,6 +458,10 @@ Example := Window { The FocusScope exposes callback to intercept the pressed key when it has focus. +The KeyEvent has a text property which is a character of the key entered. +When a non-printable key is pressed, the character will be either a control character, +or a private unicode character. The special characters are available in the `Keys` namespace + ### Properties * **`has-focus`** (*bool*): Set to `true` when item is focused and receives keyboard events. @@ -482,6 +486,9 @@ Example := Window { if (event.modifiers.control) { debug("control was pressed during this event"); } + if (event.text == Keys.Escape) { + debug("Esc key was pressed") + } accept } } diff --git a/sixtyfps_compiler/lookup.rs b/sixtyfps_compiler/lookup.rs index 34c47022a..ddb810ab1 100644 --- a/sixtyfps_compiler/lookup.rs +++ b/sixtyfps_compiler/lookup.rs @@ -88,6 +88,7 @@ pub enum LookupResult { pub enum BuiltinNamespace { Colors, Math, + Keys, } impl From for LookupResult { @@ -149,6 +150,7 @@ impl LookupObject for LookupResult { (ColorSpecific, ColorFunctions).for_each_entry(ctx, f) } LookupResult::Namespace(BuiltinNamespace::Math) => MathFunctions.for_each_entry(ctx, f), + LookupResult::Namespace(BuiltinNamespace::Keys) => KeysLookup.for_each_entry(ctx, f), } } @@ -160,6 +162,7 @@ impl LookupObject for LookupResult { (ColorSpecific, ColorFunctions).lookup(ctx, name) } LookupResult::Namespace(BuiltinNamespace::Math) => MathFunctions.lookup(ctx, name), + LookupResult::Namespace(BuiltinNamespace::Keys) => KeysLookup.lookup(ctx, name), } } } @@ -442,6 +445,27 @@ impl ColorSpecific { } } +struct KeysLookup; + +macro_rules! for_each_special_keys { + ($($char:literal # $name:ident # $($qt:ident)|* # $($winit:ident)|* ;)*) => { + use super::*; + impl LookupObject for KeysLookup { + fn for_each_entry( + &self, + _ctx: &LookupCtx, + f: &mut impl FnMut(&str, LookupResult) -> Option, + ) -> Option { + None + $(.or_else(|| { + f(stringify!($name), Expression::StringLiteral($char.into()).into()) + }))* + } + } + }; +} +mod key_codes; + struct EasingSpecific; impl LookupObject for EasingSpecific { fn for_each_entry( @@ -567,6 +591,7 @@ impl LookupObject for BuiltinNamespaceLookup { ) -> Option { None.or_else(|| f("Colors", LookupResult::Namespace(BuiltinNamespace::Colors))) .or_else(|| f("Math", LookupResult::Namespace(BuiltinNamespace::Math))) + .or_else(|| f("Keys", LookupResult::Namespace(BuiltinNamespace::Keys))) } } diff --git a/tests/cases/examples/key_press.60 b/tests/cases/examples/key_press.60 index 85e2241c2..8e089f0a3 100644 --- a/tests/cases/examples/key_press.60 +++ b/tests/cases/examples/key_press.60 @@ -14,6 +14,12 @@ W := Window { field := FocusScope { vertical_stretch: 1; key-pressed(event) => { + if (event.text == Keys.F1) { + debug("F1"); + } + if (event.text == Keys.PageUp) { + debug("PageUp"); + } if (event.modifiers.control) { debug(" (control modifier pressed)"); }