Table constructor

Table({
  1. TableSection? header,
  2. required TableSection body,
  3. TableSection? footer,
  4. CellStyle cellStyle = const CellStyle(),
  5. TableStyle? tableStyle,
})

Implementation

Table({
  this.header,
  required this.body,
  this.footer,
  this.cellStyle = const CellStyle(),
  this.tableStyle,
}) : rowCount = (header?.rows.length ?? 0) +
          body.rows.length +
          (footer?.rows.length ?? 0) {
  final rowSpanCarries = IntCounts();

  final positionedCells = <PositionedCell>[];
  final _cellTable = <List<PositionedCell?>>[];
  var rowIndex = 0;

  for (final section
      in [header, body, footer].where((element) => element != null)) {
    final sectionStyle = cellStyle + section!.cellStyle;
    for (final row in section.rows) {
      final rowStyle = sectionStyle + row.cellStyle;
      final cellRow = <PositionedCell?>[];
      _cellTable.add(cellRow);
      var columnIndex = 0;
      var rawColumnIndex = 0;
      for (final cell in row.cells) {
        // Check for any previous rows' cells whose >1 rowSpan carries them into this row.
        // When found, add them to the current row, pushing remaining cells to the right.
        while (columnIndex < rowSpanCarries.size &&
            rowSpanCarries[columnIndex] > 0) {
          cellRow.add(_cellTable[rowIndex - 1][columnIndex]);
          rowSpanCarries.set(columnIndex, rowSpanCarries[columnIndex] - 1);
          columnIndex++;
        }
        final canonicalStyle = rowStyle + cell.style;
        final positionedCell = PositionedCell(
            rowIndex: rowIndex,
            columnIndex: columnIndex,
            cell: cell,
            canonicalStyle: canonicalStyle);
        positionedCells.add(positionedCell);

        final rowSpan = cell.rowSpan;
        assert(rowIndex + rowSpan <= rowCount,
            'Cell $rawColumnIndex in row $rowIndex has rowSpan=$rowSpan but table rowCount=$rowCount');

        final rowSpanCarry = rowSpan - 1;
        var count = cell.columnSpan;
        while (count-- > 0) {
          cellRow.add(positionedCell);
          rowSpanCarries.set(columnIndex, rowSpanCarry);

          columnIndex++;
        }
        rawColumnIndex++;
      }
      // Check for any previous rows' cells whose >1 rowSpan carries them into this row.
      // When found, add them to the current row, filling any gaps with null.
      while (columnIndex < rowSpanCarries.size) {
        if (rowSpanCarries[columnIndex] > 0) {
          cellRow.add(_cellTable[rowIndex - 1][columnIndex]);
          rowSpanCarries.set(columnIndex, rowSpanCarries[columnIndex] - 1);
        } else {
          cellRow.add(null);
        }
        columnIndex++;
      }
      rowIndex++;
    }
  }
  columnCount = rowSpanCarries.size;
  this.positionedCells = positionedCells;
  this._cellTable = _cellTable;
}