You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -7,39 +7,95 @@ This document describes the implementation of QML support for the **QtNodes** li
7
7
The implementation follows a Model-View-ViewModel (MVVM) pattern adapted for Qt/QML:
8
8
9
9
### 1. C++ Integration Layer (`src/qml/`)
10
-
***`QuickGraphModel`**: The main controller class. It wraps the internal `DataFlowGraphModel` and exposes high-level operations (add/remove nodes, create connections) to QML.
10
+
***`QuickGraphModel`**: The main controller class. It wraps the internal `DataFlowGraphModel` and exposes high-level operations (add/remove nodes, create connections) to QML. It also manages an **UndoStack** for undo/redo operations.
11
11
***`NodesListModel`**: A `QAbstractListModel` that exposes the nodes in the graph. It provides roles for properties like position, caption, and input/output port counts. Crucially, it exposes the underlying `NodeDelegateModel` as a `QObject*`, allowing QML to bind directly to custom node data (e.g., numbers, text).
12
12
***`ConnectionsListModel`**: A `QAbstractListModel` that tracks active connections, providing source/destination node IDs and port indices.
13
13
14
14
### 2. QML Components (`resources/qml/`)
15
15
***`NodeGraph.qml`**: The main canvas component.
16
-
* Handles **Infinite Panning & Zooming** using a background `MouseArea` and transform/scale logic.
16
+
* Handles **Infinite Panning & Zooming**(mouse-centered) using a background `MouseArea` and transform/scale logic.
17
17
* Renders a dynamic **Infinite Grid** using a `Canvas` item (avoiding shader compatibility issues).
18
18
* Manages the lifecycle of Nodes and Connections using `Repeater`s linked to the C++ models.
19
19
* Handles **Connection Drafting**: Implements geometry-based hit-testing to reliably find target nodes/ports under the mouse cursor, ignoring z-order overlays.
20
+
* Supports **Marquee Selection** for selecting multiple nodes and connections.
21
+
* Handles **Keyboard Shortcuts**: Delete/Backspace/X for deletion, Ctrl+Z for undo, Ctrl+Shift+Z/Ctrl+Y for redo.
20
22
***`Node.qml`**: A generic node shell.
21
23
* Displays the node caption and background.
22
-
* Generates input/output ports dynamically.
24
+
* Generates input/output ports dynamically with **type-based coloring**.
23
25
* Uses a `Loader` with a `nodeContentDelegate` to allow users to inject **custom QML content** inside the node (e.g., text fields, images) with full property binding propagation.
24
-
* Handles node dragging and position updates, with feedback loops prevented by threshold checks.
26
+
* Handles node dragging and position updates, including **group dragging** for selected nodes.
27
+
* Shows visual feedback for selected state.
25
28
***`Connection.qml`**:
26
29
* Renders connections as smooth cubic Bezier curves using `QtQuick.Shapes`.
27
-
* Updates geometry in real-time when linked nodes are moved by monitoring specific `xChanged`/`yChanged` signals.
30
+
* Updates geometry in real-time when linked nodes are moved.
31
+
* Supports **selection** (click or Ctrl+click) and **hover highlighting**.
32
+
* Uses **port type colors** for visual consistency.
33
+
***`NodeGraphStyle.qml`**: A centralized styling component for theming.
34
+
* Defines colors, sizes, and appearance for canvas, nodes, ports, connections, and selection.
35
+
* Supports **custom themes** (e.g., dark/light mode) by instantiating with different property values.
36
+
* Includes port type color mapping for type safety visualization.
28
37
29
38
## Features Implemented
30
39
40
+
### Core Functionality
31
41
* ✅ **Hybrid C++/QML Architecture**: Full separation of graph logic (C++) and UI (QML).
32
42
* ✅ **Dynamic Graph Rendering**: Nodes and connections appear and update automatically based on the C++ model.
33
-
* ✅ **Interactive Workspace**: Smooth zooming and panning of the graph canvas.
43
+
* ✅ **Interactive Workspace**: Smooth zooming (mouse-centered) and panning of the graph canvas.
34
44
* ✅ **Node Manipulation**: Drag-and-drop nodes to move them.
35
45
* ✅ **Connection Creation**: Drag from any port to a compatible target port to create a connection.
36
-
* ✅ **Customizable Nodes**: Users can define the look and behavior of specific node types (e.g., "NumberSource") completely in QML.
37
-
* ✅ **Example Application**: `qml_calculator` demonstrates a working calculator where C++ handles the math and QML handles the UI.
46
+
* ✅ **Customizable Nodes**: Users can define the look and behavior of specific node types completely in QML.
47
+
48
+
### Selection & Editing
49
+
* ✅ **Node Selection**: Click to select, Ctrl+click for additive selection.
50
+
* ✅ **Marquee Selection**: Click and drag on canvas to select multiple nodes and connections.
51
+
* ✅ **Group Dragging**: Drag any selected node to move all selected nodes together.
52
+
* ✅ **Connection Selection**: Click on connections to select them, with hover highlighting.
53
+
* ✅ **Node Deletion**: Delete selected nodes via Delete/Backspace/X keys.
54
+
* ✅ **Connection Deletion**: Delete selected connections via Delete/Backspace/X keys.
55
+
* ✅ **Disconnect by Dragging**: Drag from an input port to disconnect and re-route an existing connection.
56
+
57
+
### Type Safety & Visual Feedback
58
+
* ✅ **Port Type Colors**: Ports are colored based on their data type (decimal=green, integer=blue, string=orange, boolean=purple).
59
+
* ✅ **Compatibility Highlighting**: During connection dragging, compatible ports are highlighted while incompatible ports are dimmed.
60
+
* ✅ **Connection Type Colors**: Connections inherit the color of their source port type.
61
+
62
+
### Theming & Styling
63
+
* ✅ **NodeGraphStyle.qml**: Centralized styling with customizable properties for:
64
+
* Canvas background and grid colors
65
+
* Node background, border, caption, and selection colors
66
+
* Port sizes, colors, and hover/active states
67
+
* Connection width, hover effects, and selection outline
68
+
* Marquee selection appearance
69
+
* ✅ **Theme Switching**: Support for runtime theme changes (e.g., dark/light mode toggle).
70
+
* ✅ **Reactive Styling**: All components respond to style property changes in real-time.
71
+
72
+
### Undo/Redo
73
+
* ✅ **Full Undo/Redo Support**: All graph operations are undoable:
74
+
* Add/Remove nodes
75
+
* Add/Remove connections
76
+
* ✅ **Keyboard Shortcuts**: Ctrl+Z (undo), Ctrl+Shift+Z or Ctrl+Y (redo).
77
+
* ✅ **QML API**: `canUndo`/`canRedo` properties and `undo()`/`redo()` methods exposed to QML.
78
+
79
+
### Focus Management
80
+
* ✅ **Correct Input Focus**: Text fields inside nodes properly receive and release focus.
81
+
* ✅ **Canvas Focus**: Clicking on canvas or nodes removes focus from inputs for keyboard shortcuts to work.
82
+
83
+
## Example Application
84
+
85
+
The `qml_calculator` example demonstrates all features:
***Theme Toggle Button**: Switch between dark and light themes at runtime
88
+
***Undo/Redo Buttons**: Visual buttons in toolbar with enabled/disabled state
89
+
***Custom Node Content**: Each node type has its own QML UI (text fields, labels, symbols)
90
+
***Type-Safe Connections**: Connections enforce type compatibility with visual feedback
38
91
39
92
## Technical Notes
93
+
40
94
***Grid Implementation**: The grid is drawn using an HTML5-style `Canvas` API rather than GLSL shaders. This ensures compatibility with Qt 6's RHI (which removed inline OpenGL shaders) while maintaining performance for infinite grid rendering.
41
95
***Z-Ordering & Hit Testing**: Custom geometry-based hit testing is used for connection drafting because the temporary connection line (a `Shape` item) overlays the nodes, blocking standard `childAt` calls.
42
96
***Coordinate Mapping**: All drag operations use `mapToItem`/`mapFromItem` relative to the main `canvas` item to ensure correct positioning regardless of the current pan/zoom state.
97
+
***Reactive Bindings**: Style properties use direct `graph.style` access for proper reactivity when themes change.
98
+
***Undo Commands**: Custom `QUndoCommand` subclasses handle node state serialization for proper undo/redo of node additions and deletions.
43
99
44
100
## How to Build
45
101
@@ -57,22 +113,56 @@ make
57
113
./bin/qml_calculator
58
114
```
59
115
60
-
## Next Steps (Roadmap)
61
-
62
-
To achieve full feature parity with the Widgets-based version, the following features need to be implemented:
63
-
64
-
1.**Connection Interaction**:
65
-
* Ability to select/highlight existing connections.
66
-
* Ability to delete connections (e.g., via right-click menu or keyboard shortcut).
67
-
2.**Node Deletion**:
68
-
* UI mechanism to delete selected nodes.
69
-
3.**Selection Model**:
70
-
* Support for selecting multiple nodes (marquee selection).
71
-
* Visual feedback for selected states.
72
-
4.**Undo/Redo Stack**:
73
-
* Expose the C++ `UndoStack` to QML to trigger undo/redo actions.
74
-
5.**Styling**:
75
-
* Expose more style properties (colors, line thickness) to QML for easy theming.
76
-
6.**Port Data & Type Safety**:
77
-
* Visualize port data types (colors based on type).
78
-
* Add visual feedback during connection dragging (highlight compatible ports, dim incompatible ones).
116
+
## API Reference
117
+
118
+
### QuickGraphModel (C++ → QML)
119
+
120
+
| Property/Method | Type | Description |
121
+
|-----------------|------|-------------|
122
+
|`nodes`| NodesListModel*| List model of all nodes |
123
+
|`connections`| ConnectionsListModel*| List model of all connections |
124
+
|`canUndo`| bool | Whether undo is available |
125
+
|`canRedo`| bool | Whether redo is available |
126
+
|`addNode(nodeType)`| int | Add a node, returns node ID |
127
+
|`removeNode(nodeId)`| bool | Remove a node |
128
+
|`addConnection(...)`| void | Create a connection |
129
+
|`removeConnection(...)`| void | Remove a connection |
130
+
|`undo()`| void | Undo last operation |
131
+
|`redo()`| void | Redo last undone operation |
132
+
133
+
### NodeGraph.qml
134
+
135
+
| Property | Type | Description |
136
+
|----------|------|-------------|
137
+
|`graphModel`| QuickGraphModel | The C++ model to visualize |
0 commit comments