Unverified Commit 32dc1b7d authored by xubaolin's avatar xubaolin Committed by GitHub

Add [pointerCount] property to Scale Gesture Details (#73474)

parent 80f15dcf
......@@ -36,7 +36,7 @@ class ScaleStartDetails {
/// Creates details for [GestureScaleStartCallback].
///
/// The [focalPoint] argument must not be null.
ScaleStartDetails({ this.focalPoint = Offset.zero, Offset? localFocalPoint, })
ScaleStartDetails({ this.focalPoint = Offset.zero, Offset? localFocalPoint, this.pointerCount = 0 })
: assert(focalPoint != null), localFocalPoint = localFocalPoint ?? focalPoint;
/// The initial focal point of the pointers in contact with the screen.
......@@ -60,8 +60,14 @@ class ScaleStartDetails {
/// coordinates.
final Offset localFocalPoint;
/// The number of pointers being tracked by the gesture recognizer.
///
/// Typically this is the number of fingers being used to pan the widget using the gesture
/// recognizer.
final int pointerCount;
@override
String toString() => 'ScaleStartDetails(focalPoint: $focalPoint, localFocalPoint: $localFocalPoint)';
String toString() => 'ScaleStartDetails(focalPoint: $focalPoint, localFocalPoint: $localFocalPoint, pointersCount: $pointerCount)';
}
/// Details for [GestureScaleUpdateCallback].
......@@ -78,6 +84,7 @@ class ScaleUpdateDetails {
this.horizontalScale = 1.0,
this.verticalScale = 1.0,
this.rotation = 0.0,
this.pointerCount = 0,
}) : assert(focalPoint != null),
assert(scale != null && scale >= 0.0),
assert(horizontalScale != null && horizontalScale >= 0.0),
......@@ -145,8 +152,21 @@ class ScaleUpdateDetails {
/// Expressed in radians.
final double rotation;
/// The number of pointers being tracked by the gesture recognizer.
///
/// Typically this is the number of fingers being used to pan the widget using the gesture
/// recognizer.
final int pointerCount;
@override
String toString() => 'ScaleUpdateDetails(focalPoint: $focalPoint, localFocalPoint: $localFocalPoint, scale: $scale, horizontalScale: $horizontalScale, verticalScale: $verticalScale, rotation: $rotation)';
String toString() => 'ScaleUpdateDetails('
'focalPoint: $focalPoint,'
' localFocalPoint: $localFocalPoint,'
' scale: $scale,'
' horizontalScale: $horizontalScale,'
' verticalScale: $verticalScale,'
' rotation: $rotation,'
' pointerCount: $pointerCount)';
}
/// Details for [GestureScaleEndCallback].
......@@ -154,14 +174,20 @@ class ScaleEndDetails {
/// Creates details for [GestureScaleEndCallback].
///
/// The [velocity] argument must not be null.
ScaleEndDetails({ this.velocity = Velocity.zero })
ScaleEndDetails({ this.velocity = Velocity.zero, this.pointerCount = 0 })
: assert(velocity != null);
/// The velocity of the last pointer to be lifted off of the screen.
final Velocity velocity;
/// The number of pointers being tracked by the gesture recognizer.
///
/// Typically this is the number of fingers being used to pan the widget using the gesture
/// recognizer.
final int pointerCount;
@override
String toString() => 'ScaleEndDetails(velocity: $velocity)';
String toString() => 'ScaleEndDetails(velocity: $velocity, pointerCount: $pointerCount)';
}
/// Signature for when the pointers in contact with the screen have established
......@@ -434,9 +460,9 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
final Offset pixelsPerSecond = velocity.pixelsPerSecond;
if (pixelsPerSecond.distanceSquared > kMaxFlingVelocity * kMaxFlingVelocity)
velocity = Velocity(pixelsPerSecond: (pixelsPerSecond / pixelsPerSecond.distance) * kMaxFlingVelocity);
invokeCallback<void>('onEnd', () => onEnd!(ScaleEndDetails(velocity: velocity)));
invokeCallback<void>('onEnd', () => onEnd!(ScaleEndDetails(velocity: velocity, pointerCount: _pointerQueue.length)));
} else {
invokeCallback<void>('onEnd', () => onEnd!(ScaleEndDetails(velocity: Velocity.zero)));
invokeCallback<void>('onEnd', () => onEnd!(ScaleEndDetails(velocity: Velocity.zero, pointerCount: _pointerQueue.length)));
}
}
_state = _ScaleState.accepted;
......@@ -472,6 +498,7 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
focalPoint: _currentFocalPoint,
localFocalPoint: PointerEvent.transformPosition(_lastTransform, _currentFocalPoint),
rotation: _computeRotationFactor(),
pointerCount: _pointerQueue.length,
));
});
}
......@@ -483,6 +510,7 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
onStart!(ScaleStartDetails(
focalPoint: _currentFocalPoint,
localFocalPoint: PointerEvent.transformPosition(_lastTransform, _currentFocalPoint),
pointerCount: _pointerQueue.length,
));
});
}
......
......@@ -6,7 +6,7 @@ import 'package:flutter/foundation.dart';
import '../flutter_test_alternative.dart';
// ignore: unused_field
enum _TestEnum { a, b, c, d, e, f, g, h, }
enum _TestEnum { a, b, c, d, e, f, g, h }
void main() {
test('BitField control test', () {
......
......@@ -571,4 +571,56 @@ void main() {
scale.dispose();
tap.dispose();
});
testGesture('Scale gestures pointer count test', (GestureTester tester) {
final ScaleGestureRecognizer scale = ScaleGestureRecognizer();
int pointerCountOfStart = 0;
scale.onStart = (ScaleStartDetails details) => pointerCountOfStart = details.pointerCount;
int pointerCountOfUpdate = 0;
scale.onUpdate = (ScaleUpdateDetails details) => pointerCountOfUpdate = details.pointerCount;
int pointerCountOfEnd = 0;
scale.onEnd = (ScaleEndDetails details) => pointerCountOfEnd = details.pointerCount;
final TestPointer pointer1 = TestPointer(1);
final PointerDownEvent down = pointer1.down(const Offset(0.0, 0.0));
scale.addPointer(down);
tester.closeArena(1);
// One-finger panning
tester.route(down);
// One pointer in contact with the screen now.
expect(pointerCountOfStart, 1);
tester.route(pointer1.move(const Offset(20.0, 30.0)));
expect(pointerCountOfUpdate, 1);
// Two-finger scaling
final TestPointer pointer2 = TestPointer(2);
final PointerDownEvent down2 = pointer2.down(const Offset(10.0, 20.0));
scale.addPointer(down2);
tester.closeArena(2);
tester.route(down2);
// Two pointers in contact with the screen now.
expect(pointerCountOfEnd, 2); // Additional pointer down will trigger an end event.
tester.route(pointer2.move(const Offset(0.0, 10.0)));
expect(pointerCountOfStart, 2); // The new pointer move will trigger a start event.
expect(pointerCountOfUpdate, 2);
tester.route(pointer1.up());
// One pointer in contact with the screen now.
expect(pointerCountOfEnd, 1);
tester.route(pointer2.move(const Offset(0.0, 10.0)));
expect(pointerCountOfStart, 1);
expect(pointerCountOfUpdate, 1);
tester.route(pointer2.up());
// No pointer in contact with the screen now.
expect(pointerCountOfEnd, 0);
scale.dispose();
});
}
......@@ -8695,7 +8695,7 @@ void main() {
// Regressing test for https://github.com/flutter/flutter/issues/70625
testWidgets('TextFields can inherit [FloatingLabelBehaviour] from InputDecorationTheme.', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
Widget textFieldBuilder({FloatingLabelBehavior behavior = FloatingLabelBehavior.auto, }) {
Widget textFieldBuilder({ FloatingLabelBehavior behavior = FloatingLabelBehavior.auto }) {
return MaterialApp(
theme: ThemeData(
inputDecorationTheme: InputDecorationTheme(
......
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