Unverified Commit 42a81223 authored by Amir Panahandeh's avatar Amir Panahandeh Committed by GitHub

Mirror before scaling in _AnimatedIconPainter (#93312)

parent 32122480
...@@ -91,3 +91,4 @@ Denis Grafov <grafov.denis@gmail.com> ...@@ -91,3 +91,4 @@ Denis Grafov <grafov.denis@gmail.com>
TheOneWithTheBraid <the-one@with-the-braid.cf> TheOneWithTheBraid <the-one@with-the-braid.cf>
Alberto Miola <betoman96@gmail.com> Alberto Miola <betoman96@gmail.com>
Twin Sun, LLC <google-contrib@twinsunsolutions.com> Twin Sun, LLC <google-contrib@twinsunsolutions.com>
Taskulu LDA <contributions@taskulu.com>
...@@ -156,11 +156,11 @@ class _AnimatedIconPainter extends CustomPainter { ...@@ -156,11 +156,11 @@ class _AnimatedIconPainter extends CustomPainter {
void paint(ui.Canvas canvas, Size size) { void paint(ui.Canvas canvas, Size size) {
// The RenderCustomPaint render object performs canvas.save before invoking // The RenderCustomPaint render object performs canvas.save before invoking
// this and canvas.restore after, so we don't need to do it here. // this and canvas.restore after, so we don't need to do it here.
canvas.scale(scale, scale);
if (shouldMirror) { if (shouldMirror) {
canvas.rotate(math.pi); canvas.rotate(math.pi);
canvas.translate(-size.width, -size.height); canvas.translate(-size.width, -size.height);
} }
canvas.scale(scale, scale);
final double clampedProgress = progress.value.clamp(0.0, 1.0); final double clampedProgress = progress.value.clamp(0.0, 1.0);
for (final _PathFrames path in paths) for (final _PathFrames path in paths)
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
@Tags(<String>['reduced-test-set'])
import 'dart:math' as math show pi; import 'dart:math' as math show pi;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
...@@ -26,6 +28,7 @@ class MockCanvas extends Fake implements Canvas { ...@@ -26,6 +28,7 @@ class MockCanvas extends Fake implements Canvas {
void scale(double sx, [double? sy]) { void scale(double sx, [double? sy]) {
capturedSx = sx; capturedSx = sx;
capturedSy = sy!; capturedSy = sy!;
invocations.add(RecordedScale(sx, sy));
} }
final List<RecordedCanvasCall> invocations = <RecordedCanvasCall>[]; final List<RecordedCanvasCall> invocations = <RecordedCanvasCall>[];
...@@ -75,6 +78,21 @@ class RecordedTranslate extends RecordedCanvasCall { ...@@ -75,6 +78,21 @@ class RecordedTranslate extends RecordedCanvasCall {
int get hashCode => hashValues(dx, dy); int get hashCode => hashValues(dx, dy);
} }
class RecordedScale extends RecordedCanvasCall {
const RecordedScale(this.sx, this.sy);
final double sx;
final double sy;
@override
bool operator ==(Object other) {
return other is RecordedScale && other.sx == sx && other.sy == sy;
}
@override
int get hashCode => hashValues(sx, sy);
}
void main() { void main() {
testWidgets('IconTheme color', (WidgetTester tester) async { testWidgets('IconTheme color', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
...@@ -218,9 +236,11 @@ void main() { ...@@ -218,9 +236,11 @@ void main() {
data: IconThemeData( data: IconThemeData(
color: Color(0xFF666666), color: Color(0xFF666666),
), ),
child: AnimatedIcon( child: RepaintBoundary(
progress: AlwaysStoppedAnimation<double>(0.0), child: AnimatedIcon(
icon: AnimatedIcons.arrow_menu, progress: AlwaysStoppedAnimation<double>(0.0),
icon: AnimatedIcons.arrow_menu,
),
), ),
), ),
), ),
...@@ -231,7 +251,10 @@ void main() { ...@@ -231,7 +251,10 @@ void main() {
expect(canvas.invocations, const <RecordedCanvasCall>[ expect(canvas.invocations, const <RecordedCanvasCall>[
RecordedRotate(math.pi), RecordedRotate(math.pi),
RecordedTranslate(-48, -48), RecordedTranslate(-48, -48),
RecordedScale(0.5, 0.5),
]); ]);
await expectLater(find.byType(AnimatedIcon),
matchesGoldenFile('animated_icons_test.icon.rtl.png'));
}); });
testWidgets('Inherited text direction ltr', (WidgetTester tester) async { testWidgets('Inherited text direction ltr', (WidgetTester tester) async {
...@@ -242,9 +265,11 @@ void main() { ...@@ -242,9 +265,11 @@ void main() {
data: IconThemeData( data: IconThemeData(
color: Color(0xFF666666), color: Color(0xFF666666),
), ),
child: AnimatedIcon( child: RepaintBoundary(
progress: AlwaysStoppedAnimation<double>(0.0), child: AnimatedIcon(
icon: AnimatedIcons.arrow_menu, progress: AlwaysStoppedAnimation<double>(0.0),
icon: AnimatedIcons.arrow_menu,
),
), ),
), ),
), ),
...@@ -252,7 +277,11 @@ void main() { ...@@ -252,7 +277,11 @@ void main() {
final CustomPaint customPaint = tester.widget(find.byType(CustomPaint)); final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
final MockCanvas canvas = MockCanvas(); final MockCanvas canvas = MockCanvas();
customPaint.painter!.paint(canvas, const Size(48.0, 48.0)); customPaint.painter!.paint(canvas, const Size(48.0, 48.0));
expect(canvas.invocations, isEmpty); expect(canvas.invocations, const <RecordedCanvasCall>[
RecordedScale(0.5, 0.5),
]);
await expectLater(find.byType(AnimatedIcon),
matchesGoldenFile('animated_icons_test.icon.ltr.png'));
}); });
testWidgets('Inherited text direction overridden', (WidgetTester tester) async { testWidgets('Inherited text direction overridden', (WidgetTester tester) async {
...@@ -277,8 +306,25 @@ void main() { ...@@ -277,8 +306,25 @@ void main() {
expect(canvas.invocations, const <RecordedCanvasCall>[ expect(canvas.invocations, const <RecordedCanvasCall>[
RecordedRotate(math.pi), RecordedRotate(math.pi),
RecordedTranslate(-48, -48), RecordedTranslate(-48, -48),
RecordedScale(0.5, 0.5),
]); ]);
}); });
testWidgets('Direction has no effect on position of widget', (WidgetTester tester) async {
const AnimatedIcon icon = AnimatedIcon(
progress: AlwaysStoppedAnimation<double>(0.0),
icon: AnimatedIcons.arrow_menu,
);
await tester.pumpWidget(
const Directionality(textDirection: TextDirection.rtl, child: icon),
);
final Rect rtlRect = tester.getRect(find.byType(AnimatedIcon));
await tester.pumpWidget(
const Directionality(textDirection: TextDirection.ltr, child: icon),
);
final Rect ltrRect = tester.getRect(find.byType(AnimatedIcon));
expect(rtlRect, ltrRect);
});
} }
PaintColorMatcher hasColor(int color) { PaintColorMatcher hasColor(int color) {
......
...@@ -187,9 +187,9 @@ void main() { ...@@ -187,9 +187,9 @@ void main() {
); );
painter.paint(mockCanvas, size); painter.paint(mockCanvas, size);
mockCanvas.verifyCallsInOrder(<MockCall>[ mockCanvas.verifyCallsInOrder(<MockCall>[
MockCall('scale', <dynamic>[1.0, 1.0]),
MockCall('rotate', <dynamic>[math.pi]), MockCall('rotate', <dynamic>[math.pi]),
MockCall('translate', <dynamic>[-48.0, -48.0]), MockCall('translate', <dynamic>[-48.0, -48.0]),
MockCall('scale', <dynamic>[1.0, 1.0]),
MockCall.any('drawPath'), MockCall.any('drawPath'),
]); ]);
}); });
......
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