feat(editor): five distinct type colours + wired/total badge in step header
Two operator-visible improvements:
- Five payload types now get five distinct hues that
survive both light and dark themes:
text → blue (0xFF42A5F5)
bytes → deep orange (0xFFFF7043)
json → purple (0xFFAB47BC)
file → green (0xFF66BB6A)
number → amber (0xFFFFCA28)
Previously bytes + file shared a colour and the palette
collapsed under custom theme plugins. Hardcoded hues
keep them readable everywhere.
- Step headers now carry a small "wired/total" badge.
When all with-fields carry a `$src.field` reference,
the badge collapses to a green check icon — the visual
"this module is fully wired" signal Stefan asked for.
Partial-wiring shows e.g. "3/5" in a pill matching the
step accent. Endpoint nodes don't render the badge
(ratio doesn't apply there).
Computed live from graph.edges + step.with_ values, so the
indicator updates the moment an operator drags a
connection in or out.
Version 0.5.0 -> 0.5.1.
Signed-off-by: flemming-it <sf@flemming.it>
This commit is contained in:
parent
099cd182b9
commit
e4e2d45374
3 changed files with 70 additions and 10 deletions
|
|
@ -117,6 +117,14 @@ class FlowNode extends StatelessWidget {
|
|||
/// "must wire" and this is empty.
|
||||
final Set<String> optionalLabels;
|
||||
|
||||
/// How many of [inputPortLabels] are currently wired to an
|
||||
/// upstream source. When equal to the total count, the
|
||||
/// header paints a "complete" check mark; otherwise it
|
||||
/// renders the ratio (e.g. "3/5") so the operator sees
|
||||
/// at a glance what's still to wire. Set to null on
|
||||
/// endpoint nodes where the ratio doesn't apply.
|
||||
final int? wiredCount;
|
||||
|
||||
/// Right-click handler on the node body. Canvas wires this
|
||||
/// to a popup menu at the cursor position (Duplicate /
|
||||
/// Delete / Disconnect inputs etc.).
|
||||
|
|
@ -136,6 +144,7 @@ class FlowNode extends StatelessWidget {
|
|||
this.kind = NodeVisualKind.module,
|
||||
this.portSide = NodePortSide.left,
|
||||
this.optionalLabels = const {},
|
||||
this.wiredCount,
|
||||
this.selected = false,
|
||||
this.status = FlowNodeStatus.idle,
|
||||
this.onTap,
|
||||
|
|
@ -224,7 +233,12 @@ class FlowNode extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
if (status != FlowNodeStatus.idle) _statusDot(theme),
|
||||
if (wiredCount != null && inputPortLabels.isNotEmpty)
|
||||
_wiredBadge(theme, accent),
|
||||
if (status != FlowNodeStatus.idle) ...[
|
||||
const SizedBox(width: 4),
|
||||
_statusDot(theme),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -313,6 +327,38 @@ class FlowNode extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
Widget _wiredBadge(ThemeData theme, Color accent) {
|
||||
final total = inputPortLabels.length;
|
||||
final wired = wiredCount ?? 0;
|
||||
final complete = wired >= total && total > 0;
|
||||
if (complete) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 4),
|
||||
child: Icon(Icons.check_circle, size: 14, color: Colors.green.shade400),
|
||||
);
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 4),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 1),
|
||||
decoration: BoxDecoration(
|
||||
color: accent.withValues(alpha: 0.12),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: accent.withValues(alpha: 0.4)),
|
||||
),
|
||||
child: Text(
|
||||
'$wired/$total',
|
||||
style: theme.textTheme.labelSmall?.copyWith(
|
||||
fontFamily: 'monospace',
|
||||
fontSize: 9,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: accent,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _statusDot(ThemeData theme) {
|
||||
final color = switch (status) {
|
||||
FlowNodeStatus.running => theme.colorScheme.primary,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue