Fladder/lib/util/input_handler.dart
PartyDonut 70e346b8a2
chore: Shortcuts improvements (#446)
Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
2025-08-09 16:17:14 +02:00

90 lines
2.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fladder/models/settings/key_combinations.dart';
import 'package:fladder/screens/settings/widgets/key_listener.dart';
class InputHandler<T> extends ConsumerStatefulWidget {
final bool autoFocus;
final KeyEventResult Function(FocusNode node, KeyEvent event)? onKeyEvent;
final bool Function(T result)? keyMapResult;
final Map<T, KeyCombination>? keyMap;
final Widget child;
const InputHandler({
required this.child,
this.autoFocus = true,
this.onKeyEvent,
this.keyMapResult,
this.keyMap,
super.key,
});
@override
ConsumerState<InputHandler> createState() => _InputHandlerState<T>();
}
class _InputHandlerState<T> extends ConsumerState<InputHandler<T>> {
final focusNode = FocusNode();
LogicalKeyboardKey? pressedModifier;
@override
void initState() {
super.initState();
// Focus on start
focusNode.requestFocus();
}
@override
Widget build(BuildContext context) {
return Focus(
autofocus: widget.autoFocus,
focusNode: focusNode,
onFocusChange: (value) {
if (!focusNode.hasFocus && widget.autoFocus) {
focusNode.requestFocus();
}
},
onKeyEvent: widget.onKeyEvent ?? (node, event) => _onKey(event),
child: widget.child,
);
}
KeyEventResult _onKey(KeyEvent value) {
if (changingShortCut) return KeyEventResult.ignored;
final keyMap = widget.keyMap?.entries.nonNulls.toList() ?? [];
if (value is KeyDownEvent || value is KeyRepeatEvent) {
if (KeyCombination.modifierKeys.contains(value.logicalKey)) {
pressedModifier = value.logicalKey;
}
for (var entry in keyMap) {
final hotKey = entry.key;
final keyCombination = entry.value;
bool isMainKeyPressed = value.logicalKey == keyCombination.key;
bool isModifierKeyPressed = pressedModifier == keyCombination.modifier;
bool isAltKeyPressed = value.logicalKey == keyCombination.altKey;
bool isAltModifierKeyPressed = pressedModifier == keyCombination.altModifier;
if ((isMainKeyPressed && isModifierKeyPressed) || isAltKeyPressed && isAltModifierKeyPressed) {
if (widget.keyMapResult?.call(hotKey) ?? false) {
return KeyEventResult.handled;
} else {
return KeyEventResult.ignored;
}
}
}
} else if (value is KeyUpEvent) {
if (KeyCombination.modifierKeys.contains(value.logicalKey)) {
pressedModifier = null;
}
}
return KeyEventResult.ignored;
}
}