mirror of
https://github.com/alibaba/flutter-go.git
synced 2025-07-15 03:04:25 +08:00
497 lines
18 KiB
Dart
497 lines
18 KiB
Dart
// Copyright 2016 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
// Synced 2019-05-30T14:20:56.847880.
|
|
|
|
import 'package:flutter_web_ui/ui.dart' as ui;
|
|
|
|
import 'package:flutter_web/foundation.dart';
|
|
import 'package:flutter_web/gestures.dart';
|
|
|
|
import '../flutter_test_alternative.dart';
|
|
|
|
typedef HandleEventCallback = void Function(PointerEvent event);
|
|
|
|
class TestGestureFlutterBinding extends BindingBase with GestureBinding {
|
|
HandleEventCallback callback;
|
|
|
|
@override
|
|
void handleEvent(PointerEvent event, HitTestEntry entry) {
|
|
super.handleEvent(event, entry);
|
|
if (callback != null) callback(event);
|
|
}
|
|
}
|
|
|
|
TestGestureFlutterBinding _binding = TestGestureFlutterBinding();
|
|
|
|
void ensureTestGestureBinding() {
|
|
_binding ??= TestGestureFlutterBinding();
|
|
PointerEventConverter.clearPointers();
|
|
assert(GestureBinding.instance != null);
|
|
}
|
|
|
|
void main() {
|
|
setUp(ensureTestGestureBinding);
|
|
|
|
test('Pointer tap events', () {
|
|
const ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(change: ui.PointerChange.down),
|
|
ui.PointerData(change: ui.PointerChange.up),
|
|
]);
|
|
|
|
final List<PointerEvent> events = <PointerEvent>[];
|
|
_binding.callback = events.add;
|
|
|
|
ui.window.onPointerDataPacket(packet);
|
|
expect(events.length, 2);
|
|
expect(events[0].runtimeType, equals(PointerDownEvent));
|
|
expect(events[1].runtimeType, equals(PointerUpEvent));
|
|
});
|
|
|
|
test('Pointer move events', () {
|
|
const ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(change: ui.PointerChange.down),
|
|
ui.PointerData(change: ui.PointerChange.move),
|
|
ui.PointerData(change: ui.PointerChange.up),
|
|
]);
|
|
|
|
final List<PointerEvent> events = <PointerEvent>[];
|
|
_binding.callback = events.add;
|
|
|
|
ui.window.onPointerDataPacket(packet);
|
|
expect(events.length, 3);
|
|
expect(events[0].runtimeType, equals(PointerDownEvent));
|
|
expect(events[1].runtimeType, equals(PointerMoveEvent));
|
|
expect(events[2].runtimeType, equals(PointerUpEvent));
|
|
});
|
|
|
|
test('Pointer hover events', () {
|
|
const ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(change: ui.PointerChange.hover),
|
|
ui.PointerData(change: ui.PointerChange.hover),
|
|
ui.PointerData(change: ui.PointerChange.remove),
|
|
ui.PointerData(change: ui.PointerChange.hover),
|
|
]);
|
|
|
|
final List<PointerEvent> pointerRouterEvents = <PointerEvent>[];
|
|
GestureBinding.instance.pointerRouter
|
|
.addGlobalRoute(pointerRouterEvents.add);
|
|
|
|
final List<PointerEvent> events = <PointerEvent>[];
|
|
_binding.callback = events.add;
|
|
|
|
ui.window.onPointerDataPacket(packet);
|
|
expect(events.length, 0);
|
|
expect(pointerRouterEvents.length, 6,
|
|
reason: 'pointerRouterEvents contains: $pointerRouterEvents');
|
|
expect(pointerRouterEvents[0].runtimeType, equals(PointerAddedEvent));
|
|
expect(pointerRouterEvents[1].runtimeType, equals(PointerHoverEvent));
|
|
expect(pointerRouterEvents[2].runtimeType, equals(PointerHoverEvent));
|
|
expect(pointerRouterEvents[3].runtimeType, equals(PointerRemovedEvent));
|
|
expect(pointerRouterEvents[4].runtimeType, equals(PointerAddedEvent));
|
|
expect(pointerRouterEvents[5].runtimeType, equals(PointerHoverEvent));
|
|
});
|
|
|
|
test('Synthetic move events', () {
|
|
final ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(
|
|
change: ui.PointerChange.down,
|
|
physicalX: 1.0 * ui.window.devicePixelRatio,
|
|
physicalY: 3.0 * ui.window.devicePixelRatio,
|
|
),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.up,
|
|
physicalX: 10.0 * ui.window.devicePixelRatio,
|
|
physicalY: 15.0 * ui.window.devicePixelRatio,
|
|
),
|
|
]);
|
|
|
|
final List<PointerEvent> events = <PointerEvent>[];
|
|
_binding.callback = events.add;
|
|
|
|
ui.window.onPointerDataPacket(packet);
|
|
expect(events.length, 3);
|
|
expect(events[0].runtimeType, equals(PointerDownEvent));
|
|
expect(events[1].runtimeType, equals(PointerMoveEvent));
|
|
expect(events[1].delta, equals(const Offset(9.0, 12.0)));
|
|
expect(events[2].runtimeType, equals(PointerUpEvent));
|
|
});
|
|
|
|
test('Pointer cancel events', () {
|
|
const ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(change: ui.PointerChange.down),
|
|
ui.PointerData(change: ui.PointerChange.cancel),
|
|
]);
|
|
|
|
final List<PointerEvent> events = <PointerEvent>[];
|
|
_binding.callback = events.add;
|
|
|
|
ui.window.onPointerDataPacket(packet);
|
|
expect(events.length, 2);
|
|
expect(events[0].runtimeType, equals(PointerDownEvent));
|
|
expect(events[1].runtimeType, equals(PointerCancelEvent));
|
|
});
|
|
|
|
test('Can cancel pointers', () {
|
|
const ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(change: ui.PointerChange.down),
|
|
ui.PointerData(change: ui.PointerChange.up),
|
|
]);
|
|
|
|
final List<PointerEvent> events = <PointerEvent>[];
|
|
_binding.callback = (PointerEvent event) {
|
|
events.add(event);
|
|
if (event is PointerDownEvent) _binding.cancelPointer(event.pointer);
|
|
};
|
|
|
|
ui.window.onPointerDataPacket(packet);
|
|
expect(events.length, 2);
|
|
expect(events[0].runtimeType, equals(PointerDownEvent));
|
|
expect(events[1].runtimeType, equals(PointerCancelEvent));
|
|
});
|
|
|
|
test('Can expand add and hover pointers', () {
|
|
const ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(change: ui.PointerChange.add, device: 24),
|
|
ui.PointerData(change: ui.PointerChange.hover, device: 24),
|
|
ui.PointerData(change: ui.PointerChange.remove, device: 24),
|
|
ui.PointerData(change: ui.PointerChange.hover, device: 24),
|
|
]);
|
|
|
|
final List<PointerEvent> events =
|
|
PointerEventConverter.expand(packet.data, ui.window.devicePixelRatio)
|
|
.toList();
|
|
|
|
expect(events.length, 5);
|
|
expect(events[0].runtimeType, equals(PointerAddedEvent));
|
|
expect(events[1].runtimeType, equals(PointerHoverEvent));
|
|
expect(events[2].runtimeType, equals(PointerRemovedEvent));
|
|
expect(events[3].runtimeType, equals(PointerAddedEvent));
|
|
expect(events[4].runtimeType, equals(PointerHoverEvent));
|
|
});
|
|
|
|
test('Synthetic hover and cancel for misplaced down and remove', () {
|
|
final ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(
|
|
change: ui.PointerChange.add,
|
|
device: 25,
|
|
physicalX: 10.0 * ui.window.devicePixelRatio,
|
|
physicalY: 10.0 * ui.window.devicePixelRatio),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.down,
|
|
device: 25,
|
|
physicalX: 15.0 * ui.window.devicePixelRatio,
|
|
physicalY: 17.0 * ui.window.devicePixelRatio),
|
|
const ui.PointerData(change: ui.PointerChange.remove, device: 25),
|
|
]);
|
|
|
|
final List<PointerEvent> events =
|
|
PointerEventConverter.expand(packet.data, ui.window.devicePixelRatio)
|
|
.toList();
|
|
|
|
expect(events.length, 6);
|
|
expect(events[0].runtimeType, equals(PointerAddedEvent));
|
|
expect(events[1].runtimeType, equals(PointerHoverEvent));
|
|
expect(events[1].delta, equals(const Offset(5.0, 7.0)));
|
|
expect(events[2].runtimeType, equals(PointerDownEvent));
|
|
expect(events[3].runtimeType, equals(PointerCancelEvent));
|
|
expect(events[4].runtimeType, equals(PointerHoverEvent));
|
|
expect(events[5].runtimeType, equals(PointerRemovedEvent));
|
|
});
|
|
|
|
test('Can expand pointer scroll events', () {
|
|
const ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(change: ui.PointerChange.add),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.hover,
|
|
signalKind: ui.PointerSignalKind.scroll),
|
|
]);
|
|
|
|
final List<PointerEvent> events =
|
|
PointerEventConverter.expand(packet.data, ui.window.devicePixelRatio)
|
|
.toList();
|
|
|
|
expect(events.length, 2);
|
|
expect(events[0].runtimeType, equals(PointerAddedEvent));
|
|
expect(events[1].runtimeType, equals(PointerScrollEvent));
|
|
});
|
|
|
|
test('Synthetic hover/move for misplaced scrolls', () {
|
|
final Offset lastLocation =
|
|
const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
|
|
const Offset unexpectedOffset = Offset(5.0, 7.0);
|
|
final Offset scrollLocation =
|
|
lastLocation + unexpectedOffset * ui.window.devicePixelRatio;
|
|
final ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(
|
|
change: ui.PointerChange.add,
|
|
physicalX: lastLocation.dx,
|
|
physicalY: lastLocation.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.hover,
|
|
physicalX: scrollLocation.dx,
|
|
physicalY: scrollLocation.dy,
|
|
signalKind: ui.PointerSignalKind.scroll),
|
|
// Move back to starting location, click, and repeat to test mouse-down version.
|
|
ui.PointerData(
|
|
change: ui.PointerChange.hover,
|
|
physicalX: lastLocation.dx,
|
|
physicalY: lastLocation.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.down,
|
|
physicalX: lastLocation.dx,
|
|
physicalY: lastLocation.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.hover,
|
|
physicalX: scrollLocation.dx,
|
|
physicalY: scrollLocation.dy,
|
|
signalKind: ui.PointerSignalKind.scroll),
|
|
]);
|
|
|
|
final List<PointerEvent> events =
|
|
PointerEventConverter.expand(packet.data, ui.window.devicePixelRatio)
|
|
.toList();
|
|
|
|
expect(events.length, 7);
|
|
expect(events[0].runtimeType, equals(PointerAddedEvent));
|
|
expect(events[1].runtimeType, equals(PointerHoverEvent));
|
|
expect(events[1].delta, equals(unexpectedOffset));
|
|
expect(events[2].runtimeType, equals(PointerScrollEvent));
|
|
expect(events[3].runtimeType, equals(PointerHoverEvent));
|
|
expect(events[4].runtimeType, equals(PointerDownEvent));
|
|
expect(events[5].runtimeType, equals(PointerMoveEvent));
|
|
expect(events[5].delta, equals(unexpectedOffset));
|
|
expect(events[6].runtimeType, equals(PointerScrollEvent));
|
|
});
|
|
|
|
test('Should synthesize kPrimaryButton for touch', () {
|
|
final Offset location =
|
|
const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
|
|
const PointerDeviceKind kind = PointerDeviceKind.touch;
|
|
final ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(
|
|
change: ui.PointerChange.add,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.hover,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.down,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.move,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.up,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
]);
|
|
|
|
final List<PointerEvent> events =
|
|
PointerEventConverter.expand(packet.data, ui.window.devicePixelRatio)
|
|
.toList();
|
|
|
|
expect(events.length, 5);
|
|
expect(events[0].runtimeType, equals(PointerAddedEvent));
|
|
expect(events[0].buttons, equals(0));
|
|
expect(events[1].runtimeType, equals(PointerHoverEvent));
|
|
expect(events[1].buttons, equals(0));
|
|
expect(events[2].runtimeType, equals(PointerDownEvent));
|
|
expect(events[2].buttons, equals(kPrimaryButton));
|
|
expect(events[3].runtimeType, equals(PointerMoveEvent));
|
|
expect(events[3].buttons, equals(kPrimaryButton));
|
|
expect(events[4].runtimeType, equals(PointerUpEvent));
|
|
expect(events[4].buttons, equals(0));
|
|
|
|
PointerEventConverter.clearPointers();
|
|
});
|
|
|
|
test('Should synthesize kPrimaryButton for stylus', () {
|
|
final Offset location =
|
|
const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
|
|
for (PointerDeviceKind kind in <PointerDeviceKind>[
|
|
PointerDeviceKind.stylus,
|
|
PointerDeviceKind.invertedStylus,
|
|
]) {
|
|
final ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(
|
|
change: ui.PointerChange.add,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.hover,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.down,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.move,
|
|
buttons: kSecondaryStylusButton,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.up,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
]);
|
|
|
|
final List<PointerEvent> events =
|
|
PointerEventConverter.expand(packet.data, ui.window.devicePixelRatio)
|
|
.toList();
|
|
|
|
expect(events.length, 5);
|
|
expect(events[0].runtimeType, equals(PointerAddedEvent));
|
|
expect(events[0].buttons, equals(0));
|
|
expect(events[1].runtimeType, equals(PointerHoverEvent));
|
|
expect(events[1].buttons, equals(0));
|
|
expect(events[2].runtimeType, equals(PointerDownEvent));
|
|
expect(events[2].buttons, equals(kPrimaryButton));
|
|
expect(events[3].runtimeType, equals(PointerMoveEvent));
|
|
expect(
|
|
events[3].buttons, equals(kPrimaryButton | kSecondaryStylusButton));
|
|
expect(events[4].runtimeType, equals(PointerUpEvent));
|
|
expect(events[4].buttons, equals(0));
|
|
|
|
PointerEventConverter.clearPointers();
|
|
}
|
|
});
|
|
|
|
test('Should synthesize kPrimaryButton for unknown devices', () {
|
|
final Offset location =
|
|
const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
|
|
const PointerDeviceKind kind = PointerDeviceKind.unknown;
|
|
final ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(
|
|
change: ui.PointerChange.add,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.hover,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.down,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.move,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.up,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
]);
|
|
|
|
final List<PointerEvent> events =
|
|
PointerEventConverter.expand(packet.data, ui.window.devicePixelRatio)
|
|
.toList();
|
|
|
|
expect(events.length, 5);
|
|
expect(events[0].runtimeType, equals(PointerAddedEvent));
|
|
expect(events[0].buttons, equals(0));
|
|
expect(events[1].runtimeType, equals(PointerHoverEvent));
|
|
expect(events[1].buttons, equals(0));
|
|
expect(events[2].runtimeType, equals(PointerDownEvent));
|
|
expect(events[2].buttons, equals(kPrimaryButton));
|
|
expect(events[3].runtimeType, equals(PointerMoveEvent));
|
|
expect(events[3].buttons, equals(kPrimaryButton));
|
|
expect(events[4].runtimeType, equals(PointerUpEvent));
|
|
expect(events[4].buttons, equals(0));
|
|
|
|
PointerEventConverter.clearPointers();
|
|
});
|
|
|
|
test('Should not synthesize kPrimaryButton for mouse', () {
|
|
final Offset location =
|
|
const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
|
|
for (PointerDeviceKind kind in <PointerDeviceKind>[
|
|
PointerDeviceKind.mouse,
|
|
]) {
|
|
final ui.PointerDataPacket packet =
|
|
ui.PointerDataPacket(data: <ui.PointerData>[
|
|
ui.PointerData(
|
|
change: ui.PointerChange.add,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.hover,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.down,
|
|
kind: kind,
|
|
buttons: kMiddleMouseButton,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.move,
|
|
kind: kind,
|
|
buttons: kMiddleMouseButton | kSecondaryMouseButton,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
ui.PointerData(
|
|
change: ui.PointerChange.up,
|
|
kind: kind,
|
|
physicalX: location.dx,
|
|
physicalY: location.dy),
|
|
]);
|
|
|
|
final List<PointerEvent> events =
|
|
PointerEventConverter.expand(packet.data, ui.window.devicePixelRatio)
|
|
.toList();
|
|
|
|
expect(events.length, 5);
|
|
expect(events[0].runtimeType, equals(PointerAddedEvent));
|
|
expect(events[0].buttons, equals(0));
|
|
expect(events[1].runtimeType, equals(PointerHoverEvent));
|
|
expect(events[1].buttons, equals(0));
|
|
expect(events[2].runtimeType, equals(PointerDownEvent));
|
|
expect(events[2].buttons, equals(kMiddleMouseButton));
|
|
expect(events[3].runtimeType, equals(PointerMoveEvent));
|
|
expect(events[3].buttons,
|
|
equals(kMiddleMouseButton | kSecondaryMouseButton));
|
|
expect(events[4].runtimeType, equals(PointerUpEvent));
|
|
expect(events[4].buttons, equals(0));
|
|
|
|
PointerEventConverter.clearPointers();
|
|
}
|
|
});
|
|
}
|