// Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // DO NOT EDIT -- DO NOT EDIT -- DO NOT EDIT // This file is generated by dev/tools/gen_keycodes/bin/gen_keycodes.dart and // should not be edited directly. // // Edit the template dev/tools/gen_keycodes/data/keyboard_key.tmpl instead. // See dev/tools/gen_keycodes/README.md for more information. import 'package:flutter/foundation.dart'; /// A base class for all keyboard key types. /// /// See also: /// /// * [PhysicalKeyboardKey], a class with static values that describe the keys /// that are returned from [RawKeyEvent.physicalKey]. /// * [LogicalKeyboardKey], a class with static values that describe the keys /// that are returned from [RawKeyEvent.logicalKey]. abstract class KeyboardKey extends Diagnosticable { /// A const constructor so that subclasses may be const. const KeyboardKey(); } /// A class with static values that describe the keys that are returned from /// [RawKeyEvent.logicalKey]. /// /// These represent *logical* keys, which are keys which are interpreted in the /// context of any modifiers, modes, or keyboard layouts which may be in effect. /// /// This is contrast to [PhysicalKeyboardKey], which represents a physical key /// in a particular location on the keyboard, without regard for the modifier /// state, mode, or keyboard layout. /// /// As an example, if you wanted to implement an app where the "Q" key "quit" /// something, you'd want to look at the logical key to detect this, since you /// would like to have it match the key with "Q" on it, instead of always /// looking for "the key next next to the TAB key", since on a French keyboard, /// the key next to the TAB key has an "A" on it. /// /// Conversely, if you wanted a game where the key next to the CAPS LOCK (the /// "A" key on a QWERTY keyboard) moved the player to the left, you'd want to /// look at the physical key to make sure that regardless of the character the /// key produces, you got the key that is in that location on the keyboard. /// /// {@tool sample --template=stateful_widget_scaffold} /// This example shows how to detect if the user has selected the logical "Q" /// key. /// /// ```dart imports /// import 'package:flutter/foundation.dart'; /// import 'package:flutter/services.dart'; /// ``` /// /// ```dart /// // The node used to request the keyboard focus. /// final FocusNode _focusNode = FocusNode(); /// // The message to display. /// String _message; /// /// // Focus nodes need to be disposed. /// @override /// void dispose() { /// _focusNode.dispose(); /// super.dispose(); /// } /// /// // Handles the key events from the RawKeyboardListener and update the /// // _message. /// void _handleKeyEvent(RawKeyEvent event) { /// setState(() { /// if (event.logicalKey == LogicalKeyboardKey.keyQ) { /// _message = 'Pressed the "Q" key!'; /// } else { /// if (kReleaseMode) { /// _message = 'Not a Q: Key label is "${event.logicalKey.keyLabel ?? '<none>'}"'; /// } else { /// // This will only print useful information in debug mode. /// _message = 'Not a Q: Pressed ${event.logicalKey.debugName}'; /// } /// } /// }); /// } /// /// @override /// Widget build(BuildContext context) { /// final TextTheme textTheme = Theme.of(context).textTheme; /// return Container( /// color: Colors.white, /// alignment: Alignment.center, /// child: DefaultTextStyle( /// style: textTheme.headline4, /// child: RawKeyboardListener( /// focusNode: _focusNode, /// onKey: _handleKeyEvent, /// child: AnimatedBuilder( /// animation: _focusNode, /// builder: (BuildContext context, Widget child) { /// if (!_focusNode.hasFocus) { /// return GestureDetector( /// onTap: () { /// FocusScope.of(context).requestFocus(_focusNode); /// }, /// child: const Text('Tap to focus'), /// ); /// } /// return Text(_message ?? 'Press a key'); /// }, /// ), /// ), /// ), /// ); /// } /// ``` /// {@end-tool} /// See also: /// /// * [RawKeyEvent], the keyboard event object received by widgets that listen /// to keyboard events. /// * [RawKeyboardListener], a widget used to listen to and supply handlers for /// keyboard events. class LogicalKeyboardKey extends KeyboardKey { /// Creates a LogicalKeyboardKey object with an optional key label and debug /// name. /// /// [keyId] must not be null. /// /// {@tool snippet} /// To save executable size, it is recommended that the [debugName] be null in /// release mode. You can do this by using the [kReleaseMode] constant. /// /// ```dart /// const LogicalKeyboardKey(0x0010000000a, debugName: kReleaseMode ? null : 'Special Key') /// ``` /// {@end-tool} const LogicalKeyboardKey(this.keyId, {this.debugName, this.keyLabel}) : assert(keyId != null); /// A unique code representing this key. /// /// This is an opaque code. It should not be unpacked to derive information /// from it, as the representation of the code could change at any time. final int keyId; /// The debug string to print for this keyboard key, which will be null in /// release mode. final String debugName; /// The Unicode string representing the character produced by a [RawKeyEvent]. /// /// This value is useful for describing or matching mnemonic keyboard /// shortcuts. /// /// On most platforms this is a single code point, but it could contain any /// Unicode string. The `keyLabel` differs from [RawKeyEvent.character] /// because `keyLabel` only takes into account the key being pressed, not any /// combining keys pressed before it, so, for example, an “o” that follows a /// combining dieresis (“¨”, COMBINING DIAERESIS (U+0308)) would just return /// “o” for [keyLabel], but would return “ö” for [RawKeyEvent.character]. /// /// {@macro flutter.services.RawKeyEventData.keyLabel} final String keyLabel; @override int get hashCode => keyId.hashCode; @override bool operator ==(Object other) { if (other.runtimeType != runtimeType) { return false; } return other is LogicalKeyboardKey && other.keyId == keyId; } /// Returns the [LogicalKeyboardKey] constant that matches the given ID, or /// null, if not found. static LogicalKeyboardKey findKeyByKeyId(int keyId) => _knownLogicalKeys[keyId]; /// Returns true if the given label represents a Unicode control character. /// /// Examples of control characters are characters like "U+000A LINE FEED (LF)" /// or "U+001B ESCAPE (ESC)". /// /// See <https://en.wikipedia.org/wiki/Unicode_control_characters> for more /// information. /// /// Used by [RawKeyEvent] subclasses to help construct IDs. static bool isControlCharacter(String label) { if (label.length > 1) { return false; } final int codeUnit = label.codeUnitAt(0); return (codeUnit <= 0x1f && codeUnit >= 0x00) || (codeUnit >= 0x7f && codeUnit <= 0x9f); } /// Returns true if the [keyId] of this object is one that is auto-generated by /// Flutter. /// /// Auto-generated key IDs are generated in response to platform key codes /// which Flutter doesn't recognize, and their IDs shouldn't be used in a /// persistent way. /// /// Auto-generated IDs should be a rare occurrence: Flutter supports most keys. /// /// Keys that generate Unicode characters (even if unknown to Flutter) will /// not return true for `isAutogenerated`, since they will be assigned a /// Unicode-based code that will remain stable. /// /// If Flutter adds support for a previously unsupported key code, the ID it /// reports will change, but the ID will remain stable on the platform it is /// produced on until Flutter adds support for recognizing it. /// /// So, hypothetically, if Android added a new key code of 0xffff, /// representing a new "do what I mean" key, then the auto-generated code /// would be 0x1020000ffff, but once Flutter added the "doWhatIMean" key to /// the definitions below, the new code would be 0x0020000ffff for all /// platforms that had a "do what I mean" key from then on. bool get isAutogenerated => (keyId & autogeneratedMask) != 0; /// Returns a set of pseudo-key synonyms for the given `key`. /// /// This allows finding the pseudo-keys that also represents a concrete /// `key` so that a class with a key map can match pseudo-keys as well as the /// actual generated keys. /// /// The pseudo-keys returned in the set are typically used to represent keys /// which appear in multiple places on the keyboard, such as the [shift], /// [alt], [control], and [meta] keys. The keys in the returned set won't ever /// be generated directly, but if a more specific key event is received, then /// this set can be used to find the more general pseudo-key. For example, if /// this is a [shiftLeft] key, this accessor will return the set /// `<LogicalKeyboardKey>{ shift }`. Set<LogicalKeyboardKey> get synonyms { final LogicalKeyboardKey result = _synonyms[this]; return result == null ? <LogicalKeyboardKey>{} : <LogicalKeyboardKey>{result}; } /// Takes a set of keys, and returns the same set, but with any keys that have /// synonyms replaced. /// /// It is used, for example, to make sets of keys with members like /// [controlRight] and [controlLeft] and convert that set to contain just /// [control], so that the question "is any control key down?" can be asked. static Set<LogicalKeyboardKey> collapseSynonyms(Set<LogicalKeyboardKey> input) { final Set<LogicalKeyboardKey> result = <LogicalKeyboardKey>{}; for (final LogicalKeyboardKey key in input) { final LogicalKeyboardKey synonym = _synonyms[key]; result.add(synonym ?? key); } return result; } @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties.add(StringProperty('keyId', '0x${keyId.toRadixString(16).padLeft(8, '0')}', showName: true)); properties.add(StringProperty('keyLabel', keyLabel, showName: true)); properties.add(StringProperty('debugName', debugName, showName: true, defaultValue: null)); } /// Mask for the 32-bit value portion of the key code. /// /// This is used by platform-specific code to generate Flutter key codes. static const int valueMask = 0x000FFFFFFFF; /// Mask for the platform prefix portion of the key code. /// /// This is used by platform-specific code to generate Flutter key codes. static const int platformMask = 0x0FF00000000; /// Mask for the auto-generated bit portion of the key code. /// /// This is used by platform-specific code to generate new Flutter key codes /// for keys which are not recognized. static const int autogeneratedMask = 0x10000000000; /// Mask for the synonym pseudo-keys generated for keys which appear in more /// than one place on the keyboard. /// /// IDs in this range are used to represent keys which appear in multiple /// places on the keyboard, such as the SHIFT, ALT, CTRL, and numeric keypad /// keys. These key codes will never be generated by the key event system, but /// may be used in key maps to represent the union of all the keys of each /// type in order to match them. /// /// To look up the synonyms that are defined, look in the [synonyms] map. static const int synonymMask = 0x20000000000; /// The code prefix for keys which have a Unicode representation. /// /// This is used by platform-specific code to generate Flutter key codes. static const int unicodePlane = 0x00000000000; /// The code prefix for keys which do not have a Unicode representation. /// /// This is used by platform-specific code to generate Flutter key codes using /// HID Usage codes. static const int hidPlane = 0x00100000000; @@@LOGICAL_KEY_DEFINITIONS@@@ // A list of all predefined constant LogicalKeyboardKeys so they can be // searched. static const Map<int, LogicalKeyboardKey> _knownLogicalKeys = <int, LogicalKeyboardKey>{ @@@LOGICAL_KEY_MAP@@@ }; // A map of keys to the pseudo-key synonym for that key. Used by getSynonyms. static final Map<LogicalKeyboardKey, LogicalKeyboardKey> _synonyms = <LogicalKeyboardKey, LogicalKeyboardKey>{ @@@LOGICAL_KEY_SYNONYMS@@@ }; } /// A class with static values that describe the keys that are returned from /// [RawKeyEvent.physicalKey]. /// /// These represent *physical* keys, which are keys which represent a particular /// key location on a QWERTY keyboard. It ignores any modifiers, modes, or /// keyboard layouts which may be in effect. This is contrast to /// [LogicalKeyboardKey], which represents a logical key interpreted in the /// context of modifiers, modes, and/or keyboard layouts. /// /// As an example, if you wanted a game where the key next to the CAPS LOCK (the /// "A" key on a QWERTY keyboard) moved the player to the left, you'd want to /// look at the physical key to make sure that regardless of the character the /// key produces, you got the key that is in that location on the keyboard. /// /// Conversely, if you wanted to implement an app where the "Q" key "quit" /// something, you'd want to look at the logical key to detect this, since you /// would like to have it match the key with "Q" on it, instead of always /// looking for "the key next next to the TAB key", since on a French keyboard, /// the key next to the TAB key has an "A" on it. /// /// {@tool sample --template=stateful_widget_scaffold} /// This example shows how to detect if the user has selected the physical key /// to the right of the CAPS LOCK key. /// /// ```dart imports /// import 'package:flutter/services.dart'; /// ``` /// /// ```dart /// // The node used to request the keyboard focus. /// final FocusNode _focusNode = FocusNode(); /// // The message to display. /// String _message; /// /// // Focus nodes need to be disposed. /// @override /// void dispose() { /// _focusNode.dispose(); /// super.dispose(); /// } /// /// // Handles the key events from the RawKeyboardListener and update the /// // _message. /// void _handleKeyEvent(RawKeyEvent event) { /// setState(() { /// if (event.physicalKey == PhysicalKeyboardKey.keyA) { /// _message = 'Pressed the key next to CAPS LOCK!'; /// } else { /// _message = 'Wrong key.'; /// } /// }); /// } /// /// @override /// Widget build(BuildContext context) { /// final TextTheme textTheme = Theme.of(context).textTheme; /// return Container( /// color: Colors.white, /// alignment: Alignment.center, /// child: DefaultTextStyle( /// style: textTheme.headline4, /// child: RawKeyboardListener( /// focusNode: _focusNode, /// onKey: _handleKeyEvent, /// child: AnimatedBuilder( /// animation: _focusNode, /// builder: (BuildContext context, Widget child) { /// if (!_focusNode.hasFocus) { /// return GestureDetector( /// onTap: () { /// FocusScope.of(context).requestFocus(_focusNode); /// }, /// child: Text('Tap to focus'), /// ); /// } /// return Text(_message ?? 'Press a key'); /// }, /// ), /// ), /// ), /// ); /// } /// ``` /// {@end-tool} /// /// See also: /// /// * [RawKeyEvent], the keyboard event object received by widgets that listen /// to keyboard events. /// * [RawKeyboardListener], a widget used to listen to and supply handlers for /// keyboard events. class PhysicalKeyboardKey extends KeyboardKey { /// Creates a PhysicalKeyboardKey object with an optional debug name. /// /// The [usbHidUsage] must not be null. /// /// {@tool snippet} /// To save executable size, it is recommended that the [debugName] be null in /// release mode. You can do this using the [kReleaseMode] constant. /// /// ```dart /// const PhysicalKeyboardKey(0x0000ffff, debugName: kReleaseMode ? null : 'Special Key') /// ``` /// {@end-tool} const PhysicalKeyboardKey(this.usbHidUsage, {this.debugName}) : assert(usbHidUsage != null); /// The unique USB HID usage ID of this physical key on the keyboard. /// /// Due to the variations in platform APIs, this may not be the actual HID /// usage code from the hardware, but a value derived from available /// information on the platform. /// /// See <https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf> /// for the HID usage values and their meanings. final int usbHidUsage; /// The debug string to print for this keyboard key, which will be null in /// release mode. final String debugName; /// Finds a known [PhysicalKeyboardKey] that matches the given USB HID usage /// code. static PhysicalKeyboardKey findKeyByCode(int usageCode) => _knownPhysicalKeys[usageCode]; @override int get hashCode => usbHidUsage.hashCode; @override bool operator ==(Object other) { if (other.runtimeType != runtimeType) { return false; } return other is PhysicalKeyboardKey && other.usbHidUsage == usbHidUsage; } @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties.add(StringProperty('usbHidUsage', '0x${usbHidUsage.toRadixString(16).padLeft(8, '0')}', showName: true)); properties.add(StringProperty('debugName', debugName, showName: true, defaultValue: null)); } // Key constants for all keyboard keys in the USB HID specification at the // time Flutter was built. @@@PHYSICAL_KEY_DEFINITIONS@@@ // A list of all the predefined constant PhysicalKeyboardKeys so that they // can be searched. static const Map<int, PhysicalKeyboardKey> _knownPhysicalKeys = <int, PhysicalKeyboardKey>{ @@@PHYSICAL_KEY_MAP@@@ }; }