|
@@ -1,23 +1,33 @@
|
|
|
import 'package:flutter/gestures.dart';
|
|
import 'package:flutter/gestures.dart';
|
|
|
import 'package:flutter/widgets.dart';
|
|
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/terminal_view.dart';
|
|
|
|
|
+import 'package:xterm/src/ui/controller.dart';
|
|
|
import 'package:xterm/src/ui/gesture/gesture_detector.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';
|
|
import 'package:xterm/src/ui/render.dart';
|
|
|
|
|
|
|
|
class TerminalGestureHandler extends StatefulWidget {
|
|
class TerminalGestureHandler extends StatefulWidget {
|
|
|
const TerminalGestureHandler({
|
|
const TerminalGestureHandler({
|
|
|
super.key,
|
|
super.key,
|
|
|
required this.terminalView,
|
|
required this.terminalView,
|
|
|
|
|
+ required this.terminalController,
|
|
|
this.child,
|
|
this.child,
|
|
|
this.onTapUp,
|
|
this.onTapUp,
|
|
|
this.onSingleTapUp,
|
|
this.onSingleTapUp,
|
|
|
this.onTapDown,
|
|
this.onTapDown,
|
|
|
this.onSecondaryTapDown,
|
|
this.onSecondaryTapDown,
|
|
|
this.onSecondaryTapUp,
|
|
this.onSecondaryTapUp,
|
|
|
|
|
+ this.onTertiaryTapDown,
|
|
|
|
|
+ this.onTertiaryTapUp,
|
|
|
|
|
+ this.readOnly = false,
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
final TerminalViewState terminalView;
|
|
final TerminalViewState terminalView;
|
|
|
|
|
|
|
|
|
|
+ final TerminalController terminalController;
|
|
|
|
|
+
|
|
|
final Widget? child;
|
|
final Widget? child;
|
|
|
|
|
|
|
|
final GestureTapUpCallback? onTapUp;
|
|
final GestureTapUpCallback? onTapUp;
|
|
@@ -30,6 +40,12 @@ class TerminalGestureHandler extends StatefulWidget {
|
|
|
|
|
|
|
|
final GestureTapUpCallback? onSecondaryTapUp;
|
|
final GestureTapUpCallback? onSecondaryTapUp;
|
|
|
|
|
|
|
|
|
|
+ final GestureTapDownCallback? onTertiaryTapDown;
|
|
|
|
|
+
|
|
|
|
|
+ final GestureTapUpCallback? onTertiaryTapUp;
|
|
|
|
|
+
|
|
|
|
|
+ final bool readOnly;
|
|
|
|
|
+
|
|
|
@override
|
|
@override
|
|
|
State<TerminalGestureHandler> createState() => _TerminalGestureHandlerState();
|
|
State<TerminalGestureHandler> createState() => _TerminalGestureHandlerState();
|
|
|
}
|
|
}
|
|
@@ -48,10 +64,12 @@ class _TerminalGestureHandlerState extends State<TerminalGestureHandler> {
|
|
|
return TerminalGestureDetector(
|
|
return TerminalGestureDetector(
|
|
|
child: widget.child,
|
|
child: widget.child,
|
|
|
onTapUp: widget.onTapUp,
|
|
onTapUp: widget.onTapUp,
|
|
|
- onSingleTapUp: widget.onSingleTapUp,
|
|
|
|
|
- onTapDown: widget.onTapDown,
|
|
|
|
|
- onSecondaryTapDown: widget.onSecondaryTapDown,
|
|
|
|
|
- onSecondaryTapUp: widget.onSecondaryTapUp,
|
|
|
|
|
|
|
+ onSingleTapUp: onSingleTapUp,
|
|
|
|
|
+ onTapDown: onTapDown,
|
|
|
|
|
+ onSecondaryTapDown: onSecondaryTapDown,
|
|
|
|
|
+ onSecondaryTapUp: onSecondaryTapUp,
|
|
|
|
|
+ onTertiaryTapDown: onSecondaryTapDown,
|
|
|
|
|
+ onTertiaryTapUp: onSecondaryTapUp,
|
|
|
onLongPressStart: onLongPressStart,
|
|
onLongPressStart: onLongPressStart,
|
|
|
onLongPressMoveUpdate: onLongPressMoveUpdate,
|
|
onLongPressMoveUpdate: onLongPressMoveUpdate,
|
|
|
// onLongPressUp: onLongPressUp,
|
|
// onLongPressUp: onLongPressUp,
|
|
@@ -61,6 +79,83 @@ class _TerminalGestureHandlerState extends State<TerminalGestureHandler> {
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ bool get _shouldSendTapEvent =>
|
|
|
|
|
+ !widget.readOnly &&
|
|
|
|
|
+ widget.terminalController.shouldSendPointerInput(PointerInput.tap);
|
|
|
|
|
+
|
|
|
|
|
+ void _tapDown(
|
|
|
|
|
+ GestureTapDownCallback? callback,
|
|
|
|
|
+ TapDownDetails details,
|
|
|
|
|
+ TerminalMouseButton button, {
|
|
|
|
|
+ bool forceCallback = false,
|
|
|
|
|
+ }) {
|
|
|
|
|
+ // Check if the terminal should and can handle the tap down event.
|
|
|
|
|
+ var handled = false;
|
|
|
|
|
+ if (_shouldSendTapEvent) {
|
|
|
|
|
+ handled = renderTerminal.mouseEvent(
|
|
|
|
|
+ button,
|
|
|
|
|
+ TerminalMouseButtonState.down,
|
|
|
|
|
+ details.localPosition,
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ // If the event was not handled by the terminal, use the supplied callback.
|
|
|
|
|
+ if (!handled || forceCallback) {
|
|
|
|
|
+ callback?.call(details);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ void _tapUp(
|
|
|
|
|
+ GestureTapUpCallback? callback,
|
|
|
|
|
+ TapUpDetails details,
|
|
|
|
|
+ TerminalMouseButton button, {
|
|
|
|
|
+ bool forceCallback = false,
|
|
|
|
|
+ }) {
|
|
|
|
|
+ // Check if the terminal should and can handle the tap up event.
|
|
|
|
|
+ var handled = false;
|
|
|
|
|
+ if (_shouldSendTapEvent) {
|
|
|
|
|
+ handled = renderTerminal.mouseEvent(
|
|
|
|
|
+ button,
|
|
|
|
|
+ TerminalMouseButtonState.up,
|
|
|
|
|
+ details.localPosition,
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ // If the event was not handled by the terminal, use the supplied callback.
|
|
|
|
|
+ if (!handled || forceCallback) {
|
|
|
|
|
+ callback?.call(details);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ void onTapDown(TapDownDetails details) {
|
|
|
|
|
+ // onTapDown is special, as it will always call the supplied callback.
|
|
|
|
|
+ // The TerminalView depends on it to bring the terminal into focus.
|
|
|
|
|
+ _tapDown(
|
|
|
|
|
+ widget.onTapDown,
|
|
|
|
|
+ details,
|
|
|
|
|
+ TerminalMouseButton.left,
|
|
|
|
|
+ forceCallback: true,
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ void onSingleTapUp(TapUpDetails details) {
|
|
|
|
|
+ _tapUp(widget.onSingleTapUp, details, TerminalMouseButton.left);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ void onSecondaryTapDown(TapDownDetails details) {
|
|
|
|
|
+ _tapDown(widget.onSecondaryTapDown, details, TerminalMouseButton.right);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ void onSecondaryTapUp(TapUpDetails details) {
|
|
|
|
|
+ _tapUp(widget.onSecondaryTapUp, details, TerminalMouseButton.right);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ void onTertiaryTapDown(TapDownDetails details) {
|
|
|
|
|
+ _tapDown(widget.onTertiaryTapDown, details, TerminalMouseButton.middle);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ void onTertiaryTapUp(TapUpDetails details) {
|
|
|
|
|
+ _tapUp(widget.onTertiaryTapUp, details, TerminalMouseButton.right);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
void onDoubleTapDown(TapDownDetails details) {
|
|
void onDoubleTapDown(TapDownDetails details) {
|
|
|
renderTerminal.selectWord(details.localPosition);
|
|
renderTerminal.selectWord(details.localPosition);
|
|
|
}
|
|
}
|