remove drag/scroll/right btn, update gesture

This commit is contained in:
csf 2022-02-17 18:00:44 +08:00
parent b4ed72435c
commit 6840052033
3 changed files with 219 additions and 189 deletions

View File

@ -7,7 +7,8 @@ enum CustomTouchGestureState {
oneFingerPan, oneFingerPan,
twoFingerScale, twoFingerScale,
twoFingerVerticalDrag, twoFingerVerticalDrag,
twoFingerHorizontalDrag twoFingerHorizontalDrag,
twoFingerPan
} }
const kScaleSlop = kPrecisePointerPanSlop / 10; const kScaleSlop = kPrecisePointerPanSlop / 10;
@ -43,11 +44,20 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
GestureDragUpdateCallback? onTwoFingerHorizontalDragUpdate; GestureDragUpdateCallback? onTwoFingerHorizontalDragUpdate;
GestureDragEndCallback? onTwoFingerHorizontalDragEnd; GestureDragEndCallback? onTwoFingerHorizontalDragEnd;
// twoFingerPan
GestureDragStartCallback? onTwoFingerPanStart;
GestureDragUpdateCallback? onTwoFingerPanUpdate;
GestureDragEndCallback? onTwoFingerPanEnd;
void _init() { void _init() {
debugPrint("CustomTouchGestureRecognizer init"); debugPrint("CustomTouchGestureRecognizer init");
onStart = (d) { onStart = (d) {
if (d.pointerCount == 1) { if (d.pointerCount == 1) {
_currentState = CustomTouchGestureState.oneFingerPan; _currentState = CustomTouchGestureState.oneFingerPan;
if (onOneFingerPanStart != null) {
onOneFingerPanStart!(DragStartDetails(
localPosition: d.localFocalPoint, globalPosition: d.focalPoint));
}
debugPrint("start pan"); debugPrint("start pan");
} else if (d.pointerCount == 2) { } else if (d.pointerCount == 2) {
_currentState = CustomTouchGestureState.none; _currentState = CustomTouchGestureState.none;
@ -84,6 +94,11 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
onTwoFingerVerticalDragUpdate!(_getDragUpdateDetails(d)); onTwoFingerVerticalDragUpdate!(_getDragUpdateDetails(d));
} }
break; break;
case CustomTouchGestureState.twoFingerPan:
if (onTwoFingerPanUpdate != null) {
onTwoFingerPanUpdate!(_getDragUpdateDetails(d));
}
break;
default: default:
break; break;
} }
@ -118,6 +133,12 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
onTwoFingerVerticalDragEnd!(_getDragEndDetails(d)); onTwoFingerVerticalDragEnd!(_getDragEndDetails(d));
} }
break; break;
case CustomTouchGestureState.twoFingerPan:
debugPrint("TwoFingerState.twoFingerPan onEnd");
if (onTwoFingerPanEnd != null) {
onTwoFingerPanEnd!(_getDragEndDetails(d));
}
break;
default: default:
break; break;
} }
@ -154,24 +175,27 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
if (_sumScale.abs() > kScaleSlop) { if (_sumScale.abs() > kScaleSlop) {
debugPrint("start Scale"); debugPrint("start Scale");
_currentState = CustomTouchGestureState.twoFingerScale; _currentState = CustomTouchGestureState.twoFingerScale;
if (onOneFingerPanStart != null) { if (onTwoFingerScaleStart != null) {
onOneFingerPanStart!(_getDragStartDetails(d)); onTwoFingerScaleStart!(ScaleStartDetails(
localFocalPoint: d.localFocalPoint, focalPoint: d.focalPoint));
} }
_reset(); _reset();
} else if (_sumHorizontal.abs() > kPrecisePointerPanSlop) { } else if (_sumVertical.abs() > kPrecisePointerPanSlop &&
debugPrint("start Horizontal"); _sumHorizontal.abs() < kPrecisePointerHitSlop) {
_currentState = CustomTouchGestureState.twoFingerHorizontalDrag;
if (onTwoFingerHorizontalDragUpdate != null) {
onTwoFingerHorizontalDragUpdate!(_getDragUpdateDetails(d));
}
_reset();
} else if (_sumVertical.abs() > kPrecisePointerPanSlop) {
debugPrint("start Vertical"); debugPrint("start Vertical");
if (onTwoFingerVerticalDragStart != null) { if (onTwoFingerVerticalDragStart != null) {
_getDragStartDetails(d); _getDragStartDetails(d);
} }
_currentState = CustomTouchGestureState.twoFingerVerticalDrag; _currentState = CustomTouchGestureState.twoFingerVerticalDrag;
_reset(); _reset();
} else if ((_sumHorizontal.abs() + _sumVertical.abs()) >
kPrecisePointerPanSlop) {
debugPrint("start TwoFingerPan");
_currentState = CustomTouchGestureState.twoFingerPan;
if (onTwoFingerPanStart != null) {
onTwoFingerPanStart!(_getDragStartDetails(d));
}
_reset();
} }
} }
@ -672,7 +696,8 @@ class _TapTracker {
void startTrackingPointer(PointerRoute route, Matrix4? transform) { void startTrackingPointer(PointerRoute route, Matrix4? transform) {
if (!_isTrackingPointer) { if (!_isTrackingPointer) {
_isTrackingPointer = true; _isTrackingPointer = true;
GestureBinding.instance!.pointerRouter.addRoute(pointer, route, transform); GestureBinding.instance!.pointerRouter
.addRoute(pointer, route, transform);
} }
} }
@ -716,17 +741,23 @@ class _CountdownZoned {
RawGestureDetector getMixinGestureDetector({ RawGestureDetector getMixinGestureDetector({
Widget? child, Widget? child,
GestureTapUpCallback? onTapUp, GestureTapUpCallback? onTapUp,
GestureTapDownCallback? onDoubleTapDown,
GestureDoubleTapCallback? onDoubleTap, GestureDoubleTapCallback? onDoubleTap,
GestureLongPressDownCallback? onLongPressDown,
GestureLongPressCallback? onLongPress,
GestureDragStartCallback? onHoldDragStart, GestureDragStartCallback? onHoldDragStart,
GestureDragUpdateCallback? onHoldDragUpdate, GestureDragUpdateCallback? onHoldDragUpdate,
GestureDragCancelCallback? onHoldDragCancel, GestureDragCancelCallback? onHoldDragCancel,
GestureTapDownCallback? onDoubleFinerTap, GestureTapDownCallback? onDoubleFinerTap,
GestureDragStartCallback? onOneFingerPanStart, GestureDragStartCallback? onOneFingerPanStart,
GestureDragUpdateCallback? onOneFingerPanUpdate, GestureDragUpdateCallback? onOneFingerPanUpdate,
GestureDragEndCallback? onOneFingerPanEnd,
GestureScaleUpdateCallback? onTwoFingerScaleUpdate, GestureScaleUpdateCallback? onTwoFingerScaleUpdate,
GestureScaleEndCallback? onTwoFingerScaleEnd, GestureScaleEndCallback? onTwoFingerScaleEnd,
GestureDragUpdateCallback? onTwoFingerHorizontalDragUpdate, GestureDragUpdateCallback? onTwoFingerHorizontalDragUpdate,
GestureDragUpdateCallback? onTwoFingerVerticalDragUpdate, GestureDragUpdateCallback? onTwoFingerVerticalDragUpdate,
GestureDragStartCallback? onTwoFingerPanStart,
GestureDragUpdateCallback? onTwoFingerPanUpdate,
}) { }) {
return RawGestureDetector( return RawGestureDetector(
child: child, child: child,
@ -740,7 +771,16 @@ RawGestureDetector getMixinGestureDetector({
DoubleTapGestureRecognizer: DoubleTapGestureRecognizer:
GestureRecognizerFactoryWithHandlers<DoubleTapGestureRecognizer>( GestureRecognizerFactoryWithHandlers<DoubleTapGestureRecognizer>(
() => DoubleTapGestureRecognizer(), (instance) { () => DoubleTapGestureRecognizer(), (instance) {
instance.onDoubleTap = onDoubleTap; instance
..onDoubleTapDown = onDoubleTapDown
..onDoubleTap = onDoubleTap;
}),
LongPressGestureRecognizer:
GestureRecognizerFactoryWithHandlers<LongPressGestureRecognizer>(
() => LongPressGestureRecognizer(), (instance) {
instance
..onLongPressDown = onLongPressDown
..onLongPress = onLongPress;
}), }),
// Customized // Customized
HoldTapMoveGestureRecognizer: HoldTapMoveGestureRecognizer:
@ -763,10 +803,13 @@ RawGestureDetector getMixinGestureDetector({
instance instance
..onOneFingerPanStart = onOneFingerPanStart ..onOneFingerPanStart = onOneFingerPanStart
..onOneFingerPanUpdate = onOneFingerPanUpdate ..onOneFingerPanUpdate = onOneFingerPanUpdate
..onOneFingerPanEnd = onOneFingerPanEnd
..onTwoFingerScaleUpdate = onTwoFingerScaleUpdate ..onTwoFingerScaleUpdate = onTwoFingerScaleUpdate
..onTwoFingerScaleEnd = onTwoFingerScaleEnd ..onTwoFingerScaleEnd = onTwoFingerScaleEnd
..onTwoFingerHorizontalDragUpdate = onTwoFingerHorizontalDragUpdate ..onTwoFingerHorizontalDragUpdate = onTwoFingerHorizontalDragUpdate
..onTwoFingerVerticalDragUpdate = onTwoFingerVerticalDragUpdate; ..onTwoFingerVerticalDragUpdate = onTwoFingerVerticalDragUpdate
..onTwoFingerPanStart = onTwoFingerPanStart
..onTwoFingerPanUpdate = onTwoFingerPanUpdate;
}) })
}); });
} }

