getSelectionGeometry method Null safety

  1. @protected
SelectionGeometry getSelectionGeometry()

Gets the combined selection geometry for child selectables.

Implementation

@protected
SelectionGeometry getSelectionGeometry() {
  if (currentSelectionEndIndex == -1 ||
      currentSelectionStartIndex == -1 ||
      selectables.isEmpty) {
    // There is no valid selection.
    return SelectionGeometry(
      status: SelectionStatus.none,
      hasContent: selectables.isNotEmpty,
    );
  }

  currentSelectionStartIndex = _adjustSelectionIndexBasedOnSelectionGeometry(
    currentSelectionStartIndex,
    currentSelectionEndIndex,
  );
  currentSelectionEndIndex = _adjustSelectionIndexBasedOnSelectionGeometry(
    currentSelectionEndIndex,
    currentSelectionStartIndex,
  );

  // Need to find the non-null start selection point.
  SelectionGeometry startGeometry = selectables[currentSelectionStartIndex].value;
  final bool forwardSelection = currentSelectionEndIndex >= currentSelectionStartIndex;
  int startIndexWalker = currentSelectionStartIndex;
  while (startIndexWalker != currentSelectionEndIndex && startGeometry.startSelectionPoint == null) {
    startIndexWalker += forwardSelection ? 1 : -1;
    startGeometry = selectables[startIndexWalker].value;
  }

  SelectionPoint? startPoint;
  if (startGeometry.startSelectionPoint != null) {
    final Matrix4 startTransform =  getTransformFrom(selectables[startIndexWalker]);
    final Offset start = MatrixUtils.transformPoint(startTransform, startGeometry.startSelectionPoint!.localPosition);
    // It can be NaN if it is detached or off-screen.
    if (start.isFinite) {
      startPoint = SelectionPoint(
        localPosition: start,
        lineHeight: startGeometry.startSelectionPoint!.lineHeight,
        handleType: startGeometry.startSelectionPoint!.handleType,
      );
    }
  }

  // Need to find the non-null end selection point.
  SelectionGeometry endGeometry = selectables[currentSelectionEndIndex].value;
  int endIndexWalker = currentSelectionEndIndex;
  while (endIndexWalker != currentSelectionStartIndex && endGeometry.endSelectionPoint == null) {
    endIndexWalker += forwardSelection ? -1 : 1;
    endGeometry = selectables[endIndexWalker].value;
  }
  SelectionPoint? endPoint;
  if (endGeometry.endSelectionPoint != null) {
    final Matrix4 endTransform =  getTransformFrom(selectables[endIndexWalker]);
    final Offset end = MatrixUtils.transformPoint(endTransform, endGeometry.endSelectionPoint!.localPosition);
    // It can be NaN if it is detached or off-screen.
    if (end.isFinite) {
      endPoint = SelectionPoint(
        localPosition: end,
        lineHeight: endGeometry.endSelectionPoint!.lineHeight,
        handleType: endGeometry.endSelectionPoint!.handleType,
      );
    }
  }

  return SelectionGeometry(
    startSelectionPoint: startPoint,
    endSelectionPoint: endPoint,
    status: startGeometry != endGeometry
      ? SelectionStatus.uncollapsed
      : startGeometry.status,
    // Would have at least one selectable child.
    hasContent: true,
  );
}