layout method

  1. @override
void layout(
  1. Context context,
  2. BoxConstraints constraints, {
  3. bool parentUsesSize = false,
})
override

First widget pass to calculate the children layout and bounding box

Implementation

@override
void layout(
  Context context,
  BoxConstraints constraints, {
  bool parentUsesSize = false,
}) {
  if (children.isEmpty) {
    box = PdfRect.zero;
    return;
  }

  assert(() {
    if (constraints.maxHeight.isInfinite && childAspectRatio.isInfinite) {
      print(
        'Unable to calculate the GridView dimensions. Please set the height constraints or childAspectRatio.',
      );
      return false;
    }
    return true;
  }());
  final textDirection = Directionality.of(context);
  final resolvedPadding = padding.resolve(textDirection);
  late double mainAxisExtent;
  late double crossAxisExtent;
  switch (direction) {
    case Axis.vertical:
      mainAxisExtent = constraints.maxHeight - padding.vertical;
      crossAxisExtent = constraints.maxWidth - padding.horizontal;
      break;
    case Axis.horizontal:
      mainAxisExtent = constraints.maxWidth - padding.horizontal;
      crossAxisExtent = constraints.maxHeight - padding.vertical;
      break;
  }

  if (constraints.maxHeight.isInfinite || _mainAxisCount == null) {
    _mainAxisCount =
        ((children.length - _context.firstChild) / crossAxisCount).ceil();

    _context.childCrossAxis =
        crossAxisExtent / crossAxisCount -
        (crossAxisSpacing * (crossAxisCount - 1) / crossAxisCount);

    _context.childMainAxis = math.min(
      _context.childCrossAxis! * childAspectRatio,
      mainAxisExtent / _mainAxisCount! -
          (mainAxisSpacing * (_mainAxisCount! - 1) / _mainAxisCount!),
    );

    if (_context.childCrossAxis!.isInfinite) {
      throw Exception(
        'Unable to calculate child height as the height constraint is infinite.',
      );
    }
  } else {
    _mainAxisCount =
        ((mainAxisExtent + mainAxisSpacing) /
                (mainAxisSpacing + _context.childMainAxis!))
            .floor();

    if (_mainAxisCount! < 0) {
      // Not enough space to put one line, try to ask for more space.
      _mainAxisCount = 0;
    }
  }

  final totalMain =
      (_context.childMainAxis! + mainAxisSpacing) * _mainAxisCount! -
      mainAxisSpacing;
  final totalCross =
      (_context.childCrossAxis! + crossAxisSpacing) * crossAxisCount -
      crossAxisSpacing;

  final startX = resolvedPadding.left;
  const startY = 0.0;
  late double mainAxis;
  late double crossAxis;
  BoxConstraints? innerConstraints;
  switch (direction) {
    case Axis.vertical:
      innerConstraints = BoxConstraints.tightFor(
        width: _context.childCrossAxis,
        height: _context.childMainAxis,
      );
      crossAxis = startX;
      mainAxis = startY;
      break;
    case Axis.horizontal:
      innerConstraints = BoxConstraints.tightFor(
        width: _context.childMainAxis,
        height: _context.childCrossAxis,
      );
      mainAxis = startX;
      crossAxis = startY;
      break;
  }

  var c = 0;
  _context.lastChild = _context.firstChild;

  final isRtl = textDirection == TextDirection.rtl;
  for (final child in children.sublist(
    _context.firstChild,
    math.min(
      children.length,
      _context.firstChild + crossAxisCount * _mainAxisCount!,
    ),
  )) {
    child.layout(context, innerConstraints);
    assert(child.box != null);

    switch (direction) {
      case Axis.vertical:
        child.box = PdfRect.fromPoints(
          PdfPoint(
            isRtl
                ? (_context.childCrossAxis! + child.box!.width - crossAxis)
                : (_context.childCrossAxis! - child.box!.width) / 2.0 +
                      crossAxis,
            totalMain +
                resolvedPadding.bottom -
                (_context.childMainAxis! - child.box!.height) / 2.0 -
                mainAxis -
                child.box!.height,
          ),
          child.box!.size,
        );

        break;
      case Axis.horizontal:
        child.box = PdfRect.fromPoints(
          PdfPoint(
            isRtl
                ? totalMain - (child.box!.width + mainAxis)
                : (_context.childMainAxis! - child.box!.width) / 2.0 +
                      mainAxis,
            totalCross +
                resolvedPadding.bottom -
                (_context.childCrossAxis! - child.box!.height) / 2.0 -
                crossAxis -
                child.box!.height,
          ),
          child.box!.size,
        );
        break;
    }

    if (++c >= crossAxisCount) {
      mainAxis += _context.childMainAxis! + mainAxisSpacing;
      switch (direction) {
        case Axis.vertical:
          crossAxis = startX;
          break;
        case Axis.horizontal:
          crossAxis = startY;
          break;
      }
      c = 0;

      if (mainAxis > mainAxisExtent) {
        _context.lastChild++;

        break;
      }
    } else {
      crossAxis += _context.childCrossAxis! + crossAxisSpacing;
    }
    _context.lastChild++;
  }

  switch (direction) {
    case Axis.vertical:
      box = constraints.constrainRect(
        width: totalCross + padding.horizontal,
        height: totalMain + padding.vertical,
      );
      break;
    case Axis.horizontal:
      box = constraints.constrainRect(
        width: totalMain + padding.horizontal,
        height: totalCross + padding.vertical,
      );
      break;
  }
}