feat(editor): edge selection + properties-panel edge-info + canvas-wide deselect
Three flow-editor UX upgrades:
1. Wider deselect zone. A new translucent
Positioned.fill GestureDetector wraps the outermost
Stack (above the InteractiveViewer). Tapping the dark
area outside the canvas grid — which used to do
nothing — now closes the properties panel.
2. Edge selection. Click a wire → controller.selectEdge
stamps the edge key. Click again or click background →
deselects. Selection is mutually exclusive with step
selection, enforced inside the controller so the panel
never tries to render both. Selected edges highlight
with the same accent the hover state uses.
3. Properties panel grows an edge-info mode. When an
edge is selected, the panel shows:
- source qualified name (e.g. inputs.document or
summarize.response)
- target qualified name
- type colour swatch + name per endpoint (LabVIEW
palette)
- type-compatibility pill (green / red)
- Disconnect button that removes the edge in one click
l10n: 8 new edgeInfo* strings in EN + DE.
Editor tests still pass (20).
Signed-off-by: flemming-it <sf@flemming.it>
This commit is contained in:
parent
1e9968496e
commit
59aa8fe78e
5 changed files with 369 additions and 2 deletions
|
|
@ -429,6 +429,26 @@ class _FlowCanvasState extends State<FlowCanvas>
|
|||
: BoxDecoration(color: theme.colorScheme.surface),
|
||||
child: Stack(
|
||||
children: [
|
||||
// Outer-most tap layer — catches clicks on the
|
||||
// dark area OUTSIDE the canvas grid (when the
|
||||
// operator has panned / zoomed so the grid
|
||||
// doesn't fill the viewport). Translucent so
|
||||
// InteractiveViewer below still handles pan +
|
||||
// zoom; the gesture arena gives the tap to
|
||||
// whichever child claims it first, and on
|
||||
// canvas-empty pointers nobody else does.
|
||||
Positioned.fill(
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onTap: () {
|
||||
// Deselect both step + edge so the
|
||||
// properties panel closes when the operator
|
||||
// clicks the empty backdrop.
|
||||
widget.controller.selectStep(null);
|
||||
widget.controller.selectEdge(null);
|
||||
},
|
||||
),
|
||||
),
|
||||
InteractiveViewer(
|
||||
transformationController: _transform,
|
||||
constrained: false,
|
||||
|
|
@ -489,7 +509,18 @@ class _FlowCanvasState extends State<FlowCanvas>
|
|||
layout,
|
||||
);
|
||||
if (edge == null) {
|
||||
// Empty canvas tap → close
|
||||
// properties panel (both step + edge
|
||||
// selections clear).
|
||||
widget.controller.selectStep(null);
|
||||
widget.controller.selectEdge(null);
|
||||
} else {
|
||||
// Tap on a wire → select that edge so
|
||||
// the properties panel shows its
|
||||
// source/target + type compatibility.
|
||||
// Mutually exclusive with step
|
||||
// selection inside the controller.
|
||||
widget.controller.selectEdge(edge);
|
||||
}
|
||||
},
|
||||
onSecondaryTapDown: (details) {
|
||||
|
|
@ -1066,6 +1097,7 @@ class _FlowCanvasState extends State<FlowCanvas>
|
|||
final edgeKey = '${edge.toId}:${edge.toField}';
|
||||
final highlight =
|
||||
_hoveredEdge == edgeKey ||
|
||||
widget.controller.selectedEdgeKey == edgeKey ||
|
||||
edge.fromId == widget.controller.selectedStepId ||
|
||||
edge.toId == widget.controller.selectedStepId;
|
||||
// Type-aware wire colours at both endpoints. Inputs-
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue