One drag frame’s working state, for the overlay: the plan, the cursors
driving the working corners, and — for a waypoint drag — the grabbed
corner that gets its emphasis ring.
Seed positions for an edge drag’s two boundary waypoints, or None when the
edge can’t host them. Every waypoint a drag adds must sit at least one cell
from either route anchor (one on an anchor would overlap the pin), so an edge
end that lands on an anchor — a straight pin-to-pin segment — is pulled one
cell inward along the edge. A segment shorter than three cells leaves no room
for two such waypoints and is not editable. An interior edge’s ends are
existing corners, already clear of the anchors, and are used unchanged.
Whether pos sits at least one cell from both anchors — the invariant every
waypoint added during a drag must satisfy (a closer one would overlap a pin).
Draw a drag frame: the edited route in Editing mode (halo, no stored
decorations — the document’s corner set is stale mid-drag), then the
working state on top: the session’s hypothetical handles, the text
anchors on the previewed geometry, each label pinned at its captured
drag-start anchor, and the drag’s own emphasis (the projected segment
for an edge drag, the grabbed-corner ring for a waypoint drag). Before
the first Dragging frame there is no session and the stored set is
still current, so the route draws as plain Selected instead.
Classify where pos lands on route id and return the matching lazy drag
state — reading only, staging no document mutation. The edit plan is built
on the drag’s first Dragging frame (see EditRoute::widget), after the
select→drag tool switch has re-routed the wire.
Priority: waypoint → corner → edge center.