resolve static method
DiagramControlHandle?
resolve(
- List<
DiagramControlHandle> handles, - DiagramPoint screenPoint, {
- required DiagramPoint worldToScreen(
- 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;
}