chain-studio-flow-editor/lib/src/widgets
flemming-it c15731fb1b fix(editor): inputs/outputs in layout sidecar — endpoints stop drifting
The 0.2.x canvas auto-recomputed the outputs endpoint's X
position from `max(step.x) + nodeWidth + 120` every build.
Dragging any step rebuilt the layout, the recompute kicked
in, and the outputs panel + every edge entering it
shifted across the screen. Mirror image: the inputs panel
was nailed to a hardcoded (40, 80) but the right side of
the world moved every time the operator touched a node.
Visually catastrophic; Stefan flagged it as the same kind
of "everything moves when I touch one thing" failure that
shelved the jai_client editor.

Structural fix: treat inputs and outputs as first-class
nodes with positions stored in the same layout sidecar as
every step. There is no more auto-recompute path.

Concretely:

  - AutoLayout.layout now seeds NodePositions for the
    reserved IDs `__inputs__` (column −1) and `__outputs__`
    (column max+1) on first open. Existing positions are
    never overwritten so subsequent layout passes don't
    fight operator-chosen placements.

  - FlowCanvas reads inputs/outputs positions from
    layout.positions instead of hardcoded `_inputsX` /
    `_inputsY` constants and the computed `_outputsX(...)`.
    Both functions are deleted; the canvas now has one
    single source of truth for ALL node positions, the
    sidecar.

  - The inputs / outputs endpoints render via a new
    `_endpointPositioned` helper that mirrors
    `_stepPositioned` — same FlowNode widget, same
    drag handler, same `controller.moveStep` path. The
    operator can grab the inputs panel and slide it
    wherever; the position persists to the sidecar like
    every step.

  - All port-position helpers (`_outputPortPosition`,
    `_inputPortPosition`, the inputs-endpoint port
    position) now take a single `FlowLayout` and read
    coordinates from there. No more `double outputsX`
    parameter threaded through every method.

  - Fit-to-content now expands the bounding box using the
    endpoints' SIDECAR positions rather than a re-derived
    outputs X. Same single source of truth.

Side-benefit: the editor's coordinate model is now strictly
sidecar-driven. No state derivation lives in render code.
This rules out the catastrophic "drag-mid-flight-redoes-
coordinate-transforms" failure mode jai_client hit (where
internal offsets grew during a drag and broke port
positions).

flutter analyze clean, 12/12 tests pass.

Signed-off-by: flemming-it <sf@flemming.it>
2026-06-01 16:12:15 +02:00
..
capability_picker.dart feat(editor): three-tab WYSIWYG editor — graph / text / run 2026-06-01 00:48:35 +02:00
edge_painter.dart feat(editor): three-tab WYSIWYG editor — graph / text / run 2026-06-01 00:48:35 +02:00
flow_canvas.dart fix(editor): inputs/outputs in layout sidecar — endpoints stop drifting 2026-06-01 16:12:15 +02:00
flow_node.dart feat(editor): three-tab WYSIWYG editor — graph / text / run 2026-06-01 00:48:35 +02:00
properties_panel.dart feat(editor): three-tab WYSIWYG editor — graph / text / run 2026-06-01 00:48:35 +02:00
run_tab.dart feat(editor): live step status on the graph during runs 2026-06-01 01:47:30 +02:00