Uniform rectangular borders were drawing in the wrong place. (#12179)
I inflated instead of deflating. Oops.
This commit is contained in:
parent
1a62c28b6f
commit
d15907b50b
@ -398,7 +398,7 @@ class Border {
|
|||||||
..color = top.color
|
..color = top.color
|
||||||
..strokeWidth = width
|
..strokeWidth = width
|
||||||
..style = PaintingStyle.stroke;
|
..style = PaintingStyle.stroke;
|
||||||
canvas.drawRect(rect.inflate(width / 2.0), paint);
|
canvas.drawRect(rect.deflate(width / 2.0), paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -176,6 +176,24 @@ abstract class PaintPattern {
|
|||||||
/// arguments as they were seen by the method.
|
/// arguments as they were seen by the method.
|
||||||
void rrect({ RRect rrect, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style });
|
void rrect({ RRect rrect, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style });
|
||||||
|
|
||||||
|
/// Indicates that a rounded rectangle outline is expected next.
|
||||||
|
///
|
||||||
|
/// The next call to [Canvas.drawRRect] is examined. Any arguments that are
|
||||||
|
/// passed to this method are compared to the actual [Canvas.drawRRect] call's
|
||||||
|
/// arguments and any mismatches result in failure.
|
||||||
|
///
|
||||||
|
/// If no call to [Canvas.drawRRect] was made, then this results in failure.
|
||||||
|
///
|
||||||
|
/// Any calls made between the last matched call (if any) and the
|
||||||
|
/// [Canvas.drawRRect] call are ignored.
|
||||||
|
///
|
||||||
|
/// The [Paint]-related arguments (`color`, `strokeWidth`, `hasMaskFilter`,
|
||||||
|
/// `style`) are compared against the state of the [Paint] object after the
|
||||||
|
/// painting has completed, not at the time of the call. If the same [Paint]
|
||||||
|
/// object is reused multiple times, then this may not match the actual
|
||||||
|
/// arguments as they were seen by the method.
|
||||||
|
void drrect({ RRect outer, RRect inner, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style });
|
||||||
|
|
||||||
/// Indicates that a circle is expected next.
|
/// Indicates that a circle is expected next.
|
||||||
///
|
///
|
||||||
/// The next circle is examined. Any arguments that are passed to this method
|
/// The next circle is examined. Any arguments that are passed to this method
|
||||||
@ -424,6 +442,11 @@ class _TestRecordingCanvasPatternMatcher extends _TestRecordingCanvasMatcher imp
|
|||||||
_predicates.add(new _RRectPaintPredicate(rrect: rrect, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
|
_predicates.add(new _RRectPaintPredicate(rrect: rrect, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void drrect({ RRect outer, RRect inner, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) {
|
||||||
|
_predicates.add(new _DRRectPaintPredicate(outer: outer, inner: inner, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void circle({ double x, double y, double radius, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) {
|
void circle({ double x, double y, double radius, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) {
|
||||||
_predicates.add(new _CirclePaintPredicate(x: x, y: y, radius: radius, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
|
_predicates.add(new _CirclePaintPredicate(x: x, y: y, radius: radius, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
|
||||||
@ -631,6 +654,51 @@ class _OneParameterPaintPredicate<T> extends _DrawCommandPaintPredicate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _TwoParameterPaintPredicate<T1, T2> extends _DrawCommandPaintPredicate {
|
||||||
|
_TwoParameterPaintPredicate(Symbol symbol, String name, {
|
||||||
|
@required this.expected1,
|
||||||
|
@required this.expected2,
|
||||||
|
@required Color color,
|
||||||
|
@required double strokeWidth,
|
||||||
|
@required bool hasMaskFilter,
|
||||||
|
@required PaintingStyle style
|
||||||
|
}) : super(
|
||||||
|
symbol, name, 3, 2, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style);
|
||||||
|
|
||||||
|
final T1 expected1;
|
||||||
|
|
||||||
|
final T2 expected2;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void verifyArguments(List<dynamic> arguments) {
|
||||||
|
super.verifyArguments(arguments);
|
||||||
|
final T1 actual1 = arguments[0];
|
||||||
|
if (expected1 != null && actual1 != expected1)
|
||||||
|
throw 'It called $methodName with its first argument (a $T1), $actual1, which was not exactly the expected $T1 ($expected1).';
|
||||||
|
final T2 actual2 = arguments[1];
|
||||||
|
if (expected2 != null && actual2 != expected2)
|
||||||
|
throw 'It called $methodName with its second argument (a $T2), $actual2, which was not exactly the expected $T2 ($expected2).';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void debugFillDescription(List<String> description) {
|
||||||
|
super.debugFillDescription(description);
|
||||||
|
if (expected1 != null) {
|
||||||
|
if (expected1.toString().contains(T1.toString())) {
|
||||||
|
description.add('$expected1');
|
||||||
|
} else {
|
||||||
|
description.add('$T1: $expected1');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (expected2 != null) {
|
||||||
|
if (expected2.toString().contains(T2.toString())) {
|
||||||
|
description.add('$expected2');
|
||||||
|
} else {
|
||||||
|
description.add('$T2: $expected2');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _RectPaintPredicate extends _OneParameterPaintPredicate<Rect> {
|
class _RectPaintPredicate extends _OneParameterPaintPredicate<Rect> {
|
||||||
_RectPaintPredicate({ Rect rect, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super(
|
_RectPaintPredicate({ Rect rect, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super(
|
||||||
@ -656,6 +724,19 @@ class _RRectPaintPredicate extends _OneParameterPaintPredicate<RRect> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _DRRectPaintPredicate extends _TwoParameterPaintPredicate<RRect, RRect> {
|
||||||
|
_DRRectPaintPredicate({ RRect inner, RRect outer, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super(
|
||||||
|
#drawDRRect,
|
||||||
|
'a rounded rectangle outline',
|
||||||
|
expected1: outer,
|
||||||
|
expected2: inner,
|
||||||
|
color: color,
|
||||||
|
strokeWidth: strokeWidth,
|
||||||
|
hasMaskFilter: hasMaskFilter,
|
||||||
|
style: style,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
class _CirclePaintPredicate extends _DrawCommandPaintPredicate {
|
class _CirclePaintPredicate extends _DrawCommandPaintPredicate {
|
||||||
_CirclePaintPredicate({ this.x, this.y, this.radius, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super(
|
_CirclePaintPredicate({ this.x, this.y, this.radius, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super(
|
||||||
#drawCircle, 'a circle', 3, 2, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style
|
#drawCircle, 'a circle', 3, 2, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style
|
||||||
|
@ -89,6 +89,99 @@ void main() {
|
|||||||
..path()); // all appear to have the same settings here (that of the last call).
|
..path()); // all appear to have the same settings here (that of the last call).
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('BoxDecoration paints its border correctly', (WidgetTester tester) async {
|
||||||
|
// Regression test for https://github.com/flutter/flutter/issues/12165
|
||||||
|
await tester.pumpWidget(
|
||||||
|
new Column(
|
||||||
|
children: <Widget>[
|
||||||
|
new Container(
|
||||||
|
// There's not currently a way to verify that this paints the same size as the others,
|
||||||
|
// so the pattern below just asserts that there's four paths but doesn't check the geometry.
|
||||||
|
width: 100.0,
|
||||||
|
height: 100.0,
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
border: const Border(
|
||||||
|
top: const BorderSide(
|
||||||
|
width: 10.0,
|
||||||
|
color: const Color(0xFFEEEEEE),
|
||||||
|
),
|
||||||
|
left: const BorderSide(
|
||||||
|
width: 10.0,
|
||||||
|
color: const Color(0xFFFFFFFF),
|
||||||
|
),
|
||||||
|
right: const BorderSide(
|
||||||
|
width: 10.0,
|
||||||
|
color: const Color(0xFFFFFFFF),
|
||||||
|
),
|
||||||
|
bottom: const BorderSide(
|
||||||
|
width: 10.0,
|
||||||
|
color: const Color(0xFFFFFFFF),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
new Container(
|
||||||
|
width: 100.0,
|
||||||
|
height: 100.0,
|
||||||
|
decoration: new BoxDecoration(
|
||||||
|
border: new Border.all(
|
||||||
|
width: 10.0,
|
||||||
|
color: const Color(0xFFFFFFFF),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
new Container(
|
||||||
|
width: 100.0,
|
||||||
|
height: 100.0,
|
||||||
|
decoration: new BoxDecoration(
|
||||||
|
border: new Border.all(
|
||||||
|
width: 10.0,
|
||||||
|
color: const Color(0xFFFFFFFF),
|
||||||
|
),
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topRight: const Radius.circular(10.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
new Container(
|
||||||
|
width: 100.0,
|
||||||
|
height: 100.0,
|
||||||
|
decoration: new BoxDecoration(
|
||||||
|
border: new Border.all(
|
||||||
|
width: 10.0,
|
||||||
|
color: const Color(0xFFFFFFFF),
|
||||||
|
),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(find.byType(Column), paints
|
||||||
|
..path()
|
||||||
|
..path()
|
||||||
|
..path()
|
||||||
|
..path()
|
||||||
|
..rect(rect: new Rect.fromLTRB(355.0, 105.0, 445.0, 195.0))
|
||||||
|
..drrect(
|
||||||
|
outer: new RRect.fromLTRBAndCorners(
|
||||||
|
350.0, 200.0, 450.0, 300.0,
|
||||||
|
topLeft: Radius.zero,
|
||||||
|
topRight: const Radius.circular(10.0),
|
||||||
|
bottomRight: Radius.zero,
|
||||||
|
bottomLeft: Radius.zero,
|
||||||
|
),
|
||||||
|
inner: new RRect.fromLTRBAndCorners(
|
||||||
|
360.0, 210.0, 440.0, 290.0,
|
||||||
|
topLeft: const Radius.circular(-10.0),
|
||||||
|
topRight: Radius.zero,
|
||||||
|
bottomRight: const Radius.circular(-10.0),
|
||||||
|
bottomLeft: const Radius.circular(-10.0),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
..circle(x: 400.0, y: 350.0, radius: 45.0)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Can hit test on BoxDecoration', (WidgetTester tester) async {
|
testWidgets('Can hit test on BoxDecoration', (WidgetTester tester) async {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user