|
| 1 | +# Keybinder |
| 2 | + |
| 3 | +> A Flutter package to easily manage and record custom keyboard shortcuts. |
| 4 | +
|
| 5 | +## Features |
| 6 | + |
| 7 | +- 🎹 Record custom key combinations |
| 8 | +- 💾 Abstract persistence (bring your own storage) |
| 9 | +- 🔄 Reactive updates with `ChangeNotifier` |
| 10 | +- 🌍 Localized UI |
| 11 | +- 🛠 Modular and easy to integrate |
| 12 | + |
| 13 | +## Usage |
| 14 | + |
| 15 | +### 1. Define your Intents |
| 16 | + |
| 17 | +```dart |
| 18 | +class IncrementIntent extends Intent { const IncrementIntent(); } |
| 19 | +class DecrementIntent extends Intent { const DecrementIntent(); } |
| 20 | +``` |
| 21 | + |
| 22 | +### 2. Implement Persistence (Optional) |
| 23 | + |
| 24 | +Implement `KeybinderStore` to save/load shortcuts. |
| 25 | + |
| 26 | +```dart |
| 27 | +class MyStore implements KeybinderStore { |
| 28 | + @override |
| 29 | + Future<String?> load() async { |
| 30 | + // Load from shared_preferences, file, etc. |
| 31 | + return null; |
| 32 | + } |
| 33 | +
|
| 34 | + @override |
| 35 | + Future<void> save(String data) async { |
| 36 | + // Save to shared_preferences, file, etc. |
| 37 | + } |
| 38 | +} |
| 39 | +``` |
| 40 | + |
| 41 | +### 3. Initialize Keybinder |
| 42 | + |
| 43 | +```dart |
| 44 | +final keybinder = Keybinder( |
| 45 | + definitions: [ |
| 46 | + ShortcutDefinition( |
| 47 | + id: 'increment', |
| 48 | + displayName: 'Increment Counter', |
| 49 | + intentType: IncrementIntent, |
| 50 | + defaultActivator: const SingleActivator(LogicalKeyboardKey.arrowUp), |
| 51 | + ), |
| 52 | + ShortcutDefinition( |
| 53 | + id: 'decrement', |
| 54 | + displayName: 'Decrement Counter', |
| 55 | + intentType: DecrementIntent, |
| 56 | + defaultActivator: const SingleActivator(LogicalKeyboardKey.arrowDown), |
| 57 | + ), |
| 58 | + ], |
| 59 | + store: MyStore(), // Optional |
| 60 | +); |
| 61 | +``` |
| 62 | + |
| 63 | +### 4. Use in your App |
| 64 | + |
| 65 | +Wrap your app with `Shortcuts` and listen to `Keybinder`. Don't forget to add localizations! |
| 66 | + |
| 67 | +```dart |
| 68 | +class MyApp extends StatelessWidget { |
| 69 | + @override |
| 70 | + Widget build(BuildContext context) { |
| 71 | + return ListenableBuilder( |
| 72 | + listenable: keybinder, |
| 73 | + builder: (context, child) { |
| 74 | + return MaterialApp( |
| 75 | + localizationsDelegates: KeybinderLocalizations.localizationsDelegates, |
| 76 | + supportedLocales: KeybinderLocalizations.supportedLocales, |
| 77 | + home: Shortcuts( |
| 78 | + shortcuts: keybinder.getShortcuts([ |
| 79 | + const IncrementIntent(), |
| 80 | + const DecrementIntent(), |
| 81 | + ]), |
| 82 | + child: Actions( |
| 83 | + actions: <Type, Action<Intent>>{ |
| 84 | + IncrementIntent: CallbackAction<IncrementIntent>(onInvoke: (_) => print("Increment!")), |
| 85 | + DecrementIntent: CallbackAction<DecrementIntent>(onInvoke: (_) => print("Decrement!")), |
| 86 | + }, |
| 87 | + child: HomePage(), |
| 88 | + ), |
| 89 | + ), |
| 90 | + ); |
| 91 | + }, |
| 92 | + ); |
| 93 | + } |
| 94 | +} |
| 95 | +``` |
| 96 | + |
| 97 | +### 5. Record new keys |
| 98 | + |
| 99 | +Use the `KeyRecorder` widget in your settings page. |
| 100 | + |
| 101 | +```dart |
| 102 | +KeyRecorder( |
| 103 | + currentActivator: keybinder.getActivator(IncrementIntent), |
| 104 | + onNewKey: (newKey) => keybinder.updateBinding(IncrementIntent, newKey), |
| 105 | +) |
| 106 | +``` |
0 commit comments