diff --git a/AUTHORS b/AUTHORS index e82132858f7..a8b0e85ce43 100644 --- a/AUTHORS +++ b/AUTHORS @@ -65,3 +65,4 @@ CaiJingLong Alex Li Ram Navan meritozh +Terrence Addison Tandijono(flotilla) diff --git a/packages/flutter/lib/src/widgets/interactive_viewer.dart b/packages/flutter/lib/src/widgets/interactive_viewer.dart index e3c47c57a15..9306a2e66ac 100644 --- a/packages/flutter/lib/src/widgets/interactive_viewer.dart +++ b/packages/flutter/lib/src/widgets/interactive_viewer.dart @@ -746,6 +746,7 @@ class _InteractiveViewerState extends State with TickerProvid rotation: details.rotation, )); } + final Offset focalPointScene = _transformationController.toScene( details.localFocalPoint, ); @@ -918,6 +919,22 @@ class _InteractiveViewerState extends State with TickerProvid _transformationController.value, focalPointSceneScaled - focalPointScene, ); + if (widget.onInteractionStart != null) { + widget.onInteractionStart( + ScaleStartDetails(focalPoint: focalPointSceneScaled) + ); + } + if (widget.onInteractionUpdate != null) { + widget.onInteractionUpdate(ScaleUpdateDetails( + rotation: 0.0, + scale: scaleChange, + horizontalScale: 1.0, + verticalScale: 1.0, + )); + } + if (widget.onInteractionEnd != null) { + widget.onInteractionEnd(ScaleEndDetails()); + } } } diff --git a/packages/flutter/test/widgets/interactive_viewer_test.dart b/packages/flutter/test/widgets/interactive_viewer_test.dart index de3336a69d7..76cbb95e82c 100644 --- a/packages/flutter/test/widgets/interactive_viewer_test.dart +++ b/packages/flutter/test/widgets/interactive_viewer_test.dart @@ -623,6 +623,46 @@ void main() { expect(transformationController.value.getMaxScaleOnAxis(), equals(1.0)); }); + testWidgets('Scale with mouse returns onInteraction properties', (WidgetTester tester) async{ + final TransformationController transformationController = TransformationController(); + double scaleChange; + Velocity currentVelocity; + bool calledStart; + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: InteractiveViewer( + transformationController: transformationController, + onInteractionStart: (ScaleStartDetails details){ + calledStart = true; + }, + onInteractionUpdate: (ScaleUpdateDetails details){ + scaleChange = details.scale; + }, + onInteractionEnd: (ScaleEndDetails details){ + currentVelocity = details.velocity; + }, + child: Container(width: 200.0, height: 200.0), + ), + ), + ), + ), + ); + + final Offset center = tester.getCenter(find.byType(InteractiveViewer)); + await scrollAt(center, tester, const Offset(0.0, -20.0)); + await tester.pumpAndSettle(); + const Velocity noMovement = Velocity(pixelsPerSecond: Offset(0,0)); + final double afterScaling = transformationController.value.getMaxScaleOnAxis(); + + expect(scaleChange,greaterThan(1.0)); + expect(afterScaling, isNot(equals(null))); + expect(afterScaling, isNot(equals(1.0))); + expect(currentVelocity, equals(noMovement)); + expect(calledStart, equals(true)); + }); + testWidgets('viewport changes size', (WidgetTester tester) async { final TransformationController transformationController = TransformationController(); await tester.pumpWidget(