I am trying to make a widget which will allow me to dynamically generate help screens from keyboard shortcuts, but I can only use PhysicalKeyboardKey.debugName
in debug mode.
Is there a way I can convert the PhysicalKeyboardKey
instance to LogicalKeyboardKey
to take advantage of the keyLabel
property perhaps?
Here is a stripped down version of the code I have so far:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class KeyboardShortcut {
/// Create an instance.
const KeyboardShortcut({
required this.description,
required this.key,
required this.invoke,
this.controlKey = false,
this.altKey = false,
this.shiftKey = false,
});
final String description;
final PhysicalKeyboardKey key;
final VoidCallback invoke;
final bool controlKey;
final bool shiftKey;
final bool altKey;
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(final BuildContext context) => MaterialApp(
title: 'Keyboard Shortcuts Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
class MyHomePage extends StatelessWidget {
/// Create an instance.
const MyHomePage({
super.key,
});
/// Build the widget.
@override
Widget build(final BuildContext context) {
final shortcuts = <KeyboardShortcut>[
KeyboardShortcut(
description: 'Action 1',
key: PhysicalKeyboardKey.digit1,
invoke: () {
print('Action 1.');
},
),
KeyboardShortcut(
description: 'Action 2',
key: PhysicalKeyboardKey.digit2,
invoke: () {
print('Action 2.');
},
),
];
final keyboard = HardwareKeyboard.instance;
return Scaffold(
appBar: AppBar(
title: const Text('Keyboard Shortcuts'),
),
body: ListView.builder(
itemBuilder: (final listViewContext, final index) {
if (index == 0) {
return Focus(
onKeyEvent: (final node, final event) {
if (event is KeyRepeatEvent) {
return KeyEventResult.ignored;
}
for (final shortcut in shortcuts) {
if (shortcut.key == event.physicalKey &&
shortcut.controlKey == keyboard.isControlPressed &&
shortcut.altKey == keyboard.isAltPressed &&
shortcut.shiftKey == keyboard.isShiftPressed) {
if (event is KeyDownEvent) {
shortcut.invoke();
}
return KeyEventResult.handled;
}
}
return KeyEventResult.ignored;
},
autofocus: true,
child: const ListTile(
title: Text('Keyboard area'),
),
);
}
final shortcut = shortcuts[index - 1];
final key = shortcut.key.debugName ?? 'RELEASE MODE';
return ListTile(
title: Text(key),
subtitle: Text(shortcut.description),
onTap: shortcut.invoke,
);
},
itemCount: shortcuts.length + 1,
shrinkWrap: true,
),
);
}
}
I’d rather not add a keyDescription
property to KeyboardShortcut
if I don’t have to.
Thank you all in advance.