On the swarm canvas (ClientScreen), connection lines between nodes were
display-only. The only way to remove a wiring edge was to open the downstream
node’s editor → Sources tab → tap the “✕” next to a source. Ben asked for the
connecting lines themselves to be clickable so a user can delete a connection
directly from the graph while in the swarm screens.
Not a bug — a missing affordance. The arcs are painted on full-canvas Canvas
layers (DrawTargetingArcs / DrawInputArcs) that sit below the node
composables and carry no pointerInput, so taps fell through them. Nodes
are separate composables drawn on top, so the lines were never “enclosed” in
node bounds — they just had no hit-testing.
Added connection-line selection + deletion, gated behind the existing canvas
editMode:
ConnectionHitTest.kt (new, commonMain): pure, Compose-free geometry —
arcGeometry() reconstructs the exact quadratic bezier the renderer draws
(same NODE_SIZE_DP/2 inset, 0.3·distance perpendicular control, SOURCE
bows +90° / INPUT -90°) in layout space; distanceToArc()/hitTestArc()
sample the curve; findConnectionAt() resolves the nearest source/input arc
to a tap and returns a SelectedConnection(observerId, removedId, kind).ConnectNodesWiring.kt: added ConnectionKind + disconnect() — the inverse
of the existing applyConnect(). Removes the edge from the observer node
(the TargetingConnection.targetId, which owns the wiring) via the same
withWiring/withInputs write path the Sources tab uses, then
ClientNodeManager.submit() persists it (identical to ConnectNodesWizard).ClientScreen.kt: the existing container detectTapGestures now, in edit
mode, inverts the graphicsLayer transform ((tap − center − pan) / scale)
to layout space and hit-tests; a hit sets a local selectedConnection. A new
ConnectionDeleteOverlay (inside the pan/zoom box, drawn last) highlights the
arc in colorScheme.error and floats a circular delete button at its
midpoint. No server/shared/model change — same mutation the editor already
performs.arcGeometry() is the shared helper both should use; if the draw
formulas in drawTargetingArc/drawInputArc ever change, change
arcGeometry() in lockstep (a comment in each points at the other).ConnectionHitTestTest covers
geometry, resolution, and disconnect() over Offset/fixture metadata — no
Compose host, no platform expect-vals — so the math regresses loudly.api.foojay.io (the Oracle JDK 21 daemon toolchain) and maven.google.com
(the Android Gradle Plugin), with a cold Gradle cache. The new logic was kept
pure + unit-tested so CI (which has the provisioned toolchain) compiles and
runs it; reviewers should rely on CI + the manual UI check below.