Skip to content

Commit 0e8c3e4

Browse files
committed
fix: remove selection logic from selection_api.dart and consolidate it into connection_api.dart with expanded functionalities
1 parent a6bb02b commit 0e8c3e4

File tree

8 files changed

+3303
-2915
lines changed

8 files changed

+3303
-2915
lines changed

packages/vyuh_node_flow/README.md

Lines changed: 235 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,16 @@ minimap, and more.
5858
- [Connection Labels](#connection-labels)
5959
- [Annotations](#annotations)
6060
- [Built-in Annotation Types](#built-in-annotation-types)
61+
- [Group Annotations](#group-annotations)
6162
- [Custom Annotations](#custom-annotations)
6263
- [Following Nodes](#following-nodes)
64+
- [Visibility](#visibility)
65+
- [Node Visibility](#node-visibility)
66+
- [Annotation Visibility](#annotation-visibility)
6367
- [Interactive Features](#interactive-features)
6468
- [Event System](#event-system)
6569
- [Keyboard Shortcuts](#keyboard-shortcuts)
66-
- [Feature Toggles](#feature-toggles)
70+
- [Behavior Modes](#behavior-modes)
6771
- [Minimap](#minimap)
6872
- [Read-Only Viewer](#read-only-viewer)
6973
- [Serialization](#serialization)
@@ -303,6 +307,8 @@ NodeFlowTheme
303307
├── gridTheme → Grid background appearance
304308
├── selectionTheme → Selection rectangle styling
305309
├── cursorTheme → Mouse cursor styles
310+
├── minimapTheme → Minimap overlay appearance
311+
├── resizerTheme → Resize handle appearance
306312
├── backgroundColor → Canvas background color
307313
└── connectionAnimationDuration → Animation timing
308314
```
@@ -586,6 +592,103 @@ CursorTheme(
586592

587593
</details>
588594

595+
<details>
596+
<summary><strong>MinimapTheme - Minimap Overlay</strong></summary>
597+
598+
Controls the appearance and position of the minimap navigation widget.
599+
600+
```dart
601+
MinimapTheme(
602+
// Position and size
603+
position: MinimapPosition.bottomRight, // Corner placement
604+
margin: 20.0, // Distance from edge
605+
size: Size(200, 150), // Minimap dimensions
606+
607+
// Colors
608+
backgroundColor: Color(0xFFF5F5F5), // Container background
609+
nodeColor: Color(0xFF1976D2), // Node representation color
610+
viewportColor: Color(0xFF1976D2), // Viewport indicator color
611+
borderColor: Color(0xFFBDBDBD), // Container border color
612+
613+
// Viewport indicator
614+
showViewport: true, // Show visible area indicator
615+
viewportFillOpacity: 0.1, // Viewport fill transparency
616+
viewportBorderOpacity: 0.4, // Viewport border transparency
617+
618+
// Styling
619+
borderWidth: 1.0, // Container border width
620+
borderRadius: 4.0, // Container corner radius
621+
nodeBorderRadius: 2.0, // Node rectangle corner radius
622+
padding: EdgeInsets.all(4.0), // Internal padding
623+
)
624+
```
625+
626+
**Built-in presets:**
627+
628+
```dart
629+
// Light theme minimap (default)
630+
MinimapTheme.light
631+
632+
// Dark theme minimap
633+
MinimapTheme.dark
634+
635+
// Custom minimap matching your theme
636+
final customTheme = NodeFlowTheme.light.copyWith(
637+
minimapTheme: MinimapTheme.light.copyWith(
638+
position: MinimapPosition.topLeft,
639+
size: const Size(250, 180),
640+
nodeColor: Colors.purple,
641+
),
642+
);
643+
```
644+
645+
**Position options:**
646+
- `MinimapPosition.topLeft`
647+
- `MinimapPosition.topRight`
648+
- `MinimapPosition.bottomLeft`
649+
- `MinimapPosition.bottomRight` (default)
650+
651+
</details>
652+
653+
<details>
654+
<summary><strong>ResizerTheme - Resize Handles</strong></summary>
655+
656+
Controls the appearance of resize handles on resizable elements like group annotations.
657+
658+
```dart
659+
ResizerTheme(
660+
handleSize: 10.0, // Width and height of handles
661+
color: Colors.white, // Handle fill color
662+
borderColor: Colors.blue, // Handle border color
663+
borderWidth: 1.0, // Handle border thickness
664+
snapDistance: 4.0, // Extra hit area around handles
665+
)
666+
```
667+
668+
**Built-in presets:**
669+
670+
```dart
671+
// Light theme handles (white fill, blue border)
672+
ResizerTheme.light
673+
674+
// Dark theme handles (dark fill, light blue border)
675+
ResizerTheme.dark
676+
677+
// Custom resize handles
678+
final customTheme = NodeFlowTheme.light.copyWith(
679+
resizerTheme: ResizerTheme.light.copyWith(
680+
handleSize: 12.0,
681+
borderColor: Colors.purple,
682+
snapDistance: 6.0, // Larger hit area for touch devices
683+
),
684+
);
685+
```
686+
687+
> [!TIP] Increase `snapDistance` for touch-friendly interfaces. This makes
688+
> handles easier to grab without changing their visual size.
689+
690+
</details>
691+
589692
### Theming Cascade
590693

591694
Properties are resolved using a cascade from most specific to most general:
@@ -2201,6 +2304,137 @@ controller.addAnnotation(annotation);
22012304

22022305
</details>
22032306

2307+
### Group Annotations
2308+
2309+
Group annotations allow you to visually organize related nodes together. Groups
2310+
can be resized, styled, and configured with different behavior modes that
2311+
control how nodes interact with the group.
2312+
2313+
<details>
2314+
<summary><strong>Creating Group Annotations</strong></summary>
2315+
2316+
```dart
2317+
// Create a group at a specific position and size
2318+
controller.createGroupAnnotation(
2319+
title: 'Input Processing',
2320+
position: const Offset(50, 50),
2321+
size: const Size(400, 300),
2322+
color: Colors.blue.withOpacity(0.2),
2323+
);
2324+
2325+
// Create a group around existing nodes
2326+
controller.createGroupAnnotationAroundNodes(
2327+
title: 'Data Pipeline',
2328+
nodeIds: {'node-1', 'node-2', 'node-3'},
2329+
padding: const EdgeInsets.all(30),
2330+
color: Colors.green.withOpacity(0.2),
2331+
);
2332+
```
2333+
2334+
</details>
2335+
2336+
<details>
2337+
<summary><strong>Group Behavior Modes</strong></summary>
2338+
2339+
Groups support three behavior modes that control how nodes interact with the group:
2340+
2341+
| Mode | Membership | Size | Node Movement |
2342+
|------|------------|------|---------------|
2343+
| `bounds` | Spatial (nodes inside bounds) | Manual (resizable) | Nodes can escape by dragging out |
2344+
| `explicit` | Explicit (node ID set) | Auto-computed (fits members) | Group resizes to contain nodes |
2345+
| `parent` | Explicit (node ID set) | Manual (resizable) | Nodes move with group, can leave bounds |
2346+
2347+
```dart
2348+
// Bounds mode (default) - spatial containment
2349+
final boundsGroup = GroupAnnotation(
2350+
id: 'group-1',
2351+
title: 'Bounds Group',
2352+
position: const Offset(100, 100),
2353+
size: const Size(300, 200),
2354+
behavior: GroupBehavior.bounds, // Nodes inside move with group
2355+
);
2356+
2357+
// Explicit mode - auto-sizing group
2358+
final explicitGroup = GroupAnnotation(
2359+
id: 'group-2',
2360+
title: 'Explicit Group',
2361+
position: const Offset(100, 100),
2362+
size: const Size(300, 200),
2363+
behavior: GroupBehavior.explicit,
2364+
nodeIds: {'node-1', 'node-2'}, // Group auto-fits these nodes
2365+
);
2366+
2367+
// Parent mode - linked but flexible
2368+
final parentGroup = GroupAnnotation(
2369+
id: 'group-3',
2370+
title: 'Parent Group',
2371+
position: const Offset(100, 100),
2372+
size: const Size(300, 200),
2373+
behavior: GroupBehavior.parent,
2374+
nodeIds: {'node-1', 'node-2'}, // Nodes move with group but can leave bounds
2375+
);
2376+
2377+
controller.addAnnotation(boundsGroup);
2378+
```
2379+
2380+
**Command+Drag to Add/Remove Nodes**: Hold Command (Mac) or Ctrl (Windows/Linux)
2381+
while dragging a node to add it to or remove it from a group when using `bounds`
2382+
behavior. The group will highlight when a node can be added.
2383+
2384+
</details>
2385+
2386+
---
2387+
2388+
## Visibility
2389+
2390+
Nodes and annotations support visibility toggling, allowing you to hide elements
2391+
without removing them from the graph. Hidden elements remain in the data model
2392+
and can be shown again at any time.
2393+
2394+
### Node Visibility
2395+
2396+
```dart
2397+
// Hide a node
2398+
controller.getNode('node-1')?.isVisible = false;
2399+
2400+
// Show a node
2401+
controller.getNode('node-1')?.isVisible = true;
2402+
2403+
// Check visibility
2404+
if (controller.getNode('node-1')?.isVisible ?? false) {
2405+
print('Node is visible');
2406+
}
2407+
2408+
// Create a node that starts hidden
2409+
controller.addNode(Node<String>(
2410+
id: 'hidden-node',
2411+
type: 'process',
2412+
position: const Offset(100, 100),
2413+
data: 'Hidden by default',
2414+
visible: false, // Start hidden
2415+
));
2416+
```
2417+
2418+
> [!NOTE] Hidden nodes are not rendered on the canvas and their ports cannot
2419+
> participate in new connections. Existing connections to hidden nodes remain
2420+
> in the graph data but are visually hidden.
2421+
2422+
### Annotation Visibility
2423+
2424+
```dart
2425+
// Hide all annotations
2426+
controller.hideAllAnnotations();
2427+
2428+
// Show all annotations
2429+
controller.showAllAnnotations();
2430+
2431+
// Toggle individual annotation visibility
2432+
final annotation = controller.getAnnotation('group-1');
2433+
if (annotation != null) {
2434+
annotation.isVisible = !annotation.isVisible;
2435+
}
2436+
```
2437+
22042438
---
22052439

22062440
## Interactive Features

0 commit comments

Comments
 (0)