Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 48457d7

Browse files
authored
WidgetController.startGesture trackpad support (#114631)
1 parent e1166e4 commit 48457d7

File tree

3 files changed

+72
-10
lines changed

3 files changed

+72
-10
lines changed

packages/flutter_test/lib/src/controller.dart

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,12 +1086,14 @@ abstract class WidgetController {
10861086
);
10871087
}
10881088

1089-
/// Creates a gesture with an initial down gesture at a particular point, and
1090-
/// returns the [TestGesture] object which you can use to continue the
1091-
/// gesture.
1089+
/// Creates a gesture with an initial appropriate starting gesture at a
1090+
/// particular point, and returns the [TestGesture] object which you can use
1091+
/// to continue the gesture. Usually, the starting gesture will be a down event,
1092+
/// but if [kind] is set to [PointerDeviceKind.trackpad], the gesture will start
1093+
/// with a panZoomStart gesture.
10921094
///
10931095
/// You can use [createGesture] if your gesture doesn't begin with an initial
1094-
/// down gesture.
1096+
/// down or panZoomStart gesture.
10951097
///
10961098
/// See also:
10971099
/// * [WidgetController.drag], a method to simulate a drag.
@@ -1110,7 +1112,11 @@ abstract class WidgetController {
11101112
kind: kind,
11111113
buttons: buttons,
11121114
);
1113-
await result.down(downLocation);
1115+
if (kind == PointerDeviceKind.trackpad) {
1116+
await result.panZoomStart(downLocation);
1117+
} else {
1118+
await result.down(downLocation);
1119+
}
11141120
return result;
11151121
}
11161122

