Unverified Commit c6d4a6ef authored by Hans Muller's avatar Hans Muller Committed by GitHub

Update OutlinedButton default outline geometry to be backwards compatible (#70393)

parent 0436886e
...@@ -242,7 +242,7 @@ class OutlinedButton extends ButtonStyleButton { ...@@ -242,7 +242,7 @@ class OutlinedButton extends ButtonStyleButton {
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.12), color: Theme.of(context).colorScheme.onSurface.withOpacity(0.12),
width: 1, width: 1,
), ),
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4))), shape: const _Outline(borderRadius: BorderRadius.all(Radius.circular(4))),
enabledMouseCursor: SystemMouseCursors.click, enabledMouseCursor: SystemMouseCursors.click,
disabledMouseCursor: SystemMouseCursors.forbidden, disabledMouseCursor: SystemMouseCursors.forbidden,
visualDensity: theme.visualDensity, visualDensity: theme.visualDensity,
...@@ -349,3 +349,69 @@ class _OutlinedButtonWithIconChild extends StatelessWidget { ...@@ -349,3 +349,69 @@ class _OutlinedButtonWithIconChild extends StatelessWidget {
); );
} }
} }
// This subclass only exists for the sake of backwards compatibility with the
// outline drawn by the original OutlineButton widget. The paint override
// draws a Path that's stroked with BorderSide, rather than filling a rounded
// rect whose inner path is the outer path inset by the BorderSide's width.
class _Outline extends RoundedRectangleBorder {
const _Outline({
BorderSide side = BorderSide.none,
required BorderRadiusGeometry borderRadius,
}) : super(side: side, borderRadius: borderRadius);
@override
ShapeBorder scale(double t) {
return _Outline(
side: side.scale(t),
borderRadius: borderRadius * t,
);
}
@override
ShapeBorder? lerpFrom(ShapeBorder? a, double t) {
assert(t != null);
if (a is _Outline) {
return _Outline(
side: BorderSide.lerp(a.side, side, t),
borderRadius: BorderRadiusGeometry.lerp(a.borderRadius, borderRadius, t)!,
);
}
return super.lerpFrom(a, t);
}
@override
ShapeBorder? lerpTo(ShapeBorder? b, double t) {
assert(t != null);
if (b is _Outline) {
return _Outline(
side: BorderSide.lerp(side, b.side, t),
borderRadius: BorderRadiusGeometry.lerp(borderRadius, b.borderRadius, t)!,
);
}
return super.lerpTo(b, t);
}
@override
_Outline copyWith({ BorderSide? side, BorderRadius? borderRadius }) {
return _Outline(
side: side ?? this.side,
borderRadius: borderRadius ?? this.borderRadius,
);
}
@override
void paint(Canvas canvas, Rect rect, { TextDirection? textDirection }) {
switch (side.style) {
case BorderStyle.none:
break;
case BorderStyle.solid:
if (side.width == 0.0) {
super.paint(canvas, rect, textDirection: textDirection);
} else {
canvas.drawPath(getOuterPath(rect, textDirection: textDirection), side.toPaint());
}
}
}
}
...@@ -40,13 +40,12 @@ void main() { ...@@ -40,13 +40,12 @@ void main() {
expect(material.color, Colors.transparent); expect(material.color, Colors.transparent);
expect(material.elevation, 0.0); expect(material.elevation, 0.0);
expect(material.shadowColor, const Color(0xff000000)); expect(material.shadowColor, const Color(0xff000000));
expect(material.shape, RoundedRectangleBorder(
side: BorderSide( expect(material.shape, isInstanceOf<RoundedRectangleBorder>());
width: 1, RoundedRectangleBorder materialShape = material.shape! as RoundedRectangleBorder;
color: colorScheme.onSurface.withOpacity(0.12), expect(materialShape.side, BorderSide(width: 1, color: colorScheme.onSurface.withOpacity(0.12)));
), expect(materialShape.borderRadius, BorderRadius.circular(4.0));
borderRadius: BorderRadius.circular(4.0),
));
expect(material.textStyle!.color, colorScheme.primary); expect(material.textStyle!.color, colorScheme.primary);
expect(material.textStyle!.fontFamily, 'Roboto'); expect(material.textStyle!.fontFamily, 'Roboto');
expect(material.textStyle!.fontSize, 14); expect(material.textStyle!.fontSize, 14);
...@@ -71,13 +70,12 @@ void main() { ...@@ -71,13 +70,12 @@ void main() {
expect(material.color, Colors.transparent); expect(material.color, Colors.transparent);
expect(material.elevation, 0.0); expect(material.elevation, 0.0);
expect(material.shadowColor, const Color(0xff000000)); expect(material.shadowColor, const Color(0xff000000));
expect(material.shape, RoundedRectangleBorder(
side: BorderSide( expect(material.shape, isInstanceOf<RoundedRectangleBorder>());
width: 1, materialShape = material.shape! as RoundedRectangleBorder;
color: colorScheme.onSurface.withOpacity(0.12), expect(materialShape.side, BorderSide(width: 1, color: colorScheme.onSurface.withOpacity(0.12)));
), expect(materialShape.borderRadius, BorderRadius.circular(4.0));
borderRadius: BorderRadius.circular(4.0),
));
expect(material.textStyle!.color, colorScheme.primary); expect(material.textStyle!.color, colorScheme.primary);
expect(material.textStyle!.fontFamily, 'Roboto'); expect(material.textStyle!.fontFamily, 'Roboto');
expect(material.textStyle!.fontSize, 14); expect(material.textStyle!.fontSize, 14);
...@@ -113,13 +111,12 @@ void main() { ...@@ -113,13 +111,12 @@ void main() {
expect(material.color, Colors.transparent); expect(material.color, Colors.transparent);
expect(material.elevation, 0.0); expect(material.elevation, 0.0);
expect(material.shadowColor, const Color(0xff000000)); expect(material.shadowColor, const Color(0xff000000));
expect(material.shape, RoundedRectangleBorder(
side: BorderSide( expect(material.shape, isInstanceOf<RoundedRectangleBorder>());
width: 1, materialShape = material.shape! as RoundedRectangleBorder;
color: colorScheme.onSurface.withOpacity(0.12), expect(materialShape.side, BorderSide(width: 1, color: colorScheme.onSurface.withOpacity(0.12)));
), expect(materialShape.borderRadius, BorderRadius.circular(4.0));
borderRadius: BorderRadius.circular(4.0),
));
expect(material.textStyle!.color, colorScheme.primary); expect(material.textStyle!.color, colorScheme.primary);
expect(material.textStyle!.fontFamily, 'Roboto'); expect(material.textStyle!.fontFamily, 'Roboto');
expect(material.textStyle!.fontSize, 14); expect(material.textStyle!.fontSize, 14);
...@@ -147,13 +144,12 @@ void main() { ...@@ -147,13 +144,12 @@ void main() {
expect(material.color, Colors.transparent); expect(material.color, Colors.transparent);
expect(material.elevation, 0.0); expect(material.elevation, 0.0);
expect(material.shadowColor, const Color(0xff000000)); expect(material.shadowColor, const Color(0xff000000));
expect(material.shape, RoundedRectangleBorder(
side: BorderSide( expect(material.shape, isInstanceOf<RoundedRectangleBorder>());
width: 1, materialShape = material.shape! as RoundedRectangleBorder;
color: colorScheme.onSurface.withOpacity(0.12), expect(materialShape.side, BorderSide(width: 1, color: colorScheme.onSurface.withOpacity(0.12)));
), expect(materialShape.borderRadius, BorderRadius.circular(4.0));
borderRadius: BorderRadius.circular(4.0),
));
expect(material.textStyle!.color, colorScheme.onSurface.withOpacity(0.38)); expect(material.textStyle!.color, colorScheme.onSurface.withOpacity(0.38));
expect(material.textStyle!.fontFamily, 'Roboto'); expect(material.textStyle!.fontFamily, 'Roboto');
expect(material.textStyle!.fontSize, 14); expect(material.textStyle!.fontSize, 14);
...@@ -546,12 +542,12 @@ void main() { ...@@ -546,12 +542,12 @@ void main() {
final Finder outlinedButton = find.byType(OutlinedButton); final Finder outlinedButton = find.byType(OutlinedButton);
// Default, not disabled. // Default, not disabled.
expect(outlinedButton, paints..drrect(color: defaultColor)); expect(outlinedButton, paints..path(color: defaultColor));
// Focused. // Focused.
focusNode.requestFocus(); focusNode.requestFocus();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(outlinedButton, paints..drrect(color: focusedColor)); expect(outlinedButton, paints..path(color: focusedColor));
// Hovered. // Hovered.
final Offset center = tester.getCenter(find.byType(OutlinedButton)); final Offset center = tester.getCenter(find.byType(OutlinedButton));
...@@ -562,12 +558,12 @@ void main() { ...@@ -562,12 +558,12 @@ void main() {
addTearDown(gesture.removePointer); addTearDown(gesture.removePointer);
await gesture.moveTo(center); await gesture.moveTo(center);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(outlinedButton, paints..drrect(color: hoverColor)); expect(outlinedButton, paints..path(color: hoverColor));
// Highlighted (pressed). // Highlighted (pressed).
await gesture.down(center); await gesture.down(center);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(outlinedButton, paints..drrect(color: pressedColor)); expect(outlinedButton, paints..path(color: pressedColor));
}); });
testWidgets('OutlinedButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async { testWidgets('OutlinedButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async {
......
...@@ -34,10 +34,12 @@ void main() { ...@@ -34,10 +34,12 @@ void main() {
expect(material.color, Colors.transparent); expect(material.color, Colors.transparent);
expect(material.elevation, 0.0); expect(material.elevation, 0.0);
expect(material.shadowColor, Colors.black); expect(material.shadowColor, Colors.black);
expect(material.shape, RoundedRectangleBorder(
side: BorderSide(width: 1, color: colorScheme.onSurface.withOpacity(0.12)), expect(material.shape, isInstanceOf<RoundedRectangleBorder>());
borderRadius: BorderRadius.circular(4.0), final RoundedRectangleBorder materialShape = material.shape! as RoundedRectangleBorder;
)); expect(materialShape.side, BorderSide(width: 1, color: colorScheme.onSurface.withOpacity(0.12)));
expect(materialShape.borderRadius, BorderRadius.circular(4.0));
expect(material.textStyle!.color, colorScheme.primary); expect(material.textStyle!.color, colorScheme.primary);
expect(material.textStyle!.fontFamily, 'Roboto'); expect(material.textStyle!.fontFamily, 'Roboto');
expect(material.textStyle!.fontSize, 14); expect(material.textStyle!.fontSize, 14);
......
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