getNextCoordinateInCellsBlock method

IntVector2 getNextCoordinateInCellsBlock({
  1. required IntVector2 originalCoordinate,
  2. required AxisDirection direction,
})

Given a IntVector2 and a AxisDirection return the next coordinate in the current block of cells.

If the first neighbour cell has value, it traverses the cells until it finds an empty cell and returns the previous coordinate (the last with value).

If the first neighbour cell does not have value, it traverses the cells until it fiends a cell with value and return the previous coordinate (the last empty).

Implementation

IntVector2 getNextCoordinateInCellsBlock({
  required IntVector2 originalCoordinate,
  required AxisDirection direction,
}) {
  final axis = axisDirectionToAxis(direction);
  var previousCoordinate = originalCoordinate;
  var currentCoordinate = originalCoordinate + _moveVectors[direction]!;
  final headerController =
      parent.tableDataController.getHeaderControllerFor(axis: axis);
  final limit = headerController.value.totalCount - 1;

  final isFirstNeighbourCellFilled =
      _cellMatrix[currentCoordinate]?.hasVisibleContent == true;

  /// Conditions to stop iterating and finding the next cell.
  ///
  /// - if the previous coordinate and new coordinate are the same
  /// (it probably means we reached a edge of the grid).
  /// - If the first neighbour cell was filled, then we'll keep iterating
  /// while we find filled cells.
  /// - If the first neighbour cell was not filled, then we'll keep iterating
  /// while we find empty cells.
  bool shouldContinueLookup(IntVector2 prev, IntVector2 curr) {
    if (prev == curr) {
      return false;
    }

    // Check if the current cell is hidden, if so, skip it.
    final value = axis == Axis.vertical ? curr.dy : curr.dx;
    final headerData = headerController.value.customSizedHeaders[value];
    if (headerData?.hidden == true) {
      return true;
    }

    final hasValue = _cellMatrix[curr]?.hasVisibleContent == true;
    return isFirstNeighbourCellFilled ? hasValue : !hasValue;
  }

  // Iteratively move the current coordinate until [shouldContinueLookup]
  // finds the last coordinate in the current block.
  do {
    previousCoordinate = currentCoordinate;
    currentCoordinate += _moveVectors[direction]!;
    currentCoordinate = IntVector2(
      axis == Axis.horizontal
          ? max(0, min(currentCoordinate.dx, limit))
          : currentCoordinate.dx,
      axis == Axis.vertical
          ? max(0, min(currentCoordinate.dy, limit))
          : currentCoordinate.dy,
    );
  } while (shouldContinueLookup(previousCoordinate, currentCoordinate));

  final currentCellIsEmpty =
      _cellMatrix[currentCoordinate]?.hasNoVisibleContent == true;

  return (isFirstNeighbourCellFilled || currentCellIsEmpty)
      ? previousCoordinate
      : currentCoordinate;
}