List childrenRenderProperties()

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];
  }