getEndpointsForSelection method

  1. @override
List<TextSelectionPoint> getEndpointsForSelection(
  1. TextSelection selection
)
override

Returns the local coordinates of the endpoints of the given selection.

If the selection is collapsed (and therefore occupies a single point), the returned list is of length one. Otherwise, the selection is not collapsed and the returned list is of length two. In this case, however, the two points might actually be co-located (e.g., because of a bidirectional selection that contains some text but whose ends meet in the middle).

Implementation

@override
List<TextSelectionPoint> getEndpointsForSelection(TextSelection selection) {
  // _layoutText(minWidth: constraints.minWidth, maxWidth: constraints.maxWidth);

  if (selection.isCollapsed) {
    final child = childAtPosition(selection.extent);
    final localPosition =
        TextPosition(offset: selection.extentOffset - child.node.offset);
    final localOffset = child.getOffsetForCaret(localPosition);
    final parentData = child.parentData as BoxParentData;
    final start = Offset(0.0, child.preferredLineHeight(localPosition)) +
        localOffset +
        parentData.offset;
    return <TextSelectionPoint>[TextSelectionPoint(start, null)];
  } else {
    final baseNode = node.lookup(selection.start).node;

    var baseChild = firstChild;
    while (baseChild != null) {
      if (baseChild.node == baseNode) {
        break;
      }
      baseChild = childAfter(baseChild);
    }
    assert(baseChild != null);

    final baseParentData = baseChild!.parentData as BoxParentData;
    final baseSelection =
        localSelection(baseChild.node, selection, fromParent: true);
    var basePoint = baseChild.getBaseEndpointForSelection(baseSelection);
    basePoint = TextSelectionPoint(
        basePoint.point + baseParentData.offset, basePoint.direction);

    final extentNode = node.lookup(selection.end).node;
    RenderEditableBox? extentChild = baseChild;
    while (extentChild != null) {
      if (extentChild.node == extentNode) {
        break;
      }
      extentChild = childAfter(extentChild);
    }
    assert(extentChild != null);

    final extentParentData = extentChild!.parentData as BoxParentData;
    final extentSelection =
        localSelection(extentChild.node, selection, fromParent: true);
    var extentPoint =
        extentChild.getExtentEndpointForSelection(extentSelection);
    extentPoint = TextSelectionPoint(
        extentPoint.point + extentParentData.offset, extentPoint.direction);

    return <TextSelectionPoint>[basePoint, extentPoint];
  }
}