Skip to content

Commit f789537

Browse files
committed
feat: restructure library and improve maintainability, modularize and reorganize editor package structure, extract graph events and extensions
feat: remove `AnnotationTheme` and related utilities, simplify theming by consolidating into `NodeTheme` feat: remove `ShortcutsViewerDialog` and related utilities in favor of simplified, customizable implementation in examples
1 parent a84515d commit f789537

File tree

159 files changed

+748
-1268
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

159 files changed

+748
-1268
lines changed

packages/demo/lib/examples/advanced/shortcuts.dart

Lines changed: 179 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,13 @@ class _ShortcutsExampleState extends State<ShortcutsExample> {
9191
}
9292

9393
void _showShortcutsDialog() {
94+
final shortcuts = _controller.shortcuts.keyMap;
95+
final actions = _controller.shortcuts.actions;
96+
9497
showDialog(
9598
context: context,
96-
builder: (context) => ShortcutsViewerDialog(
97-
shortcuts: _controller.shortcuts.shortcuts,
98-
actions: _controller.shortcuts.actions,
99-
),
99+
builder: (context) =>
100+
_SimpleShortcutsDialog(shortcuts: shortcuts, actions: actions),
100101
);
101102
}
102103

@@ -389,3 +390,177 @@ class _CustomExportAction extends NodeFlowAction<Map<String, dynamic>> {
389390
return true;
390391
}
391392
}
393+
394+
/// A simple shortcuts dialog built by the demo.
395+
///
396+
/// This demonstrates how external code can build its own shortcuts UI
397+
/// using the data from controller.shortcuts.keyMap and controller.shortcuts.actions.
398+
class _SimpleShortcutsDialog extends StatelessWidget {
399+
const _SimpleShortcutsDialog({
400+
required this.shortcuts,
401+
required this.actions,
402+
});
403+
404+
final Map<LogicalKeySet, String> shortcuts;
405+
final Map<String, NodeFlowAction> actions;
406+
407+
@override
408+
Widget build(BuildContext context) {
409+
final theme = Theme.of(context);
410+
411+
// Group shortcuts by category
412+
final categorized = <String, List<MapEntry<LogicalKeySet, String>>>{};
413+
for (final entry in shortcuts.entries) {
414+
final action = actions[entry.value];
415+
final category = action?.category ?? 'General';
416+
categorized.putIfAbsent(category, () => []).add(entry);
417+
}
418+
419+
return Dialog(
420+
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
421+
child: Container(
422+
width: 500,
423+
constraints: BoxConstraints(
424+
maxHeight: MediaQuery.of(context).size.height * 0.7,
425+
),
426+
padding: const EdgeInsets.all(24),
427+
child: Column(
428+
mainAxisSize: MainAxisSize.min,
429+
crossAxisAlignment: CrossAxisAlignment.start,
430+
children: [
431+
Row(
432+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
433+
children: [
434+
Text(
435+
'Keyboard Shortcuts',
436+
style: theme.textTheme.headlineSmall?.copyWith(
437+
fontWeight: FontWeight.bold,
438+
),
439+
),
440+
IconButton(
441+
icon: const Icon(Icons.close),
442+
onPressed: () => Navigator.of(context).pop(),
443+
),
444+
],
445+
),
446+
const SizedBox(height: 16),
447+
Flexible(
448+
child: ListView(
449+
shrinkWrap: true,
450+
children: [
451+
for (final category in categorized.keys) ...[
452+
Container(
453+
padding: const EdgeInsets.symmetric(
454+
horizontal: 8,
455+
vertical: 4,
456+
),
457+
decoration: BoxDecoration(
458+
color: theme.colorScheme.primaryContainer.withValues(
459+
alpha: 0.3,
460+
),
461+
borderRadius: BorderRadius.circular(4),
462+
),
463+
child: Text(
464+
category.toUpperCase(),
465+
style: theme.textTheme.labelSmall?.copyWith(
466+
fontWeight: FontWeight.bold,
467+
color: theme.colorScheme.primary,
468+
),
469+
),
470+
),
471+
const SizedBox(height: 8),
472+
for (final entry in categorized[category]!)
473+
Padding(
474+
padding: const EdgeInsets.only(bottom: 8, left: 8),
475+
child: Row(
476+
children: [
477+
SizedBox(
478+
width: 150,
479+
child: Text(
480+
_formatKeySet(entry.key),
481+
style: theme.textTheme.bodySmall?.copyWith(
482+
fontFamily: 'monospace',
483+
fontWeight: FontWeight.w500,
484+
),
485+
),
486+
),
487+
Expanded(
488+
child: Text(
489+
actions[entry.value]?.label ?? entry.value,
490+
style: theme.textTheme.bodySmall,
491+
),
492+
),
493+
],
494+
),
495+
),
496+
const SizedBox(height: 12),
497+
],
498+
],
499+
),
500+
),
501+
],
502+
),
503+
),
504+
);
505+
}
506+
507+
String _formatKeySet(LogicalKeySet keySet) {
508+
final keys = keySet.keys.toList();
509+
// Sort modifiers first
510+
keys.sort((a, b) {
511+
final aIsModifier = _isModifier(a);
512+
final bIsModifier = _isModifier(b);
513+
if (aIsModifier && !bIsModifier) return -1;
514+
if (!aIsModifier && bIsModifier) return 1;
515+
return 0;
516+
});
517+
return keys.map(_keyLabel).join(' + ');
518+
}
519+
520+
bool _isModifier(LogicalKeyboardKey key) {
521+
return key == LogicalKeyboardKey.meta ||
522+
key == LogicalKeyboardKey.metaLeft ||
523+
key == LogicalKeyboardKey.metaRight ||
524+
key == LogicalKeyboardKey.control ||
525+
key == LogicalKeyboardKey.controlLeft ||
526+
key == LogicalKeyboardKey.controlRight ||
527+
key == LogicalKeyboardKey.shift ||
528+
key == LogicalKeyboardKey.shiftLeft ||
529+
key == LogicalKeyboardKey.shiftRight ||
530+
key == LogicalKeyboardKey.alt ||
531+
key == LogicalKeyboardKey.altLeft ||
532+
key == LogicalKeyboardKey.altRight;
533+
}
534+
535+
String _keyLabel(LogicalKeyboardKey key) {
536+
if (key == LogicalKeyboardKey.meta ||
537+
key == LogicalKeyboardKey.metaLeft ||
538+
key == LogicalKeyboardKey.metaRight) {
539+
return '⌘';
540+
}
541+
if (key == LogicalKeyboardKey.control ||
542+
key == LogicalKeyboardKey.controlLeft ||
543+
key == LogicalKeyboardKey.controlRight) {
544+
return 'Ctrl';
545+
}
546+
if (key == LogicalKeyboardKey.shift ||
547+
key == LogicalKeyboardKey.shiftLeft ||
548+
key == LogicalKeyboardKey.shiftRight) {
549+
return '⇧';
550+
}
551+
if (key == LogicalKeyboardKey.alt ||
552+
key == LogicalKeyboardKey.altLeft ||
553+
key == LogicalKeyboardKey.altRight) {
554+
return '⌥';
555+
}
556+
if (key == LogicalKeyboardKey.arrowUp) return '↑';
557+
if (key == LogicalKeyboardKey.arrowDown) return '↓';
558+
if (key == LogicalKeyboardKey.arrowLeft) return '←';
559+
if (key == LogicalKeyboardKey.arrowRight) return '→';
560+
if (key == LogicalKeyboardKey.escape) return 'Esc';
561+
if (key == LogicalKeyboardKey.delete) return 'Del';
562+
if (key == LogicalKeyboardKey.backspace) return '⌫';
563+
if (key.keyLabel.length == 1) return key.keyLabel.toUpperCase();
564+
return key.keyLabel;
565+
}
566+
}

