Files
PiliPlus/lib/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart
2026-05-15 11:09:42 +08:00

81 lines
2.1 KiB
Dart

import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:flutter/foundation.dart' show PlatformDispatcher;
import 'package:flutter/gestures.dart';
mixin InitialPositionMixin on GestureRecognizer {
Offset? _initialPosition;
Offset? get initialPosition => _initialPosition;
@override
void addAllowedPointer(PointerDownEvent event) {
super.addAllowedPointer(event);
_initialPosition = event.position;
}
}
class CustomHorizontalDragGestureRecognizer
extends HorizontalDragGestureRecognizer
with InitialPositionMixin {
CustomHorizontalDragGestureRecognizer({
super.debugOwner,
super.supportedDevices,
super.allowedButtonsFilter,
});
@override
DeviceGestureSettings get gestureSettings => _gestureSettings;
final _gestureSettings = DeviceGestureSettings(touchSlop: touchSlopH);
@override
bool hasSufficientGlobalDistanceToAccept(
PointerDeviceKind pointerDeviceKind,
double? deviceTouchSlop,
) {
return _computeHitSlop(
globalDistanceMoved.abs(),
gestureSettings,
pointerDeviceKind,
_initialPosition,
lastPosition.global,
);
}
}
double touchSlopH = Pref.touchSlopH;
bool _computeHitSlop(
double globalDistanceMoved,
DeviceGestureSettings settings,
PointerDeviceKind kind,
Offset? initialPosition,
Offset lastPosition,
) {
switch (kind) {
case .mouse:
return globalDistanceMoved > kPrecisePointerHitSlop;
case .stylus:
case .invertedStylus:
case .unknown:
case .touch:
return globalDistanceMoved > settings.touchSlop! &&
_calcAngle(initialPosition!, lastPosition);
case .trackpad:
return globalDistanceMoved > settings.touchSlop!;
}
}
bool _calcAngle(Offset initialPosition, Offset lastPosition) {
final offset = lastPosition - initialPosition;
return offset.dx.abs() > offset.dy.abs() * 3;
}
final deviceTouchSlop = _calcDeviceTouchSlop();
double _calcDeviceTouchSlop() {
final view = PlatformDispatcher.instance.views.first;
final physicalTouchSlop = view.gestureSettings.physicalTouchSlop;
return physicalTouchSlop == null
? kTouchSlop
: physicalTouchSlop / view.devicePixelRatio;
}