packages/flutter_test/lib/src/test_pointer.dart

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ class TestGesture {
455455
/// Dispatch a pointer down event at the given `downLocation`, caching the
456456
/// hit test result.
457457
Future<void> down(Offset downLocation, { Duration timeStamp = Duration.zero }) async {
458+
assert(_pointer.kind != PointerDeviceKind.trackpad, 'Trackpads are expected to send panZoomStart events, not down events.');
458459
return TestAsyncUtils.guard<void>(() async {
459460
return _dispatcher(_pointer.down(downLocation, timeStamp: timeStamp));
460461
});
@@ -463,6 +464,7 @@ class TestGesture {
463464
/// Dispatch a pointer down event at the given `downLocation`, caching the
464465
/// hit test result with a custom down event.
465466
Future<void> downWithCustomEvent(Offset downLocation, PointerDownEvent event) async {
467+
assert(_pointer.kind != PointerDeviceKind.trackpad, 'Trackpads are expected to send panZoomStart events, not down events');
466468
_pointer.setDownInfo(event, downLocation);
467469
return TestAsyncUtils.guard<void>(() async {
468470
return _dispatcher(event);
@@ -507,7 +509,15 @@ class TestGesture {
507509
/// * [WidgetController.fling], a method to simulate a fling.
508510
Future<void> moveBy(Offset offset, { Duration timeStamp = Duration.zero }) {
509511
assert(_pointer.location != null);
510-
return moveTo(_pointer.location! + offset, timeStamp: timeStamp);
512+
if (_pointer.isPanZoomActive) {
513+
return panZoomUpdate(
514+
_pointer.location!,
515+
pan: (_pointer.pan ?? Offset.zero) + offset,
516+
timeStamp: timeStamp
517+
);
518+
} else {
519+
return moveTo(_pointer.location! + offset, timeStamp: timeStamp);
520+
}
511521
}
512522

513523
/// Send a move event moving the pointer to the given location.
@@ -521,6 +531,7 @@ class TestGesture {
521531
/// It sends move events at a given frequency and it is useful when there are listeners involved.
522532
/// * [WidgetController.fling], a method to simulate a fling.
523533
Future<void> moveTo(Offset location, { Duration timeStamp = Duration.zero }) {
534+
assert(_pointer.kind != PointerDeviceKind.trackpad);
524535
return TestAsyncUtils.guard<void>(() {
525536
if (_pointer._isDown) {
526537
return _dispatcher(_pointer.move(location, timeStamp: timeStamp));
@@ -530,19 +541,27 @@ class TestGesture {
530541
});
531542
}
532543

533-
/// End the gesture by releasing the pointer.
544+
/// End the gesture by releasing the pointer. For trackpad pointers this
545+
/// will send a panZoomEnd event instead of an up event.
534546
Future<void> up({ Duration timeStamp = Duration.zero }) {
535547
return TestAsyncUtils.guard<void>(() async {
536-
assert(_pointer._isDown);
537-
await _dispatcher(_pointer.up(timeStamp: timeStamp));
538-
assert(!_pointer._isDown);
548+
if (_pointer.kind == PointerDeviceKind.trackpad) {
549+
assert(_pointer._isPanZoomActive);
550+
await _dispatcher(_pointer.panZoomEnd(timeStamp: timeStamp));
551+
assert(!_pointer._isPanZoomActive);
552+
} else {
553+
assert(_pointer._isDown);
554+
await _dispatcher(_pointer.up(timeStamp: timeStamp));
555+
assert(!_pointer._isDown);
556+
}
539557
});
540558
}
541559

542560
/// End the gesture by canceling the pointer (as would happen if the
543561
/// system showed a modal dialog on top of the Flutter application,
544562
/// for instance).
545563
Future<void> cancel({ Duration timeStamp = Duration.zero }) {
564+
assert(_pointer.kind != PointerDeviceKind.trackpad, 'Trackpads do not send cancel events.');
546565
return TestAsyncUtils.guard<void>(() async {
547566
assert(_pointer._isDown);
548567
await _dispatcher(_pointer.cancel(timeStamp: timeStamp));
@@ -553,6 +572,7 @@ class TestGesture {
553572
/// Dispatch a pointer pan zoom start event at the given `location`, caching the
554573
/// hit test result.
555574
Future<void> panZoomStart(Offset location, { Duration timeStamp = Duration.zero }) async {
575+
assert(_pointer.kind == PointerDeviceKind.trackpad, 'Only trackpads can send PointerPanZoom events.');
556576
return TestAsyncUtils.guard<void>(() async {
557577
return _dispatcher(_pointer.panZoomStart(location, timeStamp: timeStamp));
558578
});
@@ -566,6 +586,7 @@ class TestGesture {
566586
double rotation = 0,
567587
Duration timeStamp = Duration.zero
568588
}) async {
589+
assert(_pointer.kind == PointerDeviceKind.trackpad, 'Only trackpads can send PointerPanZoom events.');
569590
return TestAsyncUtils.guard<void>(() async {
570591
return _dispatcher(_pointer.panZoomUpdate(location,
571592
pan: pan,
@@ -580,6 +601,7 @@ class TestGesture {
580601
Future<void> panZoomEnd({
581602
Duration timeStamp = Duration.zero
582603
}) async {
604+
assert(_pointer.kind == PointerDeviceKind.trackpad, 'Only trackpads can send PointerPanZoom events.');
583605
return TestAsyncUtils.guard<void>(() async {
584606
return _dispatcher(_pointer.panZoomEnd(
585607
timeStamp: timeStamp

packages/flutter_test/test/controller_test.dart

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,40 @@ void main() {
385385
},
386386
);
387387

388+
testWidgets(
389+
'WidgetTester.drag works with trackpad kind',
390+
(WidgetTester tester) async {
391+
final List<String> logs = <String>[];
392+
393+
await tester.pumpWidget(
394+
Directionality(
395+
textDirection: TextDirection.ltr,
396+
child: Listener(
397+
onPointerDown: (PointerDownEvent event) => logs.add('down ${event.buttons}'),
398+
onPointerMove: (PointerMoveEvent event) => logs.add('move ${event.buttons}'),
399+
onPointerUp: (PointerUpEvent event) => logs.add('up ${event.buttons}'),
400+
onPointerPanZoomStart: (PointerPanZoomStartEvent event) => logs.add('panZoomStart'),
401+
onPointerPanZoomUpdate: (PointerPanZoomUpdateEvent event) => logs.add('panZoomUpdate ${event.pan}'),
402+
onPointerPanZoomEnd: (PointerPanZoomEndEvent event) => logs.add('panZoomEnd'),
403+
child: const Text('test'),
404+
),
405+
),
406+
);
407+
408+
await tester.drag(find.text('test'), const Offset(-150.0, 200.0), kind: PointerDeviceKind.trackpad);
409+
410+
for(int i = 0; i < logs.length; i++) {
411+
if (i == 0) {
412+
expect(logs[i], 'panZoomStart');
413+
} else if (i != logs.length - 1) {
414+
expect(logs[i], startsWith('panZoomUpdate'));
415+
} else {
416+
expect(logs[i], 'panZoomEnd');
417+
}
418+
}
419+
},
420+
);
421+
388422
testWidgets(
389423
'WidgetTester.fling must respect buttons',
390424
(WidgetTester tester) async {

0 commit comments

Comments
 (0)