packages/demo/lib/examples/advanced/workbench.dart

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -394,13 +394,6 @@ class _WorkbenchExampleState extends State<WorkbenchExample> {
394394
),
395395
]),
396396
_buildGridSection('UI Tools', [
397-
GridButton(
398-
label: 'Shortcuts',
399-
icon: Icons.keyboard,
400-
onPressed: () {
401-
_controller.showShortcutsDialog(context);
402-
},
403-
),
404397
GridButton(
405398
label: 'Toggle Minimap',
406399
icon: Icons.map,

packages/vyuh_node_flow/CHANGELOG.md

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,131 @@
11
## 0.16.0
22

3-
- Added the GraphPosition to the connection end callback
3+
- Added the GraphPosition to the connection end callback
44

5-
- **FIX**: replace `setEvents` with `internalUpdateEvents` across tests for consistency.
5+
- **FIX**: replace `setEvents` with `updateEvents` across tests for consistency.
66

77
## 0.15.1
88

9-
- **REFACTOR**: replace static `fromJsonMap` methods with unified factory constructors and improve `CommentNode` color observability.
10-
- **REFACTOR**: remove unused imports and redundant test node creation in controller_init_test.
11-
- **FEAT**: add EditorInitApi for unified initialization, improve spatial index diagnostics, and update render layer prioritization.
9+
- **REFACTOR**: replace static `fromJsonMap` methods with unified factory
10+
constructors and improve `CommentNode` color observability.
11+
- **REFACTOR**: remove unused imports and redundant test node creation in
12+
controller_init_test.
13+
- **FEAT**: add EditorInitApi for unified initialization, improve spatial index
14+
diagnostics, and update render layer prioritization.
1215

1316
## 0.15.0
1417

15-
- **FEAT**: refactor test factory and add unit tests for constructor initialization.
18+
- **FEAT**: refactor test factory and add unit tests for constructor
19+
initialization.
1620

1721
## 0.14.1
1822

19-
- **FEAT**: simplify drag operations across nodes, connections and resizers.
20-
- **FEAT**: refactor context menu callbacks to use `ScreenPosition`, enhance port interaction APIs, and simplify node constructor parameters.
23+
- **FEAT**: simplify drag operations across nodes, connections and resizers.
24+
- **FEAT**: refactor context menu callbacks to use `ScreenPosition`, enhance
25+
port interaction APIs, and simplify node constructor parameters.
2126

2227
## 0.14.0
2328

24-
- **FEAT**: unify Nodes and Annotations.
29+
- **FEAT**: unify Nodes and Annotations.
2530

2631
## 0.13.3
2732

28-
- **FEAT**: remove debug logs, simplify null checks in viewport animation, and add lifecycle unit tests for animation handlers.
33+
- **FEAT**: remove debug logs, simplify null checks in viewport animation, and
34+
add lifecycle unit tests for animation handlers.
2935

3036
## 0.13.2
3137

32-
- **FEAT**: streamline port retrieval across nodes and improve viewport animation handling with token-based race condition prevention.
38+
- **FEAT**: streamline port retrieval across nodes and improve viewport
39+
animation handling with token-based race condition prevention.
3340

3441
## 0.13.1
3542

36-
- **FEAT**: initial set of tests for API, nodes, ports, graph, annotations, connections, rendering and performance.
43+
- **FEAT**: initial set of tests for API, nodes, ports, graph, annotations,
44+
connections, rendering and performance.
3745

3846
## 0.13.0
3947

40-
- **FEAT**: enhance AutoPan and Viewport Animations, add debug mode with overlays for better visualization, and integrate configurable AutoPan presets. `debugMode` is now moved into `NodeFlowConfig`.
48+
- **FEAT**: enhance AutoPan and Viewport Animations, add debug mode with
49+
overlays for better visualization, and integrate configurable AutoPan presets.
50+
`debugMode` is now moved into `NodeFlowConfig`.
4151

4252
## 0.12.0
4353

44-
- **FEAT**: introducing Auto-Pan behavior which allows the elements (nodes, annotations, connections) to move freely and go past the edges, while keeping the viewport panning in place. It also does some interesting calculations for avoiding drift, so that the element stays relative to the mouse pointer. This is all implemented on the `ElementScope` with an `AutoPanMixin`.
54+
- **FEAT**: introducing Auto-Pan behavior which allows the elements (nodes,
55+
annotations, connections) to move freely and go past the edges, while keeping
56+
the viewport panning in place. It also does some interesting calculations for
57+
avoiding drift, so that the element stays relative to the mouse pointer. This
58+
is all implemented on the `ElementScope` with an `AutoPanMixin`.
4559

4660
## 0.11.0
4761

48-
- **FEAT**: add ViewportAnimationMixin for smooth viewport animations, integrate animation methods into NodeFlowController and NodeFlowEditor, and provide API for animating to nodes, positions, bounds, and zoom levels.
62+
- **FEAT**: add ViewportAnimationMixin for smooth viewport animations, integrate
63+
animation methods into NodeFlowController and NodeFlowEditor, and provide API
64+
for animating to nodes, positions, bounds, and zoom levels.
4965

5066
## 0.10.9
5167

52-
- **FEAT**: replace custom gesture implementation with ElementScope for streamlined gesture handling, lifecycle management, and drag state cleanup; enhance interaction robustness and trackpad compatibility.
68+
- **FEAT**: replace custom gesture implementation with ElementScope for
69+
streamlined gesture handling, lifecycle management, and drag state cleanup;
70+
enhance interaction robustness and trackpad compatibility.
5371

5472
## 0.10.8
5573

56-
- **FIX**: reset connection hit flag on pointer up to prevent interaction conflicts in subsequent actions, refine hit testing hierarchy and annotation handling for consistent z-order interaction, enhance drag/selection behaviors for annotations and nodes.
57-
- **FEAT**: centralize pan state management in NodeFlowEditor for consistent interaction handling during drag, resize, and connection operations, add escape key handling to cancel annotation edits and enhance focus behaviors, add annotation editing cancellation, keyboard shortcuts, and selection clearing enhancements.
58-
- **FEAT**: centralize pan state management in NodeFlowEditor for consistent interaction handling during drag, resize, and connection operations.
59-
- **FEAT**: add escape key handling to cancel annotation edits and enhance focus behaviors.
60-
- **FEAT**: add annotation editing cancellation, keyboard shortcuts, and selection clearing enhancements.
74+
- **FIX**: reset connection hit flag on pointer up to prevent interaction
75+
conflicts in subsequent actions, refine hit testing hierarchy and annotation
76+
handling for consistent z-order interaction, enhance drag/selection behaviors
77+
for annotations and nodes.
78+
- **FEAT**: centralize pan state management in NodeFlowEditor for consistent
79+
interaction handling during drag, resize, and connection operations, add
80+
escape key handling to cancel annotation edits and enhance focus behaviors,
81+
add annotation editing cancellation, keyboard shortcuts, and selection
82+
clearing enhancements.
83+
- **FEAT**: centralize pan state management in NodeFlowEditor for consistent
84+
interaction handling during drag, resize, and connection operations.
85+
- **FEAT**: add escape key handling to cancel annotation edits and enhance focus
86+
behaviors.
87+
- **FEAT**: add annotation editing cancellation, keyboard shortcuts, and
88+
selection clearing enhancements.
6189

6290
## 0.10.7
6391

64-
- **FEAT**: centralize pan state management in NodeFlowEditor for consistent interaction handling during drag, resize, and connection operations.
65-
- **FEAT**: add escape key handling to cancel annotation edits and enhance focus behaviors.
66-
- **FEAT**: add annotation editing cancellation, keyboard shortcuts, and selection clearing enhancements.
92+
- **FEAT**: centralize pan state management in NodeFlowEditor for consistent
93+
interaction handling during drag, resize, and connection operations.
94+
- **FEAT**: add escape key handling to cancel annotation edits and enhance focus
95+
behaviors.
96+
- **FEAT**: add annotation editing cancellation, keyboard shortcuts, and
97+
selection clearing enhancements.
6798

6899
## 0.10.6
69100

70-
- **FEAT**: implement inline editing for annotation titles, add keyboard shortcut for editing, and improve canvas focus handling.
71-
- **FEAT**: add editing state support for annotations and implement auto-grow for sticky notes.
101+
- **FEAT**: implement inline editing for annotation titles, add keyboard
102+
shortcut for editing, and improve canvas focus handling.
103+
- **FEAT**: add editing state support for annotations and implement auto-grow
104+
for sticky notes.
72105

73106
## 0.10.5
74107

75-
- **REFACTOR**: remove short-distance temporary line drawing logic for consistent connection styling.
76-
- **FEAT**: replace `ConnectionControlPointsLayer` with custom gesture recognition, improve touch and trackpad interaction handling across nodes, ports, and annotations.
108+
- **REFACTOR**: remove short-distance temporary line drawing logic for
109+
consistent connection styling.
110+
- **FEAT**: replace `ConnectionControlPointsLayer` with custom gesture
111+
recognition, improve touch and trackpad interaction handling across nodes,
112+
ports, and annotations.
77113

78114
## 0.10.4
79115

80-
- **FEAT**: add transformation listener for authoritative viewport syncing and improve interaction accuracy.
116+
- **FEAT**: add transformation listener for authoritative viewport syncing and
117+
improve interaction accuracy.
81118

82119
## 0.10.3
83120

84-
- **FEAT**: add selection mode tracking with cursor feedback and shift key interaction.
121+
- **FEAT**: add selection mode tracking with cursor feedback and shift key
122+
interaction.
85123

86124
## 0.10.2
87125

88-
- **FIX**: hit testing outside the bounds of resizer and group-annotation.
89-
- **FEAT**: introduce `coordinates.dart` to enforce type safety in coordinate transformations and refactor usage across the package.
126+
- **FIX**: hit testing outside the bounds of resizer and group-annotation.
127+
- **FEAT**: introduce `coordinates.dart` to enforce type safety in coordinate
128+
transformations and refactor usage across the package.
90129

91130
## 0.10.1
92131

0 commit comments

Comments
 (0)