diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index a3ae7b33..fbd8a9df 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,9 +2,9 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 190; + static const int build = 191; static const String engine = "Flutter 3.7.0 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision b06b8b2710 (5 days ago) • 2023-01-23 16:55:55 -0800\nEngine • revision b24591ed32\nTools • Dart 2.19.0 • DevTools 2.20.1\n"; - static const String buildAt = "2023-01-28 21:12:37.408372"; - static const int modifications = 19; + static const String buildAt = "2023-01-28 22:51:04.087758"; + static const int modifications = 3; } diff --git a/lib/view/page/ssh.dart b/lib/view/page/ssh.dart index 74f45d5d..d798184b 100644 --- a/lib/view/page/ssh.dart +++ b/lib/view/page/ssh.dart @@ -3,7 +3,7 @@ import 'dart:convert'; import 'package:dartssh2/dartssh2.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:toolbox/data/res/font_style.dart'; +import 'package:toolbox/view/widget/two_line_text.dart'; import 'package:xterm/xterm.dart'; import '../../core/utils.dart'; @@ -11,7 +11,6 @@ import '../../data/model/server/server_private_info.dart'; import '../../data/provider/server.dart'; import '../../data/res/terminal_theme.dart'; import '../../locator.dart'; -import '../widget/virtual_keyboard.dart'; class SSHPage extends StatefulWidget { final ServerPrivateInfo spi; @@ -25,8 +24,8 @@ class _SSHPageState extends State { late final terminal = Terminal(inputHandler: keyboard); late final SSHSession session; final keyboard = VirtualKeyboard(defaultInputHandler); + late double _screenWidth; - var title = ''; var isDark = false; @override @@ -39,6 +38,7 @@ class _SSHPageState extends State { void didChangeDependencies() { super.didChangeDependencies(); isDark = isDarkMode(context); + _screenWidth = MediaQuery.of(context).size.width; } @override @@ -72,10 +72,6 @@ class _SSHPageState extends State { terminal.buffer.clear(); terminal.buffer.setCursor(0, 0); - terminal.onTitleChange = (title) { - setState(() => this.title = title); - }; - terminal.onResize = (width, height, pixelWidth, pixelHeight) { session.resizeTerminal(width, height, pixelWidth, pixelHeight); }; @@ -97,9 +93,12 @@ class _SSHPageState extends State { @override Widget build(BuildContext context) { + final termTheme = isDark ? termDarkTheme : termLightTheme; return Scaffold( + backgroundColor: termTheme.background, appBar: AppBar( - title: Text(title, style: textSize18), + centerTitle: true, + title: TwoLineText(up: 'SSH', down: widget.spi.name), ), body: Column( children: [ @@ -107,13 +106,119 @@ class _SSHPageState extends State { child: TerminalView( terminal, keyboardType: TextInputType.visiblePassword, - theme: isDark ? termDarkTheme : termLightTheme, + theme: termTheme, keyboardAppearance: isDark ? Brightness.dark : Brightness.light, ), ), - VirtualKeyboardView(keyboard), + _buildVirtualKey(), ], ), ); } + + Widget _buildVirtualKey() { + final half = virtualKeys.length ~/ 2; + final top = virtualKeys.sublist(0, half); + final bottom = virtualKeys.sublist(half); + return Column( + children: [ + Row( + children: top + .map((e) => _buildVirtualKeyItem(e)) + .toList(), + ), + Row( + children: bottom + .map((e) => _buildVirtualKeyItem(e)) + .toList(), + ) + ], + ); + } + + Widget _buildVirtualKeyItem(VirtualKey item) { + var selected = false; + switch (item.key) { + case TerminalKey.control: + selected = keyboard.ctrl; + break; + case TerminalKey.alt: + selected = keyboard.alt; + break; + default: + break; + } + + final child = item.icon != null + ? Icon(item.icon, color: isDark ? Colors.white : Colors.black, size: 17,) + : Text(item.text, style: TextStyle(color: selected ? Colors.blue : null, fontSize: 15)); + + return InkWell( + onTap: () { + switch (item.key) { + case TerminalKey.control: + keyboard.ctrl = !keyboard.ctrl; + setState(() {}); + break; + case TerminalKey.alt: + keyboard.alt = !keyboard.alt; + setState(() {}); + break; + default: + terminal.keyInput(item.key); + break; + } + }, + child: SizedBox( + width: _screenWidth / (virtualKeys.length / 2), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 5.7), + child: Center( + child: child, + ), + ), + ), + ); + } } + +class VirtualKey { + final TerminalKey key; + final String text; + final bool toggleable; + final IconData? icon; + + VirtualKey(this.key, this.text, {this.toggleable = false, this.icon}); +} + +var virtualKeys = [ + VirtualKey(TerminalKey.escape, 'Esc'), + VirtualKey(TerminalKey.alt, 'Alt', toggleable: true), + VirtualKey(TerminalKey.pageUp, 'PgUp'), + VirtualKey(TerminalKey.arrowUp, 'Up', icon: Icons.arrow_upward), + VirtualKey(TerminalKey.pageDown, 'PgDn'), + VirtualKey(TerminalKey.end, 'End'), + VirtualKey(TerminalKey.tab, 'Tab'), + VirtualKey(TerminalKey.control, 'Ctrl', toggleable: true), + VirtualKey(TerminalKey.arrowLeft, 'Left', icon: Icons.arrow_back), + VirtualKey(TerminalKey.arrowDown, 'Down', icon: Icons.arrow_downward), + VirtualKey(TerminalKey.arrowRight, 'Right', icon: Icons.arrow_forward), + VirtualKey(TerminalKey.home, 'Home'), +]; + +class VirtualKeyboard extends TerminalInputHandler with ChangeNotifier { + final TerminalInputHandler inputHandler; + + VirtualKeyboard(this.inputHandler); + + bool ctrl = false; + bool alt = false; + + @override + String? call(TerminalKeyboardEvent event) { + return inputHandler.call(event.copyWith( + ctrl: event.ctrl || ctrl, + alt: event.alt || alt, + )); + } +} \ No newline at end of file diff --git a/lib/view/widget/virtual_keyboard.dart b/lib/view/widget/virtual_keyboard.dart deleted file mode 100644 index 3b35f9d1..00000000 --- a/lib/view/widget/virtual_keyboard.dart +++ /dev/null @@ -1,81 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:xterm/xterm.dart'; - -class VirtualKeyboardView extends StatelessWidget { - const VirtualKeyboardView(this.keyboard, {super.key}); - - final VirtualKeyboard keyboard; - - @override - Widget build(BuildContext context) { - return AnimatedBuilder( - animation: keyboard, - builder: (context, child) => ToggleButtons( - renderBorder: false, - isSelected: [keyboard.ctrl, keyboard.alt, keyboard.shift], - onPressed: (index) { - switch (index) { - case 0: - keyboard.ctrl = !keyboard.ctrl; - break; - case 1: - keyboard.alt = !keyboard.alt; - break; - case 2: - keyboard.shift = !keyboard.shift; - break; - } - }, - children: const [Text('Ctrl'), Text('Alt'), Text('Shift')], - ), - ); - } -} - -class VirtualKeyboard extends TerminalInputHandler with ChangeNotifier { - final TerminalInputHandler _inputHandler; - - VirtualKeyboard(this._inputHandler); - - bool _ctrl = false; - - bool get ctrl => _ctrl; - - set ctrl(bool value) { - if (_ctrl != value) { - _ctrl = value; - notifyListeners(); - } - } - - bool _shift = false; - - bool get shift => _shift; - - set shift(bool value) { - if (_shift != value) { - _shift = value; - notifyListeners(); - } - } - - bool _alt = false; - - bool get alt => _alt; - - set alt(bool value) { - if (_alt != value) { - _alt = value; - notifyListeners(); - } - } - - @override - String? call(TerminalKeyboardEvent event) { - return _inputHandler.call(event.copyWith( - ctrl: event.ctrl || _ctrl, - shift: event.shift || _shift, - alt: event.alt || _alt, - )); - } -}