Commit 2447f918 authored by xster's avatar xster Committed by GitHub

Pass on original pointer event timestamps to drag events (#11988)

* Record original pointer event timestamp

* review

* review

* review
parent 8566777d
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment