performBoxLayout method

  1. @override
void performBoxLayout(
  1. BoxConstraints constraints
)
override

Perform layout with typed box constraints

Subclasses override this instead of performLayout. The default implementation sizes to the maxima, treating an unbounded axis as the corresponding lower bound.

Implementation

@override
void performBoxLayout(BoxConstraints constraints) {
  final columns = _content.fold<int>(
    0,
    (count, row) => math.max(count, row.length),
  );
  if (columns == 0 || _content.isEmpty) {
    _columnWidths = const <int>[];
    _rowHeights = const <int>[];
    _cells = const <_TableCellLayout>[];
    _gridWidth = 0;
    size = Size(
      constraints.constrainWidth(0),
      constraints.constrainHeight(0),
    );
    return;
  }

  final intrinsic = List<int>.filled(columns, 1);
  for (final row in _content) {
    for (var column = 0; column < row.length; column++) {
      final span = row[column];
      if (span == null) continue;
      final layout = const TextLayoutEngine().layout(
        span,
        const BoxConstraints(),
      );
      intrinsic[column] = math.max(intrinsic[column], layout.maxLineWidth);
    }
  }
  final outer = _outerBorder && _showBorders ? 2 : 0;
  final separators = columns - 1;
  final separatorWidth = _showBorders ? 1 : _columnGap;
  final structural =
      outer + separators * separatorWidth + columns * _cellPaddingX * 2;
  final intrinsicContent = intrinsic.fold<int>(
    0,
    (sum, value) => sum + value,
  );
  final boundedContent = constraints.maxWidth == null
      ? intrinsicContent
      : math.max(columns, constraints.maxWidth! - structural);
  if (intrinsicContent < boundedContent) {
    _columnWidths = _columnWidthMode == TextTableColumnWidthMode.full
        ? _expandWidths(intrinsic, boundedContent)
        : List<int>.unmodifiable(intrinsic);
  } else if (intrinsicContent > boundedContent &&
      _wrapMode != TextTableWrapMode.none) {
    _columnWidths = _fitWidths(intrinsic, boundedContent, _columnFitter);
  } else {
    _columnWidths = List<int>.unmodifiable(intrinsic);
  }

  final cells = <_TableCellLayout>[];
  final rowHeights = <int>[];
  var sourceBase = 0;
  for (var rowIndex = 0; rowIndex < _content.length; rowIndex++) {
    final row = _content[rowIndex];
    var rowHeight = 1 + _cellPaddingY * 2;
    for (var column = 0; column < columns; column++) {
      final span = column < row.length ? row[column] : null;
      final effective = span ?? const TextSpan(text: '');
      final layout = _layoutCell(effective, _columnWidths[column], _wrapMode);
      cells.add(
        _TableCellLayout(
          row: rowIndex,
          column: column,
          layout: layout,
          sourceBase: sourceBase,
        ),
      );
      rowHeight = math.max(rowHeight, layout.lineCount + _cellPaddingY * 2);
      sourceBase += layout.text.length;
      if (column < columns - 1) sourceBase++;
    }
    rowHeights.add(rowHeight);
    if (rowIndex < _content.length - 1) sourceBase++;
  }
  _rowHeights = List<int>.unmodifiable(rowHeights);
  _cells = List<_TableCellLayout>.unmodifiable(cells);

  final width =
      structural + _columnWidths.fold<int>(0, (sum, value) => sum + value);
  _gridWidth = width;
  final horizontalRules = _showBorders
      ? (_outerBorder ? 2 : 0) + (_content.length - 1)
      : 0;
  final height =
      horizontalRules + rowHeights.fold<int>(0, (sum, value) => sum + value);
  size = Size(
    constraints.constrainWidth(width),
    constraints.constrainHeight(height),
  );
}