From 3b6fb6194b9825501b4905a1a321377629da7eda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lollipopkit=F0=9F=8F=B3=EF=B8=8F=E2=80=8D=E2=9A=A7?= =?UTF-8?q?=EF=B8=8F?= <10864310+lollipopkit@users.noreply.github.com> Date: Sat, 28 Sep 2024 14:40:22 +0800 Subject: [PATCH] opt.: more virtual keys (#596) --- lib/data/model/ssh/virtual_key.dart | 214 ++++++++++++++------------ lib/data/model/ssh/virtual_key.g.dart | 80 ++++++++++ lib/data/store/setting.dart | 2 +- lib/view/page/ssh/page.dart | 7 +- 4 files changed, 201 insertions(+), 102 deletions(-) diff --git a/lib/data/model/ssh/virtual_key.dart b/lib/data/model/ssh/virtual_key.dart index a0d11613b..7d2211a11 100644 --- a/lib/data/model/ssh/virtual_key.dart +++ b/lib/data/model/ssh/virtual_key.dart @@ -5,6 +5,8 @@ import 'package:xterm/core.dart'; part 'virtual_key.g.dart'; +enum VirtualKeyFunc { toggleIME, backspace, clipboard, snippet, file } + @HiveType(typeId: 4) enum VirtKey { @HiveField(0) @@ -38,23 +40,80 @@ enum VirtKey { @HiveField(14) pgup, @HiveField(15) - pgdn; + pgdn, + @HiveField(16) + slash, + @HiveField(17) + backSlash, + @HiveField(18) + underscore, + @HiveField(19) + plus, + @HiveField(20) + equal, + @HiveField(21) + minus, + @HiveField(22) + parenLeft, + @HiveField(23) + parenRight, + @HiveField(24) + bracketLeft, + @HiveField(25) + bracketRight, + @HiveField(26) + braceLeft, + @HiveField(27) + braceRight, + @HiveField(28) + chevronLeft, + @HiveField(29) + chevronRight, + @HiveField(30) + colon, + @HiveField(31) + semicolon, + ; +} +extension VirtKeyX on VirtKey { + /// Used for input to terminal + String? get inputRaw => switch (this) { + VirtKey.slash => '/', + VirtKey.backSlash => '\\', + VirtKey.underscore => '_', + VirtKey.plus => '+', + VirtKey.equal => '=', + VirtKey.minus => '-', + VirtKey.parenLeft => '(', + VirtKey.parenRight => ')', + VirtKey.bracketLeft => '[', + VirtKey.bracketRight => ']', + VirtKey.braceLeft => '{', + VirtKey.braceRight => '}', + VirtKey.chevronLeft => '<', + VirtKey.chevronRight => '>', + VirtKey.colon => ':', + VirtKey.semicolon => ';', + _ => null, + }; + + /// Used for displaying on UI String get text { - switch (this) { - case VirtKey.pgdn: - return 'PgDn'; - case VirtKey.pgup: - return 'PgUp'; - default: - if (name.length > 1) { - return name.substring(0, 1).toUpperCase() + name.substring(1); - } - return name; + final t = inputRaw; + if (t != null) return t; + + if (this == VirtKey.pgdn) return 'PgDn'; + if (this == VirtKey.pgup) return 'PgUp'; + + if (name.length > 1) { + return name.substring(0, 1).toUpperCase() + name.substring(1); } + return name; } - static final defaultOrder = [ + /// Default order of virtual keys + static const defaultOrder = [ VirtKey.esc, VirtKey.alt, VirtKey.home, @@ -71,99 +130,56 @@ enum VirtKey { VirtKey.ime, ]; - TerminalKey? get key { - switch (this) { - case VirtKey.esc: - return TerminalKey.escape; - case VirtKey.alt: - return TerminalKey.alt; - case VirtKey.home: - return TerminalKey.home; - case VirtKey.up: - return TerminalKey.arrowUp; - case VirtKey.end: - return TerminalKey.end; - case VirtKey.tab: - return TerminalKey.tab; - case VirtKey.ctrl: - return TerminalKey.control; - case VirtKey.left: - return TerminalKey.arrowLeft; - case VirtKey.down: - return TerminalKey.arrowDown; - case VirtKey.right: - return TerminalKey.arrowRight; - case VirtKey.pgup: - return TerminalKey.pageUp; - case VirtKey.pgdn: - return TerminalKey.pageDown; - default: - return null; - } - } + /// Corresponding [TerminalKey] + TerminalKey? get key => switch (this) { + VirtKey.esc => TerminalKey.escape, + VirtKey.alt => TerminalKey.alt, + VirtKey.home => TerminalKey.home, + VirtKey.up => TerminalKey.arrowUp, + VirtKey.end => TerminalKey.end, + VirtKey.tab => TerminalKey.tab, + VirtKey.ctrl => TerminalKey.control, + VirtKey.left => TerminalKey.arrowLeft, + VirtKey.down => TerminalKey.arrowDown, + VirtKey.right => TerminalKey.arrowRight, + VirtKey.pgup => TerminalKey.pageUp, + VirtKey.pgdn => TerminalKey.pageDown, + _ => null, + }; - IconData? get icon { - switch (this) { - case VirtKey.up: - return Icons.arrow_upward; - case VirtKey.left: - return Icons.arrow_back; - case VirtKey.down: - return Icons.arrow_downward; - case VirtKey.right: - return Icons.arrow_forward; - case VirtKey.sftp: - return Icons.file_open; - case VirtKey.snippet: - return Icons.code; - case VirtKey.clipboard: - return Icons.paste; - case VirtKey.ime: - return Icons.keyboard; - default: - return null; - } - } + /// Icons for virtual keys + IconData? get icon => switch (this) { + VirtKey.up => Icons.arrow_upward, + VirtKey.left => Icons.arrow_back, + VirtKey.down => Icons.arrow_downward, + VirtKey.right => Icons.arrow_forward, + VirtKey.sftp => Icons.file_open, + VirtKey.snippet => Icons.code, + VirtKey.clipboard => Icons.paste, + VirtKey.ime => Icons.keyboard, + _ => null, + }; // Use [VirtualKeyFunc] instead of [VirtKey] // This can help linter to enum all [VirtualKeyFunc] // and make sure all [VirtualKeyFunc] are handled - VirtualKeyFunc? get func { - switch (this) { - case VirtKey.sftp: - return VirtualKeyFunc.file; - case VirtKey.snippet: - return VirtualKeyFunc.snippet; - case VirtKey.clipboard: - return VirtualKeyFunc.clipboard; - case VirtKey.ime: - return VirtualKeyFunc.toggleIME; - default: - return null; - } - } + VirtualKeyFunc? get func => switch (this) { + VirtKey.sftp => VirtualKeyFunc.file, + VirtKey.snippet => VirtualKeyFunc.snippet, + VirtKey.clipboard => VirtualKeyFunc.clipboard, + VirtKey.ime => VirtualKeyFunc.toggleIME, + _ => null, + }; - bool get toggleable { - switch (this) { - case VirtKey.alt: - case VirtKey.ctrl: - return true; - default: - return false; - } - } + bool get toggleable => switch (this) { + VirtKey.alt || VirtKey.ctrl => true, + _ => false, + }; - bool get canLongPress { - switch (this) { - case VirtKey.up: - case VirtKey.left: - case VirtKey.down: - case VirtKey.right: - return true; - default: - return false; - } - } + bool get canLongPress => switch (this) { + VirtKey.up || VirtKey.left || VirtKey.down || VirtKey.right => true, + _ => false, + }; String? get help => switch (this) { VirtKey.sftp => l10n.virtKeyHelpSFTP, @@ -172,5 +188,3 @@ enum VirtKey { _ => null, }; } - -enum VirtualKeyFunc { toggleIME, backspace, clipboard, snippet, file } diff --git a/lib/data/model/ssh/virtual_key.g.dart b/lib/data/model/ssh/virtual_key.g.dart index a43ee6547..a4af59011 100644 --- a/lib/data/model/ssh/virtual_key.g.dart +++ b/lib/data/model/ssh/virtual_key.g.dart @@ -45,6 +45,38 @@ class VirtKeyAdapter extends TypeAdapter { return VirtKey.pgup; case 15: return VirtKey.pgdn; + case 16: + return VirtKey.slash; + case 17: + return VirtKey.backSlash; + case 18: + return VirtKey.underscore; + case 19: + return VirtKey.plus; + case 20: + return VirtKey.equal; + case 21: + return VirtKey.minus; + case 22: + return VirtKey.parenLeft; + case 23: + return VirtKey.parenRight; + case 24: + return VirtKey.bracketLeft; + case 25: + return VirtKey.bracketRight; + case 26: + return VirtKey.braceLeft; + case 27: + return VirtKey.braceRight; + case 28: + return VirtKey.chevronLeft; + case 29: + return VirtKey.chevronRight; + case 30: + return VirtKey.colon; + case 31: + return VirtKey.semicolon; default: return VirtKey.esc; } @@ -101,6 +133,54 @@ class VirtKeyAdapter extends TypeAdapter { case VirtKey.pgdn: writer.writeByte(15); break; + case VirtKey.slash: + writer.writeByte(16); + break; + case VirtKey.backSlash: + writer.writeByte(17); + break; + case VirtKey.underscore: + writer.writeByte(18); + break; + case VirtKey.plus: + writer.writeByte(19); + break; + case VirtKey.equal: + writer.writeByte(20); + break; + case VirtKey.minus: + writer.writeByte(21); + break; + case VirtKey.parenLeft: + writer.writeByte(22); + break; + case VirtKey.parenRight: + writer.writeByte(23); + break; + case VirtKey.bracketLeft: + writer.writeByte(24); + break; + case VirtKey.bracketRight: + writer.writeByte(25); + break; + case VirtKey.braceLeft: + writer.writeByte(26); + break; + case VirtKey.braceRight: + writer.writeByte(27); + break; + case VirtKey.chevronLeft: + writer.writeByte(28); + break; + case VirtKey.chevronRight: + writer.writeByte(29); + break; + case VirtKey.colon: + writer.writeByte(30); + break; + case VirtKey.semicolon: + writer.writeByte(31); + break; } } diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index 59b46b177..f7b85d27b 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -106,7 +106,7 @@ class SettingStore extends PersistentStore { late final sshVirtKeys = listProperty( 'sshVirtKeys', - VirtKey.defaultOrder.map((e) => e.index).toList(), + VirtKeyX.defaultOrder.map((e) => e.index).toList(), ); late final netViewType = property('netViewType', NetViewType.speed); diff --git a/lib/view/page/ssh/page.dart b/lib/view/page/ssh/page.dart index 7d189d5c8..6b7b20579 100644 --- a/lib/view/page/ssh/page.dart +++ b/lib/view/page/ssh/page.dart @@ -213,7 +213,7 @@ class SSHPageState extends State ); } final rows = _virtKeysList - .map((e) => Row(children: e.map((f) => _buildVirtKeyItem(f)).toList())) + .map((e) => Row(children: e.map(_buildVirtKeyItem).toList())) .toList(); return Column( mainAxisSize: MainAxisSize.min, @@ -280,6 +280,11 @@ class SSHPageState extends State HapticFeedback.mediumImpact(); _doVirtualKeyInput(item.key!); } + final inputRaw = item.inputRaw; + if (inputRaw != null) { + HapticFeedback.mediumImpact(); + _terminal.textInput(inputRaw); + } } void _doVirtualKeyInput(TerminalKey key) {