mirror of
https://github.com/flutter/flutter
synced 2024-10-02 14:34:22 +00:00
Reverts: flutter/flutter#146260 Initiated by: chingjun Reason for reverting: Broke internal tests. See b/338308016 Original PR Author: LongCatIsLooong Reviewed By: {goderbauer} This change reverts the following previous change:
This commit is contained in:
parent
8025af0aa6
commit
706f39b0a0
|
@ -806,8 +806,7 @@ class RenderTable extends RenderBox {
|
||||||
double? _baselineDistance;
|
double? _baselineDistance;
|
||||||
@override
|
@override
|
||||||
double? computeDistanceToActualBaseline(TextBaseline baseline) {
|
double? computeDistanceToActualBaseline(TextBaseline baseline) {
|
||||||
// returns the baseline offset of the cell in the first row with
|
// returns the baseline of the first cell that has a baseline in the first row
|
||||||
// the lowest baseline, and uses `TableCellVerticalAlignment.baseline`.
|
|
||||||
assert(!debugNeedsLayout);
|
assert(!debugNeedsLayout);
|
||||||
return _baselineDistance;
|
return _baselineDistance;
|
||||||
}
|
}
|
||||||
|
@ -1027,36 +1026,6 @@ class RenderTable extends RenderBox {
|
||||||
return Rect.fromLTRB(0.0, _rowTops[row], size.width, _rowTops[row + 1]);
|
return Rect.fromLTRB(0.0, _rowTops[row], size.width, _rowTops[row + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
double? computeDryBaseline(covariant BoxConstraints constraints, TextBaseline baseline) {
|
|
||||||
if (rows * columns == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final List<double> widths = _computeColumnWidths(constraints);
|
|
||||||
double? baselineOffset;
|
|
||||||
for (int col = 0; col < columns; col += 1) {
|
|
||||||
final RenderBox? child = _children[col];
|
|
||||||
final BoxConstraints childConstraints = BoxConstraints.tightFor(width: widths[col]);
|
|
||||||
if (child == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final TableCellParentData childParentData = child.parentData! as TableCellParentData;
|
|
||||||
final double? childBaseline = switch (childParentData.verticalAlignment ?? defaultVerticalAlignment) {
|
|
||||||
TableCellVerticalAlignment.baseline => child.getDryBaseline(childConstraints, baseline),
|
|
||||||
TableCellVerticalAlignment.baseline ||
|
|
||||||
TableCellVerticalAlignment.top ||
|
|
||||||
TableCellVerticalAlignment.middle ||
|
|
||||||
TableCellVerticalAlignment.bottom ||
|
|
||||||
TableCellVerticalAlignment.fill ||
|
|
||||||
TableCellVerticalAlignment.intrinsicHeight => null,
|
|
||||||
};
|
|
||||||
if (childBaseline != null && (baselineOffset == null || baselineOffset < childBaseline)) {
|
|
||||||
baselineOffset = childBaseline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return baselineOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@protected
|
@protected
|
||||||
Size computeDryLayout(covariant BoxConstraints constraints) {
|
Size computeDryLayout(covariant BoxConstraints constraints) {
|
||||||
|
|
|
@ -11,41 +11,6 @@ import 'layer.dart';
|
||||||
import 'layout_helper.dart';
|
import 'layout_helper.dart';
|
||||||
import 'object.dart';
|
import 'object.dart';
|
||||||
|
|
||||||
typedef _NextChild = RenderBox? Function(RenderBox child);
|
|
||||||
typedef _PositionChild = void Function(Offset offset, RenderBox child);
|
|
||||||
typedef _GetChildSize = Size Function(RenderBox child);
|
|
||||||
// A 2D vector that uses a [RenderWrap]'s main axis and cross axis as its first and second coordinate axes.
|
|
||||||
// It represents the same vector as (double mainAxisExtent, double crossAxisExtent).
|
|
||||||
extension type const _AxisSize._(Size _size) {
|
|
||||||
_AxisSize({ required double mainAxisExtent, required double crossAxisExtent }) : this._(Size(mainAxisExtent, crossAxisExtent));
|
|
||||||
_AxisSize.fromSize({ required Size size, required Axis direction }) : this._(_convert(size, direction));
|
|
||||||
|
|
||||||
static const _AxisSize empty = _AxisSize._(Size.zero);
|
|
||||||
|
|
||||||
static Size _convert(Size size, Axis direction) {
|
|
||||||
return switch (direction) {
|
|
||||||
Axis.horizontal => size,
|
|
||||||
Axis.vertical => size.flipped,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
double get mainAxisExtent => _size.width;
|
|
||||||
double get crossAxisExtent => _size.height;
|
|
||||||
|
|
||||||
Size toSize(Axis direction) => _convert(_size, direction);
|
|
||||||
|
|
||||||
_AxisSize applyConstraints(BoxConstraints constraints, Axis direction) {
|
|
||||||
final BoxConstraints effectiveConstraints = switch (direction) {
|
|
||||||
Axis.horizontal => constraints,
|
|
||||||
Axis.vertical => constraints.flipped,
|
|
||||||
};
|
|
||||||
return _AxisSize._(effectiveConstraints.constrain(_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
_AxisSize get flipped => _AxisSize._(_size.flipped);
|
|
||||||
_AxisSize operator +(_AxisSize other) => _AxisSize._(Size(_size.width + other._size.width, math.max(_size.height, other._size.height)));
|
|
||||||
_AxisSize operator -(_AxisSize other) => _AxisSize._(Size(_size.width - other._size.width, _size.height - other._size.height));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// How [Wrap] should align objects.
|
/// How [Wrap] should align objects.
|
||||||
///
|
///
|
||||||
/// Used both to align children within a run in the main axis as well as to
|
/// Used both to align children within a run in the main axis as well as to
|
||||||
|
@ -81,22 +46,7 @@ enum WrapAlignment {
|
||||||
|
|
||||||
/// Place the free space evenly between the objects as well as before and
|
/// Place the free space evenly between the objects as well as before and
|
||||||
/// after the first and last objects.
|
/// after the first and last objects.
|
||||||
spaceEvenly;
|
spaceEvenly,
|
||||||
|
|
||||||
(double leadingSpace, double betweenSpace) _distributeSpace(double freeSpace, double itemSpacing, int itemCount, bool flipped) {
|
|
||||||
assert(itemCount > 0);
|
|
||||||
return switch (this) {
|
|
||||||
WrapAlignment.start => (flipped ? freeSpace : 0.0, itemSpacing),
|
|
||||||
|
|
||||||
WrapAlignment.end => WrapAlignment.start._distributeSpace(freeSpace, itemSpacing, itemCount, !flipped),
|
|
||||||
WrapAlignment.spaceBetween when itemCount < 2 => WrapAlignment.start._distributeSpace(freeSpace, itemSpacing, itemCount, flipped),
|
|
||||||
|
|
||||||
WrapAlignment.center => (freeSpace / 2.0, itemSpacing),
|
|
||||||
WrapAlignment.spaceBetween => (0, freeSpace / (itemCount - 1) + itemSpacing),
|
|
||||||
WrapAlignment.spaceAround => (freeSpace / itemCount / 2, freeSpace / itemCount + itemSpacing),
|
|
||||||
WrapAlignment.spaceEvenly => (freeSpace / (itemCount + 1), freeSpace / (itemCount + 1) + itemSpacing),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Who [Wrap] should align children within a run in the cross axis.
|
/// Who [Wrap] should align children within a run in the cross axis.
|
||||||
|
@ -123,48 +73,23 @@ enum WrapCrossAlignment {
|
||||||
|
|
||||||
/// Place the children as close to the middle of the run in the cross axis as
|
/// Place the children as close to the middle of the run in the cross axis as
|
||||||
/// possible.
|
/// possible.
|
||||||
center;
|
center,
|
||||||
|
|
||||||
// TODO(ianh): baseline.
|
// TODO(ianh): baseline.
|
||||||
|
|
||||||
WrapCrossAlignment get _flipped => switch (this) {
|
|
||||||
WrapCrossAlignment.start => WrapCrossAlignment.end,
|
|
||||||
WrapCrossAlignment.end => WrapCrossAlignment.start,
|
|
||||||
WrapCrossAlignment.center => WrapCrossAlignment.center,
|
|
||||||
};
|
|
||||||
|
|
||||||
double get _alignment => switch (this) {
|
|
||||||
WrapCrossAlignment.start => 0,
|
|
||||||
WrapCrossAlignment.end => 1,
|
|
||||||
WrapCrossAlignment.center => 0.5,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _RunMetrics {
|
class _RunMetrics {
|
||||||
_RunMetrics(this.leadingChild, this.axisSize);
|
_RunMetrics(this.mainAxisExtent, this.crossAxisExtent, this.childCount);
|
||||||
|
|
||||||
_AxisSize axisSize;
|
final double mainAxisExtent;
|
||||||
int childCount = 1;
|
final double crossAxisExtent;
|
||||||
RenderBox leadingChild;
|
final int childCount;
|
||||||
|
|
||||||
// Look ahead, creates a new run if incorporating the child would exceed the allowed line width.
|
|
||||||
_RunMetrics? tryAddingNewChild(RenderBox child, _AxisSize childSize, bool flipMainAxis, double spacing, double maxMainExtent) {
|
|
||||||
final bool needsNewRun = axisSize.mainAxisExtent + childSize.mainAxisExtent + spacing - maxMainExtent > precisionErrorTolerance;
|
|
||||||
if (needsNewRun) {
|
|
||||||
return _RunMetrics(child, childSize);
|
|
||||||
} else {
|
|
||||||
axisSize += childSize + _AxisSize(mainAxisExtent: spacing, crossAxisExtent: 0.0);
|
|
||||||
childCount += 1;
|
|
||||||
if (flipMainAxis) {
|
|
||||||
leadingChild = child;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parent data for use with [RenderWrap].
|
/// Parent data for use with [RenderWrap].
|
||||||
class WrapParentData extends ContainerBoxParentData<RenderBox> { }
|
class WrapParentData extends ContainerBoxParentData<RenderBox> {
|
||||||
|
int _runIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// Displays its children in multiple horizontal or vertical runs.
|
/// Displays its children in multiple horizontal or vertical runs.
|
||||||
///
|
///
|
||||||
|
@ -549,42 +474,16 @@ class RenderWrap extends RenderBox
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
(bool flipHorizontal, bool flipVertical) get _areAxesFlipped {
|
double _getChildCrossAxisOffset(bool flipCrossAxis, double runCrossAxisExtent, double childCrossAxisExtent) {
|
||||||
final bool flipHorizontal = switch (textDirection ?? TextDirection.ltr) {
|
final double freeSpace = runCrossAxisExtent - childCrossAxisExtent;
|
||||||
TextDirection.ltr => false,
|
return switch (crossAxisAlignment) {
|
||||||
TextDirection.rtl => true,
|
WrapCrossAlignment.start => flipCrossAxis ? freeSpace : 0.0,
|
||||||
};
|
WrapCrossAlignment.end => flipCrossAxis ? 0.0 : freeSpace,
|
||||||
final bool flipVertical = switch (verticalDirection) {
|
WrapCrossAlignment.center => freeSpace / 2.0,
|
||||||
VerticalDirection.down => false,
|
|
||||||
VerticalDirection.up => true,
|
|
||||||
};
|
|
||||||
return switch (direction) {
|
|
||||||
Axis.horizontal => (flipHorizontal, flipVertical),
|
|
||||||
Axis.vertical => (flipVertical, flipHorizontal),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
bool _hasVisualOverflow = false;
|
||||||
double? computeDryBaseline(covariant BoxConstraints constraints, TextBaseline baseline) {
|
|
||||||
if (firstChild == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final BoxConstraints childConstraints = switch (direction) {
|
|
||||||
Axis.horizontal => BoxConstraints(maxWidth: constraints.maxWidth),
|
|
||||||
Axis.vertical => BoxConstraints(maxHeight: constraints.maxHeight),
|
|
||||||
};
|
|
||||||
|
|
||||||
final (_AxisSize childrenAxisSize, List<_RunMetrics> runMetrics) = _computeRuns(constraints, ChildLayoutHelper.dryLayoutChild);
|
|
||||||
final _AxisSize containerAxisSize = childrenAxisSize.applyConstraints(constraints, direction);
|
|
||||||
|
|
||||||
BaselineOffset baselineOffset = BaselineOffset.noBaseline;
|
|
||||||
void findHighestBaseline(Offset offset, RenderBox child) {
|
|
||||||
baselineOffset = baselineOffset.minOf(BaselineOffset(child.getDryBaseline(childConstraints, baseline)) + offset.dy);
|
|
||||||
}
|
|
||||||
Size getChildSize(RenderBox child) => child.getDryLayout(childConstraints);
|
|
||||||
_positionChildren(runMetrics, childrenAxisSize, containerAxisSize, findHighestBaseline, getChildSize);
|
|
||||||
return baselineOffset.offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@protected
|
@protected
|
||||||
|
@ -633,97 +532,184 @@ class RenderWrap extends RenderBox
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static Size _getChildSize(RenderBox child) => child.size;
|
|
||||||
static void _setChildPosition(Offset offset, RenderBox child) {
|
|
||||||
(child.parentData! as WrapParentData).offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _hasVisualOverflow = false;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void performLayout() {
|
void performLayout() {
|
||||||
final BoxConstraints constraints = this.constraints;
|
final BoxConstraints constraints = this.constraints;
|
||||||
assert(_debugHasNecessaryDirections);
|
assert(_debugHasNecessaryDirections);
|
||||||
if (firstChild == null) {
|
_hasVisualOverflow = false;
|
||||||
|
RenderBox? child = firstChild;
|
||||||
|
if (child == null) {
|
||||||
size = constraints.smallest;
|
size = constraints.smallest;
|
||||||
_hasVisualOverflow = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final BoxConstraints childConstraints;
|
||||||
final (_AxisSize childrenAxisSize, List<_RunMetrics> runMetrics) = _computeRuns(constraints, ChildLayoutHelper.layoutChild);
|
double mainAxisLimit = 0.0;
|
||||||
final _AxisSize containerAxisSize = childrenAxisSize.applyConstraints(constraints, direction);
|
bool flipMainAxis = false;
|
||||||
size = containerAxisSize.toSize(direction);
|
bool flipCrossAxis = false;
|
||||||
final _AxisSize freeAxisSize = containerAxisSize - childrenAxisSize;
|
switch (direction) {
|
||||||
_hasVisualOverflow = freeAxisSize.mainAxisExtent < 0.0 || freeAxisSize.crossAxisExtent < 0.0;
|
case Axis.horizontal:
|
||||||
_positionChildren(runMetrics, freeAxisSize, containerAxisSize, _setChildPosition, _getChildSize);
|
childConstraints = BoxConstraints(maxWidth: constraints.maxWidth);
|
||||||
}
|
mainAxisLimit = constraints.maxWidth;
|
||||||
|
if (textDirection == TextDirection.rtl) {
|
||||||
(_AxisSize childrenSize, List<_RunMetrics> runMetrics) _computeRuns(BoxConstraints constraints, ChildLayouter layoutChild) {
|
flipMainAxis = true;
|
||||||
assert(firstChild != null);
|
}
|
||||||
final (BoxConstraints childConstraints, double mainAxisLimit) = switch (direction) {
|
if (verticalDirection == VerticalDirection.up) {
|
||||||
Axis.horizontal => (BoxConstraints(maxWidth: constraints.maxWidth), constraints.maxWidth),
|
flipCrossAxis = true;
|
||||||
Axis.vertical => (BoxConstraints(maxHeight: constraints.maxHeight), constraints.maxHeight),
|
}
|
||||||
};
|
case Axis.vertical:
|
||||||
|
childConstraints = BoxConstraints(maxHeight: constraints.maxHeight);
|
||||||
final (bool flipMainAxis, _) = _areAxesFlipped;
|
mainAxisLimit = constraints.maxHeight;
|
||||||
final double spacing = this.spacing;
|
if (verticalDirection == VerticalDirection.up) {
|
||||||
final List<_RunMetrics> runMetrics = <_RunMetrics>[];
|
flipMainAxis = true;
|
||||||
|
}
|
||||||
_RunMetrics? currentRun;
|
if (textDirection == TextDirection.rtl) {
|
||||||
_AxisSize childrenAxisSize = _AxisSize.empty;
|
flipCrossAxis = true;
|
||||||
for (RenderBox? child = firstChild; child != null; child = childAfter(child)) {
|
}
|
||||||
final _AxisSize childSize = _AxisSize.fromSize(size: layoutChild(child, childConstraints), direction: direction);
|
|
||||||
final _RunMetrics? newRun = currentRun == null
|
|
||||||
? _RunMetrics(child, childSize)
|
|
||||||
: currentRun.tryAddingNewChild(child, childSize, flipMainAxis, spacing, mainAxisLimit);
|
|
||||||
if (newRun != null) {
|
|
||||||
runMetrics.add(newRun);
|
|
||||||
childrenAxisSize += currentRun?.axisSize.flipped ?? _AxisSize.empty;
|
|
||||||
currentRun = newRun;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
assert(runMetrics.isNotEmpty);
|
|
||||||
final double totalRunSpacing = runSpacing * (runMetrics.length - 1);
|
|
||||||
childrenAxisSize += _AxisSize(mainAxisExtent: totalRunSpacing, crossAxisExtent: 0.0) + currentRun!.axisSize.flipped;
|
|
||||||
return (childrenAxisSize.flipped, runMetrics);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _positionChildren(List<_RunMetrics> runMetrics, _AxisSize freeAxisSize, _AxisSize containerAxisSize, _PositionChild positionChild, _GetChildSize getChildSize) {
|
|
||||||
assert(runMetrics.isNotEmpty);
|
|
||||||
|
|
||||||
final double spacing = this.spacing;
|
final double spacing = this.spacing;
|
||||||
|
final double runSpacing = this.runSpacing;
|
||||||
final double crossAxisFreeSpace = math.max(0.0, freeAxisSize.crossAxisExtent);
|
final List<_RunMetrics> runMetrics = <_RunMetrics>[];
|
||||||
|
double mainAxisExtent = 0.0;
|
||||||
final (bool flipMainAxis, bool flipCrossAxis) = _areAxesFlipped;
|
double crossAxisExtent = 0.0;
|
||||||
final WrapCrossAlignment effectiveCrossAlignment = flipCrossAxis ? crossAxisAlignment._flipped : crossAxisAlignment;
|
double runMainAxisExtent = 0.0;
|
||||||
final (double runLeadingSpace, double runBetweenSpace) = runAlignment._distributeSpace(
|
double runCrossAxisExtent = 0.0;
|
||||||
crossAxisFreeSpace,
|
int childCount = 0;
|
||||||
runSpacing,
|
while (child != null) {
|
||||||
runMetrics.length,
|
child.layout(childConstraints, parentUsesSize: true);
|
||||||
flipCrossAxis,
|
final double childMainAxisExtent = _getMainAxisExtent(child.size);
|
||||||
);
|
final double childCrossAxisExtent = _getCrossAxisExtent(child.size);
|
||||||
final _NextChild nextChild = flipMainAxis ? childBefore : childAfter;
|
if (childCount > 0 && runMainAxisExtent + spacing + childMainAxisExtent > mainAxisLimit) {
|
||||||
|
mainAxisExtent = math.max(mainAxisExtent, runMainAxisExtent);
|
||||||
double runCrossAxisOffset = runLeadingSpace;
|
crossAxisExtent += runCrossAxisExtent;
|
||||||
final Iterable<_RunMetrics> runs = flipCrossAxis ? runMetrics.reversed : runMetrics;
|
if (runMetrics.isNotEmpty) {
|
||||||
for (final _RunMetrics run in runs) {
|
crossAxisExtent += runSpacing;
|
||||||
final double runCrossAxisExtent = run.axisSize.crossAxisExtent;
|
}
|
||||||
final int childCount = run.childCount;
|
runMetrics.add(_RunMetrics(runMainAxisExtent, runCrossAxisExtent, childCount));
|
||||||
|
runMainAxisExtent = 0.0;
|
||||||
final double mainAxisFreeSpace = math.max(0.0, containerAxisSize.mainAxisExtent - run.axisSize.mainAxisExtent);
|
runCrossAxisExtent = 0.0;
|
||||||
final (double childLeadingSpace, double childBetweenSpace) = alignment._distributeSpace(mainAxisFreeSpace, spacing, childCount, flipMainAxis);
|
childCount = 0;
|
||||||
|
}
|
||||||
double childMainAxisOffset = childLeadingSpace;
|
runMainAxisExtent += childMainAxisExtent;
|
||||||
|
if (childCount > 0) {
|
||||||
int remainingChildCount = run.childCount;
|
runMainAxisExtent += spacing;
|
||||||
for (RenderBox? child = run.leadingChild; child != null && remainingChildCount > 0; child = nextChild(child), remainingChildCount -= 1) {
|
}
|
||||||
final _AxisSize(mainAxisExtent: double childMainAxisExtent, crossAxisExtent: double childCrossAxisExtent) = _AxisSize.fromSize(size: getChildSize(child), direction: direction);
|
runCrossAxisExtent = math.max(runCrossAxisExtent, childCrossAxisExtent);
|
||||||
final double childCrossAxisOffset = effectiveCrossAlignment._alignment * (runCrossAxisExtent - childCrossAxisExtent);
|
childCount += 1;
|
||||||
positionChild(_getOffset(childMainAxisOffset, runCrossAxisOffset + childCrossAxisOffset), child);
|
final WrapParentData childParentData = child.parentData! as WrapParentData;
|
||||||
childMainAxisOffset += childMainAxisExtent + childBetweenSpace;
|
childParentData._runIndex = runMetrics.length;
|
||||||
|
child = childParentData.nextSibling;
|
||||||
|
}
|
||||||
|
if (childCount > 0) {
|
||||||
|
mainAxisExtent = math.max(mainAxisExtent, runMainAxisExtent);
|
||||||
|
crossAxisExtent += runCrossAxisExtent;
|
||||||
|
if (runMetrics.isNotEmpty) {
|
||||||
|
crossAxisExtent += runSpacing;
|
||||||
|
}
|
||||||
|
runMetrics.add(_RunMetrics(runMainAxisExtent, runCrossAxisExtent, childCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
final int runCount = runMetrics.length;
|
||||||
|
assert(runCount > 0);
|
||||||
|
|
||||||
|
double containerMainAxisExtent = 0.0;
|
||||||
|
double containerCrossAxisExtent = 0.0;
|
||||||
|
|
||||||
|
switch (direction) {
|
||||||
|
case Axis.horizontal:
|
||||||
|
size = constraints.constrain(Size(mainAxisExtent, crossAxisExtent));
|
||||||
|
containerMainAxisExtent = size.width;
|
||||||
|
containerCrossAxisExtent = size.height;
|
||||||
|
case Axis.vertical:
|
||||||
|
size = constraints.constrain(Size(crossAxisExtent, mainAxisExtent));
|
||||||
|
containerMainAxisExtent = size.height;
|
||||||
|
containerCrossAxisExtent = size.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
_hasVisualOverflow = containerMainAxisExtent < mainAxisExtent || containerCrossAxisExtent < crossAxisExtent;
|
||||||
|
|
||||||
|
final double crossAxisFreeSpace = math.max(0.0, containerCrossAxisExtent - crossAxisExtent);
|
||||||
|
double runLeadingSpace = 0.0;
|
||||||
|
double runBetweenSpace = 0.0;
|
||||||
|
switch (runAlignment) {
|
||||||
|
case WrapAlignment.start:
|
||||||
|
break;
|
||||||
|
case WrapAlignment.end:
|
||||||
|
runLeadingSpace = crossAxisFreeSpace;
|
||||||
|
case WrapAlignment.center:
|
||||||
|
runLeadingSpace = crossAxisFreeSpace / 2.0;
|
||||||
|
case WrapAlignment.spaceBetween:
|
||||||
|
runBetweenSpace = runCount > 1 ? crossAxisFreeSpace / (runCount - 1) : 0.0;
|
||||||
|
case WrapAlignment.spaceAround:
|
||||||
|
runBetweenSpace = crossAxisFreeSpace / runCount;
|
||||||
|
runLeadingSpace = runBetweenSpace / 2.0;
|
||||||
|
case WrapAlignment.spaceEvenly:
|
||||||
|
runBetweenSpace = crossAxisFreeSpace / (runCount + 1);
|
||||||
|
runLeadingSpace = runBetweenSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
runBetweenSpace += runSpacing;
|
||||||
|
double crossAxisOffset = flipCrossAxis ? containerCrossAxisExtent - runLeadingSpace : runLeadingSpace;
|
||||||
|
|
||||||
|
child = firstChild;
|
||||||
|
for (int i = 0; i < runCount; ++i) {
|
||||||
|
final _RunMetrics metrics = runMetrics[i];
|
||||||
|
final double runMainAxisExtent = metrics.mainAxisExtent;
|
||||||
|
final double runCrossAxisExtent = metrics.crossAxisExtent;
|
||||||
|
final int childCount = metrics.childCount;
|
||||||
|
|
||||||
|
final double mainAxisFreeSpace = math.max(0.0, containerMainAxisExtent - runMainAxisExtent);
|
||||||
|
double childLeadingSpace = 0.0;
|
||||||
|
double childBetweenSpace = 0.0;
|
||||||
|
|
||||||
|
switch (alignment) {
|
||||||
|
case WrapAlignment.start:
|
||||||
|
break;
|
||||||
|
case WrapAlignment.end:
|
||||||
|
childLeadingSpace = mainAxisFreeSpace;
|
||||||
|
case WrapAlignment.center:
|
||||||
|
childLeadingSpace = mainAxisFreeSpace / 2.0;
|
||||||
|
case WrapAlignment.spaceBetween:
|
||||||
|
childBetweenSpace = childCount > 1 ? mainAxisFreeSpace / (childCount - 1) : 0.0;
|
||||||
|
case WrapAlignment.spaceAround:
|
||||||
|
childBetweenSpace = mainAxisFreeSpace / childCount;
|
||||||
|
childLeadingSpace = childBetweenSpace / 2.0;
|
||||||
|
case WrapAlignment.spaceEvenly:
|
||||||
|
childBetweenSpace = mainAxisFreeSpace / (childCount + 1);
|
||||||
|
childLeadingSpace = childBetweenSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
childBetweenSpace += spacing;
|
||||||
|
double childMainPosition = flipMainAxis ? containerMainAxisExtent - childLeadingSpace : childLeadingSpace;
|
||||||
|
|
||||||
|
if (flipCrossAxis) {
|
||||||
|
crossAxisOffset -= runCrossAxisExtent;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (child != null) {
|
||||||
|
final WrapParentData childParentData = child.parentData! as WrapParentData;
|
||||||
|
if (childParentData._runIndex != i) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
final double childMainAxisExtent = _getMainAxisExtent(child.size);
|
||||||
|
final double childCrossAxisExtent = _getCrossAxisExtent(child.size);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flipCrossAxis) {
|
||||||
|
crossAxisOffset -= runBetweenSpace;
|
||||||
|
} else {
|
||||||
|
crossAxisOffset += runCrossAxisExtent + runBetweenSpace;
|
||||||
}
|
}
|
||||||
runCrossAxisOffset += runCrossAxisExtent + runBetweenSpace;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -952,18 +952,4 @@ void main() {
|
||||||
// the individual widths.
|
// the individual widths.
|
||||||
expect(tester.getSize(find.byType(IntrinsicWidth)).width, 5 * 16 + 60 + 3 * 16);
|
expect(tester.getSize(find.byType(IntrinsicWidth)).width, 5 * 16 + 60 + 3 * 16);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Wrap alignment flipped spaceInBetween', (WidgetTester tester) async {
|
|
||||||
await tester.pumpWidget(const Wrap(
|
|
||||||
textDirection: TextDirection.rtl,
|
|
||||||
alignment: WrapAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
SizedBox(width: 100.0, height: 100.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),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue