Unverified Commit 8ffe7c56 authored by Karol's avatar Karol Committed by GitHub

Fix painting material toggle (#78733) (#78744)

parent a1a360bf
......@@ -80,3 +80,4 @@ Ludwik Trammer <ludwik@gmail.com>
Marian Triebe <m.triebe@live.de>
Alexis Rouillard <contact@arouillard.fr>
Mirko Mucaria <skogsfrae@gmail.com>
Karol Czeryna <karol.czeryna@gmail.com>
......@@ -912,26 +912,69 @@ class _SwitchPainter extends ToggleablePainter {
? (currentValue < 0.5 ? onInactiveThumbImageError : onActiveThumbImageError)
: onInactiveThumbImageError;
// Paint the track
final Paint paint = Paint()
..color = trackColor;
const double trackHorizontalPadding = kRadialReactionRadius - _kTrackRadius;
final Offset trackPaintOffset = _computeTrackPaintOffset(size, _kTrackWidth, _kTrackHeight);
final Offset thumbPaintOffset = _computeThumbPaintOffset(trackPaintOffset, visualPosition);
final Offset radialReactionOrigin = Offset(thumbPaintOffset.dx + _kThumbRadius, size.height / 2);
_paintTrackWith(canvas, paint, trackPaintOffset);
paintRadialReaction(canvas: canvas, origin: radialReactionOrigin);
_paintThumbWith(
thumbPaintOffset,
canvas,
currentValue,
thumbColor,
thumbImage,
thumbErrorListener,
);
}
/// Computes canvas offset for track's upper left corner
Offset _computeTrackPaintOffset(Size canvasSize, double trackWidth, double trackHeight) {
final double horizontalOffset = (canvasSize.width - _kTrackWidth) / 2.0;
final double verticalOffset = (canvasSize.height - _kTrackHeight) / 2.0;
return Offset(horizontalOffset, verticalOffset);
}
/// Computes canvas offset for thumb's upper left corner as if it were a
/// square
Offset _computeThumbPaintOffset(Offset trackPaintOffset, double visualPosition) {
// How much thumb radius extends beyond the track
const double additionalThumbRadius = _kThumbRadius - _kTrackRadius;
final double horizontalProgress = visualPosition * trackInnerLength;
final double thumbHorizontalOffset = trackPaintOffset.dx - additionalThumbRadius + horizontalProgress;
final double thumbVerticalOffset = trackPaintOffset.dy - additionalThumbRadius;
return Offset(thumbHorizontalOffset, thumbVerticalOffset);
}
void _paintTrackWith(Canvas canvas, Paint paint, Offset trackPaintOffset) {
final Rect trackRect = Rect.fromLTWH(
trackHorizontalPadding,
(size.height - _kTrackHeight) / 2.0,
size.width - 2.0 * trackHorizontalPadding,
trackPaintOffset.dx,
trackPaintOffset.dy,
_kTrackWidth,
_kTrackHeight,
);
final RRect trackRRect = RRect.fromRectAndRadius(trackRect, const Radius.circular(_kTrackRadius));
canvas.drawRRect(trackRRect, paint);
final Offset thumbPosition = Offset(
kRadialReactionRadius + visualPosition * trackInnerLength,
size.height / 2.0,
final RRect trackRRect = RRect.fromRectAndRadius(
trackRect,
const Radius.circular(_kTrackRadius),
);
paintRadialReaction(canvas: canvas, origin: thumbPosition);
canvas.drawRRect(trackRRect, paint);
}
void _paintThumbWith(
Offset thumbPaintOffset,
Canvas canvas,
double currentValue,
Color thumbColor,
ImageProvider? thumbImage,
ImageErrorListener? thumbErrorListener,
) {
try {
_isPainting = true;
if (_cachedThumbPainter == null || thumbColor != _cachedThumbColor || thumbImage != _cachedThumbImage || thumbErrorListener != _cachedThumbErrorListener) {
......@@ -946,9 +989,10 @@ class _SwitchPainter extends ToggleablePainter {
// The thumb contracts slightly during the animation
final double inset = 1.0 - (currentValue - 0.5).abs() * 2.0;
final double radius = _kThumbRadius - inset;
thumbPainter.paint(
canvas,
thumbPosition - Offset(radius, radius),
thumbPaintOffset + Offset(0, inset),
configuration.copyWith(size: Size.fromRadius(radius)),
);
} finally {
......
......@@ -92,6 +92,57 @@ void main() {
expect(tester.getSize(find.byType(Switch)), const Size(59.0, 40.0));
});
testWidgets('Switch does not get distorted upon changing constraints with parent', (WidgetTester tester) async {
const double maxWidth = 300;
const double maxHeight = 100;
const ValueKey<String> boundaryKey = ValueKey<String>('switch container');
Widget buildSwitch({required double width, required double height}) {
return MaterialApp(
home: Scaffold(
body: Directionality(
textDirection: TextDirection.ltr,
child: SizedBox(
width: maxWidth,
height: maxHeight,
child: RepaintBoundary(
key: boundaryKey,
child: SizedBox(
width: width,
height: height,
child: Switch(
dragStartBehavior: DragStartBehavior.down,
value: true,
onChanged: (_) {},
),
),
),
),
),
),
);
}
await tester.pumpWidget(buildSwitch(
width: maxWidth,
height: maxHeight,
));
await expectLater(
find.byKey(boundaryKey),
matchesGoldenFile('switch_test.big.on.png'),
);
await tester.pumpWidget(buildSwitch(
width: 20,
height: 10,
));
await expectLater(
find.byKey(boundaryKey),
matchesGoldenFile('switch_test.small.on.png'),
);
});
testWidgets('Switch can drag (LTR)', (WidgetTester tester) async {
bool value = false;
......
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