resolve static method

DiagramControlHandle? resolve(
  1. List<DiagramControlHandle> handles,
  2. DiagramPoint screenPoint, {
  3. required DiagramPoint worldToScreen(
    1. DiagramPoint world
    ),
})

The handle under screenPoint, or null.

Point targets win over side bands. Among point targets, corners win over rotation, rotation over side resize, and the nearest wins a tie. Corners own their full square; side bands stop short of every corner target.

Implementation

static DiagramControlHandle? resolve(
  List<DiagramControlHandle> handles,
  DiagramPoint screenPoint, {
  required DiagramPoint Function(DiagramPoint world) worldToScreen,
}) {
  DiagramControlHandle? best;
  var bestPriority = 0;
  var bestDistance = 0.0;
  for (final handle in handles) {
    if (!_insidePointZone(screenPoint, handle, handles, worldToScreen)) {
      continue;
    }
    final priority = _priority(handle);
    final distance =
        (screenPoint - worldToScreen(handle.worldPosition)).magnitude;
    if (best == null ||
        priority < bestPriority ||
        (priority == bestPriority && distance < bestDistance)) {
      best = handle;
      bestPriority = priority;
      bestDistance = distance;
    }
  }
  if (best != null) return best;
  for (final handle in handles.reversed) {
    final start = handle.worldSegmentStart;
    final end = handle.worldSegmentEnd;
    if (handle.kind != DiagramControlHandleKind.resize ||
        start == null ||
        end == null) {
      continue;
    }
    final screenStart = worldToScreen(start);
    final screenEnd = worldToScreen(end);
    // Side bands are deliberately shortened by the complete corner target.
    // This makes the hit regions disjoint instead of merely relying on hit
    // order when both a side and a corner could claim the pointer.
    if ((screenPoint - screenStart).magnitude <=
            DiagramSelectionChromeProjection.handleHitRadius ||
        (screenPoint - screenEnd).magnitude <=
            DiagramSelectionChromeProjection.handleHitRadius) {
      continue;
    }
    if (segmentDistance(screenPoint, screenStart, screenEnd) <=
        sideBandTolerance) {
      return handle;
    }
  }
  return null;
}