@@ -359,8 +359,8 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
|
||||
/// Determines the order to lay children out horizontally and how to interpret
|
||||
/// `start` and `end` in the horizontal direction.
|
||||
///
|
||||
/// If the [direction] is [Axis.horizontal], this controls which order
|
||||
/// children are painted in (left-to-right or right-to-left), and the meaning
|
||||
/// If the [direction] is [Axis.horizontal], this controls the order in which
|
||||
/// children are positioned (left-to-right or right-to-left), and the meaning
|
||||
/// of the [mainAxisAlignment] property's [MainAxisAlignment.start] and
|
||||
/// [MainAxisAlignment.end] values.
|
||||
///
|
||||
|
||||
@@ -13,9 +13,21 @@ import 'object.dart';
|
||||
/// align the runs themselves in the cross axis.
|
||||
enum WrapAlignment {
|
||||
/// Place the objects as close to the start of the axis as possible.
|
||||
///
|
||||
/// If this value is used in a horizontal direction, a [TextDirection] must be
|
||||
/// available to determine if the start is the left or the right.
|
||||
///
|
||||
/// If this value is used in a vertical direction, a [VerticalDirection] must be
|
||||
/// available to determine if the start is the top or the bottom.
|
||||
start,
|
||||
|
||||
/// Place the objects as close to the end of the axis as possible.
|
||||
///
|
||||
/// If this value is used in a horizontal direction, a [TextDirection] must be
|
||||
/// available to determine if the end is the left or the right.
|
||||
///
|
||||
/// If this value is used in a vertical direction, a [VerticalDirection] must be
|
||||
/// available to determine if the end is the top or the bottom.
|
||||
end,
|
||||
|
||||
/// Place the objects as close to the middle of the axis as possible.
|
||||
@@ -37,10 +49,22 @@ enum WrapAlignment {
|
||||
enum WrapCrossAlignment {
|
||||
/// Place the children as close to the start of the run in the cross axis as
|
||||
/// possible.
|
||||
///
|
||||
/// If this value is used in a horizontal direction, a [TextDirection] must be
|
||||
/// available to determine if the start is the left or the right.
|
||||
///
|
||||
/// If this value is used in a vertical direction, a [VerticalDirection] must be
|
||||
/// available to determine if the start is the top or the bottom.
|
||||
start,
|
||||
|
||||
/// Place the children as close to the end of the run in the cross axis as
|
||||
/// possible.
|
||||
///
|
||||
/// If this value is used in a horizontal direction, a [TextDirection] must be
|
||||
/// available to determine if the end is the left or the right.
|
||||
///
|
||||
/// If this value is used in a vertical direction, a [VerticalDirection] must be
|
||||
/// available to determine if the end is the top or the bottom.
|
||||
end,
|
||||
|
||||
/// Place the children as close to the middle of the run in the cross axis as
|
||||
@@ -91,6 +115,8 @@ class RenderWrap extends RenderBox with ContainerRenderObjectMixin<RenderBox, Wr
|
||||
WrapAlignment runAlignment: WrapAlignment.start,
|
||||
double runSpacing: 0.0,
|
||||
WrapCrossAlignment crossAxisAlignment: WrapCrossAlignment.start,
|
||||
TextDirection textDirection,
|
||||
VerticalDirection verticalDirection: VerticalDirection.down,
|
||||
}) : assert(direction != null),
|
||||
assert(alignment != null),
|
||||
assert(spacing != null),
|
||||
@@ -102,7 +128,9 @@ class RenderWrap extends RenderBox with ContainerRenderObjectMixin<RenderBox, Wr
|
||||
_spacing = spacing,
|
||||
_runAlignment = runAlignment,
|
||||
_runSpacing = runSpacing,
|
||||
_crossAxisAlignment = crossAxisAlignment {
|
||||
_crossAxisAlignment = crossAxisAlignment,
|
||||
_textDirection = textDirection,
|
||||
_verticalDirection = verticalDirection {
|
||||
addAll(children);
|
||||
}
|
||||
|
||||
@@ -235,6 +263,118 @@ class RenderWrap extends RenderBox with ContainerRenderObjectMixin<RenderBox, Wr
|
||||
markNeedsLayout();
|
||||
}
|
||||
|
||||
/// Determines the order to lay children out horizontally and how to interpret
|
||||
/// `start` and `end` in the horizontal direction.
|
||||
///
|
||||
/// If the [direction] is [Axis.horizontal], this controls the order in which
|
||||
/// children are positioned (left-to-right or right-to-left), and the meaning
|
||||
/// of the [alignment] property's [WrapAlignment.start] and
|
||||
/// [WrapAlignment.end] values.
|
||||
///
|
||||
/// If the [direction] is [Axis.horizontal], and either the
|
||||
/// [alignment] is either [WrapAlignment.start] or [WrapAlignment.end], or
|
||||
/// there's more than one child, then the [textDirection] must not be null.
|
||||
///
|
||||
/// If the [direction] is [Axis.vertical], this controls the order in
|
||||
/// which runs are positioned, the meaning of the [runAlignment] property's
|
||||
/// [WrapAlignment.start] and [WrapAlignment.end] values, as well as the
|
||||
/// [crossAxisAlignment] property's [WrapCrossAlignment.start] and
|
||||
/// [WrapCrossAlignment.end] values.
|
||||
///
|
||||
/// If the [direction] is [Axis.vertical], and either the
|
||||
/// [runAlignment] is either [WrapAlignment.start] or [WrapAlignment.end], the
|
||||
/// [crossAxisAlignment] is either [WrapCrossAlignment.start] or
|
||||
/// [WrapCrossAlignment.end], or there's more than one child, then the
|
||||
/// [textDirection] must not be null.
|
||||
TextDirection get textDirection => _textDirection;
|
||||
TextDirection _textDirection;
|
||||
set textDirection(TextDirection value) {
|
||||
if (_textDirection != value) {
|
||||
_textDirection = value;
|
||||
markNeedsLayout();
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines the order to lay children out vertically and how to interpret
|
||||
/// `start` and `end` in the vertical direction.
|
||||
///
|
||||
/// If the [direction] is [Axis.vertical], this controls which order children
|
||||
/// are painted in (down or up), the meaning of the [alignment] property's
|
||||
/// [WrapAlignment.start] and [WrapAlignment.end] values.
|
||||
///
|
||||
/// If the [direction] is [Axis.vertical], and either the [alignment]
|
||||
/// is either [WrapAlignment.start] or [WrapAlignment.end], or there's
|
||||
/// more than one child, then the [verticalDirection] must not be null.
|
||||
///
|
||||
/// If the [direction] is [Axis.horizontal], this controls the order in which
|
||||
/// runs are positioned, the meaning of the [runAlignment] property's
|
||||
/// [WrapAlignment.start] and [WrapAlignment.end] values, as well as the
|
||||
/// [crossAxisAlignment] property's [WrapCrossAlignment.start] and
|
||||
/// [WrapCrossAlignment.end] values.
|
||||
///
|
||||
/// If the [direction] is [Axis.horizontal], and either the
|
||||
/// [runAlignment] is either [WrapAlignment.start] or [WrapAlignment.end], the
|
||||
/// [crossAxisAlignment] is either [WrapCrossAlignment.start] or
|
||||
/// [WrapCrossAlignment.end], or there's more than one child, then the
|
||||
/// [verticalDirection] must not be null.
|
||||
VerticalDirection get verticalDirection => _verticalDirection;
|
||||
VerticalDirection _verticalDirection;
|
||||
set verticalDirection(VerticalDirection value) {
|
||||
if (_verticalDirection != value) {
|
||||
_verticalDirection = value;
|
||||
markNeedsLayout();
|
||||
}
|
||||
}
|
||||
|
||||
bool get _debugHasNecessaryDirections {
|
||||
assert(direction != null);
|
||||
assert(alignment != null);
|
||||
assert(runAlignment != null);
|
||||
assert(crossAxisAlignment != null);
|
||||
if (firstChild != null && lastChild != firstChild) {
|
||||
// i.e. there's more than one child
|
||||
switch (direction) {
|
||||
case Axis.horizontal:
|
||||
assert(textDirection != null, 'Horizontal $runtimeType with multiple children has a null textDirection, so the layout order is undefined.');
|
||||
break;
|
||||
case Axis.vertical:
|
||||
assert(verticalDirection != null, 'Vertical $runtimeType with multiple children has a null verticalDirection, so the layout order is undefined.');
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (alignment == WrapAlignment.start || alignment == WrapAlignment.end) {
|
||||
switch (direction) {
|
||||
case Axis.horizontal:
|
||||
assert(textDirection != null, 'Horizontal $runtimeType with alignment $alignment has a null textDirection, so the alignment cannot be resolved.');
|
||||
break;
|
||||
case Axis.vertical:
|
||||
assert(verticalDirection != null, 'Vertical $runtimeType with alignment $alignment has a null verticalDirection, so the alignment cannot be resolved.');
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (runAlignment == WrapAlignment.start || runAlignment == WrapAlignment.end) {
|
||||
switch (direction) {
|
||||
case Axis.horizontal:
|
||||
assert(verticalDirection != null, 'Horizontal $runtimeType with runAlignment $runAlignment has a null verticalDirection, so the alignment cannot be resolved.');
|
||||
break;
|
||||
case Axis.vertical:
|
||||
assert(textDirection != null, 'Vertical $runtimeType with runAlignment $runAlignment has a null textDirection, so the alignment cannot be resolved.');
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (crossAxisAlignment == WrapCrossAlignment.start || crossAxisAlignment == WrapCrossAlignment.end) {
|
||||
switch (direction) {
|
||||
case Axis.horizontal:
|
||||
assert(verticalDirection != null, 'Horizontal $runtimeType with crossAxisAlignment $crossAxisAlignment has a null verticalDirection, so the alignment cannot be resolved.');
|
||||
break;
|
||||
case Axis.vertical:
|
||||
assert(textDirection != null, 'Vertical $runtimeType with crossAxisAlignment $crossAxisAlignment has a null textDirection, so the alignment cannot be resolved.');
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
void setupParentData(RenderBox child) {
|
||||
if (child.parentData is! WrapParentData)
|
||||
@@ -408,14 +548,15 @@ class RenderWrap extends RenderBox with ContainerRenderObjectMixin<RenderBox, Wr
|
||||
return Offset.zero;
|
||||
}
|
||||
|
||||
double _getChildCrossAxisOffset(double runCrossAxisExtent, double childCrossAxisExtent) {
|
||||
double _getChildCrossAxisOffset(bool flipCrossAxis, double runCrossAxisExtent, double childCrossAxisExtent) {
|
||||
final double freeSpace = runCrossAxisExtent - childCrossAxisExtent;
|
||||
switch (crossAxisAlignment) {
|
||||
case WrapCrossAlignment.start:
|
||||
return 0.0;
|
||||
case WrapCrossAlignment.center:
|
||||
return (runCrossAxisExtent - childCrossAxisExtent) / 2.0;
|
||||
return flipCrossAxis ? freeSpace : 0.0;
|
||||
case WrapCrossAlignment.end:
|
||||
return (runCrossAxisExtent - childCrossAxisExtent);
|
||||
return flipCrossAxis ? 0.0 : freeSpace;
|
||||
case WrapCrossAlignment.center:
|
||||
return freeSpace / 2.0;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
@@ -424,6 +565,7 @@ class RenderWrap extends RenderBox with ContainerRenderObjectMixin<RenderBox, Wr
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
assert(_debugHasNecessaryDirections);
|
||||
_hasVisualOverflow = false;
|
||||
RenderBox child = firstChild;
|
||||
if (child == null) {
|
||||
@@ -432,18 +574,30 @@ class RenderWrap extends RenderBox with ContainerRenderObjectMixin<RenderBox, Wr
|
||||
}
|
||||
BoxConstraints childConstraints;
|
||||
double mainAxisLimit = 0.0;
|
||||
bool flipMainAxis = false;
|
||||
bool flipCrossAxis = false;
|
||||
switch (direction) {
|
||||
case Axis.horizontal:
|
||||
childConstraints = new BoxConstraints(maxWidth: constraints.maxWidth);
|
||||
mainAxisLimit = constraints.maxWidth;
|
||||
if (textDirection == TextDirection.rtl)
|
||||
flipMainAxis = true;
|
||||
if (verticalDirection == VerticalDirection.up)
|
||||
flipCrossAxis = true;
|
||||
break;
|
||||
case Axis.vertical:
|
||||
childConstraints = new BoxConstraints(maxHeight: constraints.maxHeight);
|
||||
mainAxisLimit = constraints.maxHeight;
|
||||
if (verticalDirection == VerticalDirection.up)
|
||||
flipMainAxis = true;
|
||||
if (textDirection == TextDirection.rtl)
|
||||
flipCrossAxis = true;
|
||||
break;
|
||||
}
|
||||
assert(childConstraints != null);
|
||||
assert(mainAxisLimit != null);
|
||||
final double spacing = this.spacing;
|
||||
final double runSpacing = this.runSpacing;
|
||||
final List<_RunMetrics> runMetrics = <_RunMetrics>[];
|
||||
double mainAxisExtent = 0.0;
|
||||
double crossAxisExtent = 0.0;
|
||||
@@ -526,7 +680,9 @@ class RenderWrap extends RenderBox with ContainerRenderObjectMixin<RenderBox, Wr
|
||||
break;
|
||||
}
|
||||
|
||||
double crossAxisOffset = runLeadingSpace;
|
||||
runBetweenSpace += runSpacing;
|
||||
double crossAxisOffset = flipCrossAxis ? containerCrossAxisExtent - runLeadingSpace : runLeadingSpace;
|
||||
|
||||
child = firstChild;
|
||||
for (int i = 0; i < runCount; ++i) {
|
||||
final _RunMetrics metrics = runMetrics[i];
|
||||
@@ -560,20 +716,33 @@ class RenderWrap extends RenderBox with ContainerRenderObjectMixin<RenderBox, Wr
|
||||
break;
|
||||
}
|
||||
|
||||
double childMainAxisOffset = childLeadingSpace;
|
||||
childBetweenSpace += spacing;
|
||||
double childMainPosition = flipMainAxis ? containerMainAxisExtent - childLeadingSpace : childLeadingSpace;
|
||||
|
||||
if (flipCrossAxis)
|
||||
crossAxisOffset -= runCrossAxisExtent;
|
||||
|
||||
while (child != null) {
|
||||
final WrapParentData childParentData = child.parentData;
|
||||
if (childParentData._runIndex != i)
|
||||
break;
|
||||
final double childMainAxisExtent = _getMainAxisExtent(child);
|
||||
final double childCrossAxisExtent = _getCrossAxisExtent(child);
|
||||
final double childCrossAxisOffset = _getChildCrossAxisOffset(runCrossAxisExtent, childCrossAxisExtent);
|
||||
childParentData.offset = _getOffset(childMainAxisOffset, crossAxisOffset + childCrossAxisOffset);
|
||||
childMainAxisOffset += childMainAxisExtent + spacing + childBetweenSpace;
|
||||
final double childCrossAxisOffset = _getChildCrossAxisOffset(flipCrossAxis, runCrossAxisExtent, childCrossAxisExtent);
|
||||
if (flipMainAxis)
|
||||
childMainPosition -= childMainAxisExtent;
|
||||
childParentData.offset = _getOffset(childMainPosition, crossAxisOffset + childCrossAxisOffset);
|
||||
if (flipMainAxis)
|
||||
childMainPosition -= childBetweenSpace;
|
||||
else
|
||||
childMainPosition += childMainAxisExtent + childBetweenSpace;
|
||||
child = childParentData.nextSibling;
|
||||
}
|
||||
|
||||
crossAxisOffset += runCrossAxisExtent + runSpacing + runBetweenSpace;
|
||||
if (flipCrossAxis)
|
||||
crossAxisOffset -= runBetweenSpace;
|
||||
else
|
||||
crossAxisOffset += runCrossAxisExtent + runBetweenSpace;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -601,5 +770,7 @@ class RenderWrap extends RenderBox with ContainerRenderObjectMixin<RenderBox, Wr
|
||||
description.add(new EnumProperty<WrapAlignment>('runAlignment', runAlignment));
|
||||
description.add(new DoubleProperty('runSpacing', runSpacing));
|
||||
description.add(new DoubleProperty('crossAxisAlignment', runSpacing));
|
||||
description.add(new EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
|
||||
description.add(new EnumProperty<VerticalDirection>('verticalDirection', verticalDirection, defaultValue: VerticalDirection.down));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2740,9 +2740,9 @@ class Flex extends MultiChildRenderObjectWidget {
|
||||
///
|
||||
/// Defaults to the ambient [Directionality].
|
||||
///
|
||||
/// If the [direction] is [Axis.horizontal], this controls which order
|
||||
/// children are painted in (left-to-right or right-to-left), and the meaning
|
||||
/// of the [mainAxisAlignment] property's [MainAxisAlignment.start] and
|
||||
/// If the [direction] is [Axis.horizontal], this controls the order in which
|
||||
/// the children are positioned (left-to-right or right-to-left), and the
|
||||
/// meaning of the [mainAxisAlignment] property's [MainAxisAlignment.start] and
|
||||
/// [MainAxisAlignment.end] values.
|
||||
///
|
||||
/// If the [direction] is [Axis.horizontal], and either the
|
||||
@@ -3321,6 +3321,12 @@ class Wrap extends MultiChildRenderObjectWidget {
|
||||
///
|
||||
/// By default, the wrap layout is horizontal and both the children and the
|
||||
/// runs are aligned to the start.
|
||||
///
|
||||
/// The [textDirection] argument defaults to the ambient [Directionality], if
|
||||
/// any. If there is no ambient directionality, and a text direction is going
|
||||
/// to be necessary to decide which direction to lay the children in or to
|
||||
/// disambiguate `start` or `end` values for the main or cross axis
|
||||
/// directions, the [textDirection] must not be null.
|
||||
Wrap({
|
||||
Key key,
|
||||
this.direction: Axis.horizontal,
|
||||
@@ -3329,6 +3335,8 @@ class Wrap extends MultiChildRenderObjectWidget {
|
||||
this.runAlignment: WrapAlignment.start,
|
||||
this.runSpacing: 0.0,
|
||||
this.crossAxisAlignment: WrapCrossAlignment.start,
|
||||
this.textDirection,
|
||||
this.verticalDirection: VerticalDirection.down,
|
||||
List<Widget> children: const <Widget>[],
|
||||
}) : super(key: key, children: children);
|
||||
|
||||
@@ -3412,6 +3420,58 @@ class Wrap extends MultiChildRenderObjectWidget {
|
||||
/// other in the cross axis.
|
||||
final WrapCrossAlignment crossAxisAlignment;
|
||||
|
||||
/// Determines the order to lay children out horizontally and how to interpret
|
||||
/// `start` and `end` in the horizontal direction.
|
||||
///
|
||||
/// Defaults to the ambient [Directionality].
|
||||
///
|
||||
/// If the [direction] is [Axis.horizontal], this controls order in which the
|
||||
/// children are positioned (left-to-right or right-to-left), and the meaning
|
||||
/// of the [alignment] property's [WrapAlignment.start] and
|
||||
/// [WrapAlignment.end] values.
|
||||
///
|
||||
/// If the [direction] is [Axis.horizontal], and either the
|
||||
/// [alignment] is either [WrapAlignment.start] or [WrapAlignment.end], or
|
||||
/// there's more than one child, then the [textDirection] (or the ambient
|
||||
/// [Directionality]) must not be null.
|
||||
///
|
||||
/// If the [direction] is [Axis.vertical], this controls the order in which
|
||||
/// runs are positioned, the meaning of the [runAlignment] property's
|
||||
/// [WrapAlignment.start] and [WrapAlignment.end] values, as well as the
|
||||
/// [crossAxisAlignment] property's [WrapCrossAlignment.start] and
|
||||
/// [WrapCrossAlignment.end] values.
|
||||
///
|
||||
/// If the [direction] is [Axis.vertical], and either the
|
||||
/// [runAlignment] is either [WrapAlignment.start] or [WrapAlignment.end], the
|
||||
/// [crossAxisAlignment] is either [WrapCrossAlignment.start] or
|
||||
/// [WrapCrossAlignment.end], or there's more than one child, then the
|
||||
/// [textDirection] (or the ambient [Directionality]) must not be null.
|
||||
final TextDirection textDirection;
|
||||
|
||||
/// Determines the order to lay children out vertically and how to interpret
|
||||
/// `start` and `end` in the vertical direction.
|
||||
///
|
||||
/// If the [direction] is [Axis.vertical], this controls which order children
|
||||
/// are painted in (down or up), the meaning of the [alignment] property's
|
||||
/// [WrapAlignment.start] and [WrapAlignment.end] values.
|
||||
///
|
||||
/// If the [direction] is [Axis.vertical], and either the [alignment]
|
||||
/// is either [WrapAlignment.start] or [WrapAlignment.end], or there's
|
||||
/// more than one child, then the [verticalDirection] must not be null.
|
||||
///
|
||||
/// If the [direction] is [Axis.horizontal], this controls the order in which
|
||||
/// runs are positioned, the meaning of the [runAlignment] property's
|
||||
/// [WrapAlignment.start] and [WrapAlignment.end] values, as well as the
|
||||
/// [crossAxisAlignment] property's [WrapCrossAlignment.start] and
|
||||
/// [WrapCrossAlignment.end] values.
|
||||
///
|
||||
/// If the [direction] is [Axis.horizontal], and either the
|
||||
/// [runAlignment] is either [WrapAlignment.start] or [WrapAlignment.end], the
|
||||
/// [crossAxisAlignment] is either [WrapCrossAlignment.start] or
|
||||
/// [WrapCrossAlignment.end], or there's more than one child, then the
|
||||
/// [verticalDirection] must not be null.
|
||||
final VerticalDirection verticalDirection;
|
||||
|
||||
@override
|
||||
RenderWrap createRenderObject(BuildContext context) {
|
||||
return new RenderWrap(
|
||||
@@ -3421,6 +3481,8 @@ class Wrap extends MultiChildRenderObjectWidget {
|
||||
runAlignment: runAlignment,
|
||||
runSpacing: runSpacing,
|
||||
crossAxisAlignment: crossAxisAlignment,
|
||||
textDirection: textDirection ?? Directionality.of(context),
|
||||
verticalDirection: verticalDirection,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3432,7 +3494,22 @@ class Wrap extends MultiChildRenderObjectWidget {
|
||||
..spacing = spacing
|
||||
..runAlignment = runAlignment
|
||||
..runSpacing = runSpacing
|
||||
..crossAxisAlignment = crossAxisAlignment;
|
||||
..crossAxisAlignment = crossAxisAlignment
|
||||
..textDirection = textDirection ?? Directionality.of(context)
|
||||
..verticalDirection = verticalDirection;
|
||||
}
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder description) {
|
||||
super.debugFillProperties(description);
|
||||
description.add(new EnumProperty<Axis>('direction', direction));
|
||||
description.add(new EnumProperty<WrapAlignment>('alignment', alignment));
|
||||
description.add(new DoubleProperty('spacing', spacing));
|
||||
description.add(new EnumProperty<WrapAlignment>('runAlignment', runAlignment));
|
||||
description.add(new DoubleProperty('runSpacing', runSpacing));
|
||||
description.add(new DoubleProperty('crossAxisAlignment', runSpacing));
|
||||
description.add(new EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
|
||||
description.add(new EnumProperty<VerticalDirection>('verticalDirection', verticalDirection, defaultValue: VerticalDirection.down));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,11 @@ void verify(WidgetTester tester, List<Offset> answerKey) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('Basic Wrap test', (WidgetTester tester) async {
|
||||
testWidgets('Basic Wrap test (LTR)', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
new Wrap(
|
||||
alignment: WrapAlignment.start,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
@@ -38,6 +39,7 @@ void main() {
|
||||
await tester.pumpWidget(
|
||||
new Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
@@ -56,6 +58,7 @@ void main() {
|
||||
await tester.pumpWidget(
|
||||
new Wrap(
|
||||
alignment: WrapAlignment.end,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
@@ -75,6 +78,7 @@ void main() {
|
||||
new Wrap(
|
||||
alignment: WrapAlignment.start,
|
||||
crossAxisAlignment: WrapCrossAlignment.start,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 300.0, height: 50.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
@@ -94,6 +98,7 @@ void main() {
|
||||
new Wrap(
|
||||
alignment: WrapAlignment.start,
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 300.0, height: 50.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
@@ -113,6 +118,7 @@ void main() {
|
||||
new Wrap(
|
||||
alignment: WrapAlignment.start,
|
||||
crossAxisAlignment: WrapCrossAlignment.end,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 300.0, height: 50.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
@@ -130,15 +136,139 @@ void main() {
|
||||
|
||||
});
|
||||
|
||||
testWidgets('Basic Wrap test (RTL)', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
new Wrap(
|
||||
alignment: WrapAlignment.start,
|
||||
textDirection: TextDirection.rtl,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
],
|
||||
),
|
||||
);
|
||||
verify(tester, <Offset>[
|
||||
const Offset(500.0, 0.0),
|
||||
const Offset(200.0, 0.0),
|
||||
const Offset(500.0, 100.0),
|
||||
const Offset(200.0, 100.0),
|
||||
]);
|
||||
|
||||
await tester.pumpWidget(
|
||||
new Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
textDirection: TextDirection.rtl,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
],
|
||||
),
|
||||
);
|
||||
verify(tester, <Offset>[
|
||||
const Offset(400.0, 0.0),
|
||||
const Offset(100.0, 0.0),
|
||||
const Offset(400.0, 100.0),
|
||||
const Offset(100.0, 100.0),
|
||||
]);
|
||||
|
||||
await tester.pumpWidget(
|
||||
new Wrap(
|
||||
alignment: WrapAlignment.end,
|
||||
textDirection: TextDirection.rtl,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
],
|
||||
),
|
||||
);
|
||||
verify(tester, <Offset>[
|
||||
const Offset(300.0, 0.0),
|
||||
const Offset(0.0, 0.0),
|
||||
const Offset(300.0, 100.0),
|
||||
const Offset(0.0, 100.0),
|
||||
]);
|
||||
|
||||
await tester.pumpWidget(
|
||||
new Wrap(
|
||||
alignment: WrapAlignment.start,
|
||||
crossAxisAlignment: WrapCrossAlignment.start,
|
||||
textDirection: TextDirection.ltr,
|
||||
verticalDirection: VerticalDirection.up,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 300.0, height: 50.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 50.0),
|
||||
],
|
||||
),
|
||||
);
|
||||
verify(tester, <Offset>[
|
||||
const Offset(0.0, 550.0),
|
||||
const Offset(300.0, 500.0),
|
||||
const Offset(0.0, 400.0),
|
||||
const Offset(300.0, 450.0),
|
||||
]);
|
||||
|
||||
await tester.pumpWidget(
|
||||
new Wrap(
|
||||
alignment: WrapAlignment.start,
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
textDirection: TextDirection.ltr,
|
||||
verticalDirection: VerticalDirection.up,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 300.0, height: 50.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 50.0),
|
||||
],
|
||||
),
|
||||
);
|
||||
verify(tester, <Offset>[
|
||||
const Offset(0.0, 525.0),
|
||||
const Offset(300.0, 500.0),
|
||||
const Offset(0.0, 400.0),
|
||||
const Offset(300.0, 425.0),
|
||||
]);
|
||||
|
||||
await tester.pumpWidget(
|
||||
new Wrap(
|
||||
alignment: WrapAlignment.start,
|
||||
crossAxisAlignment: WrapCrossAlignment.end,
|
||||
textDirection: TextDirection.ltr,
|
||||
verticalDirection: VerticalDirection.up,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 300.0, height: 50.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 100.0),
|
||||
const SizedBox(width: 300.0, height: 50.0),
|
||||
],
|
||||
),
|
||||
);
|
||||
verify(tester, <Offset>[
|
||||
const Offset(0.0, 500.0),
|
||||
const Offset(300.0, 500.0),
|
||||
const Offset(0.0, 400.0),
|
||||
const Offset(300.0, 400.0),
|
||||
]);
|
||||
|
||||
});
|
||||
|
||||
testWidgets('Empty wrap', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(new Center(child: new Wrap()));
|
||||
await tester.pumpWidget(new Center(child: new Wrap(alignment: WrapAlignment.center)));
|
||||
expect(tester.renderObject<RenderBox>(find.byType(Wrap)).size, equals(Size.zero));
|
||||
});
|
||||
|
||||
testWidgets('Wrap alignment', (WidgetTester tester) async {
|
||||
testWidgets('Wrap alignment (LTR)', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(new Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
spacing: 5.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
@@ -155,6 +285,7 @@ void main() {
|
||||
await tester.pumpWidget(new Wrap(
|
||||
alignment: WrapAlignment.spaceBetween,
|
||||
spacing: 5.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
@@ -171,6 +302,7 @@ void main() {
|
||||
await tester.pumpWidget(new Wrap(
|
||||
alignment: WrapAlignment.spaceAround,
|
||||
spacing: 5.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
@@ -187,6 +319,7 @@ void main() {
|
||||
await tester.pumpWidget(new Wrap(
|
||||
alignment: WrapAlignment.spaceEvenly,
|
||||
spacing: 5.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
@@ -201,10 +334,81 @@ void main() {
|
||||
]);
|
||||
});
|
||||
|
||||
testWidgets('Wrap runAlignment', (WidgetTester tester) async {
|
||||
testWidgets('Wrap alignment (RTL)', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(new Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
spacing: 5.0,
|
||||
textDirection: TextDirection.rtl,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
const SizedBox(width: 300.0, height: 30.0),
|
||||
],
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(find.byType(Wrap)).size, equals(const Size(800.0, 600.0)));
|
||||
verify(tester, <Offset>[
|
||||
const Offset(605.0, 0.0),
|
||||
const Offset(400.0, 0.0),
|
||||
const Offset(95.0, 0.0),
|
||||
]);
|
||||
|
||||
await tester.pumpWidget(new Wrap(
|
||||
alignment: WrapAlignment.spaceBetween,
|
||||
spacing: 5.0,
|
||||
textDirection: TextDirection.rtl,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
const SizedBox(width: 300.0, height: 30.0),
|
||||
],
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(find.byType(Wrap)).size, equals(const Size(800.0, 600.0)));
|
||||
verify(tester, <Offset>[
|
||||
const Offset(700.0, 0.0),
|
||||
const Offset(400.0, 0.0),
|
||||
const Offset(0.0, 0.0),
|
||||
]);
|
||||
|
||||
await tester.pumpWidget(new Wrap(
|
||||
alignment: WrapAlignment.spaceAround,
|
||||
spacing: 5.0,
|
||||
textDirection: TextDirection.rtl,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
const SizedBox(width: 310.0, height: 30.0),
|
||||
],
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(find.byType(Wrap)).size, equals(const Size(800.0, 600.0)));
|
||||
verify(tester, <Offset>[
|
||||
const Offset(670.0, 0.0),
|
||||
const Offset(405.0, 0.0),
|
||||
const Offset(30.0, 0.0),
|
||||
]);
|
||||
|
||||
await tester.pumpWidget(new Wrap(
|
||||
alignment: WrapAlignment.spaceEvenly,
|
||||
spacing: 5.0,
|
||||
textDirection: TextDirection.rtl,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
const SizedBox(width: 310.0, height: 30.0),
|
||||
],
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(find.byType(Wrap)).size, equals(const Size(800.0, 600.0)));
|
||||
verify(tester, <Offset>[
|
||||
const Offset(655.0, 0.0),
|
||||
const Offset(405.0, 0.0),
|
||||
const Offset(45.0, 0.0),
|
||||
]);
|
||||
});
|
||||
|
||||
testWidgets('Wrap runAlignment (DOWN)', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(new Wrap(
|
||||
runAlignment: WrapAlignment.center,
|
||||
runSpacing: 5.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
@@ -225,6 +429,7 @@ void main() {
|
||||
await tester.pumpWidget(new Wrap(
|
||||
runAlignment: WrapAlignment.spaceBetween,
|
||||
runSpacing: 5.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
@@ -245,6 +450,7 @@ void main() {
|
||||
await tester.pumpWidget(new Wrap(
|
||||
runAlignment: WrapAlignment.spaceAround,
|
||||
runSpacing: 5.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
@@ -265,6 +471,7 @@ void main() {
|
||||
await tester.pumpWidget(new Wrap(
|
||||
runAlignment: WrapAlignment.spaceEvenly,
|
||||
runSpacing: 5.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
@@ -284,6 +491,97 @@ void main() {
|
||||
|
||||
});
|
||||
|
||||
testWidgets('Wrap runAlignment (UP)', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(new Wrap(
|
||||
runAlignment: WrapAlignment.center,
|
||||
runSpacing: 5.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
verticalDirection: VerticalDirection.up,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
const SizedBox(width: 300.0, height: 30.0),
|
||||
const SizedBox(width: 400.0, height: 40.0),
|
||||
const SizedBox(width: 500.0, height: 60.0),
|
||||
],
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(find.byType(Wrap)).size, equals(const Size(800.0, 600.0)));
|
||||
verify(tester, <Offset>[
|
||||
const Offset(0.0, 360.0),
|
||||
const Offset(100.0, 350.0),
|
||||
const Offset(300.0, 340.0),
|
||||
const Offset(0.0, 295.0),
|
||||
const Offset(0.0, 230.0),
|
||||
]);
|
||||
|
||||
await tester.pumpWidget(new Wrap(
|
||||
runAlignment: WrapAlignment.spaceBetween,
|
||||
runSpacing: 5.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
verticalDirection: VerticalDirection.up,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
const SizedBox(width: 300.0, height: 30.0),
|
||||
const SizedBox(width: 400.0, height: 40.0),
|
||||
const SizedBox(width: 500.0, height: 60.0),
|
||||
],
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(find.byType(Wrap)).size, equals(const Size(800.0, 600.0)));
|
||||
verify(tester, <Offset>[
|
||||
const Offset(0.0, 590.0),
|
||||
const Offset(100.0, 580.0),
|
||||
const Offset(300.0, 570.0),
|
||||
const Offset(0.0, 295.0),
|
||||
const Offset(0.0, 0.0),
|
||||
]);
|
||||
|
||||
await tester.pumpWidget(new Wrap(
|
||||
runAlignment: WrapAlignment.spaceAround,
|
||||
runSpacing: 5.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
verticalDirection: VerticalDirection.up,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
const SizedBox(width: 300.0, height: 30.0),
|
||||
const SizedBox(width: 400.0, height: 40.0),
|
||||
const SizedBox(width: 500.0, height: 70.0),
|
||||
],
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(find.byType(Wrap)).size, equals(const Size(800.0, 600.0)));
|
||||
verify(tester, <Offset>[
|
||||
const Offset(0.0, 515.0),
|
||||
const Offset(100.0, 505.0),
|
||||
const Offset(300.0, 495.0),
|
||||
const Offset(0.0, 300.0),
|
||||
const Offset(0.0, 75.0),
|
||||
]);
|
||||
|
||||
await tester.pumpWidget(new Wrap(
|
||||
runAlignment: WrapAlignment.spaceEvenly,
|
||||
runSpacing: 5.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
verticalDirection: VerticalDirection.up,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
const SizedBox(width: 300.0, height: 30.0),
|
||||
const SizedBox(width: 400.0, height: 40.0),
|
||||
const SizedBox(width: 500.0, height: 60.0),
|
||||
],
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(find.byType(Wrap)).size, equals(const Size(800.0, 600.0)));
|
||||
verify(tester, <Offset>[
|
||||
const Offset(0.0, 475.0),
|
||||
const Offset(100.0, 465.0),
|
||||
const Offset(300.0, 455.0),
|
||||
const Offset(0.0, 295.0),
|
||||
const Offset(0.0, 115.0),
|
||||
]);
|
||||
|
||||
});
|
||||
|
||||
testWidgets('Shrink-wrapping Wrap test', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
new Align(
|
||||
@@ -291,6 +589,7 @@ void main() {
|
||||
child: new Wrap(
|
||||
alignment: WrapAlignment.end,
|
||||
crossAxisAlignment: WrapCrossAlignment.end,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 100.0, height: 10.0),
|
||||
const SizedBox(width: 200.0, height: 20.0),
|
||||
@@ -314,6 +613,7 @@ void main() {
|
||||
child: new Wrap(
|
||||
alignment: WrapAlignment.end,
|
||||
crossAxisAlignment: WrapCrossAlignment.end,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 400.0, height: 40.0),
|
||||
const SizedBox(width: 300.0, height: 30.0),
|
||||
@@ -340,6 +640,7 @@ void main() {
|
||||
runSpacing: 10.0,
|
||||
alignment: WrapAlignment.start,
|
||||
crossAxisAlignment: WrapCrossAlignment.start,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 500.0, height: 10.0),
|
||||
const SizedBox(width: 500.0, height: 20.0),
|
||||
@@ -368,6 +669,7 @@ void main() {
|
||||
runSpacing: 15.0,
|
||||
alignment: WrapAlignment.start,
|
||||
crossAxisAlignment: WrapCrossAlignment.start,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 10.0, height: 250.0),
|
||||
const SizedBox(width: 20.0, height: 250.0),
|
||||
@@ -396,6 +698,7 @@ void main() {
|
||||
direction: Axis.horizontal,
|
||||
spacing: 12.0,
|
||||
runSpacing: 8.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 10.0, height: 250.0),
|
||||
const SizedBox(width: 20.0, height: 250.0),
|
||||
@@ -420,6 +723,7 @@ void main() {
|
||||
|
||||
testWidgets('Visual overflow generates a clip', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(new Wrap(
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 500.0, height: 500.0),
|
||||
],
|
||||
@@ -428,6 +732,7 @@ void main() {
|
||||
expect(tester.renderObject<RenderBox>(find.byType(Wrap)), isNot(paints..clipRect()));
|
||||
|
||||
await tester.pumpWidget(new Wrap(
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 500.0, height: 500.0),
|
||||
const SizedBox(width: 500.0, height: 500.0),
|
||||
@@ -443,6 +748,7 @@ void main() {
|
||||
await tester.pumpWidget(new Wrap(
|
||||
spacing: 10.0,
|
||||
runSpacing: 15.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 200.0, height: 300.0),
|
||||
const SizedBox(width: 200.0, height: 300.0),
|
||||
@@ -473,7 +779,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('RenderWrap toStringShallow control test', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(new Wrap());
|
||||
await tester.pumpWidget(new Wrap(alignment: WrapAlignment.center));
|
||||
|
||||
final RenderBox wrap = tester.renderObject(find.byType(Wrap));
|
||||
expect(wrap.toStringShallow(), hasOneLineDescription);
|
||||
@@ -483,6 +789,7 @@ void main() {
|
||||
await tester.pumpWidget(new Wrap(
|
||||
direction: Axis.vertical,
|
||||
runSpacing: 7.0,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const SizedBox(width: 500.0, height: 400.0),
|
||||
const SizedBox(width: 500.0, height: 400.0),
|
||||
@@ -508,6 +815,7 @@ void main() {
|
||||
fontSize: 100.0,
|
||||
),
|
||||
child: new Wrap(
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
const Text('X'),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user