Bläddra i källkod

first double-tap select functionality

selects word, then row
sometimes the tap seems to immediately stop the selection => needs investigation (maybe use onTap instead of onTapDown)
devmil 4 år sedan
förälder
incheckning
5167977ba8

+ 7 - 2
lib/frontend/terminal_view.dart

@@ -222,9 +222,14 @@ class _TerminalViewState extends State<TerminalView> {
     return GestureDetector(
       behavior: HitTestBehavior.deferToChild,
       dragStartBehavior: DragStartBehavior.down,
-      onDoubleTapDown: (details) {
-        print('details : $details');
+      onDoubleTapDown: (detail) {
+        final pos = detail.localPosition;
+        final offset = getMouseOffset(pos.dx, pos.dy);
+        widget.terminal.onMouseDoubleTap(offset);
+        widget.terminal.refresh();
       },
+      // this is needed to activate double tap
+      onDoubleTap: () {},
       onTapDown: (detail) {
         if (widget.terminal.selection?.isEmpty ?? true) {
           InputListener.of(context)!.requestKeyboard();

+ 6 - 0
lib/mouse/mouse_mode.dart

@@ -10,6 +10,7 @@ abstract class MouseMode {
   // static const buttonEvent = MouseModeX10();
 
   void onTap(Terminal terminal, Position offset);
+  void onDoubleTap(Terminal terminal, Position offset) {}
   void onPanStart(Terminal terminal, Position offset) {}
   void onPanUpdate(Terminal terminal, Position offset) {}
 }
@@ -22,6 +23,11 @@ class MouseModeNone extends MouseMode {
     terminal.debug.onMsg('tap: $offset');
   }
 
+  @override
+  void onDoubleTap(Terminal terminal, Position offset) {
+    terminal.selectWordOrRow(offset);
+  }
+
   @override
   void onPanStart(Terminal terminal, Position offset) {
     terminal.selection!.init(offset);

+ 52 - 0
lib/terminal/terminal.dart

@@ -466,6 +466,53 @@ class Terminal with Observable implements TerminalUiInteraction {
     }
   }
 
+  void selectWordOrRow(Position position) {
+    if (position.y > buffer.lines.length) {
+      return;
+    }
+
+    final row = position.y;
+
+    final line = buffer.lines[row];
+
+    if (_selection.contains(position)) {
+      // select area on an already existing selection extends it to the full line
+      _selection.clear();
+      _selection.init(Position(0, row));
+      _selection.update(Position(terminalWidth, row));
+    } else {
+      // select the word that is under position
+
+      var start = position.x;
+      var end = position.x;
+
+      do {
+        if (start == 0) {
+          break;
+        }
+        final content = line.cellGetContent(start - 1);
+        if (content == 0 || content == ' '.runes.first) {
+          break;
+        }
+        start--;
+      } while (true);
+      do {
+        if (end >= terminalWidth - 1) {
+          break;
+        }
+        final content = line.cellGetContent(end + 1);
+        if (content == 0 || content == ' '.runes.first) {
+          break;
+        }
+        end++;
+      } while (true);
+
+      _selection.clear();
+      _selection.init(Position(start, row));
+      _selection.update(Position(end, row));
+    }
+  }
+
   String? getSelectedText() {
     if (_selection.isEmpty) {
       return null;
@@ -591,6 +638,11 @@ class Terminal with Observable implements TerminalUiInteraction {
     mouseMode.onTap(this, position);
   }
 
+  @override
+  onMouseDoubleTap(Position position) {
+    mouseMode.onDoubleTap(this, position);
+  }
+
   @override
   void onPanStart(Position position) {
     mouseMode.onPanStart(this, position);

+ 8 - 0
lib/terminal/terminal_isolate.dart

@@ -21,6 +21,7 @@ enum _IsolateCommand {
   refresh,
   clearSelection,
   mouseTap,
+  mouseDoubleTap,
   mousePanStart,
   mousePanUpdate,
   setScrollOffsetFromTop,
@@ -94,6 +95,9 @@ void terminalMain(SendPort port) async {
       case _IsolateCommand.mouseTap:
         _terminal?.mouseMode.onTap(_terminal, msg[1]);
         break;
+      case _IsolateCommand.mouseDoubleTap:
+        _terminal?.mouseMode.onDoubleTap(_terminal, msg[1]);
+        break;
       case _IsolateCommand.mousePanStart:
         _terminal?.mouseMode.onPanStart(_terminal, msg[1]);
         break;
@@ -405,6 +409,10 @@ class TerminalIsolate with Observable implements TerminalUiInteraction {
     _sendPort?.send([_IsolateCommand.mouseTap, position]);
   }
 
+  void onMouseDoubleTap(Position position) {
+    _sendPort?.send([_IsolateCommand.mouseDoubleTap, position]);
+  }
+
   void onPanStart(Position position) {
     _sendPort?.send([_IsolateCommand.mousePanStart, position]);
   }

+ 3 - 0
lib/terminal/terminal_ui_interaction.dart

@@ -71,6 +71,9 @@ abstract class TerminalUiInteraction with Observable {
   /// notify the Terminal about a mouse tap
   void onMouseTap(Position position);
 
+  /// notify the Terminal about a mouse double tap
+  void onMouseDoubleTap(Position position);
+
   /// notify the Terminal about a pan start
   void onPanStart(Position position);