Files
Qlyra/lib/frontend/widgets/rightward_drag_recognizer.dart
T
2026-05-28 12:52:15 +07:00

82 lines
2.3 KiB
Dart

import 'package:flutter/gestures.dart';
class RightwardDragRecognizer extends HorizontalDragGestureRecognizer {
RightwardDragRecognizer({super.debugOwner}) {
onlyAcceptDragOnThreshold = true;
}
static const double _kMinAcceptVelocity = 700.0;
static const double _kMinAcceptDistance = 20.0;
final Map<int, Offset> _initialPositions = {};
final Map<int, VelocityTracker> _velocityTrackers = {};
final Map<int, double> _currentDeltaX = {};
@override
void addAllowedPointer(PointerDownEvent event) {
_initialPositions[event.pointer] = event.position;
final tracker = VelocityTracker.withKind(event.kind);
tracker.addPosition(event.timeStamp, event.localPosition);
_velocityTrackers[event.pointer] = tracker;
super.addAllowedPointer(event);
}
@override
void handleEvent(PointerEvent event) {
if (event is PointerMoveEvent) {
_velocityTrackers[event.pointer]
?.addPosition(event.timeStamp, event.localPosition);
final initial = _initialPositions[event.pointer];
if (initial != null) {
final dx = event.position.dx - initial.dx;
_currentDeltaX[event.pointer] = dx;
if (dx < -kTouchSlop) {
stopTrackingPointer(event.pointer);
_cleanup(event.pointer);
return;
}
}
}
super.handleEvent(event);
}
@override
bool hasSufficientGlobalDistanceToAccept(
PointerDeviceKind pointerDeviceKind,
double? deviceTouchSlop,
) {
if (!super.hasSufficientGlobalDistanceToAccept(
pointerDeviceKind, deviceTouchSlop)) {
return false;
}
double maxDx = 0;
for (final dx in _currentDeltaX.values) {
if (dx > maxDx) maxDx = dx;
}
if (maxDx < _kMinAcceptDistance) return false;
for (final tracker in _velocityTrackers.values) {
final vx = tracker.getVelocity().pixelsPerSecond.dx;
if (vx >= _kMinAcceptVelocity) return true;
}
return false;
}
void _cleanup(int pointer) {
_initialPositions.remove(pointer);
_velocityTrackers.remove(pointer);
_currentDeltaX.remove(pointer);
}
@override
void didStopTrackingLastPointer(int pointer) {
_cleanup(pointer);
super.didStopTrackingLastPointer(pointer);
}
@override
void rejectGesture(int pointer) {
_cleanup(pointer);
super.rejectGesture(pointer);
}
}