Commit 393521de authored by Dwayne Slater's avatar Dwayne Slater Committed by Greg Spencer

Allow PointerEnterEvent and PointerExitEvents to be created from any PointerEvent (#28602)

Avoids an implicit downcast + crash in MouseTracker, since the last
pointer event can be a Move or Down event, in addition to Hover.
parent 64a28e36
......@@ -518,30 +518,35 @@ class PointerEnterEvent extends PointerEvent {
/// Creates an enter event from a [PointerHoverEvent].
///
/// This is used by the [MouseTracker] to synthesize enter events, since it
/// only actually receives hover events.
PointerEnterEvent.fromHoverEvent(PointerHoverEvent hover) : super(
timeStamp: hover?.timeStamp,
kind: hover?.kind,
device: hover?.device,
position: hover?.position,
delta: hover?.delta,
buttons: hover?.buttons,
down: hover?.down,
obscured: hover?.obscured,
pressure: hover?.pressure,
pressureMin: hover?.pressureMin,
pressureMax: hover?.pressureMax,
distance: hover?.distance,
distanceMax: hover?.distanceMax,
size: hover?.size,
radiusMajor: hover?.radiusMajor,
radiusMinor: hover?.radiusMinor,
radiusMin: hover?.radiusMin,
radiusMax: hover?.radiusMax,
orientation: hover?.orientation,
tilt: hover?.tilt,
synthesized: hover?.synthesized,
/// Deprecated. Please use [PointerEnterEvent.fromMouseEvent] instead.
@Deprecated('use PointerEnterEvent.fromMouseEvent instead')
PointerEnterEvent.fromHoverEvent(PointerHoverEvent event) : this.fromMouseEvent(event);
/// Creates an enter event from a [PointerEvent].
///
/// This is used by the [MouseTracker] to synthesize enter events.
PointerEnterEvent.fromMouseEvent(PointerEvent event) : super(
timeStamp: event?.timeStamp,
kind: event?.kind,
device: event?.device,
position: event?.position,
delta: event?.delta,
buttons: event?.buttons,
down: event?.down,
obscured: event?.obscured,
pressure: event?.pressure,
pressureMin: event?.pressureMin,
pressureMax: event?.pressureMax,
distance: event?.distance,
distanceMax: event?.distanceMax,
size: event?.size,
radiusMajor: event?.radiusMajor,
radiusMinor: event?.radiusMinor,
radiusMin: event?.radiusMin,
radiusMax: event?.radiusMax,
orientation: event?.orientation,
tilt: event?.tilt,
synthesized: event?.synthesized,
);
}
......@@ -606,30 +611,35 @@ class PointerExitEvent extends PointerEvent {
/// Creates an exit event from a [PointerHoverEvent].
///
/// This is used by the [MouseTracker] to synthesize exit events, since it
/// only actually receives hover events.
PointerExitEvent.fromHoverEvent(PointerHoverEvent hover) : super(
timeStamp: hover?.timeStamp,
kind: hover?.kind,
device: hover?.device,
position: hover?.position,
delta: hover?.delta,
buttons: hover?.buttons,
down: hover?.down,
obscured: hover?.obscured,
pressure: hover?.pressure,
pressureMin: hover?.pressureMin,
pressureMax: hover?.pressureMax,
distance: hover?.distance,
distanceMax: hover?.distanceMax,
size: hover?.size,
radiusMajor: hover?.radiusMajor,
radiusMinor: hover?.radiusMinor,
radiusMin: hover?.radiusMin,
radiusMax: hover?.radiusMax,
orientation: hover?.orientation,
tilt: hover?.tilt,
synthesized: hover?.synthesized,
/// Deprecated. Please use [PointerExitEvent.fromMouseEvent] instead.
@Deprecated('use PointerExitEvent.fromMouseEvent instead')
PointerExitEvent.fromHoverEvent(PointerHoverEvent event) : this.fromMouseEvent(event);
/// Creates an exit event from a [PointerEvent].
///
/// This is used by the [MouseTracker] to synthesize exit events.
PointerExitEvent.fromMouseEvent(PointerEvent event) : super(
timeStamp: event?.timeStamp,
kind: event?.kind,
device: event?.device,
position: event?.position,
delta: event?.delta,
buttons: event?.buttons,
down: event?.down,
obscured: event?.obscured,
pressure: event?.pressure,
pressureMin: event?.pressureMin,
pressureMax: event?.pressureMax,
distance: event?.distance,
distanceMax: event?.distanceMax,
size: event?.size,
radiusMajor: event?.radiusMajor,
radiusMinor: event?.radiusMinor,
radiusMin: event?.radiusMin,
radiusMax: event?.radiusMax,
orientation: event?.orientation,
tilt: event?.tilt,
synthesized: event?.synthesized,
);
}
......
......@@ -122,7 +122,7 @@ class MouseTracker {
final _TrackedAnnotation trackedAnnotation = _findAnnotation(annotation);
assert(trackedAnnotation != null, "Tried to detach an annotation that wasn't attached: $annotation");
for (int deviceId in trackedAnnotation.activeDevices) {
annotation.onExit(PointerExitEvent.fromHoverEvent(_lastMouseEvent[deviceId]));
annotation.onExit(PointerExitEvent.fromMouseEvent(_lastMouseEvent[deviceId]));
}
_trackedAnnotations.remove(annotation);
}
......@@ -194,7 +194,7 @@ class MouseTracker {
void collectMousePositions() {
void exitAnnotation(_TrackedAnnotation trackedAnnotation, int deviceId) {
if (trackedAnnotation.annotation?.onExit != null && trackedAnnotation.activeDevices.contains(deviceId)) {
trackedAnnotation.annotation.onExit(PointerExitEvent.fromHoverEvent(_lastMouseEvent[deviceId]));
trackedAnnotation.annotation.onExit(PointerExitEvent.fromMouseEvent(_lastMouseEvent[deviceId]));
trackedAnnotation.activeDevices.remove(deviceId);
}
}
......@@ -236,10 +236,10 @@ class MouseTracker {
// event sent to it.
hitAnnotation.activeDevices.add(deviceId);
if (hitAnnotation.annotation?.onEnter != null) {
hitAnnotation.annotation.onEnter(PointerEnterEvent.fromHoverEvent(lastEvent));
hitAnnotation.annotation.onEnter(PointerEnterEvent.fromMouseEvent(lastEvent));
}
}
if (hitAnnotation.annotation?.onHover != null) {
if (hitAnnotation.annotation?.onHover != null && lastEvent is PointerHoverEvent) {
hitAnnotation.annotation.onHover(lastEvent);
}
......@@ -251,7 +251,7 @@ class MouseTracker {
}
if (trackedAnnotation.activeDevices.contains(deviceId)) {
if (trackedAnnotation.annotation?.onExit != null) {
trackedAnnotation.annotation.onExit(PointerExitEvent.fromHoverEvent(lastEvent));
trackedAnnotation.annotation.onExit(PointerExitEvent.fromMouseEvent(lastEvent));
}
trackedAnnotation.activeDevices.remove(deviceId);
}
......
......@@ -256,5 +256,50 @@ void main() {
expect(exit.first.device, isNull);
expect(exit.first.runtimeType, equals(PointerExitEvent));
});
test('handles mouse down and move', () {
final ui.PointerDataPacket packet1 = ui.PointerDataPacket(data: <ui.PointerData>[
ui.PointerData(
change: ui.PointerChange.hover,
physicalX: 0.0 * ui.window.devicePixelRatio,
physicalY: 0.0 * ui.window.devicePixelRatio,
kind: PointerDeviceKind.mouse,
),
ui.PointerData(
change: ui.PointerChange.hover,
physicalX: 1.0 * ui.window.devicePixelRatio,
physicalY: 101.0 * ui.window.devicePixelRatio,
kind: PointerDeviceKind.mouse,
),
]);
final ui.PointerDataPacket packet2 = ui.PointerDataPacket(data: <ui.PointerData>[
ui.PointerData(
change: ui.PointerChange.down,
physicalX: 1.0 * ui.window.devicePixelRatio,
physicalY: 101.0 * ui.window.devicePixelRatio,
kind: PointerDeviceKind.mouse,
),
ui.PointerData(
change: ui.PointerChange.move,
physicalX: 1.0 * ui.window.devicePixelRatio,
physicalY: 201.0 * ui.window.devicePixelRatio,
kind: PointerDeviceKind.mouse,
),
]);
isInHitRegion = true;
tracker.attachAnnotation(annotation);
ui.window.onPointerDataPacket(packet1);
tracker.collectMousePositions();
ui.window.onPointerDataPacket(packet2);
tracker.collectMousePositions();
expect(enter.length, equals(1), reason: 'enter contains $enter');
expect(enter.first.position, equals(const Offset(1.0, 101.0)));
expect(enter.first.device, equals(0));
expect(enter.first.runtimeType, equals(PointerEnterEvent));
expect(move.length, equals(1), reason: 'move contains $move');
expect(move.first.position, equals(const Offset(1.0, 101.0)));
expect(move.first.device, equals(0));
expect(move.first.runtimeType, equals(PointerHoverEvent));
expect(exit.length, equals(0), reason: 'exit contains $exit');
});
});
}
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