Unverified Commit 74fe6bff authored by Tong Mu's avatar Tong Mu Committed by GitHub

Lazily compute PointerEvent's transformed positions (#63813)

* PointerEvent.local* properties are calculated lazily; other properties are delegated to original.
* Transformed PointerEvent becomes a subclass of its original class.
* Unnamed constructors no longer accepts transform and origin.
parent 76c0d69b
......@@ -243,9 +243,7 @@ abstract class PointerEvent with Diagnosticable {
this.kind = PointerDeviceKind.touch,
this.device = 0,
this.position = Offset.zero,
Offset? localPosition,
this.delta = Offset.zero,
Offset? localDelta,
this.buttons = 0,
this.down = false,
this.obscured = false,
......@@ -265,8 +263,7 @@ abstract class PointerEvent with Diagnosticable {
this.synthesized = false,
this.transform,
this.original,
}) : localPosition = localPosition ?? position,
localDelta = localDelta ?? delta;
});
/// Unique identifier that ties the [PointerEvent] to the embedder event that created it.
///
......@@ -307,7 +304,7 @@ abstract class PointerEvent with Diagnosticable {
///
/// * [position], which is the position in the global coordinate system of
/// the screen.
final Offset localPosition;
Offset get localPosition => position;
/// Distance in logical pixels that the pointer moved since the last
/// [PointerMoveEvent] or [PointerHoverEvent].
......@@ -329,7 +326,7 @@ abstract class PointerEvent with Diagnosticable {
///
/// * [delta], which is the distance the pointer moved in the global
/// coordinate system of the screen.
final Offset localDelta;
Offset get localDelta => delta;
/// Bit field using the *Button constants such as [kPrimaryMouseButton],
/// [kSecondaryStylusButton], etc.
......@@ -511,24 +508,32 @@ abstract class PointerEvent with Diagnosticable {
/// The coordinate space of the event receiver is described by `transform`. A
/// null value for `transform` is treated as the identity transformation.
///
/// The method may return the same object instance if for example the
/// transformation has no effect on the event.
/// The resulting event will store the base event as [original], delegates
/// most properties to [original], except for [localPosition] and [localDelta],
/// which are calculated based on [transform] on first use and cached.
///
/// Transforms are not commutative. If this method is called on a
/// [PointerEvent] that has a non-null [transform] value, that value will be
/// overridden by the provided `transform`.
/// The method may return the same object instance if for example the
/// transformation has no effect on the event. Otherwise, the resulting event
/// will be a subclass of, but not exactly, the original event class (e.g.
/// [PointerDownEvent.transformed] may return a subclass of [PointerDownEvent]).
///
/// Transforms are not commutative, and are based on [original] events.
/// If this method is called on a transformed event, the provided `transform`
/// will override (instead of multiplied onto) the existing [transform] and
/// used to calculate the new [localPosition] and [localDelta].
PointerEvent transformed(Matrix4? transform);
/// Creates a copy of event with the specified properties replaced.
///
/// Calling this method on a transformed event will return a new transformed
/// event based on the current [transform] and the provided properties.
PointerEvent copyWith({
Duration? timeStamp,
int? pointer,
PointerDeviceKind? kind,
int? device,
Offset? position,
Offset? localPosition,
Offset? delta,
Offset? localDelta,
int? buttons,
bool? obscured,
double? pressure,
......@@ -544,48 +549,9 @@ abstract class PointerEvent with Diagnosticable {
double? orientation,
double? tilt,
bool? synthesized,
Matrix4? transform,
PointerEvent? original,
int? embedderId,
});
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('position', position));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition, defaultValue: position, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<Offset>('delta', delta, defaultValue: Offset.zero, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<Offset>('localDelta', localDelta, defaultValue: delta, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<Duration>('timeStamp', timeStamp, defaultValue: Duration.zero, level: DiagnosticLevel.debug));
properties.add(IntProperty('pointer', pointer, level: DiagnosticLevel.debug));
properties.add(EnumProperty<PointerDeviceKind>('kind', kind, level: DiagnosticLevel.debug));
properties.add(IntProperty('device', device, defaultValue: 0, level: DiagnosticLevel.debug));
properties.add(IntProperty('buttons', buttons, defaultValue: 0, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<bool>('down', down, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('pressure', pressure, defaultValue: 1.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('pressureMin', pressureMin, defaultValue: 1.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('pressureMax', pressureMax, defaultValue: 1.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('distance', distance, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('distanceMin', distanceMin, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('distanceMax', distanceMax, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('size', size, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('radiusMajor', radiusMajor, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('radiusMinor', radiusMinor, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('radiusMin', radiusMin, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('radiusMax', radiusMax, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('orientation', orientation, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('tilt', tilt, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(IntProperty('platformData', platformData, defaultValue: 0, level: DiagnosticLevel.debug));
properties.add(FlagProperty('obscured', value: obscured, ifTrue: 'obscured', level: DiagnosticLevel.debug));
properties.add(FlagProperty('synthesized', value: synthesized, ifTrue: 'synthesized', level: DiagnosticLevel.debug));
properties.add(IntProperty('embedderId', embedderId, defaultValue: 0, level: DiagnosticLevel.debug));
}
/// Returns a complete textual description of this event.
String toStringFull() {
return toString(minLevel: DiagnosticLevel.fine);
}
/// Returns the transformation of `position` into the coordinate system
/// described by `transform`.
///
......@@ -642,20 +608,209 @@ abstract class PointerEvent with Diagnosticable {
}
}
// A mixin that adds implementation for [debugFillProperties] and [toStringFull]
// to [PointerEvent].
mixin _PointerEventDescription on PointerEvent {
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('position', position));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition, defaultValue: position, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<Offset>('delta', delta, defaultValue: Offset.zero, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<Offset>('localDelta', localDelta, defaultValue: delta, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<Duration>('timeStamp', timeStamp, defaultValue: Duration.zero, level: DiagnosticLevel.debug));
properties.add(IntProperty('pointer', pointer, level: DiagnosticLevel.debug));
properties.add(EnumProperty<PointerDeviceKind>('kind', kind, level: DiagnosticLevel.debug));
properties.add(IntProperty('device', device, defaultValue: 0, level: DiagnosticLevel.debug));
properties.add(IntProperty('buttons', buttons, defaultValue: 0, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<bool>('down', down, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('pressure', pressure, defaultValue: 1.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('pressureMin', pressureMin, defaultValue: 1.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('pressureMax', pressureMax, defaultValue: 1.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('distance', distance, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('distanceMin', distanceMin, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('distanceMax', distanceMax, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('size', size, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('radiusMajor', radiusMajor, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('radiusMinor', radiusMinor, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('radiusMin', radiusMin, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('radiusMax', radiusMax, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('orientation', orientation, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(DoubleProperty('tilt', tilt, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(IntProperty('platformData', platformData, defaultValue: 0, level: DiagnosticLevel.debug));
properties.add(FlagProperty('obscured', value: obscured, ifTrue: 'obscured', level: DiagnosticLevel.debug));
properties.add(FlagProperty('synthesized', value: synthesized, ifTrue: 'synthesized', level: DiagnosticLevel.debug));
properties.add(IntProperty('embedderId', embedderId, defaultValue: 0, level: DiagnosticLevel.debug));
}
/// Returns a complete textual description of this event.
String toStringFull() {
return toString(minLevel: DiagnosticLevel.fine);
}
}
abstract class _AbstractPointerEvent implements PointerEvent {}
// The base class for transformed pointer event classes.
//
// A _TransformedPointerEvent stores an [original] event and the [transform]
// matrix. It defers all field getters to the original event, except for
// [localPosition] and [localDelta], which are calculated when first used.
abstract class _TransformedPointerEvent extends _AbstractPointerEvent with Diagnosticable, _PointerEventDescription {
@override
PointerEvent get original;
@override
Matrix4 get transform;
@override
int get embedderId => original.embedderId;
@override
Duration get timeStamp => original.timeStamp;
@override
int get pointer => original.pointer;
@override
PointerDeviceKind get kind => original.kind;
@override
int get device => original.device;
@override
Offset get position => original.position;
@override
Offset get delta => original.delta;
@override
int get buttons => original.buttons;
@override
bool get down => original.down;
@override
bool get obscured => original.obscured;
@override
double get pressure => original.pressure;
@override
double get pressureMin => original.pressureMin;
@override
double get pressureMax => original.pressureMax;
@override
double get distance => original.distance;
@override
double get distanceMin => 0.0;
@override
double get distanceMax => original.distanceMax;
@override
double get size => original.size;
@override
double get radiusMajor => original.radiusMajor;
@override
double get radiusMinor => original.radiusMinor;
@override
double get radiusMin => original.radiusMin;
@override
double get radiusMax => original.radiusMax;
@override
double get orientation => original.orientation;
@override
double get tilt => original.tilt;
@override
int get platformData => original.platformData;
@override
bool get synthesized => original.synthesized;
@override
late final Offset localPosition = PointerEvent.transformPosition(transform, position);
@override
late final Offset localDelta = PointerEvent.transformDeltaViaPositions(
transform: transform,
untransformedDelta: delta,
untransformedEndPosition: position,
transformedEndPosition: localPosition,
);
}
mixin _CopyPointerAddedEvent on PointerEvent {
@override
PointerAddedEvent copyWith({
Duration? timeStamp,
int? pointer,
PointerDeviceKind? kind,
int? device,
Offset? position,
Offset? delta,
int? buttons,
bool? obscured,
double? pressure,
double? pressureMin,
double? pressureMax,
double? distance,
double? distanceMax,
double? size,
double? radiusMajor,
double? radiusMinor,
double? radiusMin,
double? radiusMax,
double? orientation,
double? tilt,
bool? synthesized,
int? embedderId,
}) {
return PointerAddedEvent(
timeStamp: timeStamp ?? this.timeStamp,
kind: kind ?? this.kind,
device: device ?? this.device,
position: position ?? this.position,
obscured: obscured ?? this.obscured,
pressureMin: pressureMin ?? this.pressureMin,
pressureMax: pressureMax ?? this.pressureMax,
distance: distance ?? this.distance,
distanceMax: distanceMax ?? this.distanceMax,
radiusMin: radiusMin ?? this.radiusMin,
radiusMax: radiusMax ?? this.radiusMax,
orientation: orientation ?? this.orientation,
tilt: tilt ?? this.tilt,
embedderId: embedderId ?? this.embedderId,
).transformed(transform);
}
}
/// The device has started tracking the pointer.
///
/// For example, the pointer might be hovering above the device, having not yet
/// made contact with the surface of the device.
class PointerAddedEvent extends PointerEvent {
class PointerAddedEvent extends PointerEvent with _PointerEventDescription, _CopyPointerAddedEvent {
/// Creates a pointer added event.
///
/// All of the arguments must be non-null.
const PointerAddedEvent({
Duration timeStamp = Duration.zero,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = Offset.zero,
Offset? localPosition,
bool obscured = false,
double pressureMin = 1.0,
double pressureMax = 1.0,
......@@ -665,15 +820,13 @@ class PointerAddedEvent extends PointerEvent {
double radiusMax = 0.0,
double orientation = 0.0,
double tilt = 0.0,
Matrix4? transform,
PointerAddedEvent? original,
int embedderId = 0,
}) : super(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
localPosition: localPosition,
obscured: obscured,
pressure: 0.0,
pressureMin: pressureMin,
......@@ -684,8 +837,6 @@ class PointerAddedEvent extends PointerEvent {
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
transform: transform,
original: original,
embedderId: embedderId,
);
......@@ -694,37 +845,33 @@ class PointerAddedEvent extends PointerEvent {
if (transform == null || transform == this.transform) {
return this;
}
return PointerAddedEvent(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
localPosition: PointerEvent.transformPosition(transform, position),
obscured: obscured,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
transform: transform,
original: original as PointerAddedEvent? ?? this,
embedderId: embedderId,
);
return _TransformedPointerAddedEvent(original as PointerAddedEvent? ?? this, transform);
}
}
class _TransformedPointerAddedEvent extends _TransformedPointerEvent with _CopyPointerAddedEvent implements PointerAddedEvent {
_TransformedPointerAddedEvent(this.original, this.transform)
: assert(original != null), assert(transform != null);
@override
PointerAddedEvent copyWith({
final PointerAddedEvent original;
@override
final Matrix4 transform;
@override
PointerAddedEvent transformed(Matrix4? transform) => original.transformed(transform);
}
mixin _CopyPointerRemovedEvent on PointerEvent {
@override
PointerRemovedEvent copyWith({
Duration? timeStamp,
int? pointer,
PointerDeviceKind? kind,
int? device,
Offset? position,
Offset? localPosition,
Offset? delta,
Offset? localDelta,
int? buttons,
bool? obscured,
double? pressure,
......@@ -740,29 +887,21 @@ class PointerAddedEvent extends PointerEvent {
double? orientation,
double? tilt,
bool? synthesized,
Matrix4? transform,
PointerEvent? original,
int? embedderId,
}) {
return PointerAddedEvent(
return PointerRemovedEvent(
timeStamp: timeStamp ?? this.timeStamp,
kind: kind ?? this.kind,
device: device ?? this.device,
position: position ?? this.position,
localPosition: localPosition ?? this.localPosition,
obscured: obscured ?? this.obscured,
pressureMin: pressureMin ?? this.pressureMin,
pressureMax: pressureMax ?? this.pressureMax,
distance: distance ?? this.distance,
distanceMax: distanceMax ?? this.distanceMax,
radiusMin: radiusMin ?? this.radiusMin,
radiusMax: radiusMax ?? this.radiusMax,
orientation: orientation ?? this.orientation,
tilt: tilt ?? this.tilt,
transform: transform ?? this.transform,
original: original as PointerAddedEvent? ?? this,
embedderId: embedderId ?? this.embedderId,
);
).transformed(transform);
}
}
......@@ -770,31 +909,30 @@ class PointerAddedEvent extends PointerEvent {
///
/// For example, the pointer might have drifted out of the device's hover
/// detection range or might have been disconnected from the system entirely.
class PointerRemovedEvent extends PointerEvent {
class PointerRemovedEvent extends PointerEvent with _PointerEventDescription, _CopyPointerRemovedEvent {
/// Creates a pointer removed event.
///
/// All of the arguments must be non-null.
const PointerRemovedEvent({
Duration timeStamp = Duration.zero,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = Offset.zero,
Offset? localPosition,
bool obscured = false,
double pressureMin = 1.0,
double pressureMax = 1.0,
double distanceMax = 0.0,
double radiusMin = 0.0,
double radiusMax = 0.0,
Matrix4? transform,
PointerRemovedEvent? original,
int embedderId = 0,
}) : super(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
localPosition: localPosition,
obscured: obscured,
pressure: 0.0,
pressureMin: pressureMin,
......@@ -802,7 +940,6 @@ class PointerRemovedEvent extends PointerEvent {
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
transform: transform,
original: original,
embedderId: embedderId,
);
......@@ -812,34 +949,33 @@ class PointerRemovedEvent extends PointerEvent {
if (transform == null || transform == this.transform) {
return this;
}
return PointerRemovedEvent(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
localPosition: PointerEvent.transformPosition(transform, position),
obscured: obscured,
pressureMin: pressureMin,
pressureMax: pressureMax,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
transform: transform,
original: original as PointerRemovedEvent? ?? this,
embedderId: embedderId,
);
return _TransformedPointerRemovedEvent(original as PointerRemovedEvent? ?? this, transform);
}
}
class _TransformedPointerRemovedEvent extends _TransformedPointerEvent with _CopyPointerRemovedEvent implements PointerRemovedEvent {
_TransformedPointerRemovedEvent(this.original, this.transform)
: assert(original != null), assert(transform != null);
@override
PointerRemovedEvent copyWith({
final PointerRemovedEvent original;
@override
final Matrix4 transform;
@override
PointerRemovedEvent transformed(Matrix4? transform) => original.transformed(transform);
}
mixin _CopyPointerHoverEvent on PointerEvent {
@override
PointerHoverEvent copyWith({
Duration? timeStamp,
int? pointer,
PointerDeviceKind? kind,
int? device,
Offset? position,
Offset? localPosition,
Offset? delta,
Offset? localDelta,
int? buttons,
bool? obscured,
double? pressure,
......@@ -855,26 +991,30 @@ class PointerRemovedEvent extends PointerEvent {
double? orientation,
double? tilt,
bool? synthesized,
Matrix4? transform,
PointerEvent? original,
int? embedderId,
}) {
return PointerRemovedEvent(
return PointerHoverEvent(
timeStamp: timeStamp ?? this.timeStamp,
kind: kind ?? this.kind,
device: device ?? this.device,
position: position ?? this.position,
localPosition: localPosition ?? this.localPosition,
delta: delta ?? this.delta,
buttons: buttons ?? this.buttons,
obscured: obscured ?? this.obscured,
pressureMin: pressureMin ?? this.pressureMin,
pressureMax: pressureMax ?? this.pressureMax,
distance: distance ?? this.distance,
distanceMax: distanceMax ?? this.distanceMax,
size: size ?? this.size,
radiusMajor: radiusMajor ?? this.radiusMajor,
radiusMinor: radiusMinor ?? this.radiusMinor,
radiusMin: radiusMin ?? this.radiusMin,
radiusMax: radiusMax ?? this.radiusMax,
transform: transform ?? this.transform,
original: original as PointerRemovedEvent? ?? this,
orientation: orientation ?? this.orientation,
tilt: tilt ?? this.tilt,
synthesized: synthesized ?? this.synthesized,
embedderId: embedderId ?? this.embedderId,
);
).transformed(transform);
}
}
......@@ -890,18 +1030,17 @@ class PointerRemovedEvent extends PointerEvent {
/// contact with the device.
/// * [Listener.onPointerHover], which allows callers to be notified of these
/// events in a widget tree.
class PointerHoverEvent extends PointerEvent {
class PointerHoverEvent extends PointerEvent with _PointerEventDescription, _CopyPointerHoverEvent {
/// Creates a pointer hover event.
///
/// All of the arguments must be non-null.
const PointerHoverEvent({
Duration timeStamp = Duration.zero,
PointerDeviceKind kind = PointerDeviceKind.touch,
int pointer = 0,
int device = 0,
Offset position = Offset.zero,
Offset? localPosition,
Offset delta = Offset.zero,
Offset? localDelta,
int buttons = 0,
bool obscured = false,
double pressureMin = 1.0,
......@@ -916,17 +1055,14 @@ class PointerHoverEvent extends PointerEvent {
double orientation = 0.0,
double tilt = 0.0,
bool synthesized = false,
Matrix4? transform,
PointerHoverEvent? original,
int embedderId = 0,
}) : super(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
localPosition: localPosition,
delta: delta,
localDelta: localDelta,
buttons: buttons,
down: false,
obscured: obscured,
......@@ -943,8 +1079,6 @@ class PointerHoverEvent extends PointerEvent {
orientation: orientation,
tilt: tilt,
synthesized: synthesized,
transform: transform,
original: original,
embedderId: embedderId,
);
......@@ -953,50 +1087,33 @@ class PointerHoverEvent extends PointerEvent {
if (transform == null || transform == this.transform) {
return this;
}
final Offset transformedPosition = PointerEvent.transformPosition(transform, position);
return PointerHoverEvent(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
localPosition: transformedPosition,
delta: delta,
localDelta: PointerEvent.transformDeltaViaPositions(
transform: transform,
untransformedDelta: delta,
untransformedEndPosition: position,
transformedEndPosition: transformedPosition,
),
buttons: buttons,
obscured: obscured,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
synthesized: synthesized,
transform: transform,
original: original as PointerHoverEvent? ?? this,
embedderId: embedderId,
);
return _TransformedPointerHoverEvent(original as PointerHoverEvent? ?? this, transform);
}
}
class _TransformedPointerHoverEvent extends _TransformedPointerEvent with _CopyPointerHoverEvent implements PointerHoverEvent {
_TransformedPointerHoverEvent(this.original, this.transform)
: assert(original != null), assert(transform != null);
@override
PointerHoverEvent copyWith({
final PointerHoverEvent original;
@override
final Matrix4 transform;
@override
PointerHoverEvent transformed(Matrix4? transform) => original.transformed(transform);
}
mixin _CopyPointerEnterEvent on PointerEvent {
@override
PointerEnterEvent copyWith({
Duration? timeStamp,
int? pointer,
PointerDeviceKind? kind,
int? device,
Offset? position,
Offset? localPosition,
Offset? delta,
Offset? localDelta,
int? buttons,
bool? obscured,
double? pressure,
......@@ -1012,18 +1129,14 @@ class PointerHoverEvent extends PointerEvent {
double? orientation,
double? tilt,
bool? synthesized,
Matrix4? transform,
PointerEvent? original,
int? embedderId,
}) {
return PointerHoverEvent(
return PointerEnterEvent(
timeStamp: timeStamp ?? this.timeStamp,
kind: kind ?? this.kind,
device: device ?? this.device,
position: position ?? this.position,
localPosition: localPosition ?? this.localPosition,
delta: delta ?? this.delta,
localDelta: localDelta ?? this.localDelta,
buttons: buttons ?? this.buttons,
obscured: obscured ?? this.obscured,
pressureMin: pressureMin ?? this.pressureMin,
......@@ -1038,10 +1151,8 @@ class PointerHoverEvent extends PointerEvent {
orientation: orientation ?? this.orientation,
tilt: tilt ?? this.tilt,
synthesized: synthesized ?? this.synthesized,
transform: transform ?? this.transform,
original: original as PointerHoverEvent? ?? this,
embedderId: embedderId ?? this.embedderId,
);
).transformed(transform);
}
}
......@@ -1057,18 +1168,17 @@ class PointerHoverEvent extends PointerEvent {
/// contact with the device.
/// * [MouseRegion.onEnter], which allows callers to be notified of these
/// events in a widget tree.
class PointerEnterEvent extends PointerEvent {
class PointerEnterEvent extends PointerEvent with _PointerEventDescription, _CopyPointerEnterEvent {
/// Creates a pointer enter event.
///
/// All of the arguments must be non-null.
const PointerEnterEvent({
Duration timeStamp = Duration.zero,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = Offset.zero,
Offset? localPosition,
Offset delta = Offset.zero,
Offset? localDelta,
int buttons = 0,
bool obscured = false,
double pressureMin = 1.0,
......@@ -1084,17 +1194,14 @@ class PointerEnterEvent extends PointerEvent {
double tilt = 0.0,
bool down = false,
bool synthesized = false,
Matrix4? transform,
PointerEnterEvent? original,
int embedderId = 0,
}) : super(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
localPosition: localPosition,
delta: delta,
localDelta: localDelta,
buttons: buttons,
down: down,
obscured: obscured,
......@@ -1111,8 +1218,6 @@ class PointerEnterEvent extends PointerEvent {
orientation: orientation,
tilt: tilt,
synthesized: synthesized,
transform: transform,
original: original,
embedderId: embedderId,
);
......@@ -1123,19 +1228,18 @@ class PointerEnterEvent extends PointerEvent {
'Use PointerEnterEvent.fromMouseEvent instead. '
'This feature was deprecated after v1.4.3.'
)
PointerEnterEvent.fromHoverEvent(PointerHoverEvent event) : this.fromMouseEvent(event);
factory PointerEnterEvent.fromHoverEvent(PointerHoverEvent event) => PointerEnterEvent.fromMouseEvent(event);
/// Creates an enter event from a [PointerEvent].
///
/// This is used by the [MouseTracker] to synthesize enter events.
PointerEnterEvent.fromMouseEvent(PointerEvent event) : this(
factory PointerEnterEvent.fromMouseEvent(PointerEvent event) => PointerEnterEvent(
timeStamp: event.timeStamp,
pointer: event.pointer,
kind: event.kind,
device: event.device,
position: event.position,
localPosition: event.localPosition,
delta: event.delta,
localDelta: event.localDelta,
buttons: event.buttons,
obscured: event.obscured,
pressureMin: event.pressureMin,
......@@ -1151,60 +1255,40 @@ class PointerEnterEvent extends PointerEvent {
tilt: event.tilt,
down: event.down,
synthesized: event.synthesized,
transform: event.transform,
original: null,
);
).transformed(event.transform);
@override
PointerEnterEvent transformed(Matrix4? transform) {
if (transform == null || transform == this.transform) {
return this;
}
final Offset transformedPosition = PointerEvent.transformPosition(transform, position);
return PointerEnterEvent(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
localPosition: transformedPosition,
delta: delta,
localDelta: PointerEvent.transformDeltaViaPositions(
transform: transform,
untransformedDelta: delta,
untransformedEndPosition: position,
transformedEndPosition: transformedPosition,
),
buttons: buttons,
obscured: obscured,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
down: down,
synthesized: synthesized,
transform: transform,
original: original as PointerEnterEvent? ?? this,
embedderId: embedderId,
);
return _TransformedPointerEnterEvent(original as PointerEnterEvent? ?? this, transform);
}
}
class _TransformedPointerEnterEvent extends _TransformedPointerEvent with _CopyPointerEnterEvent implements PointerEnterEvent {
_TransformedPointerEnterEvent(this.original, this.transform)
: assert(original != null), assert(transform != null);
@override
PointerEnterEvent copyWith({
final PointerEnterEvent original;
@override
final Matrix4 transform;
@override
PointerEnterEvent transformed(Matrix4? transform) => original.transformed(transform);
}
mixin _CopyPointerExitEvent on PointerEvent {
@override
PointerExitEvent copyWith({
Duration? timeStamp,
int? pointer,
PointerDeviceKind? kind,
int? device,
Offset? position,
Offset? localPosition,
Offset? delta,
Offset? localDelta,
int? buttons,
bool? obscured,
double? pressure,
......@@ -1220,18 +1304,14 @@ class PointerEnterEvent extends PointerEvent {
double? orientation,
double? tilt,
bool? synthesized,
Matrix4? transform,
PointerEvent? original,
int? embedderId,
}) {
return PointerEnterEvent(
return PointerExitEvent(
timeStamp: timeStamp ?? this.timeStamp,
kind: kind ?? this.kind,
device: device ?? this.device,
position: position ?? this.position,
localPosition: localPosition ?? this.localPosition,
delta: delta ?? this.delta,
localDelta: localDelta ?? this.localDelta,
buttons: buttons ?? this.buttons,
obscured: obscured ?? this.obscured,
pressureMin: pressureMin ?? this.pressureMin,
......@@ -1246,10 +1326,8 @@ class PointerEnterEvent extends PointerEvent {
orientation: orientation ?? this.orientation,
tilt: tilt ?? this.tilt,
synthesized: synthesized ?? this.synthesized,
transform: transform ?? this.transform,
original: original as PointerEnterEvent? ?? this,
embedderId: embedderId ?? this.embedderId,
);
).transformed(transform);
}
}
......@@ -1265,18 +1343,17 @@ class PointerEnterEvent extends PointerEvent {
/// contact with the device.
/// * [MouseRegion.onExit], which allows callers to be notified of these
/// events in a widget tree.
class PointerExitEvent extends PointerEvent {
class PointerExitEvent extends PointerEvent with _PointerEventDescription, _CopyPointerExitEvent {
/// Creates a pointer exit event.
///
/// All of the arguments must be non-null.
const PointerExitEvent({
Duration timeStamp = Duration.zero,
PointerDeviceKind kind = PointerDeviceKind.touch,
int pointer = 0,
int device = 0,
Offset position = Offset.zero,
Offset? localPosition,
Offset delta = Offset.zero,
Offset? localDelta,
int buttons = 0,
bool obscured = false,
double pressureMin = 1.0,
......@@ -1292,17 +1369,14 @@ class PointerExitEvent extends PointerEvent {
double tilt = 0.0,
bool down = false,
bool synthesized = false,
Matrix4? transform,
PointerExitEvent? original,
int embedderId = 0,
}) : super(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
localPosition: localPosition,
delta: delta,
localDelta: localDelta,
buttons: buttons,
down: down,
obscured: obscured,
......@@ -1319,31 +1393,28 @@ class PointerExitEvent extends PointerEvent {
orientation: orientation,
tilt: tilt,
synthesized: synthesized,
transform: transform,
original: original,
embedderId: embedderId,
);
/// Creates an exit event from a [PointerHoverEvent].
/// Creates an enter event from a [PointerHoverEvent].
///
/// Deprecated. Please use [PointerExitEvent.fromMouseEvent] instead.
@Deprecated(
'Use PointerExitEvent.fromMouseEvent instead. '
'This feature was deprecated after v1.4.3.'
)
PointerExitEvent.fromHoverEvent(PointerHoverEvent event) : this.fromMouseEvent(event);
factory PointerExitEvent.fromHoverEvent(PointerHoverEvent event) => PointerExitEvent.fromMouseEvent(event);
/// Creates an exit event from a [PointerEvent].
///
/// This is used by the [MouseTracker] to synthesize exit events.
PointerExitEvent.fromMouseEvent(PointerEvent event) : this(
factory PointerExitEvent.fromMouseEvent(PointerEvent event) => PointerExitEvent(
timeStamp: event.timeStamp,
pointer: event.pointer,
kind: event.kind,
device: event.device,
position: event.position,
localPosition: event.localPosition,
delta: event.delta,
localDelta: event.localDelta,
buttons: event.buttons,
obscured: event.obscured,
pressureMin: event.pressureMin,
......@@ -1359,60 +1430,41 @@ class PointerExitEvent extends PointerEvent {
tilt: event.tilt,
down: event.down,
synthesized: event.synthesized,
transform: event.transform,
original: null,
);
).transformed(event.transform);
@override
PointerExitEvent transformed(Matrix4? transform) {
if (transform == null || transform == this.transform) {
return this;
}
final Offset transformedPosition = PointerEvent.transformPosition(transform, position);
return PointerExitEvent(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
localPosition: transformedPosition,
delta: delta,
localDelta: PointerEvent.transformDeltaViaPositions(
transform: transform,
untransformedDelta: delta,
untransformedEndPosition: position,
transformedEndPosition: transformedPosition,
),
buttons: buttons,
obscured: obscured,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
down: down,
synthesized: synthesized,
transform: transform,
original: original as PointerExitEvent? ?? this,
embedderId: embedderId,
);
return _TransformedPointerExitEvent(original as PointerExitEvent? ?? this, transform);
}
}
class _TransformedPointerExitEvent extends _TransformedPointerEvent with _CopyPointerExitEvent implements PointerExitEvent {
_TransformedPointerExitEvent(this.original, this.transform)
: assert(original != null), assert(transform != null);
@override
PointerExitEvent copyWith({
final PointerExitEvent original;
@override
final Matrix4 transform;
@override
PointerExitEvent transformed(Matrix4? transform) => original.transformed(transform);
}
mixin _CopyPointerDownEvent on PointerEvent {
@override
PointerDownEvent copyWith({
Duration? timeStamp,
int? pointer,
PointerDeviceKind? kind,
int? device,
Offset? position,
Offset? localPosition,
Offset? delta,
Offset? localDelta,
int? buttons,
bool? obscured,
double? pressure,
......@@ -1428,23 +1480,19 @@ class PointerExitEvent extends PointerEvent {
double? orientation,
double? tilt,
bool? synthesized,
Matrix4? transform,
PointerEvent? original,
int? embedderId,
}) {
return PointerExitEvent(
return PointerDownEvent(
timeStamp: timeStamp ?? this.timeStamp,
pointer: pointer ?? this.pointer,
kind: kind ?? this.kind,
device: device ?? this.device,
position: position ?? this.position,
localPosition: localPosition ?? this.localPosition,
delta: delta ?? this.delta,
localDelta: localDelta ?? this.localDelta,
buttons: buttons ?? this.buttons,
obscured: obscured ?? this.obscured,
pressure: pressure ?? this.pressure,
pressureMin: pressureMin ?? this.pressureMin,
pressureMax: pressureMax ?? this.pressureMax,
distance: distance ?? this.distance,
distanceMax: distanceMax ?? this.distanceMax,
size: size ?? this.size,
radiusMajor: radiusMajor ?? this.radiusMajor,
......@@ -1453,11 +1501,8 @@ class PointerExitEvent extends PointerEvent {
radiusMax: radiusMax ?? this.radiusMax,
orientation: orientation ?? this.orientation,
tilt: tilt ?? this.tilt,
synthesized: synthesized ?? this.synthesized,
transform: transform ?? this.transform,
original: original as PointerExitEvent? ?? this,
embedderId: embedderId ?? this.embedderId,
);
).transformed(transform);
}
}
......@@ -1467,7 +1512,7 @@ class PointerExitEvent extends PointerEvent {
///
/// * [Listener.onPointerDown], which allows callers to be notified of these
/// events in a widget tree.
class PointerDownEvent extends PointerEvent {
class PointerDownEvent extends PointerEvent with _PointerEventDescription, _CopyPointerDownEvent {
/// Creates a pointer down event.
///
/// All of the arguments must be non-null.
......@@ -1477,7 +1522,6 @@ class PointerDownEvent extends PointerEvent {
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = Offset.zero,
Offset? localPosition,
int buttons = kPrimaryButton,
bool obscured = false,
double pressure = 1.0,
......@@ -1491,8 +1535,6 @@ class PointerDownEvent extends PointerEvent {
double radiusMax = 0.0,
double orientation = 0.0,
double tilt = 0.0,
Matrix4? transform,
PointerDownEvent? original,
int embedderId = 0,
}) : super(
timeStamp: timeStamp,
......@@ -1500,7 +1542,6 @@ class PointerDownEvent extends PointerEvent {
kind: kind,
device: device,
position: position,
localPosition: localPosition,
buttons: buttons,
down: true,
obscured: obscured,
......@@ -1516,8 +1557,6 @@ class PointerDownEvent extends PointerEvent {
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
transform: transform,
original: original,
embedderId: embedderId,
);
......@@ -1526,42 +1565,33 @@ class PointerDownEvent extends PointerEvent {
if (transform == null || transform == this.transform) {
return this;
}
return PointerDownEvent(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
localPosition: PointerEvent.transformPosition(transform, position),
buttons: buttons,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
transform: transform,
original: original as PointerDownEvent? ?? this,
embedderId: embedderId,
);
return _TransformedPointerDownEvent(original as PointerDownEvent? ?? this, transform);
}
}
class _TransformedPointerDownEvent extends _TransformedPointerEvent with _CopyPointerDownEvent implements PointerDownEvent {
_TransformedPointerDownEvent(this.original, this.transform)
: assert(original != null), assert(transform != null);
@override
PointerDownEvent copyWith({
final PointerDownEvent original;
@override
final Matrix4 transform;
@override
PointerDownEvent transformed(Matrix4? transform) => original.transformed(transform);
}
mixin _CopyPointerMoveEvent on PointerEvent {
@override
PointerMoveEvent copyWith({
Duration? timeStamp,
int? pointer,
PointerDeviceKind? kind,
int? device,
Offset? position,
Offset? localPosition,
Offset? delta,
Offset? localDelta,
int? buttons,
bool? obscured,
double? pressure,
......@@ -1577,17 +1607,15 @@ class PointerDownEvent extends PointerEvent {
double? orientation,
double? tilt,
bool? synthesized,
Matrix4? transform,
PointerEvent? original,
int? embedderId,
}) {
return PointerDownEvent(
return PointerMoveEvent(
timeStamp: timeStamp ?? this.timeStamp,
pointer: pointer ?? this.pointer,
kind: kind ?? this.kind,
device: device ?? this.device,
position: position ?? this.position,
localPosition: localPosition ?? this.localPosition,
delta: delta ?? this.delta,
buttons: buttons ?? this.buttons,
obscured: obscured ?? this.obscured,
pressure: pressure ?? this.pressure,
......@@ -1601,10 +1629,9 @@ class PointerDownEvent extends PointerEvent {
radiusMax: radiusMax ?? this.radiusMax,
orientation: orientation ?? this.orientation,
tilt: tilt ?? this.tilt,
transform: transform ?? this.transform,
original: original as PointerDownEvent? ?? this,
synthesized: synthesized ?? this.synthesized,
embedderId: embedderId ?? this.embedderId,
);
).transformed(transform);
}
}
......@@ -1617,7 +1644,7 @@ class PointerDownEvent extends PointerEvent {
/// contact with the device.
/// * [Listener.onPointerMove], which allows callers to be notified of these
/// events in a widget tree.
class PointerMoveEvent extends PointerEvent {
class PointerMoveEvent extends PointerEvent with _PointerEventDescription, _CopyPointerMoveEvent {
/// Creates a pointer move event.
///
/// All of the arguments must be non-null.
......@@ -1627,9 +1654,7 @@ class PointerMoveEvent extends PointerEvent {
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = Offset.zero,
Offset? localPosition,
Offset delta = Offset.zero,
Offset? localDelta,
int buttons = kPrimaryButton,
bool obscured = false,
double pressure = 1.0,
......@@ -1645,8 +1670,6 @@ class PointerMoveEvent extends PointerEvent {
double tilt = 0.0,
int platformData = 0,
bool synthesized = false,
Matrix4? transform,
PointerMoveEvent? original,
int embedderId = 0,
}) : super(
timeStamp: timeStamp,
......@@ -1654,9 +1677,7 @@ class PointerMoveEvent extends PointerEvent {
kind: kind,
device: device,
position: position,
localPosition: localPosition,
delta: delta,
localDelta: localDelta,
buttons: buttons,
down: true,
obscured: obscured,
......@@ -1674,8 +1695,6 @@ class PointerMoveEvent extends PointerEvent {
tilt: tilt,
platformData: platformData,
synthesized: synthesized,
transform: transform,
original: original,
embedderId: embedderId,
);
......@@ -1684,45 +1703,28 @@ class PointerMoveEvent extends PointerEvent {
if (transform == null || transform == this.transform) {
return this;
}
final Offset transformedPosition = PointerEvent.transformPosition(transform, position);
return PointerMoveEvent(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
localPosition: transformedPosition,
delta: delta,
localDelta: PointerEvent.transformDeltaViaPositions(
transform: transform,
untransformedDelta: delta,
untransformedEndPosition: position,
transformedEndPosition: transformedPosition,
),
buttons: buttons,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
platformData: platformData,
synthesized: synthesized,
transform: transform,
original: original as PointerMoveEvent? ?? this,
embedderId: embedderId,
);
return _TransformedPointerMoveEvent(original as PointerMoveEvent? ?? this, transform);
}
}
class _TransformedPointerMoveEvent extends _TransformedPointerEvent with _CopyPointerMoveEvent implements PointerMoveEvent {
_TransformedPointerMoveEvent(this.original, this.transform)
: assert(original != null), assert(transform != null);
@override
PointerMoveEvent copyWith({
final PointerMoveEvent original;
@override
final Matrix4 transform;
@override
PointerMoveEvent transformed(Matrix4? transform) => original.transformed(transform);
}
mixin _CopyPointerUpEvent on PointerEvent {
@override
PointerUpEvent copyWith({
Duration? timeStamp,
int? pointer,
PointerDeviceKind? kind,
......@@ -1730,7 +1732,6 @@ class PointerMoveEvent extends PointerEvent {
Offset? position,
Offset? localPosition,
Offset? delta,
Offset? localDelta,
int? buttons,
bool? obscured,
double? pressure,
......@@ -1746,24 +1747,20 @@ class PointerMoveEvent extends PointerEvent {
double? orientation,
double? tilt,
bool? synthesized,
Matrix4? transform,
PointerEvent? original,
int? embedderId,
}) {
return PointerMoveEvent(
return PointerUpEvent(
timeStamp: timeStamp ?? this.timeStamp,
pointer: pointer ?? this.pointer,
kind: kind ?? this.kind,
device: device ?? this.device,
position: position ?? this.position,
localPosition: localPosition ?? this.localPosition,
delta: delta ?? this.delta,
localDelta: localDelta ?? this.localDelta,
buttons: buttons ?? this.buttons,
obscured: obscured ?? this.obscured,
pressure: pressure ?? this.pressure,
pressureMin: pressureMin ?? this.pressureMin,
pressureMax: pressureMax ?? this.pressureMax,
distance: distance ?? this.distance,
distanceMax: distanceMax ?? this.distanceMax,
size: size ?? this.size,
radiusMajor: radiusMajor ?? this.radiusMajor,
......@@ -1772,11 +1769,8 @@ class PointerMoveEvent extends PointerEvent {
radiusMax: radiusMax ?? this.radiusMax,
orientation: orientation ?? this.orientation,
tilt: tilt ?? this.tilt,
synthesized: synthesized ?? this.synthesized,
transform: transform ?? this.transform,
original: original as PointerMoveEvent? ?? this,
embedderId: embedderId ?? this.embedderId,
);
).transformed(transform);
}
}
......@@ -1786,7 +1780,7 @@ class PointerMoveEvent extends PointerEvent {
///
/// * [Listener.onPointerUp], which allows callers to be notified of these
/// events in a widget tree.
class PointerUpEvent extends PointerEvent {
class PointerUpEvent extends PointerEvent with _PointerEventDescription, _CopyPointerUpEvent {
/// Creates a pointer up event.
///
/// All of the arguments must be non-null.
......@@ -1796,7 +1790,6 @@ class PointerUpEvent extends PointerEvent {
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = Offset.zero,
Offset? localPosition,
int buttons = 0,
bool obscured = false,
// Allow pressure customization here because PointerUpEvent can contain
......@@ -1813,8 +1806,6 @@ class PointerUpEvent extends PointerEvent {
double radiusMax = 0.0,
double orientation = 0.0,
double tilt = 0.0,
Matrix4? transform,
PointerUpEvent? original,
int embedderId = 0,
}) : super(
timeStamp: timeStamp,
......@@ -1822,7 +1813,6 @@ class PointerUpEvent extends PointerEvent {
kind: kind,
device: device,
position: position,
localPosition: localPosition,
buttons: buttons,
down: false,
obscured: obscured,
......@@ -1838,8 +1828,6 @@ class PointerUpEvent extends PointerEvent {
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
transform: transform,
original: original,
embedderId: embedderId,
);
......@@ -1848,88 +1836,22 @@ class PointerUpEvent extends PointerEvent {
if (transform == null || transform == this.transform) {
return this;
}
return PointerUpEvent(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
localPosition: PointerEvent.transformPosition(transform, position),
buttons: buttons,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
transform: transform,
original: original as PointerUpEvent? ?? this,
embedderId: embedderId,
);
return _TransformedPointerUpEvent(original as PointerUpEvent? ?? this, transform);
}
}
class _TransformedPointerUpEvent extends _TransformedPointerEvent with _CopyPointerUpEvent implements PointerUpEvent {
_TransformedPointerUpEvent(this.original, this.transform)
: assert(original != null), assert(transform != null);
@override
PointerUpEvent copyWith({
Duration? timeStamp,
int? pointer,
PointerDeviceKind? kind,
int? device,
Offset? position,
Offset? localPosition,
Offset? delta,
Offset? localDelta,
int? buttons,
bool? obscured,
double? pressure,
double? pressureMin,
double? pressureMax,
double? distance,
double? distanceMax,
double? size,
double? radiusMajor,
double? radiusMinor,
double? radiusMin,
double? radiusMax,
double? orientation,
double? tilt,
bool? synthesized,
Matrix4? transform,
PointerEvent? original,
int? embedderId,
}) {
return PointerUpEvent(
timeStamp: timeStamp ?? this.timeStamp,
pointer: pointer ?? this.pointer,
kind: kind ?? this.kind,
device: device ?? this.device,
position: position ?? this.position,
localPosition: localPosition ?? this.localPosition,
buttons: buttons ?? this.buttons,
obscured: obscured ?? this.obscured,
pressure: pressure ?? this.pressure,
pressureMin: pressureMin ?? this.pressureMin,
pressureMax: pressureMax ?? this.pressureMax,
distance: distance ?? this.distance,
distanceMax: distanceMax ?? this.distanceMax,
size: size ?? this.size,
radiusMajor: radiusMajor ?? this.radiusMajor,
radiusMinor: radiusMinor ?? this.radiusMinor,
radiusMin: radiusMin ?? this.radiusMin,
radiusMax: radiusMax ?? this.radiusMax,
orientation: orientation ?? this.orientation,
tilt: tilt ?? this.tilt,
transform: transform ?? this.transform,
original: original as PointerUpEvent? ?? this,
embedderId: embedderId ?? this.embedderId,
);
}
final PointerUpEvent original;
@override
final Matrix4 transform;
@override
PointerUpEvent transformed(Matrix4? transform) => original.transformed(transform);
}
/// An event that corresponds to a discrete pointer signal.
......@@ -1951,9 +1873,6 @@ abstract class PointerSignalEvent extends PointerEvent {
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = Offset.zero,
Offset? localPosition,
Matrix4? transform,
PointerSignalEvent? original,
int embedderId = 0,
}) : super(
timeStamp: timeStamp,
......@@ -1961,13 +1880,50 @@ abstract class PointerSignalEvent extends PointerEvent {
kind: kind,
device: device,
position: position,
localPosition: localPosition,
transform: transform,
original: original,
embedderId: embedderId,
);
}
mixin _CopyPointerScrollEvent on PointerEvent {
/// The amount to scroll, in logical pixels.
Offset get scrollDelta;
@override
PointerScrollEvent copyWith({
Duration? timeStamp,
int? pointer,
PointerDeviceKind? kind,
int? device,
Offset? position,
Offset? delta,
int? buttons,
bool? obscured,
double? pressure,
double? pressureMin,
double? pressureMax,
double? distance,
double? distanceMax,
double? size,
double? radiusMajor,
double? radiusMinor,
double? radiusMin,
double? radiusMax,
double? orientation,
double? tilt,
bool? synthesized,
int? embedderId,
}) {
return PointerScrollEvent(
timeStamp: timeStamp ?? this.timeStamp,
kind: kind ?? this.kind,
device: device ?? this.device,
position: position ?? this.position,
scrollDelta: scrollDelta,
embedderId: embedderId ?? this.embedderId,
).transformed(transform);
}
}
/// The pointer issued a scroll event.
///
/// Scrolling the scroll wheel on a mouse is an example of an event that
......@@ -1977,7 +1933,7 @@ abstract class PointerSignalEvent extends PointerEvent {
///
/// * [Listener.onPointerSignal], which allows callers to be notified of these
/// events in a widget tree.
class PointerScrollEvent extends PointerSignalEvent {
class PointerScrollEvent extends PointerSignalEvent with _PointerEventDescription, _CopyPointerScrollEvent {
/// Creates a pointer scroll event.
///
/// All of the arguments must be non-null.
......@@ -1986,10 +1942,7 @@ class PointerScrollEvent extends PointerSignalEvent {
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = Offset.zero,
Offset? localPosition,
this.scrollDelta = Offset.zero,
Matrix4? transform,
PointerScrollEvent? original,
int embedderId = 0,
}) : assert(timeStamp != null),
assert(kind != null),
......@@ -2001,13 +1954,10 @@ class PointerScrollEvent extends PointerSignalEvent {
kind: kind,
device: device,
position: position,
localPosition: localPosition,
transform: transform,
original: original,
embedderId: embedderId,
);
/// The amount to scroll, in logical pixels.
@override
final Offset scrollDelta;
@override
......@@ -2015,29 +1965,48 @@ class PointerScrollEvent extends PointerSignalEvent {
if (transform == null || transform == this.transform) {
return this;
}
return PointerScrollEvent(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
localPosition: PointerEvent.transformPosition(transform, position),
scrollDelta: scrollDelta,
transform: transform,
original: original as PointerScrollEvent? ?? this,
embedderId: embedderId,
);
return _TransformedPointerScrollEvent(original as PointerScrollEvent? ?? this, transform);
}
@override
PointerScrollEvent copyWith({
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('scrollDelta', scrollDelta));
}
}
class _TransformedPointerScrollEvent extends _TransformedPointerEvent with _CopyPointerScrollEvent implements PointerScrollEvent {
_TransformedPointerScrollEvent(this.original, this.transform)
: assert(original != null), assert(transform != null);
@override
final PointerScrollEvent original;
@override
final Matrix4 transform;
@override
Offset get scrollDelta => original.scrollDelta;
@override
PointerScrollEvent transformed(Matrix4? transform) => original.transformed(transform);
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('scrollDelta', scrollDelta));
}
}
mixin _CopyPointerCancelEvent on PointerEvent {
@override
PointerCancelEvent copyWith({
Duration? timeStamp,
int? pointer,
PointerDeviceKind? kind,
int? device,
Offset? position,
Offset? localPosition,
Offset? delta,
Offset? localDelta,
int? buttons,
bool? obscured,
double? pressure,
......@@ -2053,27 +2022,29 @@ class PointerScrollEvent extends PointerSignalEvent {
double? orientation,
double? tilt,
bool? synthesized,
Matrix4? transform,
PointerEvent? original,
int? embedderId,
}) {
return PointerScrollEvent(
return PointerCancelEvent(
timeStamp: timeStamp ?? this.timeStamp,
pointer: pointer ?? this.pointer,
kind: kind ?? this.kind,
device: device ?? this.device,
position: position ?? this.position,
localPosition: localPosition ?? this.localPosition,
scrollDelta: scrollDelta,
transform: transform ?? this.transform,
original: original as PointerScrollEvent? ?? this,
buttons: buttons ?? this.buttons,
obscured: obscured ?? this.obscured,
pressureMin: pressureMin ?? this.pressureMin,
pressureMax: pressureMax ?? this.pressureMax,
distance: distance ?? this.distance,
distanceMax: distanceMax ?? this.distanceMax,
size: size ?? this.size,
radiusMajor: radiusMajor ?? this.radiusMajor,
radiusMinor: radiusMinor ?? this.radiusMinor,
radiusMin: radiusMin ?? this.radiusMin,
radiusMax: radiusMax ?? this.radiusMax,
orientation: orientation ?? this.orientation,
tilt: tilt ?? this.tilt,
embedderId: embedderId ?? this.embedderId,
);
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('scrollDelta', scrollDelta));
).transformed(transform);
}
}
......@@ -2083,7 +2054,7 @@ class PointerScrollEvent extends PointerSignalEvent {
///
/// * [Listener.onPointerCancel], which allows callers to be notified of these
/// events in a widget tree.
class PointerCancelEvent extends PointerEvent {
class PointerCancelEvent extends PointerEvent with _PointerEventDescription, _CopyPointerCancelEvent {
/// Creates a pointer cancel event.
///
/// All of the arguments must be non-null.
......@@ -2093,7 +2064,6 @@ class PointerCancelEvent extends PointerEvent {
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = Offset.zero,
Offset? localPosition,
int buttons = 0,
bool obscured = false,
double pressureMin = 1.0,
......@@ -2107,8 +2077,6 @@ class PointerCancelEvent extends PointerEvent {
double radiusMax = 0.0,
double orientation = 0.0,
double tilt = 0.0,
Matrix4? transform,
PointerCancelEvent? original,
int embedderId = 0,
}) : super(
timeStamp: timeStamp,
......@@ -2116,7 +2084,6 @@ class PointerCancelEvent extends PointerEvent {
kind: kind,
device: device,
position: position,
localPosition: localPosition,
buttons: buttons,
down: false,
obscured: obscured,
......@@ -2132,8 +2099,6 @@ class PointerCancelEvent extends PointerEvent {
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
transform: transform,
original: original,
embedderId: embedderId,
);
......@@ -2142,85 +2107,7 @@ class PointerCancelEvent extends PointerEvent {
if (transform == null || transform == this.transform) {
return this;
}
return PointerCancelEvent(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
localPosition: PointerEvent.transformPosition(transform, position),
buttons: buttons,
obscured: obscured,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
transform: transform,
original: original as PointerCancelEvent? ?? this,
embedderId: embedderId,
);
}
@override
PointerCancelEvent copyWith({
Duration? timeStamp,
int? pointer,
PointerDeviceKind? kind,
int? device,
Offset? position,
Offset? localPosition,
Offset? delta,
Offset? localDelta,
int? buttons,
bool? obscured,
double? pressure,
double? pressureMin,
double? pressureMax,
double? distance,
double? distanceMax,
double? size,
double? radiusMajor,
double? radiusMinor,
double? radiusMin,
double? radiusMax,
double? orientation,
double? tilt,
bool? synthesized,
Matrix4? transform,
PointerEvent? original,
int? embedderId,
}) {
return PointerCancelEvent(
timeStamp: timeStamp ?? this.timeStamp,
pointer: pointer ?? this.pointer,
kind: kind ?? this.kind,
device: device ?? this.device,
position: position ?? this.position,
localPosition: localPosition ?? this.localPosition,
buttons: buttons ?? this.buttons,
obscured: obscured ?? this.obscured,
pressureMin: pressureMin ?? this.pressureMin,
pressureMax: pressureMax ?? this.pressureMax,
distance: distance ?? this.distance,
distanceMax: distanceMax ?? this.distanceMax,
size: size ?? this.size,
radiusMajor: radiusMajor ?? this.radiusMajor,
radiusMinor: radiusMinor ?? this.radiusMinor,
radiusMin: radiusMin ?? this.radiusMin,
radiusMax: radiusMax ?? this.radiusMax,
orientation: orientation ?? this.orientation,
tilt: tilt ?? this.tilt,
transform: transform ?? this.transform,
original: original as PointerCancelEvent? ?? this,
embedderId: embedderId ?? this.embedderId,
);
return _TransformedPointerCancelEvent(original as PointerCancelEvent? ?? this, transform);
}
}
......@@ -2262,3 +2149,17 @@ double computeScaleSlop(PointerDeviceKind kind) {
return kScaleSlop;
}
}
class _TransformedPointerCancelEvent extends _TransformedPointerEvent with _CopyPointerCancelEvent implements PointerCancelEvent {
_TransformedPointerCancelEvent(this.original, this.transform)
: assert(original != null), assert(transform != null);
@override
final PointerCancelEvent original;
@override
final Matrix4 transform;
@override
PointerCancelEvent transformed(Matrix4? transform) => original.transformed(transform);
}
......@@ -568,27 +568,22 @@ class _AndroidMotionEventConverter {
}
int action;
switch (event.runtimeType) {
case PointerDownEvent:
action = numPointers == 1
? AndroidViewController.kActionDown
: AndroidViewController.pointerAction(
pointerIdx, AndroidViewController.kActionPointerDown);
break;
case PointerUpEvent:
action = numPointers == 1
? AndroidViewController.kActionUp
: AndroidViewController.pointerAction(
pointerIdx, AndroidViewController.kActionPointerUp);
break;
case PointerMoveEvent:
action = AndroidViewController.kActionMove;
break;
case PointerCancelEvent:
action = AndroidViewController.kActionCancel;
break;
default:
return null;
if (event is PointerDownEvent) {
action = numPointers == 1
? AndroidViewController.kActionDown
: AndroidViewController.pointerAction(
pointerIdx, AndroidViewController.kActionPointerDown);
} else if (event is PointerUpEvent) {
action = numPointers == 1
? AndroidViewController.kActionUp
: AndroidViewController.pointerAction(
pointerIdx, AndroidViewController.kActionPointerUp);
} else if (event is PointerMoveEvent) {
action = AndroidViewController.kActionMove;
} else if (event is PointerCancelEvent) {
action = AndroidViewController.kActionCancel;
} else {
return null;
}
return AndroidMotionEvent(
......
......@@ -83,7 +83,7 @@ void main() {
await tester.pump(const Duration(milliseconds: 7));
expect(events.length, 1);
expect(events[0].runtimeType, equals(PointerDownEvent));
expect(events[0], isA<PointerDownEvent>());
expect(events[0].timeStamp, currentTestFrameTime() + kSamplingOffset);
expect(events[0].position, Offset(5.0 / ui.window.devicePixelRatio, 0.0));
......@@ -91,7 +91,7 @@ void main() {
await tester.pump(const Duration(milliseconds: 2));
expect(events.length, 2);
expect(events[1].timeStamp, currentTestFrameTime() + kSamplingOffset);
expect(events[1].runtimeType, equals(PointerMoveEvent));
expect(events[1], isA<PointerMoveEvent>());
expect(events[1].position, Offset(25.0 / ui.window.devicePixelRatio, 0.0));
expect(events[1].delta, Offset(20.0 / ui.window.devicePixelRatio, 0.0));
......@@ -99,11 +99,11 @@ void main() {
await tester.pump(const Duration(milliseconds: 2));
expect(events.length, 4);
expect(events[2].timeStamp, currentTestFrameTime() + kSamplingOffset);
expect(events[2].runtimeType, equals(PointerMoveEvent));
expect(events[2], isA<PointerMoveEvent>());
expect(events[2].position, Offset(40.0 / ui.window.devicePixelRatio, 0.0));
expect(events[2].delta, Offset(15.0 / ui.window.devicePixelRatio, 0.0));
expect(events[3].timeStamp, currentTestFrameTime() + kSamplingOffset);
expect(events[3].runtimeType, equals(PointerUpEvent));
expect(events[3], isA<PointerUpEvent>());
expect(events[3].position, Offset(40.0 / ui.window.devicePixelRatio, 0.0));
});
}
......@@ -63,8 +63,8 @@ void main() {
ui.window.onPointerDataPacket(packet);
expect(events.length, 2);
expect(events[0].runtimeType, equals(PointerDownEvent));
expect(events[1].runtimeType, equals(PointerUpEvent));
expect(events[0], isA<PointerDownEvent>());
expect(events[1], isA<PointerUpEvent>());
});
test('Pointer move events', () {
......@@ -81,9 +81,9 @@ void main() {
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));
expect(events[0], isA<PointerDownEvent>());
expect(events[1], isA<PointerMoveEvent>());
expect(events[2], isA<PointerUpEvent>());
});
test('Pointer hover events', () {
......@@ -108,12 +108,12 @@ void main() {
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));
expect(pointerRouterEvents[0], isA<PointerAddedEvent>());
expect(pointerRouterEvents[1], isA<PointerHoverEvent>());
expect(pointerRouterEvents[2], isA<PointerHoverEvent>());
expect(pointerRouterEvents[3], isA<PointerRemovedEvent>());
expect(pointerRouterEvents[4], isA<PointerAddedEvent>());
expect(pointerRouterEvents[5], isA<PointerHoverEvent>());
});
test('Pointer cancel events', () {
......@@ -129,8 +129,8 @@ void main() {
ui.window.onPointerDataPacket(packet);
expect(events.length, 2);
expect(events[0].runtimeType, equals(PointerDownEvent));
expect(events[1].runtimeType, equals(PointerCancelEvent));
expect(events[0], isA<PointerDownEvent>());
expect(events[1], isA<PointerCancelEvent>());
});
test('Can cancel pointers', () {
......@@ -150,8 +150,8 @@ void main() {
ui.window.onPointerDataPacket(packet);
expect(events.length, 2);
expect(events[0].runtimeType, equals(PointerDownEvent));
expect(events[1].runtimeType, equals(PointerCancelEvent));
expect(events[0], isA<PointerDownEvent>());
expect(events[1], isA<PointerCancelEvent>());
});
test('Can expand add and hover pointers', () {
......@@ -169,11 +169,11 @@ void main() {
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));
expect(events[0], isA<PointerAddedEvent>());
expect(events[1], isA<PointerHoverEvent>());
expect(events[2], isA<PointerRemovedEvent>());
expect(events[3], isA<PointerAddedEvent>());
expect(events[4], isA<PointerHoverEvent>());
});
test('Can expand pointer scroll events', () {
......@@ -188,8 +188,8 @@ void main() {
packet.data, ui.window.devicePixelRatio).toList();
expect(events.length, 2);
expect(events[0].runtimeType, equals(PointerAddedEvent));
expect(events[1].runtimeType, equals(PointerScrollEvent));
expect(events[0], isA<PointerAddedEvent>());
expect(events[1], isA<PointerScrollEvent>());
});
test('Should synthesize kPrimaryButton for touch', () {
......@@ -209,15 +209,15 @@ void main() {
packet.data, ui.window.devicePixelRatio).toList();
expect(events.length, 5);
expect(events[0].runtimeType, equals(PointerAddedEvent));
expect(events[0], isA<PointerAddedEvent>());
expect(events[0].buttons, equals(0));
expect(events[1].runtimeType, equals(PointerHoverEvent));
expect(events[1], isA<PointerHoverEvent>());
expect(events[1].buttons, equals(0));
expect(events[2].runtimeType, equals(PointerDownEvent));
expect(events[2], isA<PointerDownEvent>());
expect(events[2].buttons, equals(kPrimaryButton));
expect(events[3].runtimeType, equals(PointerMoveEvent));
expect(events[3], isA<PointerMoveEvent>());
expect(events[3].buttons, equals(kPrimaryButton));
expect(events[4].runtimeType, equals(PointerUpEvent));
expect(events[4], isA<PointerUpEvent>());
expect(events[4].buttons, equals(0));
});
......@@ -242,15 +242,15 @@ void main() {
packet.data, ui.window.devicePixelRatio).toList();
expect(events.length, 5);
expect(events[0].runtimeType, equals(PointerAddedEvent));
expect(events[0], isA<PointerAddedEvent>());
expect(events[0].buttons, equals(0));
expect(events[1].runtimeType, equals(PointerHoverEvent));
expect(events[1], isA<PointerHoverEvent>());
expect(events[1].buttons, equals(0));
expect(events[2].runtimeType, equals(PointerDownEvent));
expect(events[2], isA<PointerDownEvent>());
expect(events[2].buttons, equals(kPrimaryButton));
expect(events[3].runtimeType, equals(PointerMoveEvent));
expect(events[3], isA<PointerMoveEvent>());
expect(events[3].buttons, equals(kPrimaryButton | kSecondaryStylusButton));
expect(events[4].runtimeType, equals(PointerUpEvent));
expect(events[4], isA<PointerUpEvent>());
expect(events[4].buttons, equals(0));
}
});
......@@ -272,15 +272,15 @@ void main() {
packet.data, ui.window.devicePixelRatio).toList();
expect(events.length, 5);
expect(events[0].runtimeType, equals(PointerAddedEvent));
expect(events[0], isA<PointerAddedEvent>());
expect(events[0].buttons, equals(0));
expect(events[1].runtimeType, equals(PointerHoverEvent));
expect(events[1], isA<PointerHoverEvent>());
expect(events[1].buttons, equals(0));
expect(events[2].runtimeType, equals(PointerDownEvent));
expect(events[2], isA<PointerDownEvent>());
expect(events[2].buttons, equals(kPrimaryButton));
expect(events[3].runtimeType, equals(PointerMoveEvent));
expect(events[3], isA<PointerMoveEvent>());
expect(events[3].buttons, equals(kPrimaryButton));
expect(events[4].runtimeType, equals(PointerUpEvent));
expect(events[4], isA<PointerUpEvent>());
expect(events[4].buttons, equals(0));
});
......@@ -303,15 +303,15 @@ void main() {
packet.data, ui.window.devicePixelRatio).toList();
expect(events.length, 5);
expect(events[0].runtimeType, equals(PointerAddedEvent));
expect(events[0], isA<PointerAddedEvent>());
expect(events[0].buttons, equals(0));
expect(events[1].runtimeType, equals(PointerHoverEvent));
expect(events[1], isA<PointerHoverEvent>());
expect(events[1].buttons, equals(0));
expect(events[2].runtimeType, equals(PointerDownEvent));
expect(events[2], isA<PointerDownEvent>());
expect(events[2].buttons, equals(kMiddleMouseButton));
expect(events[3].runtimeType, equals(PointerMoveEvent));
expect(events[3], isA<PointerMoveEvent>());
expect(events[3].buttons, equals(kMiddleMouseButton | kSecondaryMouseButton));
expect(events[4].runtimeType, equals(PointerUpEvent));
expect(events[4], isA<PointerUpEvent>());
expect(events[4].buttons, equals(0));
}
});
......
......@@ -59,7 +59,7 @@ void main() {
});
expect(tested, isTrue);
expect(events.length, 2);
expect(events[0].runtimeType, equals(PointerDownEvent));
expect(events[1].runtimeType, equals(PointerUpEvent));
expect(events[0], isA<PointerDownEvent>());
expect(events[1], isA<PointerUpEvent>());
});
}
......@@ -82,6 +82,8 @@ void main() {
_binding.postFrameCallbacks.clear();
});
final Matrix4 translate10by20 = Matrix4.translationValues(10, 20, 0);
test('MouseTrackerAnnotation has correct toString', () {
final MouseTrackerAnnotation annotation1 = MouseTrackerAnnotation(
onEnter: (_) {},
......@@ -125,8 +127,8 @@ void main() {
]));
addTearDown(() => dispatchRemoveDevice());
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerEnterEvent(position: Offset(0.0, 0.0)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerEnterEvent>(const PointerEnterEvent(position: Offset(0.0, 0.0))),
]));
expect(listenerLogs, <bool>[true]);
events.clear();
......@@ -136,8 +138,8 @@ void main() {
ui.window.onPointerDataPacket(ui.PointerDataPacket(data: <ui.PointerData>[
_pointerData(PointerChange.hover, const Offset(1.0, 101.0)),
]));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerHoverEvent(position: Offset(1.0, 101.0)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerHoverEvent>(const PointerHoverEvent(position: Offset(1.0, 101.0))),
]));
expect(_mouseTracker.mouseIsConnected, isTrue);
expect(listenerLogs, isEmpty);
......@@ -147,8 +149,8 @@ void main() {
ui.window.onPointerDataPacket(ui.PointerDataPacket(data: <ui.PointerData>[
_pointerData(PointerChange.remove, const Offset(1.0, 101.0)),
]));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerExitEvent(position: Offset(1.0, 101.0)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerExitEvent>(const PointerExitEvent(position: Offset(1.0, 101.0))),
]));
expect(listenerLogs, <bool>[false]);
events.clear();
......@@ -158,8 +160,8 @@ void main() {
ui.window.onPointerDataPacket(ui.PointerDataPacket(data: <ui.PointerData>[
_pointerData(PointerChange.add, const Offset(0.0, 301.0)),
]));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerEnterEvent(position: Offset(0.0, 301.0)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerEnterEvent>(const PointerEnterEvent(position: Offset(0.0, 301.0))),
]));
expect(listenerLogs, <bool>[true]);
events.clear();
......@@ -177,9 +179,9 @@ void main() {
_pointerData(PointerChange.add, const Offset(0.0, 0.0)),
_pointerData(PointerChange.hover, const Offset(0.0, 1.0)),
]));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerEnterEvent(position: Offset(0.0, 0.0)),
const PointerHoverEvent(position: Offset(0.0, 1.0)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerEnterEvent>(const PointerEnterEvent(position: Offset(0.0, 0.0))),
EventMatcher<PointerHoverEvent>(const PointerHoverEvent(position: Offset(0.0, 1.0))),
]));
expect(_mouseTracker.mouseIsConnected, isTrue);
events.clear();
......@@ -189,9 +191,9 @@ void main() {
_pointerData(PointerChange.add, const Offset(0.0, 401.0), device: 1),
_pointerData(PointerChange.hover, const Offset(1.0, 401.0), device: 1),
]));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerEnterEvent(position: Offset(0.0, 401.0), device: 1),
const PointerHoverEvent(position: Offset(1.0, 401.0), device: 1),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerEnterEvent>(const PointerEnterEvent(position: Offset(0.0, 401.0), device: 1)),
EventMatcher<PointerHoverEvent>(const PointerHoverEvent(position: Offset(1.0, 401.0), device: 1)),
]));
expect(_mouseTracker.mouseIsConnected, isTrue);
events.clear();
......@@ -200,8 +202,8 @@ void main() {
ui.window.onPointerDataPacket(ui.PointerDataPacket(data: <ui.PointerData>[
_pointerData(PointerChange.hover, const Offset(0.0, 101.0)),
]));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerHoverEvent(position: Offset(0.0, 101.0)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerHoverEvent>(const PointerHoverEvent(position: Offset(0.0, 101.0))),
]));
expect(_mouseTracker.mouseIsConnected, isTrue);
events.clear();
......@@ -210,8 +212,8 @@ void main() {
ui.window.onPointerDataPacket(ui.PointerDataPacket(data: <ui.PointerData>[
_pointerData(PointerChange.hover, const Offset(1.0, 501.0), device: 1),
]));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerHoverEvent(position: Offset(1.0, 501.0), device: 1),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerHoverEvent>(const PointerHoverEvent(position: Offset(1.0, 501.0), device: 1)),
]));
expect(_mouseTracker.mouseIsConnected, isTrue);
events.clear();
......@@ -220,8 +222,8 @@ void main() {
ui.window.onPointerDataPacket(ui.PointerDataPacket(data: <ui.PointerData>[
_pointerData(PointerChange.remove, const Offset(0.0, 101.0)),
]));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerExitEvent(position: Offset(0.0, 101.0)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerExitEvent>(const PointerExitEvent(position: Offset(0.0, 101.0))),
]));
expect(_mouseTracker.mouseIsConnected, isTrue);
events.clear();
......@@ -230,8 +232,8 @@ void main() {
ui.window.onPointerDataPacket(ui.PointerDataPacket(data: <ui.PointerData>[
_pointerData(PointerChange.hover, const Offset(1.0, 601.0), device: 1),
]));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerHoverEvent(position: Offset(1.0, 601.0), device: 1),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerHoverEvent>(const PointerHoverEvent(position: Offset(1.0, 601.0), device: 1)),
]));
expect(_mouseTracker.mouseIsConnected, isTrue);
events.clear();
......@@ -240,8 +242,8 @@ void main() {
ui.window.onPointerDataPacket(ui.PointerDataPacket(data: <ui.PointerData>[
_pointerData(PointerChange.remove, const Offset(1.0, 601.0), device: 1),
]));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerExitEvent(position: Offset(1.0, 601.0), device: 1),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerExitEvent>(const PointerExitEvent(position: Offset(1.0, 601.0), device: 1)),
]));
expect(_mouseTracker.mouseIsConnected, isFalse);
events.clear();
......@@ -256,24 +258,24 @@ void main() {
_pointerData(PointerChange.down, const Offset(0.0, 101.0)),
]));
addTearDown(() => dispatchRemoveDevice());
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
// This Enter event is triggered by the [PointerAddedEvent] The
// [PointerDownEvent] is ignored by [MouseTracker].
const PointerEnterEvent(position: Offset(0.0, 101.0)),
EventMatcher<PointerEnterEvent>(const PointerEnterEvent(position: Offset(0.0, 101.0))),
]));
events.clear();
ui.window.onPointerDataPacket(ui.PointerDataPacket(data: <ui.PointerData>[
_pointerData(PointerChange.move, const Offset(0.0, 201.0)),
]));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
]));
events.clear();
ui.window.onPointerDataPacket(ui.PointerDataPacket(data: <ui.PointerData>[
_pointerData(PointerChange.up, const Offset(0.0, 301.0)),
]));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
]));
events.clear();
});
......@@ -299,7 +301,7 @@ void main() {
_pointerData(PointerChange.add, const Offset(0.0, 100.0)),
]));
addTearDown(() => dispatchRemoveDevice());
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
]));
expect(_mouseTracker.mouseIsConnected, isTrue);
events.clear();
......@@ -310,8 +312,8 @@ void main() {
expect(_binding.postFrameCallbacks, hasLength(1));
_binding.flushPostFrameCallbacks(Duration.zero);
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerEnterEvent(position: Offset(0, 100), localPosition: Offset(10, 120)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerEnterEvent>(const PointerEnterEvent(position: Offset(0, 100)).transformed(translate10by20)),
]));
events.clear();
......@@ -321,8 +323,8 @@ void main() {
expect(_binding.postFrameCallbacks, hasLength(1));
_binding.flushPostFrameCallbacks(Duration.zero);
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerExitEvent(position: Offset(0.0, 100.0), localPosition: Offset(10, 120)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerExitEvent>(const PointerExitEvent(position: Offset(0.0, 100.0)).transformed(translate10by20)),
]));
expect(_binding.postFrameCallbacks, hasLength(0));
});
......@@ -357,8 +359,8 @@ void main() {
expect(_binding.postFrameCallbacks, hasLength(1));
_binding.flushPostFrameCallbacks(Duration.zero);
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerEnterEvent(position: Offset(0.0, 100.0), localPosition: Offset(10, 120)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerEnterEvent>(const PointerEnterEvent(position: Offset(0.0, 100.0)).transformed(translate10by20)),
]));
events.clear();
......@@ -371,8 +373,8 @@ void main() {
expect(_binding.postFrameCallbacks, hasLength(1));
_binding.flushPostFrameCallbacks(Duration.zero);
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerExitEvent(position: Offset(0.0, 100.0), localPosition: Offset(10, 120)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerExitEvent>(const PointerExitEvent(position: Offset(0.0, 100.0)).transformed(translate10by20)),
]));
expect(_binding.postFrameCallbacks, hasLength(0));
});
......@@ -400,8 +402,8 @@ void main() {
]));
expect(_binding.postFrameCallbacks, hasLength(0));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerEnterEvent(position: Offset(0.0, 100.0), localPosition: Offset(10, 120)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerEnterEvent>(const PointerEnterEvent(position: Offset(0.0, 100.0)).transformed(translate10by20)),
]));
events.clear();
......@@ -410,8 +412,8 @@ void main() {
_pointerData(PointerChange.remove, const Offset(0.0, 100.0)),
]));
expect(_binding.postFrameCallbacks, hasLength(0));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerExitEvent(position: Offset(0.0, 100.0), localPosition: Offset(10, 120)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerExitEvent>(const PointerExitEvent(position: Offset(0.0, 100.0)).transformed(translate10by20)),
]));
});
......@@ -444,9 +446,9 @@ void main() {
_pointerData(PointerChange.hover, const Offset(0.0, 100.0)),
]));
expect(_binding.postFrameCallbacks, hasLength(0));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerEnterEvent(position: Offset(0.0, 100.0), localPosition: Offset(10, 120)),
const PointerHoverEvent(position: Offset(0.0, 100.0), localPosition: Offset(10, 120)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerEnterEvent>(const PointerEnterEvent(position: Offset(0.0, 100.0)).transformed(translate10by20)),
EventMatcher<PointerHoverEvent>(const PointerHoverEvent(position: Offset(0.0, 100.0)).transformed(translate10by20)),
]));
events.clear();
......@@ -456,8 +458,8 @@ void main() {
_pointerData(PointerChange.hover, const Offset(200.0, 100.0)),
]));
expect(_binding.postFrameCallbacks, hasLength(0));
expect(events, _equalToEventsOnCriticalFields(<PointerEvent>[
const PointerExitEvent(position: Offset(200.0, 100.0), localPosition: Offset(210, 120)),
expect(events, _equalToEventsOnCriticalFields(<BaseEventMatcher>[
EventMatcher<PointerExitEvent>(const PointerExitEvent(position: Offset(200.0, 100.0)).transformed(translate10by20)),
]));
});
......@@ -629,11 +631,11 @@ ui.PointerData _pointerData(
);
}
class _EventCriticalFieldsMatcher extends Matcher {
_EventCriticalFieldsMatcher(this._expected)
: assert(_expected != null);
class BaseEventMatcher extends Matcher {
BaseEventMatcher(this.expected)
: assert(expected != null);
final PointerEvent _expected;
final PointerEvent expected;
bool _matchesField(Map<dynamic, dynamic> matchState, String field,
dynamic actual, dynamic expected) {
......@@ -650,16 +652,12 @@ class _EventCriticalFieldsMatcher extends Matcher {
@override
bool matches(dynamic untypedItem, Map<dynamic, dynamic> matchState) {
if (untypedItem.runtimeType != _expected.runtimeType) {
return false;
}
final PointerEvent actual = untypedItem as PointerEvent;
if (!(
_matchesField(matchState, 'kind', actual.kind, PointerDeviceKind.mouse) &&
_matchesField(matchState, 'position', actual.position, _expected.position) &&
_matchesField(matchState, 'device', actual.device, _expected.device) &&
_matchesField(matchState, 'localPosition', actual.localPosition, _expected.localPosition)
_matchesField(matchState, 'position', actual.position, expected.position) &&
_matchesField(matchState, 'device', actual.device, expected.device) &&
_matchesField(matchState, 'localPosition', actual.localPosition, expected.localPosition)
)) {
return false;
}
......@@ -670,7 +668,7 @@ class _EventCriticalFieldsMatcher extends Matcher {
Description describe(Description description) {
return description
.add('event (critical fields only) ')
.addDescriptionOf(_expected);
.addDescriptionOf(expected);
}
@override
......@@ -680,13 +678,6 @@ class _EventCriticalFieldsMatcher extends Matcher {
Map<dynamic, dynamic> matchState,
bool verbose,
) {
if (item.runtimeType != _expected.runtimeType) {
return mismatchDescription
.add('is ')
.addDescriptionOf(item.runtimeType)
.add(" and doesn't match ")
.addDescriptionOf(_expected.runtimeType);
}
return mismatchDescription
.add('has ')
.addDescriptionOf(matchState['actual'])
......@@ -695,10 +686,40 @@ class _EventCriticalFieldsMatcher extends Matcher {
}
}
class EventMatcher<T extends PointerEvent> extends BaseEventMatcher {
EventMatcher(T expected) : super(expected);
@override
bool matches(dynamic untypedItem, Map<dynamic, dynamic> matchState) {
if (untypedItem is! T) {
return false;
}
return super.matches(untypedItem, matchState);
}
@override
Description describeMismatch(
dynamic item,
Description mismatchDescription,
Map<dynamic, dynamic> matchState,
bool verbose,
) {
if (item is! T) {
return mismatchDescription
.add('is ')
.addDescriptionOf(item.runtimeType)
.add(' and is not a subtype of ')
.addDescriptionOf(T);
}
return super.describeMismatch(item, mismatchDescription, matchState, verbose);
}
}
class _EventListCriticalFieldsMatcher extends Matcher {
_EventListCriticalFieldsMatcher(this._expected);
final Iterable<PointerEvent> _expected;
final Iterable<BaseEventMatcher> _expected;
@override
bool matches(dynamic untypedItem, Map<dynamic, dynamic> matchState) {
......@@ -709,15 +730,14 @@ class _EventListCriticalFieldsMatcher extends Matcher {
if (item.length != _expected.length)
return false;
int i = 0;
for (final PointerEvent e in _expected) {
for (final BaseEventMatcher matcher in _expected) {
iterator.moveNext();
final Matcher matcher = _EventCriticalFieldsMatcher(e);
final Map<dynamic, dynamic> subState = <dynamic, dynamic>{};
final PointerEvent actual = iterator.current;
if (!matcher.matches(actual, subState)) {
addStateInfo(matchState, <dynamic, dynamic>{
'index': i,
'expected': e,
'expected': matcher.expected,
'actual': actual,
'matcher': matcher,
'state': subState,
......@@ -769,6 +789,6 @@ class _EventListCriticalFieldsMatcher extends Matcher {
}
}
Matcher _equalToEventsOnCriticalFields(List<PointerEvent> source) {
Matcher _equalToEventsOnCriticalFields(List<BaseEventMatcher> source) {
return _EventListCriticalFieldsMatcher(source);
}
......@@ -2552,7 +2552,7 @@ void main() {
await gesture.moveTo(const Offset(400, 300));
expect(logs, <String>['enter1']);
expect(controller.dispatchedPointerEvents, hasLength(1));
expect(controller.dispatchedPointerEvents[0].runtimeType, PointerHoverEvent);
expect(controller.dispatchedPointerEvents[0], isA<PointerHoverEvent>());
logs.clear();
controller.dispatchedPointerEvents.clear();
......@@ -2582,7 +2582,7 @@ void main() {
await gesture.moveBy(const Offset(1, 1));
expect(logs, isEmpty);
expect(controller.dispatchedPointerEvents, hasLength(1));
expect(controller.dispatchedPointerEvents[0].runtimeType, PointerHoverEvent);
expect(controller.dispatchedPointerEvents[0], isA<PointerHoverEvent>());
expect(controller.dispatchedPointerEvents[0].position, const Offset(401, 301));
expect(controller.dispatchedPointerEvents[0].localPosition, const Offset(101, 101));
controller.dispatchedPointerEvents.clear();
......@@ -2617,6 +2617,6 @@ void main() {
await gesture.moveBy(const Offset(1, 1));
expect(logs, isEmpty);
expect(controller.dispatchedPointerEvents, hasLength(1));
expect(controller.dispatchedPointerEvents[0].runtimeType, PointerHoverEvent);
expect(controller.dispatchedPointerEvents[0], isA<PointerHoverEvent>());
});
}
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