View File

@ -42,7 +42,7 @@ class FfiModel with ChangeNotifier {
FfiModel() { FfiModel() {
Translator.call = translate; Translator.call = translate;
clear(); clear();
() async { () async {
await PlatformFFI.init(); await PlatformFFI.init();
_initialized = true; _initialized = true;
print("FFI initialized"); print("FFI initialized");
@ -97,14 +97,13 @@ class FfiModel with ChangeNotifier {
_permissions.clear(); _permissions.clear();
} }
void update( void update(String id,
String id,
BuildContext context, BuildContext context,
void Function( void Function(
Map<String, dynamic> evt, Map<String, dynamic> evt,
String id, String id,
) )
handleMsgbox) { handleMsgbox) {
var pos; var pos;
for (;;) { for (;;) {
var evt = FFI.popEvent(); var evt = FFI.popEvent();
@ -143,17 +142,17 @@ class FfiModel with ChangeNotifier {
final pid = FFI.id; final pid = FFI.id;
ui.decodeImageFromPixels( ui.decodeImageFromPixels(
rgba, _display.width, _display.height, ui.PixelFormat.bgra8888, rgba, _display.width, _display.height, ui.PixelFormat.bgra8888,
(image) { (image) {
PlatformFFI.clearRgbaFrame(); PlatformFFI.clearRgbaFrame();
_decoding = false; _decoding = false;
if (FFI.id != pid) return; if (FFI.id != pid) return;
try { try {
// my throw exception, because the listener maybe already dispose // my throw exception, because the listener maybe already dispose
FFI.imageModel.update(image); FFI.imageModel.update(image);
} catch (e) { } catch (e) {
print('update image: $e'); print('update image: $e');
} }
}); });
} }
} }
} }
@ -210,7 +209,9 @@ class ImageModel with ChangeNotifier {
if (isDesktop) { if (isDesktop) {
FFI.canvasModel.updateViewStyle(); FFI.canvasModel.updateViewStyle();
} else { } else {
final size = MediaQueryData.fromWindow(ui.window).size; final size = MediaQueryData
.fromWindow(ui.window)
.size;
final xscale = size.width / image.width; final xscale = size.width / image.width;
final yscale = size.height / image.height; final yscale = size.height / image.height;
FFI.canvasModel.scale = max(xscale, yscale); FFI.canvasModel.scale = max(xscale, yscale);
@ -223,7 +224,9 @@ class ImageModel with ChangeNotifier {
double get maxScale { double get maxScale {
if (_image == null) return 1.0; if (_image == null) return 1.0;
final size = MediaQueryData.fromWindow(ui.window).size; final size = MediaQueryData
.fromWindow(ui.window)
.size;
final xscale = size.width / _image!.width; final xscale = size.width / _image!.width;
final yscale = size.height / _image!.height; final yscale = size.height / _image!.height;
return max(1.0, max(xscale, yscale)); return max(1.0, max(xscale, yscale));
@ -231,7 +234,9 @@ class ImageModel with ChangeNotifier {
double get minScale { double get minScale {
if (_image == null) return 1.0; if (_image == null) return 1.0;
final size = MediaQueryData.fromWindow(ui.window).size; final size = MediaQueryData
.fromWindow(ui.window)
.size;
final xscale = size.width / _image!.width; final xscale = size.width / _image!.width;
final yscale = size.height / _image!.height; final yscale = size.height / _image!.height;
return min(xscale, yscale); return min(xscale, yscale);
@ -253,7 +258,9 @@ class CanvasModel with ChangeNotifier {
void updateViewStyle() { void updateViewStyle() {
final s = FFI.getByName('peer_option', 'view-style'); final s = FFI.getByName('peer_option', 'view-style');
final size = MediaQueryData.fromWindow(ui.window).size; final size = MediaQueryData
.fromWindow(ui.window)
.size;
final s1 = size.width / FFI.ffiModel.display.width; final s1 = size.width / FFI.ffiModel.display.width;
final s2 = size.height / FFI.ffiModel.display.height; final s2 = size.height / FFI.ffiModel.display.height;
if (s == 'shrink') { if (s == 'shrink') {
@ -282,7 +289,9 @@ class CanvasModel with ChangeNotifier {
} }
void moveDesktopMouse(double x, double y) { void moveDesktopMouse(double x, double y) {
final size = MediaQueryData.fromWindow(ui.window).size; final size = MediaQueryData
.fromWindow(ui.window)
.size;
final dw = FFI.ffiModel.display.width * _scale; final dw = FFI.ffiModel.display.width * _scale;
final dh = FFI.ffiModel.display.height * _scale; final dh = FFI.ffiModel.display.height * _scale;
var dxOffset = 0; var dxOffset = 0;
@ -298,7 +307,7 @@ class CanvasModel with ChangeNotifier {
if (dxOffset != 0 || dyOffset != 0) { if (dxOffset != 0 || dyOffset != 0) {
notifyListeners(); notifyListeners();
} }
FFI.cursorModel.move(x, y); FFI.cursorModel.moveLocal(x, y);
} }
set scale(v) { set scale(v) {
@ -377,7 +386,9 @@ class CursorModel with ChangeNotifier {
// remote physical display coordinate // remote physical display coordinate
Rect getVisibleRect() { Rect getVisibleRect() {
final size = MediaQueryData.fromWindow(ui.window).size; final size = MediaQueryData
.fromWindow(ui.window)
.size;
final xoffset = FFI.canvasModel.x; final xoffset = FFI.canvasModel.x;
final yoffset = FFI.canvasModel.y; final yoffset = FFI.canvasModel.y;
final scale = FFI.canvasModel.scale; final scale = FFI.canvasModel.scale;
@ -397,13 +408,18 @@ class CursorModel with ChangeNotifier {
return h - thresh; return h - thresh;
} }
void touch(double x, double y, bool right) { void touch(double x, double y, MouseButtons button) {
move(x, y); moveLocal(x, y);
FFI.moveMouse(_x, _y); FFI.moveMouse(_x, _y);
FFI.tap(right); FFI.tap(button);
} }
void move(double x, double y) { void move(double x, double y){
moveLocal(x, y);
FFI.moveMouse(_x, _y);
}
void moveLocal(double x, double y) {
final scale = FFI.canvasModel.scale; final scale = FFI.canvasModel.scale;
final xoffset = FFI.canvasModel.x; final xoffset = FFI.canvasModel.x;
final yoffset = FFI.canvasModel.y; final yoffset = FFI.canvasModel.y;
@ -420,10 +436,10 @@ class CursorModel with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
void updatePan(double dx, double dy, bool touchMode, bool drag) { void updatePan(double dx, double dy,bool touchMode) {
if (FFI.imageModel.image == null) return; if (FFI.imageModel.image == null) return;
if (touchMode) { if (touchMode) {
if (drag) { if (true) {
final scale = FFI.canvasModel.scale; final scale = FFI.canvasModel.scale;
_x += dx / scale; _x += dx / scale;
_y += dy / scale; _y += dy / scale;
@ -508,17 +524,17 @@ class CursorModel with ChangeNotifier {
final rgba = Uint8List.fromList(colors.map((s) => s as int).toList()); final rgba = Uint8List.fromList(colors.map((s) => s as int).toList());
var pid = FFI.id; var pid = FFI.id;
ui.decodeImageFromPixels(rgba, width, height, ui.PixelFormat.rgba8888, ui.decodeImageFromPixels(rgba, width, height, ui.PixelFormat.rgba8888,
(image) { (image) {
if (FFI.id != pid) return; if (FFI.id != pid) return;
_image = image; _image = image;
_images[id] = Tuple3(image, _hotx, _hoty); _images[id] = Tuple3(image, _hotx, _hoty);
try { try {
// my throw exception, because the listener maybe already dispose // my throw exception, because the listener maybe already dispose
notifyListeners(); notifyListeners();
} catch (e) { } catch (e) {
print('notify cursor: $e'); print('notify cursor: $e');
} }
}); });
} }
void updateCursorId(Map<String, dynamic> evt) { void updateCursorId(Map<String, dynamic> evt) {
@ -547,8 +563,8 @@ class CursorModel with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
void updateDisplayOriginWithCursor( void updateDisplayOriginWithCursor(double x, double y, double xCursor,
double x, double y, double xCursor, double yCursor) { double yCursor) {
_displayOriginX = x; _displayOriginX = x;
_displayOriginY = y; _displayOriginY = y;
_x = xCursor; _x = xCursor;
@ -655,6 +671,26 @@ class ServerModel with ChangeNotifier {
} }
} }
enum MouseButtons {
left,
right,
wheel
}
extension ToString on MouseButtons{
String get value {
switch (this) {
case MouseButtons.left:
return "left";
case MouseButtons.right:
return "right";
case MouseButtons.wheel:
return "wheel";
}
}
}
class FFI { class FFI {
static String id = ""; static String id = "";
static var shift = false; static var shift = false;
@ -671,9 +707,9 @@ class FFI {
return getByName('remote_id'); return getByName('remote_id');
} }
static void tap(bool right) { static void tap(MouseButtons button) {
sendMouse('down', right ? 'right' : 'left'); sendMouse('down', button);
sendMouse('up', right ? 'right' : 'left'); sendMouse('up', button);
} }
static void scroll(double y) { static void scroll(double y) {
@ -700,10 +736,10 @@ class FFI {
return evt; return evt;
} }
static void sendMouse(String type, String buttons) { static void sendMouse(String type, MouseButtons button) {
if (!ffiModel.keyboard()) return; if (!ffiModel.keyboard()) return;
setByName( setByName(
'send_mouse', json.encode(modify({'type': type, 'buttons': buttons}))); 'send_mouse', json.encode(modify({'type': type, 'buttons': button.value})));
} }
static void inputKey(String name) { static void inputKey(String name) {
@ -725,7 +761,7 @@ class FFI {
return peers return peers
.map((s) => s as List<dynamic>) .map((s) => s as List<dynamic>)
.map((s) => .map((s) =>
Peer.fromJson(s[0] as String, s[1] as Map<String, dynamic>)) Peer.fromJson(s[0] as String, s[1] as Map<String, dynamic>))
.toList(); .toList();
} catch (e) { } catch (e) {
print('peers(): $e'); print('peers(): $e');
@ -761,8 +797,14 @@ class FFI {
static void close() { static void close() {
if (FFI.imageModel.image != null && !isDesktop) { if (FFI.imageModel.image != null && !isDesktop) {
savePreference(id, cursorModel.x, cursorModel.y, canvasModel.x, savePreference(
canvasModel.y, canvasModel.scale, ffiModel.pi.currentDisplay); id,
cursorModel.x,
cursorModel.y,
canvasModel.x,
canvasModel.y,
canvasModel.scale,
ffiModel.pi.currentDisplay);
} }
id = ""; id = "";
setByName('close', ''); setByName('close', '');

View File

@ -1,4 +1,3 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -28,14 +27,9 @@ class _RemotePageState extends State<RemotePage> {
bool _showBar = !isDesktop; bool _showBar = !isDesktop;
double _bottom = 0; double _bottom = 0;
String _value = ''; String _value = '';
double _xOffset = 0;
double _yOffset = 0;
double _yOffset0 = 0;
double _scale = 1; double _scale = 1;
bool _mouseTools = false; bool _mouseTools = false;
var _drag = false;
var _right = false;
var _scroll = false;
var _more = true; var _more = true;
var _fn = false; var _fn = false;
final FocusNode _focusNode = FocusNode(); final FocusNode _focusNode = FocusNode();
@ -72,7 +66,6 @@ class _RemotePageState extends State<RemotePage> {
} }
void resetTool() { void resetTool() {
_scroll = _drag = _right = false;
FFI.resetModifiers(); FFI.resetModifiers();
} }
@ -227,9 +220,6 @@ class _RemotePageState extends State<RemotePage> {
} }
void resetMouse() { void resetMouse() {
_drag = false;
_scroll = false;
_right = false;
_mouseTools = false; _mouseTools = false;
} }
@ -322,7 +312,6 @@ class _RemotePageState extends State<RemotePage> {
setState(() { setState(() {
_mouseTools = !_mouseTools; _mouseTools = !_mouseTools;
resetTool(); resetTool();
if (_mouseTools) _drag = true;
}); });
}, },
)) ))
@ -348,112 +337,97 @@ class _RemotePageState extends State<RemotePage> {
); );
} }
/// touchMode only:
/// LongPress -> right click
/// OneFingerPan -> start/end -> left down start/end
/// onDoubleTapDown -> move to
/// onLongPressDown => move to
///
/// mouseMode only:
/// DoubleFiner -> right click
/// HoldDrag -> left drag
Widget getBodyForMobileWithGesture() { Widget getBodyForMobileWithGesture() {
return getMixinGestureDetector( return getMixinGestureDetector(
child: getBodyForMobile(), child: getBodyForMobile(),
onTapUp: (d) { onTapUp: (d) {
if (_drag || _scroll) return;
if (_touchMode) { if (_touchMode) {
FFI.cursorModel FFI.cursorModel.touch(
.touch(d.localPosition.dx, d.localPosition.dy, _right); d.localPosition.dx, d.localPosition.dy, MouseButtons.left);
} else { } else {
FFI.tap(_right); FFI.tap(MouseButtons.left);
}
},
onDoubleTapDown: (d){
if(_touchMode){
FFI.cursorModel.move(d.localPosition.dx, d.localPosition.dy);
} }
}, },
onDoubleTap: () { onDoubleTap: () {
if (_drag || _scroll) return; FFI.tap(MouseButtons.left);
FFI.tap(_right); FFI.tap(MouseButtons.left);
FFI.tap(_right); },
onLongPressDown: (d){
if (_touchMode){
FFI.cursorModel.move(d.localPosition.dx, d.localPosition.dy);
}
},
onLongPress: () {
if (_touchMode) {
FFI.tap(MouseButtons.right);
}
}, },
onDoubleFinerTap: (d) { onDoubleFinerTap: (d) {
if (_drag || _scroll) return; if (!_touchMode) {
FFI.tap(true); FFI.tap(MouseButtons.right);
}
}, },
onHoldDragStart: (d) { onHoldDragStart: (d) {
FFI.sendMouse('down', 'left'); if (!_touchMode) {
FFI.sendMouse('down', MouseButtons.left);
}
}, },
onHoldDragUpdate: (d) { onHoldDragUpdate: (d) {
FFI.cursorModel.updatePan(d.delta.dx, d.delta.dy, _touchMode, _drag); if (!_touchMode) {
FFI.cursorModel.updatePan(d.delta.dx, d.delta.dy, _touchMode);
}
}, },
onHoldDragCancel: () { onHoldDragCancel: () {
FFI.sendMouse('up', 'left'); if (!_touchMode) {
FFI.sendMouse('up', MouseButtons.left);
}
}, },
onOneFingerPanStart: (d) { onOneFingerPanStart: (d) {
FFI.sendMouse('up', 'left'); if (_touchMode) {
debugPrint("_touchMode , onOneFingerPanStart");
FFI.cursorModel.move(d.localPosition.dx, d.localPosition.dy);
FFI.sendMouse('down', MouseButtons.left);
} else {
FFI.sendMouse('up', MouseButtons.left);
}
}, },
onOneFingerPanUpdate: (d) { onOneFingerPanUpdate: (d) {
FFI.cursorModel.updatePan(d.delta.dx, d.delta.dy, _touchMode, _drag); FFI.cursorModel.updatePan(d.delta.dx, d.delta.dy, _touchMode);
},
onOneFingerPanEnd: (d) {
if (_touchMode) {
FFI.sendMouse('up', MouseButtons.left);
}
}, },
onTwoFingerScaleUpdate: (d) { onTwoFingerScaleUpdate: (d) {
FFI.canvasModel.updateScale(d.scale/_scale); FFI.canvasModel.updateScale(d.scale / _scale);
_scale = d.scale; _scale = d.scale;
FFI.canvasModel.panX(d.focalPointDelta.dx);
FFI.canvasModel.panY(d.focalPointDelta.dy);
}, },
onTwoFingerScaleEnd: (d)=>_scale = 1, onTwoFingerScaleEnd: (d) => _scale = 1,
onTwoFingerVerticalDragUpdate: (d) { onTwoFingerVerticalDragUpdate: (d) {
FFI.scroll(d.delta.dy / 2); FFI.scroll(d.delta.dy / 2);
},
onTwoFingerPanUpdate: (d) {
FFI.canvasModel.panX(d.delta.dx);
FFI.canvasModel.panY(d.delta.dy);
}); });
return GestureDetector(
onLongPress: () {
if (_drag || _scroll) return;
// make right click and real left long click both work
// should add "long press = right click" option?
FFI.sendMouse('down', 'left');
FFI.tap(true);
},
onLongPressUp: () {
FFI.sendMouse('up', 'left');
},
onTapUp: (details) {
if (_drag || _scroll) return;
if (_touchMode) {
FFI.cursorModel.touch(
details.localPosition.dx, details.localPosition.dy, _right);
} else {
FFI.tap(_right);
}
},
onScaleStart: (details) {
_scale = 1;
_xOffset = details.focalPoint.dx;
_yOffset = _yOffset0 = details.focalPoint.dy;
if (_drag) {
FFI.sendMouse('down', 'left');
}
},
onScaleUpdate: (details) {
var scale = details.scale;
if (scale == 1) {
if (!_scroll) {
var x = details.focalPoint.dx;
var y = details.focalPoint.dy;
var dx = x - _xOffset;
var dy = y - _yOffset;
FFI.cursorModel.updatePan(dx, dy, _touchMode, _drag);
_xOffset = x;
_yOffset = y;
} else {
_xOffset = details.focalPoint.dx;
_yOffset = details.focalPoint.dy;
}
} else if (!_drag && !_scroll) {
FFI.canvasModel.updateScale(scale / _scale);
_scale = scale;
}
},
onScaleEnd: (details) {
if (_drag) {
FFI.sendMouse('up', 'left');
setState(resetMouse);
} else if (_scroll) {
var dy = (_yOffset - _yOffset0) / 10;
if (dy.abs() > 0.1) {
if (dy > 0 && dy < 1) dy = 1;
if (dy < 0 && dy > -1) dy = -1;
FFI.scroll(dy);
}
}
},
child: getBodyForMobile());
} }
Widget getBodyForMobile() { Widget getBodyForMobile() {
@ -637,35 +611,6 @@ class _RemotePageState extends State<RemotePage> {
style: TextStyle(color: Colors.white, fontSize: 11)), style: TextStyle(color: Colors.white, fontSize: 11)),
onPressed: onPressed); onPressed: onPressed);
}; };
final mouse = <Widget>[
wrap('Drag', () {
setState(() {
_drag = !_drag;
if (_drag) {
_scroll = false;
_right = false;
}
});
}, _drag),
wrap('Scroll', () {
setState(() {
_scroll = !_scroll;
if (_scroll) {
_drag = false;
_right = false;
}
});
}, _scroll),
wrap('Right', () {
setState(() {
_right = !_right;
if (_right) {
_scroll = false;
_drag = false;
}
});
}, _right)
];
final pi = FFI.ffiModel.pi; final pi = FFI.ffiModel.pi;
final isMac = pi.platform == "Mac OS"; final isMac = pi.platform == "Mac OS";
final modifiers = <Widget>[ final modifiers = <Widget>[
@ -772,7 +717,7 @@ class _RemotePageState extends State<RemotePage> {
children: <Widget>[SizedBox(width: 9999)] + children: <Widget>[SizedBox(width: 9999)] +
(keyboard (keyboard
? modifiers + keys + (_fn ? fn : []) + (_more ? more : []) ? modifiers + keys + (_fn ? fn : []) + (_more ? more : [])
: mouse + modifiers), : modifiers),
)); ));
} }
} }
@ -987,14 +932,14 @@ void showOptions(BuildContext context) {
} }
} }
var setQuality = (String? value) { var setQuality = (String? value) {
if(value == null) return; if (value == null) return;
setState(() { setState(() {
quality = value; quality = value;
FFI.setByName('image_quality', value); FFI.setByName('image_quality', value);
}); });
}; };
var setViewStyle = (String? value) { var setViewStyle = (String? value) {
if(value == null) return; if (value == null) return;
setState(() { setState(() {
viewStyle = value; viewStyle = value;
FFI.setByName( FFI.setByName(
@ -1050,7 +995,7 @@ void showSetOSPassword(BuildContext context, bool login) {
), ),
value: autoLogin, value: autoLogin,
onChanged: (v) { onChanged: (v) {
if(v==null) return; if (v == null) return;
setState(() => autoLogin = v); setState(() => autoLogin = v);
}, },
), ),