in packages/devtools_app/lib/src/inspector/inspector_data_models.dart [486:677]
List<RenderProperties> childrenRenderProperties({
@required double smallestRenderWidth,
@required double largestRenderWidth,
@required double smallestRenderHeight,
@required double largestRenderHeight,
@required double Function(Axis) maxSizeAvailable,
}) {
/// calculate the render empty spaces
final freeSpace = dimension(direction) - sum(childrenDimensions(direction));
final displayMainAxisAlignment =
startIsTopLeft ? mainAxisAlignment : mainAxisAlignment.reversed;
double leadingSpace(double freeSpace) {
if (children.isEmpty) return 0.0;
switch (displayMainAxisAlignment) {
case MainAxisAlignment.start:
case MainAxisAlignment.end:
return freeSpace;
case MainAxisAlignment.center:
return freeSpace * 0.5;
case MainAxisAlignment.spaceBetween:
return 0.0;
case MainAxisAlignment.spaceAround:
final spaceBetweenChildren = freeSpace / children.length;
return spaceBetweenChildren * 0.5;
case MainAxisAlignment.spaceEvenly:
return freeSpace / (children.length + 1);
default:
return 0.0;
}
}
double betweenSpace(double freeSpace) {
if (children.isEmpty) return 0.0;
switch (displayMainAxisAlignment) {
case MainAxisAlignment.start:
case MainAxisAlignment.end:
case MainAxisAlignment.center:
return 0.0;
case MainAxisAlignment.spaceBetween:
if (children.length == 1) return freeSpace;
return freeSpace / (children.length - 1);
case MainAxisAlignment.spaceAround:
return freeSpace / children.length;
case MainAxisAlignment.spaceEvenly:
return freeSpace / (children.length + 1);
default:
return 0.0;
}
}
double smallestRenderSize(Axis axis) {
return axis == Axis.horizontal
? smallestRenderWidth
: smallestRenderHeight;
}
double largestRenderSize(Axis axis) {
final lrs =
axis == Axis.horizontal ? largestRenderWidth : largestRenderHeight;
// use all the space when visualizing cross axis
return (axis == direction) ? lrs : maxSizeAvailable(axis);
}
List<double> renderSizes(Axis axis) {
final sizes = childrenDimensions(axis);
if (freeSpace > 0.0 && axis == direction) {
/// include free space in the computation
sizes.add(freeSpace);
}
final smallestSize = min(sizes);
final largestSize = max(sizes);
if (axis == direction ||
(crossAxisAlignment != CrossAxisAlignment.stretch &&
smallestSize != largestSize)) {
return computeRenderSizes(
sizes: sizes,
smallestSize: smallestSize,
largestSize: largestSize,
smallestRenderSize: smallestRenderSize(axis),
largestRenderSize: largestRenderSize(axis),
maxSizeAvailable: maxSizeAvailable(axis),
);
} else {
// uniform cross axis sizes.
double size = crossAxisAlignment == CrossAxisAlignment.stretch
? maxSizeAvailable(axis)
: largestSize /
math.max(dimension(axis), 1.0) *
maxSizeAvailable(axis);
size = math.max(size, smallestRenderSize(axis));
return sizes.map((_) => size).toList();
}
}
final widths = renderSizes(Axis.horizontal);
final heights = renderSizes(Axis.vertical);
final renderFreeSpace = freeSpace > 0.0
? (isMainAxisHorizontal ? widths.last : heights.last)
: 0.0;
final renderLeadingSpace = leadingSpace(renderFreeSpace);
final renderBetweenSpace = betweenSpace(renderFreeSpace);
final childrenRenderProps = <RenderProperties>[];
double lastMainAxisOffset() {
if (childrenRenderProps.isEmpty) return 0.0;
return childrenRenderProps.last.mainAxisOffset;
}
double lastMainAxisDimension() {
if (childrenRenderProps.isEmpty) return 0.0;
return childrenRenderProps.last.mainAxisDimension;
}
double space(int index) {
if (index == 0) {
if (displayMainAxisAlignment == MainAxisAlignment.start) return 0.0;
return renderLeadingSpace;
}
return renderBetweenSpace;
}
double calculateMainAxisOffset(int i) {
return lastMainAxisOffset() + lastMainAxisDimension() + space(i);
}
double calculateCrossAxisOffset(int i) {
final maxDimension = maxSizeAvailable(crossAxisDirection);
final usedDimension =
crossAxisDirection == Axis.horizontal ? widths[i] : heights[i];
if (crossAxisAlignment == CrossAxisAlignment.start ||
crossAxisAlignment == CrossAxisAlignment.stretch ||
maxDimension == usedDimension) return 0.0;
final emptySpace = math.max(0.0, maxDimension - usedDimension);
if (crossAxisAlignment == CrossAxisAlignment.end) return emptySpace;
return emptySpace * 0.5;
}
for (var i = 0; i < children.length; ++i) {
childrenRenderProps.add(
RenderProperties(
axis: direction,
size: Size(widths[i], heights[i]),
offset: Offset.zero,
realSize: displayChildren[i].size,
)
..mainAxisOffset = calculateMainAxisOffset(i)
..crossAxisOffset = calculateCrossAxisOffset(i)
..layoutProperties = displayChildren[i],
);
}
final spaces = <RenderProperties>[];
final actualLeadingSpace = leadingSpace(freeSpace);
final actualBetweenSpace = betweenSpace(freeSpace);
final renderPropsWithFullCrossAxisDimension =
RenderProperties(axis: direction)
..crossAxisDimension = maxSizeAvailable(crossAxisDirection)
..crossAxisRealDimension = dimension(crossAxisDirection)
..crossAxisOffset = 0.0
..isFreeSpace = true
..layoutProperties = this;
if (actualLeadingSpace > 0.0 &&
displayMainAxisAlignment != MainAxisAlignment.start) {
spaces.add(renderPropsWithFullCrossAxisDimension.clone()
..mainAxisOffset = 0.0
..mainAxisDimension = renderLeadingSpace
..mainAxisRealDimension = actualLeadingSpace);
}
if (actualBetweenSpace > 0.0) {
for (var i = 0; i < childrenRenderProps.length - 1; ++i) {
final child = childrenRenderProps[i];
spaces.add(renderPropsWithFullCrossAxisDimension.clone()
..mainAxisDimension = renderBetweenSpace
..mainAxisRealDimension = actualBetweenSpace
..mainAxisOffset = child.mainAxisOffset + child.mainAxisDimension);
}
}
if (actualLeadingSpace > 0.0 &&
displayMainAxisAlignment != MainAxisAlignment.end) {
spaces.add(renderPropsWithFullCrossAxisDimension.clone()
..mainAxisOffset = childrenRenderProps.last.mainAxisDimension +
childrenRenderProps.last.mainAxisOffset
..mainAxisDimension = renderLeadingSpace
..mainAxisRealDimension = actualLeadingSpace);
}
return [...childrenRenderProps, ...spaces];
}