add three fingers vertical drag -> scroll

This commit is contained in:
csf 2022-05-12 17:30:39 +08:00
parent 1e20041057
commit 3a66d52c2d
2 changed files with 57 additions and 116 deletions

View File

@ -541,7 +541,7 @@ class _RemotePageState extends State<RemotePage> {
_scale = 1; _scale = 1;
FFI.setByName('peer_option', '{"name": "view-style", "value": ""}'); FFI.setByName('peer_option', '{"name": "view-style", "value": ""}');
}, },
onTwoFingerVerticalDragUpdate: FFI.ffiModel.isPeerAndroid onThreeFingerVerticalDragUpdate: FFI.ffiModel.isPeerAndroid
? null ? null
: (d) { : (d) {
FFI.scroll(d.delta.dy / 2); FFI.scroll(d.delta.dy / 2);

View File

@ -6,13 +6,9 @@ enum CustomTouchGestureState {
none, none,
oneFingerPan, oneFingerPan,
twoFingerScale, twoFingerScale,
twoFingerVerticalDrag, threeFingerVerticalDrag
twoFingerHorizontalDrag,
} }
// Adjust Carefully! balance vertical and pan
const kScaleSlop = kPrecisePointerPanSlop / 28;
class CustomTouchGestureRecognizer extends ScaleGestureRecognizer { class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
CustomTouchGestureRecognizer({ CustomTouchGestureRecognizer({
Object? debugOwner, Object? debugOwner,
@ -34,39 +30,56 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
GestureScaleUpdateCallback? onTwoFingerScaleUpdate; GestureScaleUpdateCallback? onTwoFingerScaleUpdate;
GestureScaleEndCallback? onTwoFingerScaleEnd; GestureScaleEndCallback? onTwoFingerScaleEnd;
// twoFingerVerticalDrag // threeFingerVerticalDrag
GestureDragStartCallback? onTwoFingerVerticalDragStart; GestureDragStartCallback? onThreeFingerVerticalDragStart;
GestureDragUpdateCallback? onTwoFingerVerticalDragUpdate; GestureDragUpdateCallback? onThreeFingerVerticalDragUpdate;
GestureDragEndCallback? onTwoFingerVerticalDragEnd; GestureDragEndCallback? onThreeFingerVerticalDragEnd;
// twoFingerHorizontalDrag var _currentState = CustomTouchGestureState.none;
GestureDragStartCallback? onTwoFingerHorizontalDragStart; Timer? _startEventDebounceTimer;
GestureDragUpdateCallback? onTwoFingerHorizontalDragUpdate;
GestureDragEndCallback? onTwoFingerHorizontalDragEnd;
void _init() { void _init() {
debugPrint("CustomTouchGestureRecognizer init"); debugPrint("CustomTouchGestureRecognizer init");
onStart = (d) { onStart = (d) {
_startEventDebounceTimer?.cancel();
if (d.pointerCount == 1) { if (d.pointerCount == 1) {
_currentState = CustomTouchGestureState.oneFingerPan; _currentState = CustomTouchGestureState.oneFingerPan;
if (onOneFingerPanStart != null) { if (onOneFingerPanStart != null) {
onOneFingerPanStart!(DragStartDetails( onOneFingerPanStart!(DragStartDetails(
localPosition: d.localFocalPoint, globalPosition: d.focalPoint)); localPosition: d.localFocalPoint, globalPosition: d.focalPoint));
} }
debugPrint("start pan"); debugPrint("start oneFingerPan");
} else if (d.pointerCount == 2) { } else if (d.pointerCount == 2) {
_currentState = CustomTouchGestureState.none; if (_currentState == CustomTouchGestureState.threeFingerVerticalDrag) {
startWatchTimer(); // 3 -> 2 debounce
} else { _startEventDebounceTimer = Timer(Duration(milliseconds: 200), () {
_currentState = CustomTouchGestureState.none; _currentState = CustomTouchGestureState.twoFingerScale;
_reset(); if (onTwoFingerScaleStart != null) {
onTwoFingerScaleStart!(ScaleStartDetails(
localFocalPoint: d.localFocalPoint,
focalPoint: d.focalPoint));
}
debugPrint("debounce start twoFingerScale success");
});
}
_currentState = CustomTouchGestureState.twoFingerScale;
// startWatchTimer();
if (onTwoFingerScaleStart != null) {
onTwoFingerScaleStart!(ScaleStartDetails(
localFocalPoint: d.localFocalPoint, focalPoint: d.focalPoint));
}
debugPrint("start twoFingerScale");
} else if (d.pointerCount == 3) {
_currentState = CustomTouchGestureState.threeFingerVerticalDrag;
if (onThreeFingerVerticalDragStart != null) {
onThreeFingerVerticalDragStart!(
DragStartDetails(globalPosition: d.localFocalPoint));
}
debugPrint("start threeFingerScale");
// _reset();
} }
}; };
onUpdate = (d) { onUpdate = (d) {
if (_isWatch) {
_updateCompute(d);
return;
}
if (_currentState != CustomTouchGestureState.none) { if (_currentState != CustomTouchGestureState.none) {
switch (_currentState) { switch (_currentState) {
case CustomTouchGestureState.oneFingerPan: case CustomTouchGestureState.oneFingerPan:
@ -79,14 +92,9 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
onTwoFingerScaleUpdate!(d); onTwoFingerScaleUpdate!(d);
} }
break; break;
case CustomTouchGestureState.twoFingerHorizontalDrag: case CustomTouchGestureState.threeFingerVerticalDrag:
if (onTwoFingerHorizontalDragUpdate != null) { if (onThreeFingerVerticalDragUpdate != null) {
onTwoFingerHorizontalDragUpdate!(_getDragUpdateDetails(d)); onThreeFingerVerticalDragUpdate!(_getDragUpdateDetails(d));
}
break;
case CustomTouchGestureState.twoFingerVerticalDrag:
if (onTwoFingerVerticalDragUpdate != null) {
onTwoFingerVerticalDragUpdate!(_getDragUpdateDetails(d));
} }
break; break;
default: default:
@ -111,85 +119,19 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
onTwoFingerScaleEnd!(d); onTwoFingerScaleEnd!(d);
} }
break; break;
case CustomTouchGestureState.twoFingerHorizontalDrag: case CustomTouchGestureState.threeFingerVerticalDrag:
debugPrint("TwoFingerState.horizontal onEnd"); debugPrint("ThreeFingerState.vertical onEnd");
if (onTwoFingerHorizontalDragEnd != null) { if (onThreeFingerVerticalDragEnd != null) {
onTwoFingerHorizontalDragEnd!(_getDragEndDetails(d)); onThreeFingerVerticalDragEnd!(_getDragEndDetails(d));
}
break;
case CustomTouchGestureState.twoFingerVerticalDrag:
debugPrint("TwoFingerState.vertical onEnd");
if (onTwoFingerVerticalDragEnd != null) {
onTwoFingerVerticalDragEnd!(_getDragEndDetails(d));
} }
break; break;
default: default:
break; break;
} }
_currentState = CustomTouchGestureState.none; _currentState = CustomTouchGestureState.none;
_reset();
}; };
} }
var _currentState = CustomTouchGestureState.none;
var _isWatch = false;
Timer? _timer;
double _sumScale = 0;
double _sumVertical = 0;
double _sumHorizontal = 0;
void _clearSum() {
_sumScale = 0;
_sumVertical = 0;
_sumHorizontal = 0;
}
void _reset() {
_isWatch = false;
_clearSum();
if (_timer != null) _timer!.cancel();
}
void _updateCompute(ScaleUpdateDetails d) {
_sumScale += d.scale - 1;
_sumHorizontal += d.focalPointDelta.dx;
_sumVertical += d.focalPointDelta.dy;
// start , order is important
if (onTwoFingerScaleUpdate != null && _sumScale.abs() > kScaleSlop) {
debugPrint("start Scale");
_currentState = CustomTouchGestureState.twoFingerScale;
if (onTwoFingerScaleStart != null) {
onTwoFingerScaleStart!(ScaleStartDetails(
localFocalPoint: d.localFocalPoint, focalPoint: d.focalPoint));
}
_reset();
} else if (onTwoFingerVerticalDragUpdate != null &&
_sumVertical.abs() > kPrecisePointerPanSlop &&
_sumHorizontal.abs() < kPrecisePointerPanSlop) {
debugPrint("start Vertical");
if (onTwoFingerVerticalDragStart != null) {
onTwoFingerVerticalDragStart!(_getDragStartDetails(d));
}
_currentState = CustomTouchGestureState.twoFingerVerticalDrag;
_reset();
}
}
void startWatchTimer() {
debugPrint("startWatchTimer");
_isWatch = true;
_clearSum();
if (_timer != null) _timer!.cancel();
_timer = Timer(const Duration(milliseconds: 200), _reset);
}
DragStartDetails _getDragStartDetails(ScaleUpdateDetails d) =>
DragStartDetails(
globalPosition: d.focalPoint,
localPosition: d.localFocalPoint,
);
DragUpdateDetails _getDragUpdateDetails(ScaleUpdateDetails d) => DragUpdateDetails _getDragUpdateDetails(ScaleUpdateDetails d) =>
DragUpdateDetails( DragUpdateDetails(
globalPosition: d.focalPoint, globalPosition: d.focalPoint,
@ -344,13 +286,16 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
} }
void _reject(_TapTracker tracker) { void _reject(_TapTracker tracker) {
_checkCancel(); try {
_checkCancel();
_isStart = false; _isStart = false;
_trackers.remove(tracker.pointer); _trackers.remove(tracker.pointer);
tracker.entry.resolve(GestureDisposition.rejected); tracker.entry.resolve(GestureDisposition.rejected);
_freezeTracker(tracker); _freezeTracker(tracker);
_reset(); _reset();
} catch (e) {
debugPrint("Failed to _reject:$e");
}
} }
@override @override
@ -729,10 +674,7 @@ RawGestureDetector getMixinGestureDetector({
GestureDragEndCallback? onOneFingerPanEnd, GestureDragEndCallback? onOneFingerPanEnd,
GestureScaleUpdateCallback? onTwoFingerScaleUpdate, GestureScaleUpdateCallback? onTwoFingerScaleUpdate,
GestureScaleEndCallback? onTwoFingerScaleEnd, GestureScaleEndCallback? onTwoFingerScaleEnd,
GestureDragUpdateCallback? onTwoFingerHorizontalDragUpdate, GestureDragUpdateCallback? onThreeFingerVerticalDragUpdate,
GestureDragUpdateCallback? onTwoFingerVerticalDragUpdate,
GestureDragStartCallback? onTwoFingerPanStart,
GestureDragUpdateCallback? onTwoFingerPanUpdate,
}) { }) {
return RawGestureDetector( return RawGestureDetector(
child: child, child: child,
@ -782,8 +724,7 @@ RawGestureDetector getMixinGestureDetector({
..onOneFingerPanEnd = onOneFingerPanEnd ..onOneFingerPanEnd = onOneFingerPanEnd
..onTwoFingerScaleUpdate = onTwoFingerScaleUpdate ..onTwoFingerScaleUpdate = onTwoFingerScaleUpdate
..onTwoFingerScaleEnd = onTwoFingerScaleEnd ..onTwoFingerScaleEnd = onTwoFingerScaleEnd
..onTwoFingerHorizontalDragUpdate = onTwoFingerHorizontalDragUpdate ..onThreeFingerVerticalDragUpdate = onThreeFingerVerticalDragUpdate;
..onTwoFingerVerticalDragUpdate = onTwoFingerVerticalDragUpdate; }),
})
}); });
} }