Introduces PositionedGestureDetails (#160714)

Resolves #101530

`PositionedGestureDetails` is an abstract interface that is meant to
contain positions for pointer events.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
Alex Li 2025-04-22 10:45:01 +08:00 committed by GitHub
parent eea3fdf2a8
commit 3ac8b26bc4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 559 additions and 198 deletions

View File

@ -17,6 +17,7 @@ export 'src/gestures/drag_details.dart';
export 'src/gestures/eager.dart';
export 'src/gestures/events.dart';
export 'src/gestures/force_press.dart';
export 'src/gestures/gesture_details.dart';
export 'src/gestures/gesture_settings.dart';
export 'src/gestures/hit_test.dart';
export 'src/gestures/long_press.dart';

View File

@ -7,6 +7,7 @@ library;
import 'package:flutter/foundation.dart';
import 'gesture_details.dart';
import 'velocity_tracker.dart';
export 'dart:ui' show Offset, PointerDeviceKind;
@ -21,29 +22,25 @@ export 'velocity_tracker.dart' show Velocity;
/// * [DragStartDetails], the details for [GestureDragStartCallback].
/// * [DragUpdateDetails], the details for [GestureDragUpdateCallback].
/// * [DragEndDetails], the details for [GestureDragEndCallback].
class DragDownDetails {
class DragDownDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates details for a [GestureDragDownCallback].
DragDownDetails({this.globalPosition = Offset.zero, Offset? localPosition})
: localPosition = localPosition ?? globalPosition;
/// The global position at which the pointer contacted the screen.
///
/// Defaults to the origin if not specified in the constructor.
///
/// See also:
///
/// * [localPosition], which is the [globalPosition] transformed to the
/// coordinate space of the event receiver.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// The local position in the coordinate system of the event receiver at
/// which the pointer contacted the screen.
///
/// Defaults to [globalPosition] if not specified in the constructor.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
@override
String toString() => '${objectRuntimeType(this, 'DragDownDetails')}($globalPosition)';
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
}
}
/// Signature for when a pointer has contacted the screen and might begin to
@ -62,46 +59,40 @@ typedef GestureDragDownCallback = void Function(DragDownDetails details);
/// * [DragDownDetails], the details for [GestureDragDownCallback].
/// * [DragUpdateDetails], the details for [GestureDragUpdateCallback].
/// * [DragEndDetails], the details for [GestureDragEndCallback].
class DragStartDetails {
class DragStartDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates details for a [GestureDragStartCallback].
DragStartDetails({
this.sourceTimeStamp,
this.globalPosition = Offset.zero,
Offset? localPosition,
this.sourceTimeStamp,
this.kind,
}) : localPosition = localPosition ?? globalPosition;
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// Recorded timestamp of the source pointer event that triggered the drag
/// event.
///
/// Could be null if triggered from proxied events such as accessibility.
final Duration? sourceTimeStamp;
/// The global position at which the pointer contacted the screen.
///
/// Defaults to the origin if not specified in the constructor.
///
/// See also:
///
/// * [localPosition], which is the [globalPosition] transformed to the
/// coordinate space of the event receiver.
final Offset globalPosition;
/// The local position in the coordinate system of the event receiver at
/// which the pointer contacted the screen.
///
/// Defaults to [globalPosition] if not specified in the constructor.
final Offset localPosition;
/// The kind of the device that initiated the event.
final PointerDeviceKind? kind;
// TODO(ianh): Expose the current position, so that you can have a no-jump
// drag even when disambiguating (though of course it would lag the finger
// instead).
@override
String toString() => '${objectRuntimeType(this, 'DragStartDetails')}($globalPosition)';
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(DiagnosticsProperty<Duration?>('sourceTimeStamp', sourceTimeStamp));
properties.add(EnumProperty<PointerDeviceKind?>('kind', kind));
}
}
/// {@template flutter.gestures.dragdetails.GestureDragStartCallback}
@ -122,17 +113,17 @@ typedef GestureDragStartCallback = void Function(DragStartDetails details);
/// * [DragDownDetails], the details for [GestureDragDownCallback].
/// * [DragStartDetails], the details for [GestureDragStartCallback].
/// * [DragEndDetails], the details for [GestureDragEndCallback].
class DragUpdateDetails {
class DragUpdateDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates details for a [GestureDragUpdateCallback].
///
/// If [primaryDelta] is non-null, then its value must match one of the
/// coordinates of [delta] and the other coordinate must be zero.
DragUpdateDetails({
required this.globalPosition,
Offset? localPosition,
this.sourceTimeStamp,
this.delta = Offset.zero,
this.primaryDelta,
required this.globalPosition,
Offset? localPosition,
}) : assert(
primaryDelta == null ||
(primaryDelta == delta.dx && delta.dy == 0.0) ||
@ -140,6 +131,14 @@ class DragUpdateDetails {
),
localPosition = localPosition ?? globalPosition;
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// Recorded timestamp of the source pointer event that triggered the drag
/// event.
///
@ -169,22 +168,15 @@ class DragUpdateDetails {
/// Defaults to null if not specified in the constructor.
final double? primaryDelta;
/// The pointer's global position when it triggered this update.
///
/// See also:
///
/// * [localPosition], which is the [globalPosition] transformed to the
/// coordinate space of the event receiver.
final Offset globalPosition;
/// The local position in the coordinate system of the event receiver at
/// which the pointer contacted the screen.
///
/// Defaults to [globalPosition] if not specified in the constructor.
final Offset localPosition;
@override
String toString() => '${objectRuntimeType(this, 'DragUpdateDetails')}($delta)';
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(DiagnosticsProperty<Duration?>('sourceTimeStamp', sourceTimeStamp));
properties.add(DiagnosticsProperty<Offset>('delta', delta));
properties.add(DoubleProperty('primaryDelta', primaryDelta));
}
}
/// {@template flutter.gestures.dragdetails.GestureDragUpdateCallback}
@ -206,17 +198,17 @@ typedef GestureDragUpdateCallback = void Function(DragUpdateDetails details);
/// * [DragDownDetails], the details for [GestureDragDownCallback].
/// * [DragStartDetails], the details for [GestureDragStartCallback].
/// * [DragUpdateDetails], the details for [GestureDragUpdateCallback].
class DragEndDetails {
class DragEndDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates details for a [GestureDragEndCallback].
///
/// If [primaryVelocity] is non-null, its value must match one of the
/// coordinates of `velocity.pixelsPerSecond` and the other coordinate
/// must be zero.
DragEndDetails({
this.velocity = Velocity.zero,
this.primaryVelocity,
this.globalPosition = Offset.zero,
Offset? localPosition,
this.velocity = Velocity.zero,
this.primaryVelocity,
}) : assert(
primaryVelocity == null ||
(primaryVelocity == velocity.pixelsPerSecond.dx && velocity.pixelsPerSecond.dy == 0) ||
@ -224,6 +216,14 @@ class DragEndDetails {
),
localPosition = localPosition ?? globalPosition;
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// The velocity the pointer was moving when it stopped contacting the screen.
///
/// Defaults to zero if not specified in the constructor.
@ -241,23 +241,12 @@ class DragEndDetails {
/// Defaults to null if not specified in the constructor.
final double? primaryVelocity;
/// The global position the pointer is located at when the drag
/// gesture has been completed.
///
/// Defaults to the origin if not specified in the constructor.
///
/// See also:
///
/// * [localPosition], which is the [globalPosition] transformed to the
/// coordinate space of the event receiver.
final Offset globalPosition;
/// The local position in the coordinate system of the event receiver when
/// the drag gesture has been completed.
///
/// Defaults to [globalPosition] if not specified in the constructor.
final Offset localPosition;
@override
String toString() => '${objectRuntimeType(this, 'DragEndDetails')}($velocity)';
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(DiagnosticsProperty<Velocity>('velocity', velocity));
properties.add(DoubleProperty('primaryVelocity', primaryVelocity));
}
}

View File

@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart' show clampDouble;
import 'package:flutter/foundation.dart';
import 'events.dart';
import 'gesture_details.dart';
import 'recognizer.dart';
export 'dart:ui' show Offset, PointerDeviceKind;
@ -43,20 +44,30 @@ enum _ForceState {
/// * [ForcePressGestureRecognizer.onStart], [ForcePressGestureRecognizer.onPeak],
/// [ForcePressGestureRecognizer.onEnd], and [ForcePressGestureRecognizer.onUpdate]
/// which use [ForcePressDetails].
class ForcePressDetails {
class ForcePressDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates details for a [GestureForcePressStartCallback],
/// [GestureForcePressPeakCallback] or [GestureForcePressEndCallback].
ForcePressDetails({required this.globalPosition, Offset? localPosition, required this.pressure})
: localPosition = localPosition ?? globalPosition;
/// The global position at which the function was called.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// The local position at which the function was called.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// The pressure of the pointer on the screen.
final double pressure;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(DoubleProperty('pressure', pressure));
}
}
/// Signature used by a [ForcePressGestureRecognizer] for when a pointer has

View File

@ -0,0 +1,43 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show Offset;
/// An abstract interface representing gesture details that include positional information.
///
/// This class serve as a common interface for gesture details that involve positional data,
/// such as dragging and tapping. It simplifies gesture handling by enabling the use of shared logic
/// across multiple gesture types, users can create a method to handle a single gesture details
/// with this position information. For example:
///
/// ```dart
/// void handlePositionedGestures(PositionedGestureDetails details) {
/// // Handle the positional information of the gesture details.
/// }
/// ```
abstract interface class PositionedGestureDetails {
/// Creates details with positions.
const PositionedGestureDetails({required this.globalPosition, required this.localPosition});
/// {@template flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
/// The global position at which the pointer interacts with the screen.
///
/// See also:
///
/// * [localPosition], which is the [globalPosition] transformed to the
/// coordinate space of the event receiver.
/// {@endtemplate}
final Offset globalPosition;
/// {@template flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
/// The local position in the coordinate system of the event receiver at
/// which the pointer interacts with the screen.
///
/// See also:
///
/// * [globalPosition], which is the global position at which the pointer
/// interacts with the screen.
/// {@endtemplate}
final Offset localPosition;
}

View File

@ -5,8 +5,11 @@
/// @docImport 'package:flutter/widgets.dart';
library;
import 'package:flutter/foundation.dart';
import 'constants.dart';
import 'events.dart';
import 'gesture_details.dart';
import 'recognizer.dart';
import 'velocity_tracker.dart';
@ -107,7 +110,7 @@ typedef GestureLongPressEndCallback = void Function(LongPressEndDetails details)
/// passes these details.
/// * [LongPressGestureRecognizer.onTertiaryLongPressDown], whose callback
/// passes these details.
class LongPressDownDetails {
class LongPressDownDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates the details for a [GestureLongPressDownCallback].
///
/// If the `localPosition` argument is not specified, it will default to the
@ -115,14 +118,24 @@ class LongPressDownDetails {
const LongPressDownDetails({this.globalPosition = Offset.zero, Offset? localPosition, this.kind})
: localPosition = localPosition ?? globalPosition;
/// The global position at which the pointer contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// The kind of the device that initiated the event.
final PointerDeviceKind? kind;
/// The local position at which the pointer contacted the screen.
final Offset localPosition;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(EnumProperty<PointerDeviceKind?>('kind', kind));
}
}
/// Details for callbacks that use [GestureLongPressStartCallback].
@ -132,16 +145,25 @@ class LongPressDownDetails {
/// * [LongPressGestureRecognizer.onLongPressStart], which uses [GestureLongPressStartCallback].
/// * [LongPressMoveUpdateDetails], the details for [GestureLongPressMoveUpdateCallback]
/// * [LongPressEndDetails], the details for [GestureLongPressEndCallback].
class LongPressStartDetails {
class LongPressStartDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates the details for a [GestureLongPressStartCallback].
const LongPressStartDetails({this.globalPosition = Offset.zero, Offset? localPosition})
: localPosition = localPosition ?? globalPosition;
/// The global position at which the pointer initially contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// The local position at which the pointer initially contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
}
}
/// Details for callbacks that use [GestureLongPressMoveUpdateCallback].
@ -151,7 +173,7 @@ class LongPressStartDetails {
/// * [LongPressGestureRecognizer.onLongPressMoveUpdate], which uses [GestureLongPressMoveUpdateCallback].
/// * [LongPressEndDetails], the details for [GestureLongPressEndCallback]
/// * [LongPressStartDetails], the details for [GestureLongPressStartCallback].
class LongPressMoveUpdateDetails {
class LongPressMoveUpdateDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates the details for a [GestureLongPressMoveUpdateCallback].
const LongPressMoveUpdateDetails({
this.globalPosition = Offset.zero,
@ -161,10 +183,12 @@ class LongPressMoveUpdateDetails {
}) : localPosition = localPosition ?? globalPosition,
localOffsetFromOrigin = localOffsetFromOrigin ?? offsetFromOrigin;
/// The global position of the pointer when it triggered this update.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// The local position of the pointer when it triggered this update.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// A delta offset from the point where the long press drag initially contacted
@ -176,6 +200,15 @@ class LongPressMoveUpdateDetails {
/// the screen to the point where the pointer is currently located (the
/// present [localPosition]) when this callback is triggered.
final Offset localOffsetFromOrigin;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(DiagnosticsProperty<Offset>('offsetFromOrigin', offsetFromOrigin));
properties.add(DiagnosticsProperty<Offset>('localOffsetFromOrigin', localOffsetFromOrigin));
}
}
/// Details for callbacks that use [GestureLongPressEndCallback].
@ -185,7 +218,7 @@ class LongPressMoveUpdateDetails {
/// * [LongPressGestureRecognizer.onLongPressEnd], which uses [GestureLongPressEndCallback].
/// * [LongPressMoveUpdateDetails], the details for [GestureLongPressMoveUpdateCallback].
/// * [LongPressStartDetails], the details for [GestureLongPressStartCallback].
class LongPressEndDetails {
class LongPressEndDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates the details for a [GestureLongPressEndCallback].
const LongPressEndDetails({
this.globalPosition = Offset.zero,
@ -193,16 +226,26 @@ class LongPressEndDetails {
this.velocity = Velocity.zero,
}) : localPosition = localPosition ?? globalPosition;
/// The global position at which the pointer lifted from the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// The local position at which the pointer contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// The pointer's velocity when it stopped contacting the screen.
///
/// Defaults to zero if not specified in the constructor.
final Velocity velocity;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(DiagnosticsProperty<Velocity>('velocity', velocity));
}
}
/// Recognizes when the user has pressed down at the same location for a long

View File

@ -7,10 +7,13 @@ library;
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'arena.dart';
import 'binding.dart';
import 'constants.dart';
import 'events.dart';
import 'gesture_details.dart';
import 'pointer_router.dart';
import 'recognizer.dart';
import 'tap.dart';
@ -615,7 +618,7 @@ typedef GestureSerialTapDownCallback = void Function(SerialTapDownDetails detail
///
/// * [SerialTapGestureRecognizer], which passes this information to its
/// [SerialTapGestureRecognizer.onSerialTapDown] callback.
class SerialTapDownDetails {
class SerialTapDownDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates details for a [GestureSerialTapDownCallback].
///
/// The `count` argument must be greater than zero.
@ -628,10 +631,12 @@ class SerialTapDownDetails {
}) : assert(count > 0),
localPosition = localPosition ?? globalPosition;
/// The global position at which the pointer contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// The local position at which the pointer contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// The kind of the device that initiated the event.
@ -655,6 +660,16 @@ class SerialTapDownDetails {
/// the two taps had too much distance between them), then this count will
/// reset back to `1`, and a new series will have begun.
final int count;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(EnumProperty<PointerDeviceKind>('kind', kind));
properties.add(IntProperty('buttons', buttons));
properties.add(IntProperty('count', count));
}
}
/// Signature used by [SerialTapGestureRecognizer.onSerialTapCancel] for when a
@ -669,7 +684,7 @@ typedef GestureSerialTapCancelCallback = void Function(SerialTapCancelDetails de
///
/// * [SerialTapGestureRecognizer], which passes this information to its
/// [SerialTapGestureRecognizer.onSerialTapCancel] callback.
class SerialTapCancelDetails {
class SerialTapCancelDetails with Diagnosticable {
/// Creates details for a [GestureSerialTapCancelCallback].
///
/// The `count` argument must be greater than zero.
@ -682,6 +697,12 @@ class SerialTapCancelDetails {
/// [SerialTapDownDetails.count] for the tap that is being canceled. See
/// that field for more information on how this count is reported.
final int count;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(IntProperty('count', count));
}
}
/// Signature used by [SerialTapGestureRecognizer.onSerialTapUp] for when a
@ -695,7 +716,7 @@ typedef GestureSerialTapUpCallback = void Function(SerialTapUpDetails details);
///
/// * [SerialTapGestureRecognizer], which passes this information to its
/// [SerialTapGestureRecognizer.onSerialTapUp] callback.
class SerialTapUpDetails {
class SerialTapUpDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates details for a [GestureSerialTapUpCallback].
///
/// The `count` argument must be greater than zero.
@ -707,10 +728,12 @@ class SerialTapUpDetails {
}) : assert(count > 0),
localPosition = localPosition ?? globalPosition;
/// The global position at which the pointer contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// The local position at which the pointer contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// The kind of the device that initiated the event.
@ -727,6 +750,15 @@ class SerialTapUpDetails {
/// the two taps had too much distance between them), then this count will
/// reset back to `1`, and a new series will have begun.
final int count;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(EnumProperty<PointerDeviceKind?>('kind', kind));
properties.add(IntProperty('count', count));
}
}
/// Recognizes serial taps (taps in a series).

View File

@ -4,6 +4,8 @@
import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'constants.dart';
import 'events.dart';
import 'recognizer.dart';
@ -92,7 +94,7 @@ class _PointerPanZoomData {
}
/// Details for [GestureScaleStartCallback].
class ScaleStartDetails {
class ScaleStartDetails with Diagnosticable {
/// Creates details for [GestureScaleStartCallback].
ScaleStartDetails({
this.focalPoint = Offset.zero,
@ -142,12 +144,17 @@ class ScaleStartDetails {
final PointerDeviceKind? kind;
@override
String toString() =>
'ScaleStartDetails(focalPoint: $focalPoint, localFocalPoint: $localFocalPoint, pointersCount: $pointerCount)';
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('focalPoint', focalPoint));
properties.add(DiagnosticsProperty<Offset>('localFocalPoint', localFocalPoint));
properties.add(IntProperty('pointerCount', pointerCount));
properties.add(DiagnosticsProperty<Duration?>('sourceTimeStamp', sourceTimeStamp));
}
}
/// Details for [GestureScaleUpdateCallback].
class ScaleUpdateDetails {
class ScaleUpdateDetails with Diagnosticable {
/// Creates details for [GestureScaleUpdateCallback].
///
/// The [scale], [horizontalScale], and [verticalScale] arguments must be
@ -247,21 +254,22 @@ class ScaleUpdateDetails {
final Duration? sourceTimeStamp;
@override
String toString() =>
'ScaleUpdateDetails('
'focalPoint: $focalPoint,'
' localFocalPoint: $localFocalPoint,'
' scale: $scale,'
' horizontalScale: $horizontalScale,'
' verticalScale: $verticalScale,'
' rotation: $rotation,'
' pointerCount: $pointerCount,'
' focalPointDelta: $focalPointDelta,'
' sourceTimeStamp: $sourceTimeStamp)';
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('focalPointDelta', focalPointDelta));
properties.add(DiagnosticsProperty<Offset>('focalPoint', focalPoint));
properties.add(DiagnosticsProperty<Offset>('localFocalPoint', localFocalPoint));
properties.add(DoubleProperty('scale', scale));
properties.add(DoubleProperty('horizontalScale', horizontalScale));
properties.add(DoubleProperty('verticalScale', verticalScale));
properties.add(DoubleProperty('rotation', rotation));
properties.add(IntProperty('pointerCount', pointerCount));
properties.add(DiagnosticsProperty<Duration?>('sourceTimeStamp', sourceTimeStamp));
}
}
/// Details for [GestureScaleEndCallback].
class ScaleEndDetails {
class ScaleEndDetails with Diagnosticable {
/// Creates details for [GestureScaleEndCallback].
ScaleEndDetails({this.velocity = Velocity.zero, this.scaleVelocity = 0, this.pointerCount = 0});
@ -278,8 +286,12 @@ class ScaleEndDetails {
final int pointerCount;
@override
String toString() =>
'ScaleEndDetails(velocity: $velocity, scaleVelocity: $scaleVelocity, pointerCount: $pointerCount)';
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Velocity>('velocity', velocity));
properties.add(DoubleProperty('scaleVelocity', scaleVelocity));
properties.add(IntProperty('pointerCount', pointerCount));
}
}
/// Signature for when the pointers in contact with the screen have established

View File

@ -12,6 +12,7 @@ import 'package:flutter/foundation.dart';
import 'arena.dart';
import 'constants.dart';
import 'events.dart';
import 'gesture_details.dart';
import 'recognizer.dart';
export 'dart:ui' show Offset, PointerDeviceKind;
@ -28,19 +29,29 @@ export 'events.dart' show PointerCancelEvent, PointerDownEvent, PointerEvent, Po
///
/// * [GestureDetector.onTapDown], which receives this information.
/// * [TapGestureRecognizer], which passes this information to one of its callbacks.
class TapDownDetails {
class TapDownDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates details for a [GestureTapDownCallback].
TapDownDetails({this.globalPosition = Offset.zero, Offset? localPosition, this.kind})
: localPosition = localPosition ?? globalPosition;
/// The global position at which the pointer contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// The kind of the device that initiated the event.
final PointerDeviceKind? kind;
/// The local position at which the pointer contacted the screen.
final Offset localPosition;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(EnumProperty<PointerDeviceKind?>('kind', kind));
}
}
/// {@template flutter.gestures.tap.GestureTapDownCallback}
@ -63,19 +74,29 @@ typedef GestureTapDownCallback = void Function(TapDownDetails details);
///
/// * [GestureDetector.onTapUp], which receives this information.
/// * [TapGestureRecognizer], which passes this information to one of its callbacks.
class TapUpDetails {
class TapUpDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates a [TapUpDetails] data object.
TapUpDetails({required this.kind, this.globalPosition = Offset.zero, Offset? localPosition})
TapUpDetails({this.globalPosition = Offset.zero, Offset? localPosition, required this.kind})
: localPosition = localPosition ?? globalPosition;
/// The global position at which the pointer contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// The local position at which the pointer contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// The kind of the device that initiated the event.
final PointerDeviceKind kind;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(EnumProperty<PointerDeviceKind>('kind', kind));
}
}
/// Details object for callbacks that use [GestureTapMoveCallback].
@ -400,7 +421,7 @@ abstract class BaseTapGestureRecognizer extends PrimaryPointerGestureRecognizer
defaultValue: _up?.position,
),
);
properties.add(DiagnosticsProperty<int>('button', _down?.buttons, defaultValue: null));
properties.add(IntProperty('button', _down?.buttons, defaultValue: null));
properties.add(FlagProperty('sentTapDown', value: _sentTapDown, ifTrue: 'sent tap down'));
}
}

View File

@ -13,6 +13,7 @@ import 'package:flutter/foundation.dart';
import 'constants.dart';
import 'events.dart';
import 'gesture_details.dart';
import 'monodrag.dart';
import 'recognizer.dart';
import 'scale.dart';
@ -79,7 +80,7 @@ typedef GestureTapDragDownCallback = void Function(TapDragDownDetails details);
/// * [TapDragStartDetails], the details for [GestureTapDragStartCallback].
/// * [TapDragUpdateDetails], the details for [GestureTapDragUpdateCallback].
/// * [TapDragEndDetails], the details for [GestureTapDragEndCallback].
class TapDragDownDetails with Diagnosticable {
class TapDragDownDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates details for a [GestureTapDragDownCallback].
TapDragDownDetails({
required this.globalPosition,
@ -88,10 +89,12 @@ class TapDragDownDetails with Diagnosticable {
required this.consecutiveTapCount,
});
/// The global position at which the pointer contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// The local position at which the pointer contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// The kind of the device that initiated the event.
@ -106,8 +109,8 @@ class TapDragDownDetails with Diagnosticable {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(DiagnosticsProperty<PointerDeviceKind?>('kind', kind));
properties.add(DiagnosticsProperty<int>('consecutiveTapCount', consecutiveTapCount));
properties.add(EnumProperty<PointerDeviceKind?>('kind', kind));
properties.add(IntProperty('consecutiveTapCount', consecutiveTapCount));
}
}
@ -130,19 +133,21 @@ typedef GestureTapDragUpCallback = void Function(TapDragUpDetails details);
/// * [TapDragStartDetails], the details for [GestureTapDragStartCallback].
/// * [TapDragUpdateDetails], the details for [GestureTapDragUpdateCallback].
/// * [TapDragEndDetails], the details for [GestureTapDragEndCallback].
class TapDragUpDetails with Diagnosticable {
class TapDragUpDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates details for a [GestureTapDragUpCallback].
TapDragUpDetails({
required this.kind,
required this.globalPosition,
required this.localPosition,
required this.kind,
required this.consecutiveTapCount,
});
/// The global position at which the pointer contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// The local position at which the pointer contacted the screen.
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// The kind of the device that initiated the event.
@ -157,8 +162,8 @@ class TapDragUpDetails with Diagnosticable {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(DiagnosticsProperty<PointerDeviceKind?>('kind', kind));
properties.add(DiagnosticsProperty<int>('consecutiveTapCount', consecutiveTapCount));
properties.add(EnumProperty<PointerDeviceKind?>('kind', kind));
properties.add(IntProperty('consecutiveTapCount', consecutiveTapCount));
}
}
@ -181,34 +186,30 @@ typedef GestureTapDragStartCallback = void Function(TapDragStartDetails details)
/// * [TapDragUpDetails], the details for [GestureTapDragUpCallback].
/// * [TapDragUpdateDetails], the details for [GestureTapDragUpdateCallback].
/// * [TapDragEndDetails], the details for [GestureTapDragEndCallback].
class TapDragStartDetails with Diagnosticable {
class TapDragStartDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates details for a [GestureTapDragStartCallback].
TapDragStartDetails({
this.sourceTimeStamp,
required this.globalPosition,
required this.localPosition,
this.sourceTimeStamp,
this.kind,
required this.consecutiveTapCount,
});
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// Recorded timestamp of the source pointer event that triggered the drag
/// event.
///
/// Could be null if triggered from proxied events such as accessibility.
final Duration? sourceTimeStamp;
/// The global position at which the pointer contacted the screen.
///
/// See also:
///
/// * [localPosition], which is the [globalPosition] transformed to the
/// coordinate space of the event receiver.
final Offset globalPosition;
/// The local position in the coordinate system of the event receiver at
/// which the pointer contacted the screen.
final Offset localPosition;
/// The kind of the device that initiated the event.
final PointerDeviceKind? kind;
@ -219,11 +220,11 @@ class TapDragStartDetails with Diagnosticable {
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Duration?>('sourceTimeStamp', sourceTimeStamp));
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(DiagnosticsProperty<PointerDeviceKind?>('kind', kind));
properties.add(DiagnosticsProperty<int>('consecutiveTapCount', consecutiveTapCount));
properties.add(DiagnosticsProperty<Duration?>('sourceTimeStamp', sourceTimeStamp));
properties.add(EnumProperty<PointerDeviceKind?>('kind', kind));
properties.add(IntProperty('consecutiveTapCount', consecutiveTapCount));
}
}
@ -246,18 +247,18 @@ typedef GestureTapDragUpdateCallback = void Function(TapDragUpdateDetails detail
/// * [TapDragUpDetails], the details for [GestureTapDragUpCallback].
/// * [TapDragStartDetails], the details for [GestureTapDragStartCallback].
/// * [TapDragEndDetails], the details for [GestureTapDragEndCallback].
class TapDragUpdateDetails with Diagnosticable {
class TapDragUpdateDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates details for a [GestureTapDragUpdateCallback].
///
/// If [primaryDelta] is non-null, then its value must match one of the
/// coordinates of [delta] and the other coordinate must be zero.
TapDragUpdateDetails({
required this.globalPosition,
required this.localPosition,
this.sourceTimeStamp,
this.delta = Offset.zero,
this.primaryDelta,
required this.globalPosition,
this.kind,
required this.localPosition,
required this.offsetFromOrigin,
required this.localOffsetFromOrigin,
required this.consecutiveTapCount,
@ -267,6 +268,14 @@ class TapDragUpdateDetails with Diagnosticable {
(primaryDelta == delta.dy && delta.dx == 0.0),
);
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// Recorded timestamp of the source pointer event that triggered the drag
/// event.
///
@ -296,20 +305,6 @@ class TapDragUpdateDetails with Diagnosticable {
/// Defaults to null if not specified in the constructor.
final double? primaryDelta;
/// The pointer's global position when it triggered this update.
///
/// See also:
///
/// * [localPosition], which is the [globalPosition] transformed to the
/// coordinate space of the event receiver.
final Offset globalPosition;
/// The local position in the coordinate system of the event receiver at
/// which the pointer contacted the screen.
///
/// Defaults to [globalPosition] if not specified in the constructor.
final Offset localPosition;
/// The kind of the device that initiated the event.
final PointerDeviceKind? kind;
@ -336,15 +331,15 @@ class TapDragUpdateDetails with Diagnosticable {
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Duration?>('sourceTimeStamp', sourceTimeStamp));
properties.add(DiagnosticsProperty<Offset>('delta', delta));
properties.add(DiagnosticsProperty<double?>('primaryDelta', primaryDelta));
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(DiagnosticsProperty<PointerDeviceKind?>('kind', kind));
properties.add(DiagnosticsProperty<Duration?>('sourceTimeStamp', sourceTimeStamp));
properties.add(DiagnosticsProperty<Offset>('delta', delta));
properties.add(DoubleProperty('primaryDelta', primaryDelta));
properties.add(EnumProperty<PointerDeviceKind?>('kind', kind));
properties.add(DiagnosticsProperty<Offset>('offsetFromOrigin', offsetFromOrigin));
properties.add(DiagnosticsProperty<Offset>('localOffsetFromOrigin', localOffsetFromOrigin));
properties.add(DiagnosticsProperty<int>('consecutiveTapCount', consecutiveTapCount));
properties.add(IntProperty('consecutiveTapCount', consecutiveTapCount));
}
}
@ -367,14 +362,14 @@ typedef GestureTapDragEndCallback = void Function(TapDragEndDetails endDetails);
/// * [TapDragUpDetails], the details for [GestureTapDragUpCallback].
/// * [TapDragStartDetails], the details for [GestureTapDragStartCallback].
/// * [TapDragUpdateDetails], the details for [GestureTapDragUpdateCallback].
class TapDragEndDetails with Diagnosticable {
class TapDragEndDetails with Diagnosticable implements PositionedGestureDetails {
/// Creates details for a [GestureTapDragEndCallback].
TapDragEndDetails({
this.globalPosition = Offset.zero,
Offset? localPosition,
this.velocity = Velocity.zero,
this.primaryVelocity,
required this.consecutiveTapCount,
this.globalPosition = Offset.zero,
Offset? localPosition,
}) : assert(
primaryVelocity == null ||
primaryVelocity == velocity.pixelsPerSecond.dx ||
@ -382,6 +377,14 @@ class TapDragEndDetails with Diagnosticable {
),
localPosition = localPosition ?? globalPosition;
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.globalPosition}
@override
final Offset globalPosition;
/// {@macro flutter.gestures.gesturedetails.PositionedGestureDetails.localPosition}
@override
final Offset localPosition;
/// The velocity the pointer was moving when it stopped contacting the screen.
///
/// Defaults to zero if not specified in the constructor.
@ -403,28 +406,14 @@ class TapDragEndDetails with Diagnosticable {
/// the number in the series this tap is.
final int consecutiveTapCount;
/// The global position at which the pointer lifted from the screen.
///
/// See also:
///
/// * [localPosition], which is the [globalPosition] transformed to the
/// coordinate space of the event receiver.
final Offset globalPosition;
/// The local position in the coordinate system of the event receiver at which
/// the pointer lifted from the screen.
///
/// Defaults to [globalPosition] if not specified in the constructor.
final Offset localPosition;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Velocity>('velocity', velocity));
properties.add(DiagnosticsProperty<double?>('primaryVelocity', primaryVelocity));
properties.add(DiagnosticsProperty<int>('consecutiveTapCount', consecutiveTapCount));
properties.add(DiagnosticsProperty<Offset>('globalPosition', globalPosition));
properties.add(DiagnosticsProperty<Offset>('localPosition', localPosition));
properties.add(DiagnosticsProperty<Velocity>('velocity', velocity));
properties.add(DoubleProperty('primaryVelocity', primaryVelocity));
properties.add(IntProperty('consecutiveTapCount', consecutiveTapCount));
}
}
@ -1464,12 +1453,12 @@ class TapAndPanGestureRecognizer extends BaseTapAndDragGestureRecognizer {
String get debugDescription => 'tap and pan';
}
/// {@macro flutter.gestures.selectionrecognizers.TapAndPanGestureRecognizer}
@Deprecated(
'Use TapAndPanGestureRecognizer instead. '
'TapAndPanGestureRecognizer works exactly the same but has a more disambiguated name from BaseTapAndDragGestureRecognizer. '
'This feature was deprecated after v3.9.0-19.0.pre.',
)
/// {@macro flutter.gestures.selectionrecognizers.TapAndPanGestureRecognizer}
class TapAndDragGestureRecognizer extends BaseTapAndDragGestureRecognizer {
/// Create a gesture recognizer for interactions on a plane.
@Deprecated(

View File

@ -223,4 +223,224 @@ void main() {
GestureBinding.instance.gestureArena.close(1);
tap.dispose();
});
test('Gesture details debugFillProperties', () {
final List<(Diagnosticable, List<String>)> pairs = <(Diagnosticable, List<String>)>[
(
DragDownDetails(),
<String>['globalPosition: Offset(0.0, 0.0)', 'localPosition: Offset(0.0, 0.0)'],
),
(
DragStartDetails(),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'sourceTimeStamp: null',
'kind: null',
],
),
(
DragUpdateDetails(globalPosition: Offset.zero),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'sourceTimeStamp: null',
'delta: Offset(0.0, 0.0)',
'primaryDelta: null',
],
),
(
DragEndDetails(),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'velocity: Velocity(0.0, 0.0)',
'primaryVelocity: null',
],
),
(
ForcePressDetails(globalPosition: Offset.zero, pressure: 1.0),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'pressure: 1.0',
],
),
(
const LongPressDownDetails(),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'kind: null',
],
),
(
const LongPressStartDetails(),
<String>['globalPosition: Offset(0.0, 0.0)', 'localPosition: Offset(0.0, 0.0)'],
),
(
const LongPressMoveUpdateDetails(),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'offsetFromOrigin: Offset(0.0, 0.0)',
'localOffsetFromOrigin: Offset(0.0, 0.0)',
],
),
(
const LongPressEndDetails(),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'velocity: Velocity(0.0, 0.0)',
],
),
(
SerialTapDownDetails(kind: PointerDeviceKind.unknown),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'kind: unknown',
'buttons: 0',
'count: 1',
],
),
(SerialTapCancelDetails(), <String>['count: 1']),
(
SerialTapUpDetails(),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'kind: null',
'count: 1',
],
),
(
ScaleStartDetails(),
<String>[
'focalPoint: Offset(0.0, 0.0)',
'localFocalPoint: Offset(0.0, 0.0)',
'pointerCount: 0',
'sourceTimeStamp: null',
],
),
(
ScaleUpdateDetails(),
<String>[
'focalPointDelta: Offset(0.0, 0.0)',
'focalPoint: Offset(0.0, 0.0)',
'localFocalPoint: Offset(0.0, 0.0)',
'scale: 1.0',
'horizontalScale: 1.0',
'verticalScale: 1.0',
'rotation: 0.0',
'pointerCount: 0',
'sourceTimeStamp: null',
],
),
(
ScaleEndDetails(),
<String>['velocity: Velocity(0.0, 0.0)', 'scaleVelocity: 0.0', 'pointerCount: 0'],
),
(
TapDownDetails(kind: PointerDeviceKind.unknown),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'kind: unknown',
],
),
(
TapUpDetails(kind: PointerDeviceKind.unknown),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'kind: unknown',
],
),
(
TapDragDownDetails(
globalPosition: Offset.zero,
localPosition: Offset.zero,
consecutiveTapCount: 1,
),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'kind: null',
'consecutiveTapCount: 1',
],
),
(
TapDragUpDetails(
globalPosition: Offset.zero,
localPosition: Offset.zero,
kind: PointerDeviceKind.unknown,
consecutiveTapCount: 1,
),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'kind: unknown',
'consecutiveTapCount: 1',
],
),
(
TapDragStartDetails(
globalPosition: Offset.zero,
localPosition: Offset.zero,
consecutiveTapCount: 1,
),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'sourceTimeStamp: null',
'kind: null',
'consecutiveTapCount: 1',
],
),
(
TapDragUpdateDetails(
globalPosition: Offset.zero,
localPosition: Offset.zero,
offsetFromOrigin: Offset.zero,
localOffsetFromOrigin: Offset.zero,
consecutiveTapCount: 1,
),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'sourceTimeStamp: null',
'delta: Offset(0.0, 0.0)',
'primaryDelta: null',
'kind: null',
'offsetFromOrigin: Offset(0.0, 0.0)',
'localOffsetFromOrigin: Offset(0.0, 0.0)',
'consecutiveTapCount: 1',
],
),
(
TapDragEndDetails(consecutiveTapCount: 1),
<String>[
'globalPosition: Offset(0.0, 0.0)',
'localPosition: Offset(0.0, 0.0)',
'velocity: Velocity(0.0, 0.0)',
'primaryVelocity: null',
'consecutiveTapCount: 1',
],
),
];
for (final (Diagnosticable detail, List<String> expected) in pairs) {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
// ignore: invalid_use_of_protected_member
detail.debugFillProperties(builder);
final List<String> description =
builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description, expected);
}
});
}