mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
467 lines
18 KiB
Cheetah
467 lines
18 KiB
Cheetah
// 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 snippet --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 sample}
|
|
/// 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 ==(dynamic other) {
|
|
if (other.runtimeType != runtimeType) {
|
|
return false;
|
|
}
|
|
final LogicalKeyboardKey typedOther = other;
|
|
return keyId == typedOther.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 (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 snippet --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 sample}
|
|
/// 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 ==(dynamic other) {
|
|
if (other.runtimeType != runtimeType) {
|
|
return false;
|
|
}
|
|
final PhysicalKeyboardKey typedOther = other;
|
|
return usbHidUsage == typedOther.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@@@
|
|
};
|
|
}
|