Unverified Commit 05e10633 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Adding proper accommodation for textScaleFactor in chips, and StadiumBorder border. (#12533)

In order to allow chips to be properly drawn when they expand in size (without
using IntrinsicHeight), I needed a BoxDecoration shape that would be dependent
upon the rendered height of the widget. This seemed to be pretty generally
useful, so I added a new ShapeDecoration called StadiumBorder. It uses the
minimum dimension to adjust the BorderRadius of a rounded rect in the shape
decoration.

I also converted some uses of BoxShape to be case statements, updated the
chips to use the StadiumBorder decoration, and updated some of the metrics to match
the Material spec, as well as implementing lerping to and from StadiumBorder.
parent 5c1320e5
...@@ -28,7 +28,7 @@ class _ChipDemoState extends State<ChipDemo> { ...@@ -28,7 +28,7 @@ class _ChipDemoState extends State<ChipDemo> {
), ),
const Chip( const Chip(
avatar: const CircleAvatar(child: const Text('B')), avatar: const CircleAvatar(child: const Text('B')),
label: const Text('Blueberry') label: const Text('Blueberry'),
), ),
]; ];
......
...@@ -37,6 +37,7 @@ export 'src/painting/images.dart'; ...@@ -37,6 +37,7 @@ export 'src/painting/images.dart';
export 'src/painting/matrix_utils.dart'; export 'src/painting/matrix_utils.dart';
export 'src/painting/rounded_rectangle_border.dart'; export 'src/painting/rounded_rectangle_border.dart';
export 'src/painting/shape_decoration.dart'; export 'src/painting/shape_decoration.dart';
export 'src/painting/stadium_border.dart';
export 'src/painting/text_painter.dart'; export 'src/painting/text_painter.dart';
export 'src/painting/text_span.dart'; export 'src/painting/text_span.dart';
export 'src/painting/text_style.dart'; export 'src/painting/text_style.dart';
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter/painting.dart';
import 'colors.dart'; import 'colors.dart';
import 'debug.dart'; import 'debug.dart';
...@@ -11,17 +12,6 @@ import 'feedback.dart'; ...@@ -11,17 +12,6 @@ import 'feedback.dart';
import 'icons.dart'; import 'icons.dart';
import 'tooltip.dart'; import 'tooltip.dart';
const double _kChipHeight = 32.0;
const double _kAvatarDiamater = _kChipHeight;
const TextStyle _kLabelStyle = const TextStyle(
inherit: false,
fontSize: 13.0,
fontWeight: FontWeight.w400,
color: Colors.black87,
textBaseline: TextBaseline.alphabetic,
);
/// A material design chip. /// A material design chip.
/// ///
/// Chips represent complex entities in small blocks, such as a contact. /// Chips represent complex entities in small blocks, such as a contact.
...@@ -29,7 +19,8 @@ const TextStyle _kLabelStyle = const TextStyle( ...@@ -29,7 +19,8 @@ const TextStyle _kLabelStyle = const TextStyle(
/// Supplying a non-null [onDeleted] callback will cause the chip to include a /// Supplying a non-null [onDeleted] callback will cause the chip to include a
/// button for deleting the chip. /// button for deleting the chip.
/// ///
/// Requires one of its ancestors to be a [Material] widget. /// Requires one of its ancestors to be a [Material] widget. The [label]
/// and [border] arguments must not be null.
/// ///
/// ## Sample code /// ## Sample code
/// ///
...@@ -57,11 +48,25 @@ class Chip extends StatelessWidget { ...@@ -57,11 +48,25 @@ class Chip extends StatelessWidget {
this.avatar, this.avatar,
@required this.label, @required this.label,
this.onDeleted, this.onDeleted,
this.labelStyle, TextStyle labelStyle,
this.deleteButtonTooltipMessage, this.deleteButtonTooltipMessage,
this.backgroundColor, this.backgroundColor,
this.deleteIconColor, this.deleteIconColor,
}) : super(key: key); this.border: const StadiumBorder(),
}) : assert(label != null),
assert(border != null),
labelStyle = labelStyle ?? _defaultLabelStyle,
super(key: key);
static const TextStyle _defaultLabelStyle = const TextStyle(
inherit: false,
fontSize: 13.0,
fontWeight: FontWeight.w400,
color: Colors.black87,
textBaseline: TextBaseline.alphabetic,
);
static const double _chipHeight = 32.0;
/// A widget to display prior to the chip's label. /// A widget to display prior to the chip's label.
/// ///
...@@ -90,6 +95,11 @@ class Chip extends StatelessWidget { ...@@ -90,6 +95,11 @@ class Chip extends StatelessWidget {
/// widget's label. /// widget's label.
final Color backgroundColor; final Color backgroundColor;
/// The border to draw around the chip.
///
/// Defaults to a [StadiumBorder].
final ShapeBorder border;
/// Color for delete icon, the default being black. /// Color for delete icon, the default being black.
/// ///
/// This has no effect when [onDelete] is null since no delete icon will be /// This has no effect when [onDelete] is null since no delete icon will be
...@@ -116,8 +126,8 @@ class Chip extends StatelessWidget { ...@@ -116,8 +126,8 @@ class Chip extends StatelessWidget {
children.add(new ExcludeSemantics( children.add(new ExcludeSemantics(
child: new Container( child: new Container(
margin: const EdgeInsetsDirectional.only(end: 8.0), margin: const EdgeInsetsDirectional.only(end: 8.0),
width: _kAvatarDiamater, width: _chipHeight,
height: _kAvatarDiamater, height: _chipHeight,
child: avatar, child: avatar,
), ),
)); ));
...@@ -125,7 +135,8 @@ class Chip extends StatelessWidget { ...@@ -125,7 +135,8 @@ class Chip extends StatelessWidget {
children.add(new Flexible( children.add(new Flexible(
child: new DefaultTextStyle( child: new DefaultTextStyle(
style: labelStyle ?? _kLabelStyle, overflow: TextOverflow.ellipsis,
style: labelStyle,
child: label, child: label,
), ),
)); ));
...@@ -135,12 +146,14 @@ class Chip extends StatelessWidget { ...@@ -135,12 +146,14 @@ class Chip extends StatelessWidget {
children.add(new GestureDetector( children.add(new GestureDetector(
onTap: Feedback.wrapForTap(onDeleted, context), onTap: Feedback.wrapForTap(onDeleted, context),
child: new Tooltip( child: new Tooltip(
// TODO(gspencer): Internationalize this text.
// https://github.com/flutter/flutter/issues/12378
message: deleteButtonTooltipMessage ?? 'Delete "$label"', message: deleteButtonTooltipMessage ?? 'Delete "$label"',
child: new Container( child: new Container(
padding: const EdgeInsets.symmetric(horizontal: 4.0), padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: new Icon( child: new Icon(
Icons.cancel, Icons.cancel,
size: 18.0, size: 24.0,
color: deleteIconColor ?? Colors.black54, color: deleteIconColor ?? Colors.black54,
), ),
), ),
...@@ -151,17 +164,21 @@ class Chip extends StatelessWidget { ...@@ -151,17 +164,21 @@ class Chip extends StatelessWidget {
return new Semantics( return new Semantics(
container: true, container: true,
child: new Container( child: new Container(
height: _kChipHeight, constraints: const BoxConstraints(minHeight: _chipHeight),
padding: new EdgeInsetsDirectional.only(start: startPadding, end: endPadding), padding: new EdgeInsetsDirectional.only(start: startPadding, end: endPadding),
decoration: new BoxDecoration( decoration: new ShapeDecoration(
color: backgroundColor ?? Colors.grey.shade300, color: backgroundColor ?? Colors.grey.shade300,
borderRadius: new BorderRadius.circular(16.0), shape: border,
), ),
child: new Row( child: new Center(
children: children, widthFactor: 1.0,
mainAxisSize: MainAxisSize.min, heightFactor: 1.0,
child: new Row(
children: children,
mainAxisSize: MainAxisSize.min,
),
), ),
), ),
); );
} }
} }
\ No newline at end of file
...@@ -475,16 +475,19 @@ class Border extends BoxBorder { ...@@ -475,16 +475,19 @@ class Border extends BoxBorder {
case BorderStyle.none: case BorderStyle.none:
return; return;
case BorderStyle.solid: case BorderStyle.solid:
if (shape == BoxShape.circle) { switch (shape) {
assert(borderRadius == null, 'A borderRadius can only be given for rectangular boxes.'); case BoxShape.circle:
BoxBorder._paintUniformBorderWithCircle(canvas, rect, top); assert(borderRadius == null, 'A borderRadius can only be given for rectangular boxes.');
return; BoxBorder._paintUniformBorderWithCircle(canvas, rect, top);
break;
case BoxShape.rectangle:
if (borderRadius != null) {
BoxBorder._paintUniformBorderWithRadius(canvas, rect, top, borderRadius);
return;
}
BoxBorder._paintUniformBorderWithRectangle(canvas, rect, top);
break;
} }
if (borderRadius != null) {
BoxBorder._paintUniformBorderWithRadius(canvas, rect, top, borderRadius);
return;
}
BoxBorder._paintUniformBorderWithRectangle(canvas, rect, top);
return; return;
} }
} }
...@@ -777,16 +780,19 @@ class BorderDirectional extends BoxBorder { ...@@ -777,16 +780,19 @@ class BorderDirectional extends BoxBorder {
case BorderStyle.none: case BorderStyle.none:
return; return;
case BorderStyle.solid: case BorderStyle.solid:
if (shape == BoxShape.circle) { switch (shape) {
assert(borderRadius == null, 'A borderRadius can only be given for rectangular boxes.'); case BoxShape.circle:
BoxBorder._paintUniformBorderWithCircle(canvas, rect, top); assert(borderRadius == null, 'A borderRadius can only be given for rectangular boxes.');
return; BoxBorder._paintUniformBorderWithCircle(canvas, rect, top);
} break;
if (borderRadius != null) { case BoxShape.rectangle:
BoxBorder._paintUniformBorderWithRadius(canvas, rect, top, borderRadius); if (borderRadius != null) {
return; BoxBorder._paintUniformBorderWithRadius(canvas, rect, top, borderRadius);
return;
}
BoxBorder._paintUniformBorderWithRectangle(canvas, rect, top);
break;
} }
BoxBorder._paintUniformBorderWithRectangle(canvas, rect, top);
return; return;
} }
} }
......
...@@ -25,7 +25,7 @@ class CircleBorder extends ShapeBorder { ...@@ -25,7 +25,7 @@ class CircleBorder extends ShapeBorder {
/// Create a circle border. /// Create a circle border.
/// ///
/// The [side] argument must not be null. /// The [side] argument must not be null.
const CircleBorder([ this.side = BorderSide.none ]) : assert(side != null); const CircleBorder({ this.side = BorderSide.none }) : assert(side != null);
/// The style of this border. /// The style of this border.
final BorderSide side; final BorderSide side;
...@@ -36,19 +36,19 @@ class CircleBorder extends ShapeBorder { ...@@ -36,19 +36,19 @@ class CircleBorder extends ShapeBorder {
} }
@override @override
ShapeBorder scale(double t) => new CircleBorder(side.scale(t)); ShapeBorder scale(double t) => new CircleBorder(side: side.scale(t));
@override @override
ShapeBorder lerpFrom(ShapeBorder a, double t) { ShapeBorder lerpFrom(ShapeBorder a, double t) {
if (a is CircleBorder) if (a is CircleBorder)
return new CircleBorder(BorderSide.lerp(a.side, side, t)); return new CircleBorder(side: BorderSide.lerp(a.side, side, t));
return super.lerpFrom(a, t); return super.lerpFrom(a, t);
} }
@override @override
ShapeBorder lerpTo(ShapeBorder b, double t) { ShapeBorder lerpTo(ShapeBorder b, double t) {
if (b is CircleBorder) if (b is CircleBorder)
return new CircleBorder(BorderSide.lerp(side, b.side, t)); return new CircleBorder(side: BorderSide.lerp(side, b.side, t));
return super.lerpTo(b, t); return super.lerpTo(b, t);
} }
......
...@@ -94,7 +94,7 @@ class ShapeDecoration extends Decoration { ...@@ -94,7 +94,7 @@ class ShapeDecoration extends Decoration {
case BoxShape.circle: case BoxShape.circle:
if (source.border != null) { if (source.border != null) {
assert(source.border.isUniform); assert(source.border.isUniform);
shape = new CircleBorder(source.border.top); shape = new CircleBorder(side: source.border.top);
} else { } else {
shape = const CircleBorder(); shape = const CircleBorder();
} }
......
This diff is collapsed.
...@@ -361,7 +361,7 @@ class RenderLimitedBox extends RenderProxyBox { ...@@ -361,7 +361,7 @@ class RenderLimitedBox extends RenderProxyBox {
/// Attempts to size the child to a specific aspect ratio. /// Attempts to size the child to a specific aspect ratio.
/// ///
/// The render object first tries the largest width permited by the layout /// The render object first tries the largest width permitted by the layout
/// constraints. The height of the render object is determined by applying the /// constraints. The height of the render object is determined by applying the
/// given aspect ratio to the width, expressed as a ratio of width to height. /// given aspect ratio to the width, expressed as a ratio of width to height.
/// ///
...@@ -1372,12 +1372,15 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> { ...@@ -1372,12 +1372,15 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> {
@override @override
RRect get _defaultClip { RRect get _defaultClip {
assert(hasSize); assert(hasSize);
if (_shape == BoxShape.rectangle) { assert(_shape != null);
return (borderRadius ?? BorderRadius.zero).toRRect(Offset.zero & size); switch (_shape) {
} else { case BoxShape.rectangle:
final Rect rect = Offset.zero & size; return (borderRadius ?? BorderRadius.zero).toRRect(Offset.zero & size);
return new RRect.fromRectXY(rect, rect.width / 2, rect.height / 2); case BoxShape.circle:
final Rect rect = Offset.zero & size;
return new RRect.fromRectXY(rect, rect.width / 2, rect.height / 2);
} }
return null;
} }
@override @override
......
...@@ -1885,7 +1885,7 @@ class _OffstageElement extends SingleChildRenderObjectElement { ...@@ -1885,7 +1885,7 @@ class _OffstageElement extends SingleChildRenderObjectElement {
/// A widget that attempts to size the child to a specific aspect ratio. /// A widget that attempts to size the child to a specific aspect ratio.
/// ///
/// The widget first tries the largest width permited by the layout /// The widget first tries the largest width permitted by the layout
/// constraints. The height of the widget is determined by applying the /// constraints. The height of the widget is determined by applying the
/// given aspect ratio to the width, expressed as a ratio of width to height. /// given aspect ratio to the width, expressed as a ratio of width to height.
/// ///
......
...@@ -36,12 +36,17 @@ class BoxConstraintsTween extends Tween<BoxConstraints> { ...@@ -36,12 +36,17 @@ class BoxConstraintsTween extends Tween<BoxConstraints> {
/// This class specializes the interpolation of [Tween<BoxConstraints>] to use /// This class specializes the interpolation of [Tween<BoxConstraints>] to use
/// [Decoration.lerp]. /// [Decoration.lerp].
/// ///
/// Typically this will only have useful results if the [begin] and [end] /// For [ShapeDecoration]s which know how to [ShapeDecoration.lerpTo] or
/// decorations have the same type; decorations of differing types generally do /// [ShapeDecoration.lerpFrom] each other, this will produce a smooth
/// not have a useful animation defined, and will just jump to the [end] /// interpolation between decorations.
/// immediately.
/// ///
/// See [Tween] for a discussion on how to use interpolation objects. /// See also:
/// * [Tween] for a discussion on how to use interpolation objects.
/// * [ShapeDecoration], [RoundedRectangleBorder], [CircleBorder], and
/// [StadiumBorder] for examples of shape borders that can be smoothly
/// interpolated.
/// * [BoxBorder] for a border that can only be smoothly interpolated between other
/// [BoxBorder]s.
class DecorationTween extends Tween<Decoration> { class DecorationTween extends Tween<Decoration> {
/// Creates a decoration tween. /// Creates a decoration tween.
/// ///
......
...@@ -254,6 +254,159 @@ void main() { ...@@ -254,6 +254,159 @@ void main() {
expect(tester.getCenter(find.text('ABC')).dx, lessThan(tester.getCenter(find.byType(Icon)).dx)); expect(tester.getCenter(find.text('ABC')).dx, lessThan(tester.getCenter(find.byType(Icon)).dx));
}); });
testWidgets('Chip responds to textScaleFactor', (WidgetTester tester) async {
await tester.pumpWidget(
new MaterialApp(
home: new Material(
child: new Column(
children: <Widget>[
const Chip(
avatar: const CircleAvatar(
child: const Text('A')
),
label: const Text('Chip A'),
),
const Chip(
avatar: const CircleAvatar(
child: const Text('B')
),
label: const Text('Chip B'),
),
],
),
),
),
);
// TODO(gspencer): Update this test when the font metric bug is fixed to remove the anyOfs.
// https://github.com/flutter/flutter/issues/12357
expect(
tester.getSize(find.text('Chip A')),
anyOf(const Size(79.0, 13.0), const Size(78.0, 13.0)),
);
expect(
tester.getSize(find.text('Chip B')),
anyOf(const Size(79.0, 13.0), const Size(78.0, 13.0)),
);
expect(
tester.getSize(find.byType(Chip).first),
anyOf(const Size(131.0, 32.0), const Size(130.0, 32.0))
);
expect(
tester.getSize(find.byType(Chip).last),
anyOf(const Size(131.0, 32.0), const Size(130.0, 32.0))
);
await tester.pumpWidget(
new MaterialApp(
home: new MediaQuery(
data: const MediaQueryData(textScaleFactor: 3.0),
child: new Material(
child: new Column(
children: <Widget>[
const Chip(
avatar: const CircleAvatar(
child: const Text('A')
),
label: const Text('Chip A'),
),
const Chip(
avatar: const CircleAvatar(
child: const Text('B')
),
label: const Text('Chip B'),
),
],
),
),
),
),
);
// TODO(gspencer): Update this test when the font metric bug is fixed to remove the anyOfs.
// https://github.com/flutter/flutter/issues/12357
expect(tester.getSize(find.text('Chip A')), anyOf(const Size(234.0, 39.0), const Size(235.0, 39.0)));
expect(tester.getSize(find.text('Chip B')), anyOf(const Size(234.0, 39.0), const Size(235.0, 39.0)));
expect(tester.getSize(find.byType(Chip).first).width, anyOf(286.0, 287.0));
expect(tester.getSize(find.byType(Chip).first).height, equals(39.0));
expect(tester.getSize(find.byType(Chip).last).width, anyOf(286.0, 287.0));
expect(tester.getSize(find.byType(Chip).last).height, equals(39.0));
// Check that individual text scales are taken into account.
await tester.pumpWidget(
new MaterialApp(
home: new Material(
child: new Column(
children: <Widget>[
const Chip(
avatar: const CircleAvatar(
child: const Text('A')
),
label: const Text('Chip A', textScaleFactor: 3.0),
),
const Chip(
avatar: const CircleAvatar(
child: const Text('B')
),
label: const Text('Chip B'),
),
],
),
),
),
);
// TODO(gspencer): Update this test when the font metric bug is fixed to remove the anyOfs.
// https://github.com/flutter/flutter/issues/12357
expect(tester.getSize(find.text('Chip A')), anyOf(const Size(234.0, 39.0), const Size(235.0, 39.0)));
expect(tester.getSize(find.text('Chip B')), anyOf(const Size(78.0, 13.0), const Size(79.0, 13.0)));
expect(tester.getSize(find.byType(Chip).first).width, anyOf(286.0, 287.0));
expect(tester.getSize(find.byType(Chip).first).height, equals(39.0));
expect(tester.getSize(find.byType(Chip).last), anyOf(const Size(130.0, 32.0), const Size(131.0, 32.0)));
});
testWidgets('Labels can be non-text widgets', (WidgetTester tester) async {
final Key keyA = new GlobalKey();
final Key keyB = new GlobalKey();
await tester.pumpWidget(
new MaterialApp(
home: new Material(
child: new Column(
children: <Widget>[
new Chip(
avatar: const CircleAvatar(
child: const Text('A')
),
label: new Text('Chip A', key: keyA),
),
new Chip(
avatar: const CircleAvatar(
child: const Text('B')
),
label: new Container(key: keyB, width: 10.0, height: 10.0),
),
],
),
),
),
);
// TODO(gspencer): Update this test when the font metric bug is fixed to remove the anyOfs.
// https://github.com/flutter/flutter/issues/12357
expect(
tester.getSize(find.byKey(keyA)),
anyOf(const Size(79.0, 13.0), const Size(78.0, 13.0)),
);
expect(tester.getSize(find.byKey(keyB)), const Size(10.0, 10.0));
expect(
tester.getSize(find.byType(Chip).first),
anyOf(const Size(131.0, 32.0), const Size(130.0, 32.0)),
);
expect(tester.getSize(find.byType(Chip).last), const Size(62.0, 32.0));
});
testWidgets('Chip padding - LTR', (WidgetTester tester) async { testWidgets('Chip padding - LTR', (WidgetTester tester) async {
final GlobalKey keyA = new GlobalKey(); final GlobalKey keyA = new GlobalKey();
final GlobalKey keyB = new GlobalKey(); final GlobalKey keyB = new GlobalKey();
...@@ -281,10 +434,10 @@ void main() { ...@@ -281,10 +434,10 @@ void main() {
); );
expect(tester.getTopLeft(find.byKey(keyA)), const Offset(0.0, 284.0)); expect(tester.getTopLeft(find.byKey(keyA)), const Offset(0.0, 284.0));
expect(tester.getBottomRight(find.byKey(keyA)), const Offset(32.0, 316.0)); expect(tester.getBottomRight(find.byKey(keyA)), const Offset(32.0, 316.0));
expect(tester.getTopLeft(find.byKey(keyB)), const Offset(40.0, 284.0)); expect(tester.getTopLeft(find.byKey(keyB)), const Offset(40.0, 0.0));
expect(tester.getBottomRight(find.byKey(keyB)), const Offset(774.0, 316.0)); expect(tester.getBottomRight(find.byKey(keyB)), const Offset(768.0, 600.0));
expect(tester.getTopLeft(find.byType(Icon)), const Offset(778.0, 291.0)); expect(tester.getTopLeft(find.byType(Icon)), const Offset(772.0, 288.0));
expect(tester.getBottomRight(find.byType(Icon)), const Offset(796.0, 309.0)); expect(tester.getBottomRight(find.byType(Icon)), const Offset(796.0, 312.0));
}); });
testWidgets('Chip padding - RTL', (WidgetTester tester) async { testWidgets('Chip padding - RTL', (WidgetTester tester) async {
...@@ -314,9 +467,9 @@ void main() { ...@@ -314,9 +467,9 @@ void main() {
); );
expect(tester.getTopRight(find.byKey(keyA)), const Offset(800.0 - 0.0, 284.0)); expect(tester.getTopRight(find.byKey(keyA)), const Offset(800.0 - 0.0, 284.0));
expect(tester.getBottomLeft(find.byKey(keyA)), const Offset(800.0 - 32.0, 316.0)); expect(tester.getBottomLeft(find.byKey(keyA)), const Offset(800.0 - 32.0, 316.0));
expect(tester.getTopRight(find.byKey(keyB)), const Offset(800.0 - 40.0, 284.0)); expect(tester.getTopRight(find.byKey(keyB)), const Offset(800.0 - 40.0, 0.0));
expect(tester.getBottomLeft(find.byKey(keyB)), const Offset(800.0 - 774.0, 316.0)); expect(tester.getBottomLeft(find.byKey(keyB)), const Offset(800.0 - 768.0, 600.0));
expect(tester.getTopRight(find.byType(Icon)), const Offset(800.0 - 778.0, 291.0)); expect(tester.getTopRight(find.byType(Icon)), const Offset(800.0 - 772.0, 288.0));
expect(tester.getBottomLeft(find.byType(Icon)), const Offset(800.0 - 796.0, 309.0)); expect(tester.getBottomLeft(find.byType(Icon)), const Offset(800.0 - 796.0, 312.0));
}); });
} }
...@@ -10,9 +10,9 @@ import 'common_matchers.dart'; ...@@ -10,9 +10,9 @@ import 'common_matchers.dart';
void main() { void main() {
test('CircleBorder', () { test('CircleBorder', () {
final CircleBorder c10 = const CircleBorder(const BorderSide(width: 10.0)); final CircleBorder c10 = const CircleBorder(side: const BorderSide(width: 10.0));
final CircleBorder c15 = const CircleBorder(const BorderSide(width: 15.0)); final CircleBorder c15 = const CircleBorder(side: const BorderSide(width: 15.0));
final CircleBorder c20 = const CircleBorder(const BorderSide(width: 20.0)); final CircleBorder c20 = const CircleBorder(side: const BorderSide(width: 20.0));
expect(c10.dimensions, const EdgeInsets.all(10.0)); expect(c10.dimensions, const EdgeInsets.all(10.0));
expect(c10.scale(2.0), c20); expect(c10.scale(2.0), c20);
expect(c20.scale(0.5), c10); expect(c20.scale(0.5), c10);
......
...@@ -38,7 +38,7 @@ void main() { ...@@ -38,7 +38,7 @@ void main() {
test('RoundedRectangleBorder and CircleBorder', () { test('RoundedRectangleBorder and CircleBorder', () {
final RoundedRectangleBorder r = new RoundedRectangleBorder(side: BorderSide.none, borderRadius: new BorderRadius.circular(10.0)); final RoundedRectangleBorder r = new RoundedRectangleBorder(side: BorderSide.none, borderRadius: new BorderRadius.circular(10.0));
final CircleBorder c = const CircleBorder(BorderSide.none); final CircleBorder c = const CircleBorder(side: BorderSide.none);
final Rect rect = new Rect.fromLTWH(0.0, 0.0, 100.0, 20.0); // center is x=40..60 y=10 final Rect rect = new Rect.fromLTWH(0.0, 0.0, 100.0, 20.0); // center is x=40..60 y=10
final Matcher looksLikeR = isPathThat( final Matcher looksLikeR = isPathThat(
includes: const <Offset>[ const Offset(30.0, 10.0), const Offset(50.0, 10.0), ], includes: const <Offset>[ const Offset(30.0, 10.0), const Offset(50.0, 10.0), ],
......
...@@ -21,7 +21,7 @@ void main() { ...@@ -21,7 +21,7 @@ void main() {
expect(() => new ShapeDecoration(color: colorR, shape: null), throwsAssertionError); expect(() => new ShapeDecoration(color: colorR, shape: null), throwsAssertionError);
expect( expect(
new ShapeDecoration.fromBoxDecoration(const BoxDecoration(shape: BoxShape.circle)), new ShapeDecoration.fromBoxDecoration(const BoxDecoration(shape: BoxShape.circle)),
const ShapeDecoration(shape: const CircleBorder(BorderSide.none)), const ShapeDecoration(shape: const CircleBorder(side: BorderSide.none)),
); );
expect( expect(
new ShapeDecoration.fromBoxDecoration(new BoxDecoration(shape: BoxShape.rectangle, borderRadius: new BorderRadiusDirectional.circular(100.0))), new ShapeDecoration.fromBoxDecoration(new BoxDecoration(shape: BoxShape.rectangle, borderRadius: new BorderRadiusDirectional.circular(100.0))),
...@@ -29,7 +29,7 @@ void main() { ...@@ -29,7 +29,7 @@ void main() {
); );
expect( expect(
new ShapeDecoration.fromBoxDecoration(new BoxDecoration(shape: BoxShape.circle, border: new Border.all(color: colorG))), new ShapeDecoration.fromBoxDecoration(new BoxDecoration(shape: BoxShape.circle, border: new Border.all(color: colorG))),
new ShapeDecoration(shape: new CircleBorder(new BorderSide(color: colorG))), new ShapeDecoration(shape: new CircleBorder(side: new BorderSide(color: colorG))),
); );
expect( expect(
new ShapeDecoration.fromBoxDecoration(new BoxDecoration(shape: BoxShape.rectangle, border: new Border.all(color: colorR))), new ShapeDecoration.fromBoxDecoration(new BoxDecoration(shape: BoxShape.rectangle, border: new Border.all(color: colorR))),
......
This diff is collapsed.
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