Pass on original pointer event timestamps to drag events (#11988)
* Record original pointer event timestamp * review * review * review
This commit is contained in:
parent
8566777dee
commit
2447f91844
@ -52,9 +52,15 @@ class DragStartDetails {
|
||||
/// Creates details for a [GestureDragStartCallback].
|
||||
///
|
||||
/// The [globalPosition] argument must not be null.
|
||||
DragStartDetails({ this.globalPosition: Offset.zero })
|
||||
DragStartDetails({ this.sourceTimeStamp, this.globalPosition: Offset.zero })
|
||||
: assert(globalPosition != null);
|
||||
|
||||
/// Recorded timestamp of the source pointer event that triggered the drag
|
||||
/// event.
|
||||
///
|
||||
/// Could be null if triggered from proxied events such as accessibility.
|
||||
final Duration sourceTimeStamp;
|
||||
|
||||
/// The global position at which the pointer contacted the screen.
|
||||
///
|
||||
/// Defaults to the origin if not specified in the constructor.
|
||||
@ -94,6 +100,7 @@ class DragUpdateDetails {
|
||||
///
|
||||
/// The [globalPosition] argument must be provided and must not be null.
|
||||
DragUpdateDetails({
|
||||
this.sourceTimeStamp,
|
||||
this.delta: Offset.zero,
|
||||
this.primaryDelta,
|
||||
@required this.globalPosition
|
||||
@ -102,6 +109,12 @@ class DragUpdateDetails {
|
||||
|| (primaryDelta == delta.dx && delta.dy == 0.0)
|
||||
|| (primaryDelta == delta.dy && delta.dx == 0.0));
|
||||
|
||||
/// Recorded timestamp of the source pointer event that triggered the drag
|
||||
/// event.
|
||||
///
|
||||
/// Could be null if triggered from proxied events such as accessibility.
|
||||
final Duration sourceTimeStamp;
|
||||
|
||||
/// The amount the pointer has moved since the previous update.
|
||||
///
|
||||
/// If the [GestureDragUpdateCallback] is for a one-dimensional drag (e.g.,
|
||||
|
@ -101,6 +101,7 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
|
||||
_DragState _state = _DragState.ready;
|
||||
Offset _initialPosition;
|
||||
Offset _pendingDragOffset;
|
||||
Duration _lastPendingEventTimestamp;
|
||||
|
||||
bool _isFlingGesture(VelocityEstimate estimate);
|
||||
Offset _getDeltaForDetails(Offset delta);
|
||||
@ -117,6 +118,7 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
|
||||
_state = _DragState.possible;
|
||||
_initialPosition = event.position;
|
||||
_pendingDragOffset = Offset.zero;
|
||||
_lastPendingEventTimestamp = event.timeStamp;
|
||||
if (onDown != null)
|
||||
invokeCallback<Null>('onDown', () => onDown(new DragDownDetails(globalPosition: _initialPosition))); // ignore: STRONG_MODE_INVALID_CAST_FUNCTION_EXPR, https://github.com/dart-lang/sdk/issues/27504
|
||||
} else if (_state == _DragState.accepted) {
|
||||
@ -139,6 +141,7 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
|
||||
if (_state == _DragState.accepted) {
|
||||
if (onUpdate != null) {
|
||||
invokeCallback<Null>('onUpdate', () => onUpdate(new DragUpdateDetails( // ignore: STRONG_MODE_INVALID_CAST_FUNCTION_EXPR, https://github.com/dart-lang/sdk/issues/27504
|
||||
sourceTimeStamp: event.timeStamp,
|
||||
delta: _getDeltaForDetails(delta),
|
||||
primaryDelta: _getPrimaryValueFromOffset(delta),
|
||||
globalPosition: event.position,
|
||||
@ -146,6 +149,7 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
|
||||
}
|
||||
} else {
|
||||
_pendingDragOffset += delta;
|
||||
_lastPendingEventTimestamp = event.timeStamp;
|
||||
if (_hasSufficientPendingDragDeltaToAccept)
|
||||
resolve(GestureDisposition.accepted);
|
||||
}
|
||||
@ -158,14 +162,18 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
|
||||
if (_state != _DragState.accepted) {
|
||||
_state = _DragState.accepted;
|
||||
final Offset delta = _pendingDragOffset;
|
||||
final Duration timestamp = _lastPendingEventTimestamp;
|
||||
_pendingDragOffset = Offset.zero;
|
||||
_lastPendingEventTimestamp = null;
|
||||
if (onStart != null) {
|
||||
invokeCallback<Null>('onStart', () => onStart(new DragStartDetails( // ignore: STRONG_MODE_INVALID_CAST_FUNCTION_EXPR, https://github.com/dart-lang/sdk/issues/27504
|
||||
sourceTimeStamp: timestamp,
|
||||
globalPosition: _initialPosition,
|
||||
)));
|
||||
}
|
||||
if (delta != Offset.zero && onUpdate != null) {
|
||||
invokeCallback<Null>('onUpdate', () => onUpdate(new DragUpdateDetails( // ignore: STRONG_MODE_INVALID_CAST_FUNCTION_EXPR, https://github.com/dart-lang/sdk/issues/27504
|
||||
sourceTimeStamp: timestamp,
|
||||
delta: _getDeltaForDetails(delta),
|
||||
primaryDelta: _getPrimaryValueFromOffset(delta),
|
||||
globalPosition: _initialPosition,
|
||||
|
@ -45,6 +45,8 @@ abstract class MultiDragPointerState {
|
||||
Offset get pendingDelta => _pendingDelta;
|
||||
Offset _pendingDelta = Offset.zero;
|
||||
|
||||
Duration _lastPendingEventTimestamp;
|
||||
|
||||
GestureArenaEntry _arenaEntry;
|
||||
void _setArenaEntry(GestureArenaEntry entry) {
|
||||
assert(_arenaEntry == null);
|
||||
@ -68,12 +70,14 @@ abstract class MultiDragPointerState {
|
||||
assert(pendingDelta == null);
|
||||
// Call client last to avoid reentrancy.
|
||||
_client.update(new DragUpdateDetails(
|
||||
sourceTimeStamp: event.timeStamp,
|
||||
delta: event.delta,
|
||||
globalPosition: event.position,
|
||||
));
|
||||
} else {
|
||||
assert(pendingDelta != null);
|
||||
_pendingDelta += event.delta;
|
||||
_lastPendingEventTimestamp = event.timeStamp;
|
||||
checkForResolutionAfterMove();
|
||||
}
|
||||
}
|
||||
@ -101,6 +105,7 @@ abstract class MultiDragPointerState {
|
||||
assert(_client == null);
|
||||
assert(pendingDelta != null);
|
||||
_pendingDelta = null;
|
||||
_lastPendingEventTimestamp = null;
|
||||
_arenaEntry = null;
|
||||
}
|
||||
|
||||
@ -111,10 +116,12 @@ abstract class MultiDragPointerState {
|
||||
assert(pendingDelta != null);
|
||||
_client = client;
|
||||
final DragUpdateDetails details = new DragUpdateDetails(
|
||||
sourceTimeStamp: _lastPendingEventTimestamp,
|
||||
delta: pendingDelta,
|
||||
globalPosition: initialPosition,
|
||||
);
|
||||
_pendingDelta = null;
|
||||
_lastPendingEventTimestamp = null;
|
||||
// Call client last to avoid reentrancy.
|
||||
_client.update(details);
|
||||
}
|
||||
@ -131,6 +138,7 @@ abstract class MultiDragPointerState {
|
||||
} else {
|
||||
assert(pendingDelta != null);
|
||||
_pendingDelta = null;
|
||||
_lastPendingEventTimestamp = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,6 +153,7 @@ abstract class MultiDragPointerState {
|
||||
} else {
|
||||
assert(pendingDelta != null);
|
||||
_pendingDelta = null;
|
||||
_lastPendingEventTimestamp = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,6 +133,37 @@ void main() {
|
||||
drag.dispose();
|
||||
});
|
||||
|
||||
testGesture('Should report original timestamps', (GestureTester tester) {
|
||||
final HorizontalDragGestureRecognizer drag = new HorizontalDragGestureRecognizer();
|
||||
|
||||
Duration startTimestamp;
|
||||
drag.onStart = (DragStartDetails details) {
|
||||
startTimestamp = details.sourceTimeStamp;
|
||||
};
|
||||
|
||||
Duration updatedTimestamp;
|
||||
drag.onUpdate = (DragUpdateDetails details) {
|
||||
updatedTimestamp = details.sourceTimeStamp;
|
||||
};
|
||||
|
||||
final TestPointer pointer = new TestPointer(5);
|
||||
final PointerDownEvent down = pointer.down(const Offset(10.0, 10.0), timeStamp: const Duration(milliseconds: 100));
|
||||
drag.addPointer(down);
|
||||
tester.closeArena(5);
|
||||
expect(startTimestamp, isNull);
|
||||
|
||||
tester.route(down);
|
||||
expect(startTimestamp, const Duration(milliseconds: 100));
|
||||
|
||||
tester.route(pointer.move(const Offset(20.0, 25.0), timeStamp: const Duration(milliseconds: 200)));
|
||||
expect(updatedTimestamp, const Duration(milliseconds: 200));
|
||||
|
||||
tester.route(pointer.move(const Offset(20.0, 25.0), timeStamp: const Duration(milliseconds: 300)));
|
||||
expect(updatedTimestamp, const Duration(milliseconds: 300));
|
||||
|
||||
drag.dispose();
|
||||
});
|
||||
|
||||
testGesture('Drag with multiple pointers', (GestureTester tester) {
|
||||
final HorizontalDragGestureRecognizer drag1 = new HorizontalDragGestureRecognizer();
|
||||
final VerticalDragGestureRecognizer drag2 = new VerticalDragGestureRecognizer();
|
||||
|
Loading…
x
Reference in New Issue
Block a user