WidgetController.startGesture trackpad support (#114631)
This commit is contained in:
parent
e1166e43f8
commit
48457d736b
@ -1086,12 +1086,14 @@ abstract class WidgetController {
|
||||
);
|
||||
}
|
||||
|
||||
/// Creates a gesture with an initial down gesture at a particular point, and
|
||||
/// returns the [TestGesture] object which you can use to continue the
|
||||
/// gesture.
|
||||
/// Creates a gesture with an initial appropriate starting gesture at a
|
||||
/// particular point, and returns the [TestGesture] object which you can use
|
||||
/// to continue the gesture. Usually, the starting gesture will be a down event,
|
||||
/// but if [kind] is set to [PointerDeviceKind.trackpad], the gesture will start
|
||||
/// with a panZoomStart gesture.
|
||||
///
|
||||
/// You can use [createGesture] if your gesture doesn't begin with an initial
|
||||
/// down gesture.
|
||||
/// down or panZoomStart gesture.
|
||||
///
|
||||
/// See also:
|
||||
/// * [WidgetController.drag], a method to simulate a drag.
|
||||
@ -1110,7 +1112,11 @@ abstract class WidgetController {
|
||||
kind: kind,
|
||||
buttons: buttons,
|
||||
);
|
||||
await result.down(downLocation);
|
||||
if (kind == PointerDeviceKind.trackpad) {
|
||||
await result.panZoomStart(downLocation);
|
||||
} else {
|
||||
await result.down(downLocation);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -455,6 +455,7 @@ class TestGesture {
|
||||
/// Dispatch a pointer down event at the given `downLocation`, caching the
|
||||
/// hit test result.
|
||||
Future<void> down(Offset downLocation, { Duration timeStamp = Duration.zero }) async {
|
||||
assert(_pointer.kind != PointerDeviceKind.trackpad, 'Trackpads are expected to send panZoomStart events, not down events.');
|
||||
return TestAsyncUtils.guard<void>(() async {
|
||||
return _dispatcher(_pointer.down(downLocation, timeStamp: timeStamp));
|
||||
});
|
||||
@ -463,6 +464,7 @@ class TestGesture {
|
||||
/// Dispatch a pointer down event at the given `downLocation`, caching the
|
||||
/// hit test result with a custom down event.
|
||||
Future<void> downWithCustomEvent(Offset downLocation, PointerDownEvent event) async {
|
||||
assert(_pointer.kind != PointerDeviceKind.trackpad, 'Trackpads are expected to send panZoomStart events, not down events');
|
||||
_pointer.setDownInfo(event, downLocation);
|
||||
return TestAsyncUtils.guard<void>(() async {
|
||||
return _dispatcher(event);
|
||||
@ -507,7 +509,15 @@ class TestGesture {
|
||||
/// * [WidgetController.fling], a method to simulate a fling.
|
||||
Future<void> moveBy(Offset offset, { Duration timeStamp = Duration.zero }) {
|
||||
assert(_pointer.location != null);
|
||||
return moveTo(_pointer.location! + offset, timeStamp: timeStamp);
|
||||
if (_pointer.isPanZoomActive) {
|
||||
return panZoomUpdate(
|
||||
_pointer.location!,
|
||||
pan: (_pointer.pan ?? Offset.zero) + offset,
|
||||
timeStamp: timeStamp
|
||||
);
|
||||
} else {
|
||||
return moveTo(_pointer.location! + offset, timeStamp: timeStamp);
|
||||
}
|
||||
}
|
||||
|
||||
/// Send a move event moving the pointer to the given location.
|
||||
@ -521,6 +531,7 @@ class TestGesture {
|
||||
/// It sends move events at a given frequency and it is useful when there are listeners involved.
|
||||
/// * [WidgetController.fling], a method to simulate a fling.
|
||||
Future<void> moveTo(Offset location, { Duration timeStamp = Duration.zero }) {
|
||||
assert(_pointer.kind != PointerDeviceKind.trackpad);
|
||||
return TestAsyncUtils.guard<void>(() {
|
||||
if (_pointer._isDown) {
|
||||
return _dispatcher(_pointer.move(location, timeStamp: timeStamp));
|
||||
@ -530,12 +541,19 @@ class TestGesture {
|
||||
});
|
||||
}
|
||||
|
||||
/// End the gesture by releasing the pointer.
|
||||
/// End the gesture by releasing the pointer. For trackpad pointers this
|
||||
/// will send a panZoomEnd event instead of an up event.
|
||||
Future<void> up({ Duration timeStamp = Duration.zero }) {
|
||||
return TestAsyncUtils.guard<void>(() async {
|
||||
assert(_pointer._isDown);
|
||||
await _dispatcher(_pointer.up(timeStamp: timeStamp));
|
||||
assert(!_pointer._isDown);
|
||||
if (_pointer.kind == PointerDeviceKind.trackpad) {
|
||||
assert(_pointer._isPanZoomActive);
|
||||
await _dispatcher(_pointer.panZoomEnd(timeStamp: timeStamp));
|
||||
assert(!_pointer._isPanZoomActive);
|
||||
} else {
|
||||
assert(_pointer._isDown);
|
||||
await _dispatcher(_pointer.up(timeStamp: timeStamp));
|
||||
assert(!_pointer._isDown);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -543,6 +561,7 @@ class TestGesture {
|
||||
/// system showed a modal dialog on top of the Flutter application,
|
||||
/// for instance).
|
||||
Future<void> cancel({ Duration timeStamp = Duration.zero }) {
|
||||
assert(_pointer.kind != PointerDeviceKind.trackpad, 'Trackpads do not send cancel events.');
|
||||
return TestAsyncUtils.guard<void>(() async {
|
||||
assert(_pointer._isDown);
|
||||
await _dispatcher(_pointer.cancel(timeStamp: timeStamp));
|
||||
@ -553,6 +572,7 @@ class TestGesture {
|
||||
/// Dispatch a pointer pan zoom start event at the given `location`, caching the
|
||||
/// hit test result.
|
||||
Future<void> panZoomStart(Offset location, { Duration timeStamp = Duration.zero }) async {
|
||||
assert(_pointer.kind == PointerDeviceKind.trackpad, 'Only trackpads can send PointerPanZoom events.');
|
||||
return TestAsyncUtils.guard<void>(() async {
|
||||
return _dispatcher(_pointer.panZoomStart(location, timeStamp: timeStamp));
|
||||
});
|
||||
@ -566,6 +586,7 @@ class TestGesture {
|
||||
double rotation = 0,
|
||||
Duration timeStamp = Duration.zero
|
||||
}) async {
|
||||
assert(_pointer.kind == PointerDeviceKind.trackpad, 'Only trackpads can send PointerPanZoom events.');
|
||||
return TestAsyncUtils.guard<void>(() async {
|
||||
return _dispatcher(_pointer.panZoomUpdate(location,
|
||||
pan: pan,
|
||||
@ -580,6 +601,7 @@ class TestGesture {
|
||||
Future<void> panZoomEnd({
|
||||
Duration timeStamp = Duration.zero
|
||||
}) async {
|
||||
assert(_pointer.kind == PointerDeviceKind.trackpad, 'Only trackpads can send PointerPanZoom events.');
|
||||
return TestAsyncUtils.guard<void>(() async {
|
||||
return _dispatcher(_pointer.panZoomEnd(
|
||||
timeStamp: timeStamp
|
||||
|
@ -385,6 +385,40 @@ void main() {
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'WidgetTester.drag works with trackpad kind',
|
||||
(WidgetTester tester) async {
|
||||
final List<String> logs = <String>[];
|
||||
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Listener(
|
||||
onPointerDown: (PointerDownEvent event) => logs.add('down ${event.buttons}'),
|
||||
onPointerMove: (PointerMoveEvent event) => logs.add('move ${event.buttons}'),
|
||||
onPointerUp: (PointerUpEvent event) => logs.add('up ${event.buttons}'),
|
||||
onPointerPanZoomStart: (PointerPanZoomStartEvent event) => logs.add('panZoomStart'),
|
||||
onPointerPanZoomUpdate: (PointerPanZoomUpdateEvent event) => logs.add('panZoomUpdate ${event.pan}'),
|
||||
onPointerPanZoomEnd: (PointerPanZoomEndEvent event) => logs.add('panZoomEnd'),
|
||||
child: const Text('test'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.drag(find.text('test'), const Offset(-150.0, 200.0), kind: PointerDeviceKind.trackpad);
|
||||
|
||||
for(int i = 0; i < logs.length; i++) {
|
||||
if (i == 0) {
|
||||
expect(logs[i], 'panZoomStart');
|
||||
} else if (i != logs.length - 1) {
|
||||
expect(logs[i], startsWith('panZoomUpdate'));
|
||||
} else {
|
||||
expect(logs[i], 'panZoomEnd');
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'WidgetTester.fling must respect buttons',
|
||||
(WidgetTester tester) async {
|
||||
|
Loading…
x
Reference in New Issue
Block a user