Refactor StrokeAlign to allow double values. (#108339)

This commit is contained in:
Bernardo Ferrari 2022-08-15 17:23:20 -03:00 committed by GitHub
parent 21f802e0e0
commit dd8573b871
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 465 additions and 566 deletions

View file

@ -80,7 +80,7 @@ class _MyHomePageState extends State<MyHomePage> {
color: Colors.blue.shade100,
shape: lerpBorder(
StarBorder.polygon(
side: const BorderSide(strokeAlign: StrokeAlign.center, width: 2),
side: const BorderSide(strokeAlign: BorderSide.strokeAlignCenter, width: 2),
sides: _model.points,
pointRounding: _model.pointRounding,
rotation: _model.rotation,
@ -102,7 +102,7 @@ class _MyHomePageState extends State<MyHomePage> {
color: Colors.blue.shade100,
shape: lerpBorder(
StarBorder(
side: const BorderSide(strokeAlign: StrokeAlign.center, width: 2),
side: const BorderSide(strokeAlign: BorderSide.strokeAlignCenter, width: 2),
points: _model.points,
innerRadiusRatio: _model.innerRadiusRatio,
pointRounding: _model.pointRounding,

View file

@ -0,0 +1,204 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/// Flutter code sample for [BorderSide].
import 'package:flutter/material.dart';
void main() => runApp(const BorderSideApp());
class BorderSideApp extends StatelessWidget {
const BorderSideApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(home: BorderSideExample());
}
}
class BorderSideExample extends StatefulWidget {
const BorderSideExample({super.key});
@override
State<BorderSideExample> createState() => _BorderSideExampleState();
}
class _BorderSideExampleState extends State<BorderSideExample>
with TickerProviderStateMixin {
late final AnimationController animation;
@override
void initState() {
super.initState();
animation =
AnimationController(vsync: this, duration: const Duration(seconds: 1));
animation.repeat(reverse: true);
animation.addListener(_markDirty);
}
@override
void dispose() {
animation.dispose();
super.dispose();
}
void _markDirty() {
setState(() {});
}
static const double borderWidth = 10;
static const double cornerRadius = 10;
static const Color borderColor = Color(0x8000b4fc);
@override
Widget build(BuildContext context) {
return Material(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
TestBox(
shape: StadiumBorder(
side: BorderSide(
color: borderColor,
width: borderWidth,
strokeAlign: (animation.value * 2) - 1,
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
TestBox(
shape: CircleBorder(
side: BorderSide(
color: borderColor,
width: borderWidth,
strokeAlign: (animation.value * 2) - 1,
),
),
),
TestBox(
shape: OvalBorder(
side: BorderSide(
color: borderColor,
width: borderWidth,
strokeAlign: (animation.value * 2) - 1,
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
TestBox(
shape: BeveledRectangleBorder(
side: BorderSide(
color: borderColor,
width: borderWidth,
strokeAlign: (animation.value * 2) - 1,
),
),
),
TestBox(
shape: BeveledRectangleBorder(
borderRadius: BorderRadius.circular(cornerRadius),
side: BorderSide(
color: borderColor,
width: borderWidth,
strokeAlign: (animation.value * 2) - 1,
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
TestBox(
shape: RoundedRectangleBorder(
side: BorderSide(
color: borderColor,
width: borderWidth,
strokeAlign: (animation.value * 2) - 1,
),
),
),
TestBox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(cornerRadius),
side: BorderSide(
color: borderColor,
width: borderWidth,
strokeAlign: (animation.value * 2) - 1,
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
TestBox(
shape: StarBorder(
side: BorderSide(
color: borderColor,
width: borderWidth,
strokeAlign: (animation.value * 2) - 1,
),
),
),
TestBox(
shape: StarBorder(
pointRounding: 1,
innerRadiusRatio: 0.5,
points: 8,
side: BorderSide(
color: borderColor,
width: borderWidth,
strokeAlign: (animation.value * 2) - 1,
),
),
),
TestBox(
shape: StarBorder.polygon(
sides: 6,
pointRounding: 0.5,
side: BorderSide(
color: borderColor,
width: borderWidth,
strokeAlign: (animation.value * 2) - 1,
),
),
),
],
),
],
),
),
);
}
}
class TestBox extends StatelessWidget {
const TestBox({
super.key,
required this.shape,
});
final ShapeBorder shape;
@override
Widget build(BuildContext context) {
return Container(
width: 100,
height: 50,
decoration: ShapeDecoration(
color: const Color(0xff012677),
shape: shape,
),
);
}
}

View file

@ -0,0 +1,21 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter_api_samples/painting/borders/border_side.0.dart'
as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Finds the expected TestBox', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: example.BorderSideExample(),
),
);
expect(find.byType(example.BorderSideExample), findsOneWidget);
expect(find.byType(example.TestBox), findsNWidgets(10));
});
}

View file

@ -9,7 +9,6 @@ import 'package:flutter/foundation.dart';
import 'basic_types.dart';
import 'border_radius.dart';
import 'borders.dart';
import 'edge_insets.dart';
/// A rectangular border with flattened or "beveled" corners.
///
@ -40,18 +39,6 @@ class BeveledRectangleBorder extends OutlinedBorder {
/// [getOuterPath].
final BorderRadiusGeometry borderRadius;
@override
EdgeInsetsGeometry get dimensions {
switch (side.strokeAlign) {
case StrokeAlign.inside:
return EdgeInsets.all(side.width);
case StrokeAlign.center:
return EdgeInsets.all(side.width / 2);
case StrokeAlign.outside:
return EdgeInsets.zero;
}
}
@override
ShapeBorder scale(double t) {
return BeveledRectangleBorder(
@ -125,21 +112,7 @@ class BeveledRectangleBorder extends OutlinedBorder {
@override
Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
final RRect borderRect = borderRadius.resolve(textDirection).toRRect(rect);
final RRect adjustedRect;
switch (side.strokeAlign) {
case StrokeAlign.inside:
adjustedRect = borderRect.deflate(side.width);
break;
case StrokeAlign.center:
adjustedRect = borderRect.deflate(side.width / 2);
break;
case StrokeAlign.outside:
adjustedRect = borderRect;
break;
}
return _getPath(adjustedRect);
return _getPath(borderRadius.resolve(textDirection).toRRect(rect).deflate(side.strokeInset));
}
@override
@ -156,21 +129,7 @@ class BeveledRectangleBorder extends OutlinedBorder {
case BorderStyle.none:
break;
case BorderStyle.solid:
final RRect borderRect = borderRadius.resolve(textDirection).toRRect(rect);
final RRect adjustedRect;
switch (side.strokeAlign) {
case StrokeAlign.inside:
adjustedRect = borderRect;
break;
case StrokeAlign.center:
adjustedRect = borderRect.inflate(side.width / 2);
break;
case StrokeAlign.outside:
adjustedRect = borderRect.inflate(side.width);
break;
}
final Path path = _getPath(adjustedRect)
..addPath(getInnerPath(rect, textDirection: textDirection), Offset.zero);
final Path path = _getPath(borderRadius.resolve(textDirection).toRRect(rect).inflate(side.strokeOffset / 2));
canvas.drawPath(path, side.toPaint());
break;
}

View file

@ -21,27 +21,6 @@ enum BorderStyle {
// if you add more, think about how they will lerp
}
/// The relative position of the stroke on a [BorderSide] in a [Border] or [OutlinedBorder].
/// When set to [inside], the stroke is drawn completely inside the widget.
/// For [center] and [outside], a property such as [Container.clipBehavior]
/// can be used in an outside widget to clip it.
/// If [Container.decoration] has a border, the container may incorporate
/// [BorderSide.width] as additional padding:
/// - [inside] provides padding with full [BorderSide.width].
/// - [center] provides padding with half [BorderSide.width].
/// - [outside] provides zero padding, as stroke is drawn entirely outside.
enum StrokeAlign {
/// The border is drawn on the inside of the border path.
inside,
/// The border is drawn on the center of the border path, with half of the
/// [BorderSide.width] on the inside, and the other half on the outside of the path.
center,
/// The border is drawn on the outside of the border path.
outside,
}
/// A side of a border of a box.
///
/// A [Border] consists of four [BorderSide] objects: [Border.top],
@ -79,7 +58,7 @@ enum StrokeAlign {
/// ([TableBorder.horizontalInside] and [TableBorder.verticalInside]), both
/// of which are also [BorderSide] objects.
@immutable
class BorderSide {
class BorderSide with Diagnosticable {
/// Creates the side of a border.
///
/// By default, the border is 1.0 logical pixels wide and solid black.
@ -87,11 +66,12 @@ class BorderSide {
this.color = const Color(0xFF000000),
this.width = 1.0,
this.style = BorderStyle.solid,
this.strokeAlign = StrokeAlign.inside,
this.strokeAlign = strokeAlignInside,
}) : assert(color != null),
assert(width != null),
assert(width >= 0.0),
assert(style != null);
assert(style != null),
assert(strokeAlign != null);
/// Creates a [BorderSide] that represents the addition of the two given
/// [BorderSide]s.
@ -124,6 +104,7 @@ class BorderSide {
return BorderSide(
color: a.color, // == b.color
width: a.width + b.width,
strokeAlign: math.max(a.strokeAlign, b.strokeAlign),
style: a.style, // == b.style
);
}
@ -151,20 +132,50 @@ class BorderSide {
/// A hairline black border that is not rendered.
static const BorderSide none = BorderSide(width: 0.0, style: BorderStyle.none);
/// The direction of where the border will be drawn relative to the container.
final StrokeAlign strokeAlign;
/// The relative position of the stroke on a [BorderSide] in an
/// [OutlinedBorder] or [Border].
///
/// Values typically range from -1.0 ([strokeAlignInside], inside border,
/// default) to 1.0 ([strokeAlignOutside], outside border), without any
/// bound constraints (e.g., a value of -2.0 is is not typical, but allowed).
/// A value of 0 ([strokeAlignCenter]) will center the border on the edge
/// of the widget.
///
/// When set to [strokeAlignInside], the stroke is drawn completely inside
/// the widget. For [strokeAlignCenter] and [strokeAlignOutside], a property
/// such as [Container.clipBehavior] can be used in an outside widget to clip
/// it. If [Container.decoration] has a border, the container may incorporate
/// [width] as additional padding:
/// - [strokeAlignInside] provides padding with full [width].
/// - [strokeAlignCenter] provides padding with half [width].
/// - [strokeAlignOutside] provides zero padding, as stroke is drawn entirely outside.
final double strokeAlign;
/// The border is drawn fully inside of the border path.
///
/// This is the default.
static const double strokeAlignInside = -1.0;
/// The border is drawn on the center of the border path, with half of the
/// [BorderSide.width] on the inside, and the other half on the outside of
/// the path.
static const double strokeAlignCenter = 0.0;
/// The border is drawn on the outside of the border path.
static const double strokeAlignOutside = 1.0;
/// Creates a copy of this border but with the given fields replaced with the new values.
BorderSide copyWith({
Color? color,
double? width,
BorderStyle? style,
double? strokeAlign,
}) {
assert(width == null || width >= 0.0);
return BorderSide(
color: color ?? this.color,
width: width ?? this.width,
style: style ?? this.style,
strokeAlign: strokeAlign ?? this.strokeAlign,
);
}
@ -229,8 +240,7 @@ class BorderSide {
return true;
}
return a.style == b.style
&& a.color == b.color
&& a.strokeAlign == b.strokeAlign;
&& a.color == b.color;
}
/// Linearly interpolate between two border sides.
@ -278,13 +288,10 @@ class BorderSide {
break;
}
if (a.strokeAlign != b.strokeAlign) {
// When strokeAlign changes, lerp to 0, then from 0 to the target width.
// All StrokeAlign values share a common zero width state.
final StrokeAlign strokeAlign = t > 0.5 ? b.strokeAlign : a.strokeAlign;
return BorderSide(
color: Color.lerp(colorA, colorB, t)!,
width: t > 0.5 ? ui.lerpDouble(0, b.width, t * 2 - 1)! : ui.lerpDouble(a.width, 0, t * 2)!,
strokeAlign: strokeAlign,
width: width,
strokeAlign: ui.lerpDouble(a.strokeAlign, b.strokeAlign, t)!,
);
}
return BorderSide(
@ -294,6 +301,26 @@ class BorderSide {
);
}
/// Get the amount of the stroke width that lies inside of the [BorderSide].
///
/// For example, this will return the [width] for a [strokeAlign] of -1, half
/// the [width] for a [strokeAlign] of 0, and 0 for a [strokeAlign] of 1.
double get strokeInset => width * (1 - (1 + strokeAlign) / 2);
/// Get the amount of the stroke width that lies outside of the [BorderSide].
///
/// For example, this will return 0 for a [strokeAlign] of -1, half the
/// [width] for a [strokeAlign] of 0, and the [width] for a [strokeAlign]
/// of 1.
double get strokeOutset => width * (1 + strokeAlign) / 2;
/// The offset of the stroke, taking into account the stroke alignment.
///
/// For example, this will return the negative [width] of the stroke
/// for a [strokeAlign] of -1, 0 for a [strokeAlign] of 0, and the
/// [width] for a [strokeAlign] of -1.
double get strokeOffset => width * strokeAlign;
@override
bool operator ==(Object other) {
if (identical(this, other)) {
@ -313,11 +340,15 @@ class BorderSide {
int get hashCode => Object.hash(color, width, style, strokeAlign);
@override
String toString() {
if (strokeAlign == StrokeAlign.inside) {
return '${objectRuntimeType(this, 'BorderSide')}($color, ${width.toStringAsFixed(1)}, $style)';
}
return '${objectRuntimeType(this, 'BorderSide')}($color, ${width.toStringAsFixed(1)}, $style, $strokeAlign)';
String toStringShort() => 'BorderSide';
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: const Color(0xFF000000)));
properties.add(DoubleProperty('width', width, defaultValue: 1.0));
properties.add(DoubleProperty('strokeAlign', strokeAlign, defaultValue: strokeAlignInside));
properties.add(EnumProperty<BorderStyle>('style', style, defaultValue: BorderStyle.solid));
}
}
@ -557,6 +588,9 @@ abstract class OutlinedBorder extends ShapeBorder {
/// The value of [side] must not be null.
const OutlinedBorder({ this.side = BorderSide.none }) : assert(side != null);
@override
EdgeInsetsGeometry get dimensions => EdgeInsets.all(math.max(side.strokeInset, 0));
/// The border outline's color and weight.
///
/// If [side] is [BorderSide.none], which is the default, an outline is not drawn.

View file

@ -219,62 +219,22 @@ abstract class BoxBorder extends ShapeBorder {
..strokeWidth = 0.0;
canvas.drawRRect(borderRadius.toRRect(rect), paint);
} else {
if (side.strokeAlign == StrokeAlign.inside) {
final RRect outer = borderRadius.toRRect(rect);
final RRect inner = outer.deflate(width);
canvas.drawDRRect(outer, inner, paint);
} else {
final Rect inner;
final Rect outer;
if (side.strokeAlign == StrokeAlign.center) {
inner = rect.deflate(width / 2);
outer = rect.inflate(width / 2);
} else {
inner = rect;
outer = rect.inflate(width);
}
canvas.drawDRRect(borderRadius.toRRect(outer), borderRadius.toRRect(inner), paint);
}
final RRect borderRect = borderRadius.toRRect(rect);
final RRect inner = borderRect.deflate(side.strokeInset);
final RRect outer = borderRect.inflate(side.strokeOutset);
canvas.drawDRRect(outer, inner, paint);
}
}
static void _paintUniformBorderWithCircle(Canvas canvas, Rect rect, BorderSide side) {
assert(side.style != BorderStyle.none);
final double width = side.width;
final Paint paint = side.toPaint();
final double radius;
switch (side.strokeAlign) {
case StrokeAlign.inside:
radius = (rect.shortestSide - width) / 2.0;
break;
case StrokeAlign.center:
radius = rect.shortestSide / 2.0;
break;
case StrokeAlign.outside:
radius = (rect.shortestSide + width) / 2.0;
break;
}
canvas.drawCircle(rect.center, radius, paint);
final double radius = (rect.shortestSide + side.strokeOffset) / 2;
canvas.drawCircle(rect.center, radius, side.toPaint());
}
static void _paintUniformBorderWithRectangle(Canvas canvas, Rect rect, BorderSide side) {
assert(side.style != BorderStyle.none);
final double width = side.width;
final Paint paint = side.toPaint();
final Rect rectToBeDrawn;
switch (side.strokeAlign) {
case StrokeAlign.inside:
rectToBeDrawn = rect.deflate(width / 2.0);
break;
case StrokeAlign.center:
rectToBeDrawn = rect;
break;
case StrokeAlign.outside:
rectToBeDrawn = rect.inflate(width / 2.0);
break;
}
canvas.drawRect(rectToBeDrawn, paint);
canvas.drawRect(rect.inflate(side.strokeOffset / 2), side.toPaint());
}
}
@ -388,7 +348,7 @@ class Border extends BoxBorder {
Color color = const Color(0xFF000000),
double width = 1.0,
BorderStyle style = BorderStyle.solid,
StrokeAlign strokeAlign = StrokeAlign.inside,
double strokeAlign = BorderSide.strokeAlignInside,
}) {
final BorderSide side = BorderSide(color: color, width: width, style: style, strokeAlign: strokeAlign);
return Border.fromBorderSide(side);
@ -430,17 +390,10 @@ class Border extends BoxBorder {
@override
EdgeInsetsGeometry get dimensions {
if (isUniform) {
switch (top.strokeAlign) {
case StrokeAlign.inside:
return EdgeInsets.all(top.width);
case StrokeAlign.center:
return EdgeInsets.all(top.width / 2);
case StrokeAlign.outside:
return EdgeInsets.zero;
}
if (_widthIsUniform) {
return EdgeInsets.all(top.strokeInset);
}
return EdgeInsets.fromLTRB(left.width, top.width, right.width, bottom.width);
return EdgeInsets.fromLTRB(left.strokeInset, top.strokeInset, right.strokeInset, bottom.strokeInset);
}
@override
@ -462,7 +415,7 @@ class Border extends BoxBorder {
}
bool get _strokeAlignIsUniform {
final StrokeAlign topStrokeAlign = top.strokeAlign;
final double topStrokeAlign = top.strokeAlign;
return right.strokeAlign == topStrokeAlign
&& bottom.strokeAlign == topStrokeAlign
&& left.strokeAlign == topStrokeAlign;
@ -569,7 +522,7 @@ class Border extends BoxBorder {
BoxBorder._paintUniformBorderWithCircle(canvas, rect, top);
break;
case BoxShape.rectangle:
if (borderRadius != null) {
if (borderRadius != null && borderRadius != BorderRadius.zero) {
BoxBorder._paintUniformBorderWithRadius(canvas, rect, top, borderRadius);
return;
}
@ -607,9 +560,9 @@ class Border extends BoxBorder {
return true;
}());
assert(() {
if (!_strokeAlignIsUniform || top.strokeAlign != StrokeAlign.inside) {
if (!_strokeAlignIsUniform || top.strokeAlign != BorderSide.strokeAlignInside) {
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('A Border can only draw strokeAlign different than StrokeAlign.inside on uniform borders.'),
ErrorSummary('A Border can only draw strokeAlign different than BorderSide.strokeAlignInside on uniform borders.'),
]);
}
return true;
@ -741,16 +694,9 @@ class BorderDirectional extends BoxBorder {
@override
EdgeInsetsGeometry get dimensions {
if (isUniform) {
switch (top.strokeAlign) {
case StrokeAlign.inside:
return EdgeInsetsDirectional.all(top.width);
case StrokeAlign.center:
return EdgeInsetsDirectional.all(top.width / 2);
case StrokeAlign.outside:
return EdgeInsetsDirectional.zero;
}
return EdgeInsetsDirectional.all(top.strokeInset);
}
return EdgeInsetsDirectional.fromSTEB(start.width, top.width, end.width, bottom.width);
return EdgeInsetsDirectional.fromSTEB(start.strokeInset, top.strokeInset, end.strokeInset, bottom.strokeInset);
}
@override
@ -784,7 +730,7 @@ class BorderDirectional extends BoxBorder {
}
bool get _strokeAlignIsUniform {
final StrokeAlign topStrokeAlign = top.strokeAlign;
final double topStrokeAlign = top.strokeAlign;
return start.strokeAlign == topStrokeAlign
&& bottom.strokeAlign == topStrokeAlign
&& end.strokeAlign == topStrokeAlign;
@ -927,7 +873,7 @@ class BorderDirectional extends BoxBorder {
BoxBorder._paintUniformBorderWithCircle(canvas, rect, top);
break;
case BoxShape.rectangle:
if (borderRadius != null) {
if (borderRadius != null && borderRadius != BorderRadius.zero) {
BoxBorder._paintUniformBorderWithRadius(canvas, rect, top, borderRadius);
return;
}
@ -940,7 +886,7 @@ class BorderDirectional extends BoxBorder {
assert(borderRadius == null, 'A borderRadius can only be given for uniform borders.');
assert(shape == BoxShape.rectangle, 'A border can only be drawn as a circle if it is uniform.');
assert(_strokeAlignIsUniform && top.strokeAlign == StrokeAlign.inside, 'A Border can only draw strokeAlign different than StrokeAlign.inside on uniform borders.');
assert(_strokeAlignIsUniform && top.strokeAlign == BorderSide.strokeAlignInside, 'A Border can only draw strokeAlign different than strokeAlignInside on uniform borders.');
final BorderSide left, right;
assert(textDirection != null, 'Non-uniform BorderDirectional objects require a TextDirection when painting.');

View file

@ -431,7 +431,7 @@ class _BoxDecorationPainter extends BoxPainter {
canvas.drawCircle(center, radius, paint);
break;
case BoxShape.rectangle:
if (_decoration.borderRadius == null) {
if (_decoration.borderRadius == null || _decoration.borderRadius == BorderRadius.zero) {
canvas.drawRect(rect, paint);
} else {
canvas.drawRRect(_decoration.borderRadius!.resolve(textDirection).toRRect(rect), paint);

View file

@ -8,7 +8,6 @@ import 'package:flutter/foundation.dart';
import 'basic_types.dart';
import 'borders.dart';
import 'edge_insets.dart';
/// A border that fits a circle within the available space.
///
@ -45,18 +44,6 @@ class CircleBorder extends OutlinedBorder {
/// When 1.0, it draws an oval touching all sides of the rectangle.
final double eccentricity;
@override
EdgeInsetsGeometry get dimensions {
switch (side.strokeAlign) {
case StrokeAlign.inside:
return EdgeInsets.all(side.width);
case StrokeAlign.center:
return EdgeInsets.all(side.width / 2);
case StrokeAlign.outside:
return EdgeInsets.zero;
}
}
@override
ShapeBorder scale(double t) => CircleBorder(side: side.scale(t), eccentricity: eccentricity);
@ -84,25 +71,12 @@ class CircleBorder extends OutlinedBorder {
@override
Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
final double delta;
switch (side.strokeAlign) {
case StrokeAlign.inside:
delta = side.width;
break;
case StrokeAlign.center:
delta = side.width / 2.0;
break;
case StrokeAlign.outside:
delta = 0;
break;
}
final Rect adjustedRect = _adjustRect(rect).deflate(delta);
return Path()..addOval(adjustedRect);
return Path()..addOval(_adjustRect(rect).deflate(side.strokeInset));
}
@override
Path getOuterPath(Rect rect, { TextDirection? textDirection }) {
return Path()..addOval(_adjustRect(rect));
return Path()..addOval(_adjustRect(rect));
}
@override
@ -116,35 +90,11 @@ class CircleBorder extends OutlinedBorder {
case BorderStyle.none:
break;
case BorderStyle.solid:
if (eccentricity != 0.0) {
final Rect borderRect = _adjustRect(rect);
final Rect adjustedRect;
switch (side.strokeAlign) {
case StrokeAlign.inside:
adjustedRect = borderRect.deflate(side.width / 2.0);
break;
case StrokeAlign.center:
adjustedRect = borderRect;
break;
case StrokeAlign.outside:
adjustedRect = borderRect.inflate(side.width / 2.0);
break;
}
canvas.drawOval(adjustedRect, side.toPaint());
if (eccentricity == 0.0) {
canvas.drawCircle(rect.center, (rect.shortestSide + side.strokeOffset) / 2, side.toPaint());
} else {
final double radius;
switch (side.strokeAlign) {
case StrokeAlign.inside:
radius = (rect.shortestSide - side.width) / 2.0;
break;
case StrokeAlign.center:
radius = rect.shortestSide / 2.0;
break;
case StrokeAlign.outside:
radius = (rect.shortestSide + side.width) / 2.0;
break;
}
canvas.drawCircle(rect.center, radius, side.toPaint());
final Rect borderRect = _adjustRect(rect);
canvas.drawOval(borderRect.inflate(side.strokeOffset / 2), side.toPaint());
}
}
}

View file

@ -149,7 +149,7 @@ class ContinuousRectangleBorder extends OutlinedBorder {
break;
case BorderStyle.solid:
final Path path = getOuterPath(rect, textDirection: textDirection);
final Paint paint = side.toPaint();
final Paint paint = side.toPaint()..strokeJoin = StrokeJoin.round;
canvas.drawPath(path, paint);
break;
}

View file

@ -10,7 +10,6 @@ import 'basic_types.dart';
import 'border_radius.dart';
import 'borders.dart';
import 'circle_border.dart';
import 'edge_insets.dart';
/// A rectangular border with rounded corners.
///
@ -37,18 +36,6 @@ class RoundedRectangleBorder extends OutlinedBorder {
/// The radii for each corner.
final BorderRadiusGeometry borderRadius;
@override
EdgeInsetsGeometry get dimensions {
switch (side.strokeAlign) {
case StrokeAlign.inside:
return EdgeInsets.all(side.width);
case StrokeAlign.center:
return EdgeInsets.all(side.width / 2);
case StrokeAlign.outside:
return EdgeInsets.zero;
}
}
@override
ShapeBorder scale(double t) {
return RoundedRectangleBorder(
@ -110,18 +97,7 @@ class RoundedRectangleBorder extends OutlinedBorder {
@override
Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
final RRect borderRect = borderRadius.resolve(textDirection).toRRect(rect);
final RRect adjustedRect;
switch (side.strokeAlign) {
case StrokeAlign.inside:
adjustedRect = borderRect.deflate(side.width);
break;
case StrokeAlign.center:
adjustedRect = borderRect.deflate(side.width / 2);
break;
case StrokeAlign.outside:
adjustedRect = borderRect;
break;
}
final RRect adjustedRect = borderRect.deflate(side.strokeInset);
return Path()
..addRRect(adjustedRect);
}
@ -138,30 +114,12 @@ class RoundedRectangleBorder extends OutlinedBorder {
case BorderStyle.none:
break;
case BorderStyle.solid:
final double width = side.width;
if (width == 0.0) {
canvas.drawRRect(borderRadius.resolve(textDirection).toRRect(rect), side.toPaint());
} else {
final Paint paint = Paint()
..color = side.color;
if (side.strokeAlign == StrokeAlign.inside) {
final RRect outer = borderRadius.resolve(textDirection).toRRect(rect);
final RRect inner = outer.deflate(width);
canvas.drawDRRect(outer, inner, paint);
} else {
final Rect inner;
final Rect outer;
if (side.strokeAlign == StrokeAlign.center) {
inner = rect.deflate(width / 2);
outer = rect.inflate(width / 2);
} else {
inner = rect;
outer = rect.inflate(width);
}
final BorderRadius borderRadiusResolved = borderRadius.resolve(textDirection);
canvas.drawDRRect(borderRadiusResolved.toRRect(outer), borderRadiusResolved.toRRect(inner), paint);
}
}
final Paint paint = Paint()
..color = side.color;
final RRect borderRect = borderRadius.resolve(textDirection).toRRect(rect);
final RRect inner = borderRect.deflate(side.strokeInset);
final RRect outer = borderRect.inflate(side.strokeOutset);
canvas.drawDRRect(outer, inner, paint);
}
}
@ -198,18 +156,6 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder {
final double circleness;
final double eccentricity;
@override
EdgeInsetsGeometry get dimensions {
switch (side.strokeAlign) {
case StrokeAlign.inside:
return EdgeInsets.all(side.width);
case StrokeAlign.center:
return EdgeInsets.all(side.width / 2);
case StrokeAlign.outside:
return EdgeInsets.zero;
}
}
@override
ShapeBorder scale(double t) {
return _RoundedRectangleToCircleBorder(
@ -330,18 +276,7 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder {
@override
Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
final RRect borderRect = _adjustBorderRadius(rect, textDirection)!.toRRect(_adjustRect(rect));
final RRect adjustedRect;
switch (side.strokeAlign) {
case StrokeAlign.inside:
adjustedRect = borderRect.deflate(side.width);
break;
case StrokeAlign.center:
adjustedRect = borderRect.deflate(side.width / 2);
break;
case StrokeAlign.outside:
adjustedRect = borderRect;
break;
}
final RRect adjustedRect = borderRect.deflate(ui.lerpDouble(side.width, 0, side.strokeAlign)!);
return Path()
..addRRect(adjustedRect);
}
@ -368,25 +303,9 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder {
case BorderStyle.none:
break;
case BorderStyle.solid:
final double width = side.width;
if (width == 0.0) {
canvas.drawRRect(_adjustBorderRadius(rect, textDirection)!.toRRect(_adjustRect(rect)), side.toPaint());
} else {
final RRect borderRect = _adjustBorderRadius(rect, textDirection)!.toRRect(_adjustRect(rect));
final RRect adjustedRect;
switch (side.strokeAlign) {
case StrokeAlign.inside:
adjustedRect = borderRect.deflate(width / 2);
break;
case StrokeAlign.center:
adjustedRect = borderRect;
break;
case StrokeAlign.outside:
adjustedRect = borderRect.inflate(width / 2);
break;
}
canvas.drawRRect(adjustedRect, side.toPaint());
}
final BorderRadius adjustedBorderRadius = _adjustBorderRadius(rect, textDirection)!;
final RRect borderRect = adjustedBorderRadius.toRRect(_adjustRect(rect));
canvas.drawRRect(borderRect.inflate(side.strokeOffset / 2), side.toPaint());
}
}

View file

@ -10,7 +10,6 @@ import 'basic_types.dart';
import 'border_radius.dart';
import 'borders.dart';
import 'circle_border.dart';
import 'edge_insets.dart';
import 'rounded_rectangle_border.dart';
/// A border that fits a stadium-shaped border (a box with semicircles on the ends)
@ -30,18 +29,6 @@ class StadiumBorder extends OutlinedBorder {
/// The [side] argument must not be null.
const StadiumBorder({ super.side }) : assert(side != null);
@override
EdgeInsetsGeometry get dimensions {
switch (side.strokeAlign) {
case StrokeAlign.inside:
return EdgeInsets.all(side.width);
case StrokeAlign.center:
return EdgeInsets.all(side.width / 2);
case StrokeAlign.outside:
return EdgeInsets.zero;
}
}
@override
ShapeBorder scale(double t) => StadiumBorder(side: side.scale(t));
@ -100,18 +87,7 @@ class StadiumBorder extends OutlinedBorder {
Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
final Radius radius = Radius.circular(rect.shortestSide / 2.0);
final RRect borderRect = RRect.fromRectAndRadius(rect, radius);
final RRect adjustedRect;
switch (side.strokeAlign) {
case StrokeAlign.inside:
adjustedRect = borderRect.deflate(side.width);
break;
case StrokeAlign.center:
adjustedRect = borderRect.deflate(side.width / 2);
break;
case StrokeAlign.outside:
adjustedRect = borderRect;
break;
}
final RRect adjustedRect = borderRect.deflate(side.strokeInset);
return Path()
..addRRect(adjustedRect);
}
@ -131,22 +107,7 @@ class StadiumBorder extends OutlinedBorder {
case BorderStyle.solid:
final Radius radius = Radius.circular(rect.shortestSide / 2);
final RRect borderRect = RRect.fromRectAndRadius(rect, radius);
final RRect adjustedRect;
switch (side.strokeAlign) {
case StrokeAlign.inside:
adjustedRect = borderRect.deflate(side.width / 2);
break;
case StrokeAlign.center:
adjustedRect = borderRect;
break;
case StrokeAlign.outside:
adjustedRect = borderRect.inflate(side.width / 2);
break;
}
canvas.drawRRect(
adjustedRect,
side.toPaint(),
);
canvas.drawRRect(borderRect.inflate(side.strokeOffset / 2), side.toPaint());
}
}
@ -180,18 +141,6 @@ class _StadiumToCircleBorder extends OutlinedBorder {
final double circleness;
final double eccentricity;
@override
EdgeInsetsGeometry get dimensions {
switch (side.strokeAlign) {
case StrokeAlign.inside:
return EdgeInsets.all(side.width);
case StrokeAlign.center:
return EdgeInsets.all(side.width / 2);
case StrokeAlign.outside:
return EdgeInsets.zero;
}
}
@override
ShapeBorder scale(double t) {
return _StadiumToCircleBorder(
@ -303,7 +252,7 @@ class _StadiumToCircleBorder extends OutlinedBorder {
@override
Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
return Path()
..addRRect(_adjustBorderRadius(rect).toRRect(_adjustRect(rect)).deflate(side.width));
..addRRect(_adjustBorderRadius(rect).toRRect(_adjustRect(rect)).deflate(side.strokeInset));
}
@override
@ -327,25 +276,8 @@ class _StadiumToCircleBorder extends OutlinedBorder {
case BorderStyle.none:
break;
case BorderStyle.solid:
final double width = side.width;
if (width == 0.0) {
canvas.drawRRect(_adjustBorderRadius(rect).toRRect(_adjustRect(rect)), side.toPaint());
} else {
final RRect borderRect = _adjustBorderRadius(rect).toRRect(_adjustRect(rect));
final RRect adjustedRect;
switch (side.strokeAlign) {
case StrokeAlign.inside:
adjustedRect = borderRect.deflate(width / 2);
break;
case StrokeAlign.center:
adjustedRect = borderRect;
break;
case StrokeAlign.outside:
adjustedRect = borderRect.inflate(width / 2);
break;
}
canvas.drawRRect(adjustedRect, side.toPaint());
}
final RRect borderRect = _adjustBorderRadius(rect).toRRect(_adjustRect(rect));
canvas.drawRRect(borderRect.inflate(side.strokeOffset / 2), side.toPaint());
}
}
@ -385,11 +317,6 @@ class _StadiumToRoundedRectangleBorder extends OutlinedBorder {
final double rectness;
@override
EdgeInsetsGeometry get dimensions {
return EdgeInsets.all(side.width);
}
@override
ShapeBorder scale(double t) {
return _StadiumToRoundedRectangleBorder(
@ -464,18 +391,7 @@ class _StadiumToRoundedRectangleBorder extends OutlinedBorder {
@override
Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
final RRect borderRect = _adjustBorderRadius(rect).toRRect(rect);
final RRect adjustedRect;
switch (side.strokeAlign) {
case StrokeAlign.inside:
adjustedRect = borderRect.deflate(side.width);
break;
case StrokeAlign.center:
adjustedRect = borderRect.deflate(side.width / 2);
break;
case StrokeAlign.outside:
adjustedRect = borderRect;
break;
}
final RRect adjustedRect = borderRect.deflate(ui.lerpDouble(side.width, 0, side.strokeAlign)!);
return Path()
..addRRect(adjustedRect);
}
@ -501,26 +417,9 @@ class _StadiumToRoundedRectangleBorder extends OutlinedBorder {
case BorderStyle.none:
break;
case BorderStyle.solid:
final double width = side.width;
if (width == 0.0) {
canvas.drawRRect(_adjustBorderRadius(rect).toRRect(rect), side.toPaint());
} else {
if (side.strokeAlign == StrokeAlign.inside) {
final RRect outer = _adjustBorderRadius(rect).toRRect(rect);
final RRect inner = outer.deflate(width);
final Paint paint = Paint()
..color = side.color;
canvas.drawDRRect(outer, inner, paint);
} else {
final RRect outer;
if (side.strokeAlign == StrokeAlign.center) {
outer = _adjustBorderRadius(rect).toRRect(rect);
} else {
outer = _adjustBorderRadius(rect.inflate(width)).toRRect(rect.inflate(width / 2));
}
canvas.drawRRect(outer, side.toPaint());
}
}
final BorderRadius adjustedBorderRadius = _adjustBorderRadius(rect);
final RRect borderRect = adjustedBorderRadius.resolve(textDirection).toRRect(rect);
canvas.drawRRect(borderRect.inflate(side.strokeOffset / 2), side.toPaint());
}
}

View file

@ -11,7 +11,6 @@ import 'package:vector_math/vector_math_64.dart' show Matrix4;
import 'basic_types.dart';
import 'borders.dart';
import 'circle_border.dart';
import 'edge_insets.dart';
import 'rounded_rectangle_border.dart';
import 'stadium_border.dart';
@ -166,18 +165,6 @@ class StarBorder extends OutlinedBorder {
/// Defaults to zero, and must be between zero and one, inclusive.
final double squash;
@override
EdgeInsetsGeometry get dimensions {
switch (side.strokeAlign) {
case StrokeAlign.inside:
return EdgeInsets.all(side.width);
case StrokeAlign.center:
return EdgeInsets.all(side.width / 2);
case StrokeAlign.outside:
return EdgeInsets.zero;
}
}
@override
ShapeBorder scale(double t) {
return StarBorder(
@ -388,18 +375,7 @@ class StarBorder extends OutlinedBorder {
@override
Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
final Rect adjustedRect;
switch (side.strokeAlign) {
case StrokeAlign.inside:
adjustedRect = rect.deflate(side.width);
break;
case StrokeAlign.center:
adjustedRect = rect.deflate(side.width / 2);
break;
case StrokeAlign.outside:
adjustedRect = rect;
break;
}
final Rect adjustedRect = rect.deflate(side.strokeInset);
return _StarGenerator(
points: points,
rotation: _rotationRadians,
@ -428,18 +404,7 @@ class StarBorder extends OutlinedBorder {
case BorderStyle.none:
break;
case BorderStyle.solid:
final Rect adjustedRect;
switch (side.strokeAlign) {
case StrokeAlign.inside:
adjustedRect = rect.deflate(side.width / 2);
break;
case StrokeAlign.center:
adjustedRect = rect;
break;
case StrokeAlign.outside:
adjustedRect = rect.inflate(side.width / 2);
break;
}
final Rect adjustedRect = rect.inflate(side.strokeOffset / 2);
final Path path = _StarGenerator(
points: points,
rotation: _rotationRadians,

View file

@ -51,7 +51,7 @@ void main() {
expect(description, <String>[
'backgroundColor: Color(0xffffffff)',
'elevation: 2.0',
'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(2.0))',
'shape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(2.0))',
'clipBehavior: Clip.antiAlias',
'constraints: BoxConstraints(200.0<=w<=640.0, 0.0<=h<=Infinity)',
]);

View file

@ -88,8 +88,8 @@ void main() {
'minimumSize: MaterialStatePropertyAll(Size(1.0, 2.0))',
'maximumSize: MaterialStatePropertyAll(Size(100.0, 200.0))',
'iconSize: MaterialStatePropertyAll(48.1)',
'side: MaterialStatePropertyAll(BorderSide(Color(0xfffffff6), 4.0, BorderStyle.solid))',
'shape: MaterialStatePropertyAll(StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none)))',
'side: MaterialStatePropertyAll(BorderSide(color: Color(0xfffffff6), width: 4.0))',
'shape: MaterialStatePropertyAll(StadiumBorder(BorderSide(width: 0.0, style: none)))',
'mouseCursor: MaterialStatePropertyAll(SystemMouseCursor(forbidden))',
'tapTargetSize: shrinkWrap',
'animationDuration: 0:00:01.000000',

View file

@ -119,8 +119,8 @@ void main() {
'checkMarkColor: Color(0xfffffff7)',
'labelPadding: EdgeInsets.all(1.0)',
'padding: EdgeInsets.all(2.0)',
'side: BorderSide(Color(0xff000000), 10.0, BorderStyle.solid)',
'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.zero)',
'side: BorderSide(width: 10.0)',
'shape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.zero)',
'labelStyle: TextStyle(inherit: true, size: 10.0)',
'secondaryLabelStyle: TextStyle(inherit: true, size: 20.0)',
'brightness: dark',

View file

@ -43,7 +43,7 @@ void main() {
'backgroundColor: Color(0x00000099)',
'scrimColor: Color(0x00000098)',
'elevation: 5.0',
'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(2.0))',
'shape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(2.0))',
'width: 200.0',
]);
});

View file

@ -307,7 +307,7 @@ void main() {
'hoverElevation: 10.0',
'disabledElevation: 11.0',
'highlightElevation: 43.0',
'shape: BeveledRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.zero)',
'shape: BeveledRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.zero)',
'enableFeedback: true',
'iconSize: 42.0',
'sizeConstraints: BoxConstraints(w=100.0, h=100.0)',

View file

@ -2286,7 +2286,7 @@ void main() {
'isThreeLine: THREE_LINE',
'dense: true',
'visualDensity: VisualDensity#00000(h: 0.0, v: 0.0)',
'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.zero)',
'shape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.zero)',
'style: ListTileStyle.list',
'selectedColor: Color(0xff0000ff)',
'iconColor: Color(0xff00ff00)',

View file

@ -111,7 +111,7 @@ void main() {
description,
equalsIgnoringHashCodes(<String>[
'dense: true',
'shape: StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none))',
'shape: StadiumBorder(BorderSide(width: 0.0, style: none))',
'style: drawer',
'selectedColor: Color(0x00000001)',
'iconColor: Color(0x00000002)',

View file

@ -46,7 +46,7 @@ void main() {
expect(description[1], 'backgroundColor: Color(0x00000099)');
expect(description[2], 'elevation: 20.0');
expect(description[3], 'indicatorColor: Color(0x00000098)');
expect(description[4], 'indicatorShape: CircleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none))');
expect(description[4], 'indicatorShape: CircleBorder(BorderSide(width: 0.0, style: none))');
expect(description[5], 'labelTextStyle: MaterialStatePropertyAll(TextStyle(inherit: true, size: 7.0))');
// Ignore instance address for IconThemeData.

View file

@ -60,7 +60,7 @@ void main() {
expect(description, <String>[
'color: Color(0xffffffff)',
'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(2.0))',
'shape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(2.0))',
'elevation: 2.0',
'text style: TextStyle(inherit: true, color: Color(0xffffffff))',
'mouseCursor: MaterialStateMouseCursor(clickable)',

View file

@ -58,7 +58,7 @@ void main() {
'disabledActionTextColor: Color(0xff00aa00)',
'contentTextStyle: TextStyle(inherit: true, color: Color(0xff123456))',
'elevation: 2.0',
'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(2.0))',
'shape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(2.0))',
'behavior: SnackBarBehavior.floating',
]);
});

View file

@ -86,10 +86,10 @@ void main() {
'hourMinuteTextStyle: TextStyle(<all styles inherited>)',
'dayPeriodTextStyle: TextStyle(<all styles inherited>)',
'helpTextStyle: TextStyle(<all styles inherited>)',
'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.zero)',
'hourMinuteShape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.zero)',
'dayPeriodShape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.zero)',
'dayPeriodBorderSide: BorderSide(Color(0xff000000), 1.0, BorderStyle.solid)',
'shape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.zero)',
'hourMinuteShape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.zero)',
'dayPeriodShape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.zero)',
'dayPeriodBorderSide: BorderSide',
]);
});

View file

@ -110,8 +110,8 @@ void main() {
test('BeveledRectangleBorder with StrokeAlign', () {
const BorderRadius borderRadius = BorderRadius.all(Radius.circular(10));
const BeveledRectangleBorder inside = BeveledRectangleBorder(side: BorderSide(width: 10.0), borderRadius: borderRadius);
const BeveledRectangleBorder center = BeveledRectangleBorder(side: BorderSide(width: 10.0, strokeAlign: StrokeAlign.center), borderRadius: borderRadius);
const BeveledRectangleBorder outside = BeveledRectangleBorder(side: BorderSide(width: 10.0, strokeAlign: StrokeAlign.outside), borderRadius: borderRadius);
const BeveledRectangleBorder center = BeveledRectangleBorder(side: BorderSide(width: 10.0, strokeAlign: BorderSide.strokeAlignCenter), borderRadius: borderRadius);
const BeveledRectangleBorder outside = BeveledRectangleBorder(side: BorderSide(width: 10.0, strokeAlign: BorderSide.strokeAlignOutside), borderRadius: borderRadius);
expect(inside.dimensions, const EdgeInsets.all(10.0));
expect(center.dimensions, const EdgeInsets.all(5.0));
expect(outside.dimensions, EdgeInsets.zero);

View file

@ -142,8 +142,7 @@ void main() {
' BoxBorder.lerp() was called with two objects of type SillyBorder\n'
' and Border:\n'
' SillyBorder()\n'
' Border.all(BorderSide(Color(0xff000000), 0.0,\n'
' BorderStyle.none))\n'
' Border.all(BorderSide(width: 0.0, style: none))\n'
' However, only Border and BorderDirectional classes are supported\n'
' by this method.\n'
' For a more general interpolation method, consider using\n'

View file

@ -119,21 +119,21 @@ void main() {
test('BorderSide - toString', () {
expect(
const BorderSide(color: Color(0xFFAABBCC), width: 1.2345).toString(),
'BorderSide(Color(0xffaabbcc), 1.2, BorderStyle.solid)',
'BorderSide(color: Color(0xffaabbcc), width: 1.2)',
);
});
test('BorderSide - lerp with strokeAlign', () {
const BorderSide side0 = BorderSide(width: 2.0, strokeAlign: StrokeAlign.center);
const BorderSide side1 = BorderSide(width: 2.0, strokeAlign: StrokeAlign.outside);
expect(BorderSide.lerp(side0, side1, 0), const BorderSide(width: 2.0, strokeAlign: StrokeAlign.center));
expect(BorderSide.lerp(side0, side1, 0.5), const BorderSide(width: 0.0, strokeAlign: StrokeAlign.center));
expect(BorderSide.lerp(side0, side1, 1), const BorderSide(width: 2.0, strokeAlign: StrokeAlign.outside));
const BorderSide side0 = BorderSide(width: 2.0);
const BorderSide side1 = BorderSide(width: 2.0, strokeAlign: BorderSide.strokeAlignOutside);
expect(BorderSide.lerp(side0, side1, 0), const BorderSide(width: 2.0));
expect(BorderSide.lerp(side0, side1, 0.5), const BorderSide(width: 2.0, strokeAlign: BorderSide.strokeAlignCenter));
expect(BorderSide.lerp(side0, side1, 1), const BorderSide(width: 2.0, strokeAlign: BorderSide.strokeAlignOutside));
const BorderSide side2 = BorderSide(width: 2.0);
const BorderSide side3 = BorderSide(width: 2.0, strokeAlign: StrokeAlign.center);
const BorderSide side3 = BorderSide(width: 2.0, strokeAlign: BorderSide.strokeAlignCenter);
expect(BorderSide.lerp(side2, side3, 0), const BorderSide(width: 2.0));
expect(BorderSide.lerp(side2, side3, 0.5), const BorderSide(width: 0.0));
expect(BorderSide.lerp(side2, side3, 1), const BorderSide(width: 2.0, strokeAlign: StrokeAlign.center));
expect(BorderSide.lerp(side2, side3, 0.5), const BorderSide(width: 2.0, strokeAlign: -0.5));
expect(BorderSide.lerp(side2, side3, 1), const BorderSide(width: 2.0, strokeAlign: BorderSide.strokeAlignCenter));
});
}

View file

@ -202,8 +202,8 @@ void main() {
expect(
const Border(
left: BorderSide(),
top: BorderSide(strokeAlign: StrokeAlign.center),
right: BorderSide(strokeAlign: StrokeAlign.outside),
top: BorderSide(strokeAlign: BorderSide.strokeAlignCenter),
right: BorderSide(strokeAlign: BorderSide.strokeAlignOutside),
).isUniform,
false,
);
@ -262,10 +262,10 @@ void main() {
try {
final TestCanvas canvas = TestCanvas();
// Border.all supports all StrokeAlign values.
// Border() supports StrokeAlign.inside only.
// Border() supports [BorderSide.strokeAlignInside] only.
const Border(
left: BorderSide(strokeAlign: StrokeAlign.center),
right: BorderSide(strokeAlign: StrokeAlign.outside),
left: BorderSide(strokeAlign: BorderSide.strokeAlignCenter),
right: BorderSide(strokeAlign: BorderSide.strokeAlignOutside),
).paint(canvas, const Rect.fromLTWH(10.0, 20.0, 30.0, 40.0));
} on FlutterError catch (e) {
error = e;
@ -274,7 +274,7 @@ void main() {
expect(error.diagnostics.length, 1);
expect(
error.diagnostics[0].toStringDeep(),
'A Border can only draw strokeAlign different than\nStrokeAlign.inside on uniform borders.\n',
'A Border can only draw strokeAlign different than\nBorderSide.strokeAlignInside on uniform borders.\n',
);
});
@ -282,21 +282,21 @@ void main() {
final Border insideBorder = Border.all(width: 10);
expect(insideBorder.dimensions, const EdgeInsets.all(10));
final Border centerBorder = Border.all(width: 10, strokeAlign: StrokeAlign.center);
final Border centerBorder = Border.all(width: 10, strokeAlign: BorderSide.strokeAlignCenter);
expect(centerBorder.dimensions, const EdgeInsets.all(5));
final Border outsideBorder = Border.all(width: 10, strokeAlign: StrokeAlign.outside);
final Border outsideBorder = Border.all(width: 10, strokeAlign: BorderSide.strokeAlignOutside);
expect(outsideBorder.dimensions, EdgeInsets.zero);
const BorderSide insideSide = BorderSide(width: 10);
const BorderDirectional insideBorderDirectional = BorderDirectional(top: insideSide, bottom: insideSide, start: insideSide, end: insideSide);
expect(insideBorderDirectional.dimensions, const EdgeInsetsDirectional.all(10));
const BorderSide centerSide = BorderSide(width: 10, strokeAlign: StrokeAlign.center);
const BorderSide centerSide = BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignCenter);
const BorderDirectional centerBorderDirectional = BorderDirectional(top: centerSide, bottom: centerSide, start: centerSide, end: centerSide);
expect(centerBorderDirectional.dimensions, const EdgeInsetsDirectional.all(5));
const BorderSide outsideSide = BorderSide(width: 10, strokeAlign: StrokeAlign.outside);
const BorderSide outsideSide = BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignOutside);
const BorderDirectional outsideBorderDirectional = BorderDirectional(top: outsideSide, bottom: outsideSide, start: outsideSide, end: outsideSide);
expect(outsideBorderDirectional.dimensions, EdgeInsetsDirectional.zero);
});

View file

@ -54,8 +54,8 @@ void main() {
style: BorderStyle.solid,
);
expect(side1.toString(), equals('BorderSide(Color(0xff000000), 1.0, BorderStyle.solid)'));
expect(side2.toString(), equals('BorderSide(Color(0xff00ffff), 2.0, BorderStyle.solid)'));
expect(side1.toString(), equals('BorderSide'));
expect(side2.toString(), equals('BorderSide(color: Color(0xff00ffff), width: 2.0)'));
});
test('Border control test', () {
@ -76,9 +76,7 @@ void main() {
test('Border toString test', () {
expect(
Border.all(width: 4.0).toString(),
equals(
'Border.all(BorderSide(Color(0xff000000), 4.0, BorderStyle.solid))',
),
equals('Border.all(BorderSide(width: 4.0))'),
);
expect(
const Border(
@ -87,9 +85,7 @@ void main() {
bottom: BorderSide(width: 3.0),
left: BorderSide(width: 3.0),
).toString(),
equals(
'Border.all(BorderSide(Color(0xff000000), 3.0, BorderStyle.solid))',
),
equals('Border.all(BorderSide(width: 3.0))'),
);
});

View file

@ -97,28 +97,28 @@ void main() {
expect(
ShapeBorder.lerp(r, c, 0.1).toString(),
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 10.0% of the way to being a CircleBorder)',
'RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(10.0), 10.0% of the way to being a CircleBorder)',
);
expect(
ShapeBorder.lerp(r, c, 0.2).toString(),
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 20.0% of the way to being a CircleBorder)',
'RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(10.0), 20.0% of the way to being a CircleBorder)',
);
expect(
ShapeBorder.lerp(ShapeBorder.lerp(r, c, 0.1), ShapeBorder.lerp(r, c, 0.9), 0.9).toString(),
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 82.0% of the way to being a CircleBorder)',
'RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(10.0), 82.0% of the way to being a CircleBorder)',
);
expect(
ShapeBorder.lerp(c, r, 0.9).toString(),
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 10.0% of the way to being a CircleBorder)',
'RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(10.0), 10.0% of the way to being a CircleBorder)',
);
expect(
ShapeBorder.lerp(c, r, 0.8).toString(),
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 20.0% of the way to being a CircleBorder)',
'RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(10.0), 20.0% of the way to being a CircleBorder)',
);
expect(
ShapeBorder.lerp(ShapeBorder.lerp(r, c, 0.9), ShapeBorder.lerp(r, c, 0.1), 0.1).toString(),
'RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(10.0), 82.0% of the way to being a CircleBorder)',
'RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(10.0), 82.0% of the way to being a CircleBorder)',
);
expect(ShapeBorder.lerp(r, c, 0.1), ShapeBorder.lerp(r, c, 0.1));
@ -135,19 +135,26 @@ void main() {
const RoundedRectangleBorder insideRoundedRectangleBorder = RoundedRectangleBorder(side: BorderSide(width: 10));
expect(insideRoundedRectangleBorder.dimensions, const EdgeInsets.all(10));
const RoundedRectangleBorder centerRoundedRectangleBorder = RoundedRectangleBorder(side: BorderSide(width: 10, strokeAlign: StrokeAlign.center));
const RoundedRectangleBorder centerRoundedRectangleBorder = RoundedRectangleBorder(side: BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignCenter));
expect(centerRoundedRectangleBorder.dimensions, const EdgeInsets.all(5));
const RoundedRectangleBorder outsideRoundedRectangleBorder = RoundedRectangleBorder(side: BorderSide(width: 10, strokeAlign: StrokeAlign.outside));
const RoundedRectangleBorder outsideRoundedRectangleBorder = RoundedRectangleBorder(side: BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignOutside));
expect(outsideRoundedRectangleBorder.dimensions, EdgeInsets.zero);
const CircleBorder insideCircleBorder = CircleBorder(side: BorderSide(width: 10));
expect(insideCircleBorder.dimensions, const EdgeInsets.all(10));
const CircleBorder centerCircleBorder = CircleBorder(side: BorderSide(width: 10, strokeAlign: StrokeAlign.center));
const CircleBorder centerCircleBorder = CircleBorder(side: BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignCenter));
expect(centerCircleBorder.dimensions, const EdgeInsets.all(5));
const CircleBorder outsideCircleBorder = CircleBorder(side: BorderSide(width: 10, strokeAlign: StrokeAlign.outside));
const CircleBorder outsideCircleBorder = CircleBorder(side: BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignOutside));
expect(outsideCircleBorder.dimensions, EdgeInsets.zero);
});
test('RoundedRectangleBorder.lerp with different StrokeAlign', () {
const RoundedRectangleBorder rInside = RoundedRectangleBorder(side: BorderSide(width: 10.0));
const RoundedRectangleBorder rOutside = RoundedRectangleBorder(side: BorderSide(width: 20.0, strokeAlign: BorderSide.strokeAlignOutside));
const RoundedRectangleBorder rCenter = RoundedRectangleBorder(side: BorderSide(width: 15.0, strokeAlign: BorderSide.strokeAlignCenter));
expect(ShapeBorder.lerp(rInside, rOutside, 0.5), rCenter);
});
}

View file

@ -13,49 +13,49 @@ void main() {
final Border b2 = Border.all(color: const Color(0xFF0000FF));
expect(
(b1 + b2).toString(),
'Border.all(BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid)) + '
'Border.all(BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid))',
'Border.all(BorderSide(color: Color(0xff00ff00))) + '
'Border.all(BorderSide(color: Color(0xff0000ff)))',
);
expect(
(b1 + (b2 + b2)).toString(),
'Border.all(BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid)) + '
'Border.all(BorderSide(Color(0xff0000ff), 2.0, BorderStyle.solid))',
'Border.all(BorderSide(color: Color(0xff00ff00))) + '
'Border.all(BorderSide(color: Color(0xff0000ff), width: 2.0))',
);
expect(
((b1 + b2) + b2).toString(),
'Border.all(BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid)) + '
'Border.all(BorderSide(Color(0xff0000ff), 2.0, BorderStyle.solid))',
'Border.all(BorderSide(color: Color(0xff00ff00))) + '
'Border.all(BorderSide(color: Color(0xff0000ff), width: 2.0))',
);
expect((b1 + b2) + b2, b1 + (b2 + b2));
expect(
(b1 + b2).scale(3.0).toString(),
'Border.all(BorderSide(Color(0xff00ff00), 3.0, BorderStyle.solid)) + '
'Border.all(BorderSide(Color(0xff0000ff), 3.0, BorderStyle.solid))',
'Border.all(BorderSide(color: Color(0xff00ff00), width: 3.0)) + '
'Border.all(BorderSide(color: Color(0xff0000ff), width: 3.0))',
);
expect(
(b1 + b2).scale(0.0).toString(),
'Border.all(BorderSide(Color(0xff00ff00), 0.0, BorderStyle.none)) + '
'Border.all(BorderSide(Color(0xff0000ff), 0.0, BorderStyle.none))',
'Border.all(BorderSide(color: Color(0xff00ff00), width: 0.0, style: none)) + '
'Border.all(BorderSide(color: Color(0xff0000ff), width: 0.0, style: none))',
);
expect(
ShapeBorder.lerp(b2 + b1, b1 + b2, 0.0).toString(),
'Border.all(BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid)) + '
'Border.all(BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid))',
'Border.all(BorderSide(color: Color(0xff0000ff))) + '
'Border.all(BorderSide(color: Color(0xff00ff00)))',
);
expect(
ShapeBorder.lerp(b2 + b1, b1 + b2, 0.25).toString(),
'Border.all(BorderSide(Color(0xff003fbf), 1.0, BorderStyle.solid)) + '
'Border.all(BorderSide(Color(0xff00bf3f), 1.0, BorderStyle.solid))',
'Border.all(BorderSide(color: Color(0xff003fbf))) + '
'Border.all(BorderSide(color: Color(0xff00bf3f)))',
);
expect(
ShapeBorder.lerp(b2 + b1, b1 + b2, 0.5).toString(),
'Border.all(BorderSide(Color(0xff007f7f), 1.0, BorderStyle.solid)) + '
'Border.all(BorderSide(Color(0xff007f7f), 1.0, BorderStyle.solid))',
'Border.all(BorderSide(color: Color(0xff007f7f))) + '
'Border.all(BorderSide(color: Color(0xff007f7f)))',
);
expect(
ShapeBorder.lerp(b2 + b1, b1 + b2, 1.0).toString(),
'Border.all(BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid)) + '
'Border.all(BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid))',
'Border.all(BorderSide(color: Color(0xff00ff00))) + '
'Border.all(BorderSide(color: Color(0xff0000ff)))',
);
expect((b1 + b2).dimensions, const EdgeInsets.all(2.0));
const Rect rect = Rect.fromLTRB(11.0, 15.0, 299.0, 175.0);
@ -78,49 +78,49 @@ void main() {
const BorderDirectional b2 = BorderDirectional(top: side2, start: side2, end: side2, bottom: side2);
expect(
(b1 + b2).toString(),
'BorderDirectional(top: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), start: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), end: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), bottom: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid)) + '
'BorderDirectional(top: BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid), start: BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid), end: BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid), bottom: BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid))',
'BorderDirectional(top: BorderSide(color: Color(0xff00ff00)), start: BorderSide(color: Color(0xff00ff00)), end: BorderSide(color: Color(0xff00ff00)), bottom: BorderSide(color: Color(0xff00ff00))) + '
'BorderDirectional(top: BorderSide(color: Color(0xff0000ff)), start: BorderSide(color: Color(0xff0000ff)), end: BorderSide(color: Color(0xff0000ff)), bottom: BorderSide(color: Color(0xff0000ff)))',
);
expect(
(b1 + (b2 + b2)).toString(),
'BorderDirectional(top: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), start: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), end: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), bottom: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid)) + '
'BorderDirectional(top: BorderSide(Color(0xff0000ff), 2.0, BorderStyle.solid), start: BorderSide(Color(0xff0000ff), 2.0, BorderStyle.solid), end: BorderSide(Color(0xff0000ff), 2.0, BorderStyle.solid), bottom: BorderSide(Color(0xff0000ff), 2.0, BorderStyle.solid))',
'BorderDirectional(top: BorderSide(color: Color(0xff00ff00)), start: BorderSide(color: Color(0xff00ff00)), end: BorderSide(color: Color(0xff00ff00)), bottom: BorderSide(color: Color(0xff00ff00))) + '
'BorderDirectional(top: BorderSide(color: Color(0xff0000ff), width: 2.0), start: BorderSide(color: Color(0xff0000ff), width: 2.0), end: BorderSide(color: Color(0xff0000ff), width: 2.0), bottom: BorderSide(color: Color(0xff0000ff), width: 2.0))',
);
expect(
((b1 + b2) + b2).toString(),
'BorderDirectional(top: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), start: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), end: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), bottom: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid)) + '
'BorderDirectional(top: BorderSide(Color(0xff0000ff), 2.0, BorderStyle.solid), start: BorderSide(Color(0xff0000ff), 2.0, BorderStyle.solid), end: BorderSide(Color(0xff0000ff), 2.0, BorderStyle.solid), bottom: BorderSide(Color(0xff0000ff), 2.0, BorderStyle.solid))',
'BorderDirectional(top: BorderSide(color: Color(0xff00ff00)), start: BorderSide(color: Color(0xff00ff00)), end: BorderSide(color: Color(0xff00ff00)), bottom: BorderSide(color: Color(0xff00ff00))) + '
'BorderDirectional(top: BorderSide(color: Color(0xff0000ff), width: 2.0), start: BorderSide(color: Color(0xff0000ff), width: 2.0), end: BorderSide(color: Color(0xff0000ff), width: 2.0), bottom: BorderSide(color: Color(0xff0000ff), width: 2.0))',
);
expect((b1 + b2) + b2, b1 + (b2 + b2));
expect(
(b1 + b2).scale(3.0).toString(),
'BorderDirectional(top: BorderSide(Color(0xff00ff00), 3.0, BorderStyle.solid), start: BorderSide(Color(0xff00ff00), 3.0, BorderStyle.solid), end: BorderSide(Color(0xff00ff00), 3.0, BorderStyle.solid), bottom: BorderSide(Color(0xff00ff00), 3.0, BorderStyle.solid)) + '
'BorderDirectional(top: BorderSide(Color(0xff0000ff), 3.0, BorderStyle.solid), start: BorderSide(Color(0xff0000ff), 3.0, BorderStyle.solid), end: BorderSide(Color(0xff0000ff), 3.0, BorderStyle.solid), bottom: BorderSide(Color(0xff0000ff), 3.0, BorderStyle.solid))',
'BorderDirectional(top: BorderSide(color: Color(0xff00ff00), width: 3.0), start: BorderSide(color: Color(0xff00ff00), width: 3.0), end: BorderSide(color: Color(0xff00ff00), width: 3.0), bottom: BorderSide(color: Color(0xff00ff00), width: 3.0)) + '
'BorderDirectional(top: BorderSide(color: Color(0xff0000ff), width: 3.0), start: BorderSide(color: Color(0xff0000ff), width: 3.0), end: BorderSide(color: Color(0xff0000ff), width: 3.0), bottom: BorderSide(color: Color(0xff0000ff), width: 3.0))',
);
expect(
(b1 + b2).scale(0.0).toString(),
'BorderDirectional(top: BorderSide(Color(0xff00ff00), 0.0, BorderStyle.none), start: BorderSide(Color(0xff00ff00), 0.0, BorderStyle.none), end: BorderSide(Color(0xff00ff00), 0.0, BorderStyle.none), bottom: BorderSide(Color(0xff00ff00), 0.0, BorderStyle.none)) + '
'BorderDirectional(top: BorderSide(Color(0xff0000ff), 0.0, BorderStyle.none), start: BorderSide(Color(0xff0000ff), 0.0, BorderStyle.none), end: BorderSide(Color(0xff0000ff), 0.0, BorderStyle.none), bottom: BorderSide(Color(0xff0000ff), 0.0, BorderStyle.none))',
'BorderDirectional(top: BorderSide(color: Color(0xff00ff00), width: 0.0, style: none), start: BorderSide(color: Color(0xff00ff00), width: 0.0, style: none), end: BorderSide(color: Color(0xff00ff00), width: 0.0, style: none), bottom: BorderSide(color: Color(0xff00ff00), width: 0.0, style: none)) + '
'BorderDirectional(top: BorderSide(color: Color(0xff0000ff), width: 0.0, style: none), start: BorderSide(color: Color(0xff0000ff), width: 0.0, style: none), end: BorderSide(color: Color(0xff0000ff), width: 0.0, style: none), bottom: BorderSide(color: Color(0xff0000ff), width: 0.0, style: none))',
);
expect(
ShapeBorder.lerp(b2 + b1, b1 + b2, 0.0).toString(),
'BorderDirectional(top: BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid), start: BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid), end: BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid), bottom: BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid)) + '
'BorderDirectional(top: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), start: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), end: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), bottom: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid))',
'BorderDirectional(top: BorderSide(color: Color(0xff0000ff)), start: BorderSide(color: Color(0xff0000ff)), end: BorderSide(color: Color(0xff0000ff)), bottom: BorderSide(color: Color(0xff0000ff))) + '
'BorderDirectional(top: BorderSide(color: Color(0xff00ff00)), start: BorderSide(color: Color(0xff00ff00)), end: BorderSide(color: Color(0xff00ff00)), bottom: BorderSide(color: Color(0xff00ff00)))',
);
expect(
ShapeBorder.lerp(b2 + b1, b1 + b2, 0.25).toString(),
'BorderDirectional(top: BorderSide(Color(0xff003fbf), 1.0, BorderStyle.solid), start: BorderSide(Color(0xff003fbf), 1.0, BorderStyle.solid), end: BorderSide(Color(0xff003fbf), 1.0, BorderStyle.solid), bottom: BorderSide(Color(0xff003fbf), 1.0, BorderStyle.solid)) + '
'BorderDirectional(top: BorderSide(Color(0xff00bf3f), 1.0, BorderStyle.solid), start: BorderSide(Color(0xff00bf3f), 1.0, BorderStyle.solid), end: BorderSide(Color(0xff00bf3f), 1.0, BorderStyle.solid), bottom: BorderSide(Color(0xff00bf3f), 1.0, BorderStyle.solid))',
'BorderDirectional(top: BorderSide(color: Color(0xff003fbf)), start: BorderSide(color: Color(0xff003fbf)), end: BorderSide(color: Color(0xff003fbf)), bottom: BorderSide(color: Color(0xff003fbf))) + '
'BorderDirectional(top: BorderSide(color: Color(0xff00bf3f)), start: BorderSide(color: Color(0xff00bf3f)), end: BorderSide(color: Color(0xff00bf3f)), bottom: BorderSide(color: Color(0xff00bf3f)))',
);
expect(
ShapeBorder.lerp(b2 + b1, b1 + b2, 0.5).toString(),
'BorderDirectional(top: BorderSide(Color(0xff007f7f), 1.0, BorderStyle.solid), start: BorderSide(Color(0xff007f7f), 1.0, BorderStyle.solid), end: BorderSide(Color(0xff007f7f), 1.0, BorderStyle.solid), bottom: BorderSide(Color(0xff007f7f), 1.0, BorderStyle.solid)) + '
'BorderDirectional(top: BorderSide(Color(0xff007f7f), 1.0, BorderStyle.solid), start: BorderSide(Color(0xff007f7f), 1.0, BorderStyle.solid), end: BorderSide(Color(0xff007f7f), 1.0, BorderStyle.solid), bottom: BorderSide(Color(0xff007f7f), 1.0, BorderStyle.solid))',
'BorderDirectional(top: BorderSide(color: Color(0xff007f7f)), start: BorderSide(color: Color(0xff007f7f)), end: BorderSide(color: Color(0xff007f7f)), bottom: BorderSide(color: Color(0xff007f7f))) + '
'BorderDirectional(top: BorderSide(color: Color(0xff007f7f)), start: BorderSide(color: Color(0xff007f7f)), end: BorderSide(color: Color(0xff007f7f)), bottom: BorderSide(color: Color(0xff007f7f)))',
);
expect(
ShapeBorder.lerp(b2 + b1, b1 + b2, 1.0).toString(),
'BorderDirectional(top: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), start: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), end: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid), bottom: BorderSide(Color(0xff00ff00), 1.0, BorderStyle.solid)) + '
'BorderDirectional(top: BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid), start: BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid), end: BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid), bottom: BorderSide(Color(0xff0000ff), 1.0, BorderStyle.solid))',
'BorderDirectional(top: BorderSide(color: Color(0xff00ff00)), start: BorderSide(color: Color(0xff00ff00)), end: BorderSide(color: Color(0xff00ff00)), bottom: BorderSide(color: Color(0xff00ff00))) + '
'BorderDirectional(top: BorderSide(color: Color(0xff0000ff)), start: BorderSide(color: Color(0xff0000ff)), end: BorderSide(color: Color(0xff0000ff)), bottom: BorderSide(color: Color(0xff0000ff)))',
);
expect((b1 + b2).dimensions, const EdgeInsetsDirectional.fromSTEB(2.0, 2.0, 2.0, 2.0));
const Rect rect = Rect.fromLTRB(11.0, 15.0, 299.0, 175.0);

View file

@ -48,8 +48,8 @@ void main() {
});
test('StadiumBorder with StrokeAlign', () {
const StadiumBorder center = StadiumBorder(side: BorderSide(width: 10.0, strokeAlign: StrokeAlign.center));
const StadiumBorder outside = StadiumBorder(side: BorderSide(width: 10.0, strokeAlign: StrokeAlign.outside));
const StadiumBorder center = StadiumBorder(side: BorderSide(width: 10.0, strokeAlign: BorderSide.strokeAlignCenter));
const StadiumBorder outside = StadiumBorder(side: BorderSide(width: 10.0, strokeAlign: BorderSide.strokeAlignOutside));
expect(center.dimensions, const EdgeInsets.all(5.0));
expect(outside.dimensions, EdgeInsets.zero);
@ -103,28 +103,28 @@ void main() {
expect(
ShapeBorder.lerp(stadium, circle, 0.1).toString(),
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 10.0% of the way to being a CircleBorder)',
'StadiumBorder(BorderSide(width: 0.0, style: none), 10.0% of the way to being a CircleBorder)',
);
expect(
ShapeBorder.lerp(stadium, circle, 0.2).toString(),
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 20.0% of the way to being a CircleBorder)',
'StadiumBorder(BorderSide(width: 0.0, style: none), 20.0% of the way to being a CircleBorder)',
);
expect(
ShapeBorder.lerp(ShapeBorder.lerp(stadium, circle, 0.1), ShapeBorder.lerp(stadium, circle, 0.9), 0.9).toString(),
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 82.0% of the way to being a CircleBorder)',
'StadiumBorder(BorderSide(width: 0.0, style: none), 82.0% of the way to being a CircleBorder)',
);
expect(
ShapeBorder.lerp(circle, stadium, 0.9).toString(),
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 10.0% of the way to being a CircleBorder)',
'StadiumBorder(BorderSide(width: 0.0, style: none), 10.0% of the way to being a CircleBorder)',
);
expect(
ShapeBorder.lerp(circle, stadium, 0.8).toString(),
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 20.0% of the way to being a CircleBorder)',
'StadiumBorder(BorderSide(width: 0.0, style: none), 20.0% of the way to being a CircleBorder)',
);
expect(
ShapeBorder.lerp(ShapeBorder.lerp(stadium, circle, 0.9), ShapeBorder.lerp(stadium, circle, 0.1), 0.1).toString(),
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), 82.0% of the way to being a CircleBorder)',
'StadiumBorder(BorderSide(width: 0.0, style: none), 82.0% of the way to being a CircleBorder)',
);
expect(ShapeBorder.lerp(stadium, circle, 0.1), ShapeBorder.lerp(stadium, circle, 0.1));
@ -182,33 +182,33 @@ void main() {
expect(
ShapeBorder.lerp(stadium, rrect, 0.1).toString(),
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
'StadiumBorder(BorderSide(width: 0.0, style: none), '
'BorderRadius.zero, 10.0% of the way to being a RoundedRectangleBorder)',
);
expect(
ShapeBorder.lerp(stadium, rrect, 0.2).toString(),
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
'StadiumBorder(BorderSide(width: 0.0, style: none), '
'BorderRadius.zero, 20.0% of the way to being a RoundedRectangleBorder)',
);
expect(
ShapeBorder.lerp(ShapeBorder.lerp(stadium, rrect, 0.1), ShapeBorder.lerp(stadium, rrect, 0.9), 0.9).toString(),
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
'StadiumBorder(BorderSide(width: 0.0, style: none), '
'BorderRadius.zero, 82.0% of the way to being a RoundedRectangleBorder)',
);
expect(
ShapeBorder.lerp(rrect, stadium, 0.9).toString(),
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
'StadiumBorder(BorderSide(width: 0.0, style: none), '
'BorderRadius.zero, 10.0% of the way to being a RoundedRectangleBorder)',
);
expect(
ShapeBorder.lerp(rrect, stadium, 0.8).toString(),
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
'StadiumBorder(BorderSide(width: 0.0, style: none), '
'BorderRadius.zero, 20.0% of the way to being a RoundedRectangleBorder)',
);
expect(
ShapeBorder.lerp(ShapeBorder.lerp(stadium, rrect, 0.9), ShapeBorder.lerp(stadium, rrect, 0.1), 0.1).toString(),
'StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), '
'StadiumBorder(BorderSide(width: 0.0, style: none), '
'BorderRadius.zero, 82.0% of the way to being a RoundedRectangleBorder)',
);

View file

@ -105,9 +105,9 @@ void main() {
await testBorder(tester, 'side_1', const StarBorder(side: BorderSide(color: Color(0xffff0000))));
await testBorder(tester, 'side_10', const StarBorder(side: BorderSide(color: Color(0xffff0000), width: 10)));
await testBorder(tester, 'side_align_center',
const StarBorder(side: BorderSide(color: Color(0xffff0000), strokeAlign: StrokeAlign.center)));
const StarBorder(side: BorderSide(color: Color(0xffff0000), strokeAlign: BorderSide.strokeAlignCenter)));
await testBorder(tester, 'side_align_outside',
const StarBorder(side: BorderSide(color: Color(0xffff0000), strokeAlign: StrokeAlign.outside)));
const StarBorder(side: BorderSide(color: Color(0xffff0000), strokeAlign: BorderSide.strokeAlignOutside)));
});
testWidgets('StarBorder.polygon parameters', (WidgetTester tester) async {
@ -127,9 +127,9 @@ void main() {
await testBorder(
tester, 'poly_side_10', const StarBorder.polygon(side: BorderSide(color: Color(0xffff0000), width: 10)));
await testBorder(tester, 'poly_side_align_center',
const StarBorder.polygon(side: BorderSide(color: Color(0xffff0000), strokeAlign: StrokeAlign.center)));
const StarBorder.polygon(side: BorderSide(color: Color(0xffff0000), strokeAlign: BorderSide.strokeAlignCenter)));
await testBorder(tester, 'poly_side_align_outside',
const StarBorder.polygon(side: BorderSide(color: Color(0xffff0000), strokeAlign: StrokeAlign.outside)));
const StarBorder.polygon(side: BorderSide(color: Color(0xffff0000), strokeAlign: BorderSide.strokeAlignOutside)));
});
testWidgets('StarBorder lerped with StarBorder', (WidgetTester tester) async {