Browse Source

feat: support deactiving some or all mouse events in the TerminalController

Georg Wechslberger 3 năm trước cách đây
mục cha
commit
88f8ddb116

+ 1 - 0
lib/src/terminal_view.dart

@@ -245,6 +245,7 @@ class TerminalViewState extends State<TerminalView> {
 
     child = TerminalGestureHandler(
       terminalView: this,
+      terminalController: _controller,
       onTapUp: _onTapUp,
       onTapDown: _onTapDown,
       onSecondaryTapDown:

+ 36 - 0
lib/src/ui/controller.dart

@@ -1,11 +1,27 @@
 import 'package:flutter/material.dart';
 import 'package:xterm/src/core/buffer/range.dart';
+import 'package:xterm/src/ui/pointer_input.dart';
 
 class TerminalController with ChangeNotifier {
   BufferRange? _selection;
 
   BufferRange? get selection => _selection;
 
+  PointerInputs _pointerInputs;
+  bool _suspendPointerInputs;
+
+  /// True if sending pointer events to the terminal is suspended.
+  bool get suspendedPointerInputs => _suspendPointerInputs;
+
+  /// The set of pointer events which will be used as mouse input for the terminal.
+  PointerInputs get pointerInput => _pointerInputs;
+
+  TerminalController({
+    PointerInputs pointerInputs = const PointerInputs.none(),
+    bool suspendPointerInput = false,
+  })  : _pointerInputs = pointerInputs,
+        _suspendPointerInputs = suspendPointerInput;
+
   void setSelection(BufferRange? range) {
     range = range?.normalized;
 
@@ -15,6 +31,26 @@ class TerminalController with ChangeNotifier {
     }
   }
 
+  // Select which type of pointer events are send to the terminal.
+  void setPointerInputs(PointerInputs pointerInput) {
+    _pointerInputs = pointerInput;
+    notifyListeners();
+  }
+
+  // Toggle sending pointer events to the terminal.
+  void setSuspendPointerInput(bool suspend) {
+    _suspendPointerInputs = suspend;
+    notifyListeners();
+  }
+
+  // Returns true if this type of PointerInput should be send to the Terminal.
+  bool shouldSendPointerInput(PointerInput pointerInput) {
+    // Always return false if pointer input is suspended.
+    return _suspendPointerInputs
+        ? false
+        : _pointerInputs.inputs.contains(pointerInput);
+  }
+
   void clearSelection() {
     _selection = null;
     notifyListeners();

+ 50 - 30
lib/src/ui/gesture/gesture_handler.dart

@@ -3,13 +3,16 @@ import 'package:flutter/widgets.dart';
 import 'package:xterm/src/core/mouse/button.dart';
 import 'package:xterm/src/core/mouse/button_state.dart';
 import 'package:xterm/src/terminal_view.dart';
+import 'package:xterm/src/ui/controller.dart';
 import 'package:xterm/src/ui/gesture/gesture_detector.dart';
+import 'package:xterm/src/ui/pointer_input.dart';
 import 'package:xterm/src/ui/render.dart';
 
 class TerminalGestureHandler extends StatefulWidget {
   const TerminalGestureHandler({
     super.key,
     required this.terminalView,
+    required this.terminalController,
     this.child,
     this.onTapUp,
     this.onSingleTapUp,
@@ -22,6 +25,8 @@ class TerminalGestureHandler extends StatefulWidget {
 
   final TerminalViewState terminalView;
 
+  final TerminalController terminalController;
+
   final Widget? child;
 
   final GestureTapUpCallback? onTapUp;
@@ -71,58 +76,73 @@ class _TerminalGestureHandlerState extends State<TerminalGestureHandler> {
     );
   }
 
+  bool get _shouldSendTapEvent =>
+      widget.terminalController.shouldSendPointerInput(PointerInput.tap);
+
   void onTapDown(TapDownDetails details) {
     widget.onTapDown?.call(details);
-    renderTerminal.mouseEvent(
-      TerminalMouseButton.left,
-      TerminalMouseButtonState.down,
-      details.localPosition,
-    );
+    if (_shouldSendTapEvent) {
+      renderTerminal.mouseEvent(
+        TerminalMouseButton.left,
+        TerminalMouseButtonState.down,
+        details.localPosition,
+      );
+    }
   }
 
   void onSingleTapUp(TapUpDetails details) {
     widget.onSingleTapUp?.call(details);
-    renderTerminal.mouseEvent(
-      TerminalMouseButton.left,
-      TerminalMouseButtonState.up,
-      details.localPosition,
-    );
+    if (_shouldSendTapEvent) {
+      renderTerminal.mouseEvent(
+        TerminalMouseButton.left,
+        TerminalMouseButtonState.up,
+        details.localPosition,
+      );
+    }
   }
 
   void onSecondaryTapDown(TapDownDetails details) {
     widget.onSecondaryTapDown?.call(details);
-    renderTerminal.mouseEvent(
-      TerminalMouseButton.right,
-      TerminalMouseButtonState.down,
-      details.localPosition,
-    );
+    if (_shouldSendTapEvent) {
+      renderTerminal.mouseEvent(
+        TerminalMouseButton.right,
+        TerminalMouseButtonState.down,
+        details.localPosition,
+      );
+    }
   }
 
   void onSecondaryTapUp(TapUpDetails details) {
     widget.onSecondaryTapUp?.call(details);
-    renderTerminal.mouseEvent(
-      TerminalMouseButton.right,
-      TerminalMouseButtonState.up,
-      details.localPosition,
-    );
+    if (_shouldSendTapEvent) {
+      renderTerminal.mouseEvent(
+        TerminalMouseButton.right,
+        TerminalMouseButtonState.up,
+        details.localPosition,
+      );
+    }
   }
 
   void onTertiaryTapDown(TapDownDetails details) {
     widget.onTertiaryTapDown?.call(details);
-    renderTerminal.mouseEvent(
-      TerminalMouseButton.middle,
-      TerminalMouseButtonState.down,
-      details.localPosition,
-    );
+    if (_shouldSendTapEvent) {
+      renderTerminal.mouseEvent(
+        TerminalMouseButton.middle,
+        TerminalMouseButtonState.down,
+        details.localPosition,
+      );
+    }
   }
 
   void onTertiaryTapUp(TapUpDetails details) {
     widget.onTertiaryTapUp?.call(details);
-    renderTerminal.mouseEvent(
-      TerminalMouseButton.middle,
-      TerminalMouseButtonState.up,
-      details.localPosition,
-    );
+    if (_shouldSendTapEvent) {
+      renderTerminal.mouseEvent(
+        TerminalMouseButton.middle,
+        TerminalMouseButtonState.up,
+        details.localPosition,
+      );
+    }
   }
 
   void onDoubleTapDown(TapDownDetails details) {

+ 28 - 0
lib/src/ui/pointer_input.dart

@@ -0,0 +1,28 @@
+enum PointerInput {
+  /// Taps / buttons presses & releases.
+  tap,
+
+  /// Scroll / mouse wheels events.
+  scroll,
+
+  /// Drag events, a pointer is in a down state and dragged across the terminal.
+  drag,
+
+  /// Move events, a pointer is in an up state and moved across the terminal.
+  move,
+}
+
+class PointerInputs {
+  final Set<PointerInput> inputs;
+  const PointerInputs(this.inputs);
+
+  const PointerInputs.none() : inputs = const <PointerInput>{};
+
+  const PointerInputs.all()
+      : inputs = const <PointerInput>{
+          PointerInput.tap,
+          PointerInput.scroll,
+          PointerInput.drag,
+          PointerInput.move,
+        };
+}

+ 1 - 0
lib/ui.dart

@@ -2,6 +2,7 @@ export 'src/terminal_view.dart';
 export 'src/ui/controller.dart';
 export 'src/ui/cursor_type.dart';
 export 'src/ui/keyboard_visibility.dart';
+export 'src/ui/pointer_input.dart';
 export 'src/ui/shortcut/shortcuts.dart';
 export 'src/ui/terminal_text_style.dart';
 export 'src/ui/terminal_theme.dart';