Selaa lähdekoodia

Copy paste for frames

David Catuhe 5 vuotta sitten
vanhempi
commit
9b3dd2e941
1 muutettua tiedostoa jossa 128 lisäystä ja 29 poistoa
  1. 128 29
      nodeEditor/src/graphEditor.tsx

+ 128 - 29
nodeEditor/src/graphEditor.tsx

@@ -19,6 +19,7 @@ import { PreviewAreaComponent } from './components/preview/previewAreaComponent'
 import { SerializationTools } from './serializationTools';
 import { GraphCanvasComponent } from './diagram/graphCanvas';
 import { GraphNode } from './diagram/graphNode';
+import { GraphFrame } from './diagram/graphFrame';
 
 require("./main.scss");
 
@@ -40,6 +41,7 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
 
     private _previewManager: PreviewManager;
     private _copiedNodes: GraphNode[] = [];
+    private _copiedFrame: Nullable<GraphFrame> = null;
     private _mouseLocationX = 0;
     private _mouseLocationY = 0;
     private _onWidgetKeyUpPointer: any;
@@ -179,6 +181,14 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
             }
 
             if (evt.key === "c") { // Copy
+                this._copiedNodes = [];
+                this._copiedFrame = null;
+
+                if (this._graphCanvas.selectedFrame) {
+                    this._copiedFrame = this._graphCanvas.selectedFrame;
+                    return;
+                }
+
                 let selectedItems = this._graphCanvas.selectedNodes;
                 if (!selectedItems.length) {
                     return;
@@ -192,51 +202,140 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
 
                 this._copiedNodes = selectedItems.slice(0);
             } else if (evt.key === "v") { // Paste
-                if (!this._copiedNodes.length) {
-                    return;
-                }
-
                 const rootElement = this.props.globalState.hostDocument!.querySelector(".diagram-container") as HTMLDivElement;
                 const zoomLevel = this._graphCanvas.zoom;
-                let currentX = (this._mouseLocationX - rootElement.offsetLeft - this._graphCanvas.x - this.NodeWidth) / zoomLevel;
                 let currentY = (this._mouseLocationY - rootElement.offsetTop - this._graphCanvas.y - 20) / zoomLevel;
-                let originalNode: Nullable<GraphNode> = null;
 
-                for (var node of this._copiedNodes) {
-                    let block = node.block;
+                if (this._copiedFrame) {                    
+                    // New frame
+                    let newFrame = new GraphFrame(null, this._graphCanvas, true);
+                    this._graphCanvas.frames.push(newFrame);
 
-                    if (!block) {
-                        continue;
-                    }
+                    newFrame.width = this._copiedFrame.width;
+                    newFrame.height = this._copiedFrame.height;newFrame.width / 2
+                    newFrame.name = this._copiedFrame.name;
+                    newFrame.color = this._copiedFrame.color;
 
-                    let clone = block.clone(this.props.globalState.nodeMaterial.getScene());
+                    let currentX = (this._mouseLocationX - rootElement.offsetLeft - this._graphCanvas.x) / zoomLevel;
+                    newFrame.x = currentX - newFrame.width / 2;
+                    newFrame.y = currentY;
 
-                    if (!clone) {
-                        return;
+                    // Paste nodes
+
+                    if (this._copiedFrame.nodes.length) {
+                        currentX = newFrame.x + this._copiedFrame.nodes[0].x - this._copiedFrame.x;
+                        currentY = newFrame.y + this._copiedFrame.nodes[0].y - this._copiedFrame.y;
+                        this.pasteSelection(this._copiedFrame.nodes, currentX, currentY);                  
                     }
-                    
-                    let newNode = this.createNodeFromObject(clone);
-
-                    let x = 0;
-                    let y = 0;
-                    if (originalNode) {
-                        x = currentX + node.x - originalNode.x;
-                        y = currentY + node.y - originalNode.y;
-                    } else {
-                        originalNode = node;
-                        x = currentX;
-                        y = currentY;
+
+                    if (this._copiedFrame.isCollapsed) {
+                        newFrame.isCollapsed = true;
                     }
+                    return;
+                }
 
-                    newNode.x = x;
-                    newNode.y = y;
-                    newNode.cleanAccumulation();
+                if (!this._copiedNodes.length) {
+                    return;
                 }
+
+                let currentX = (this._mouseLocationX - rootElement.offsetLeft - this._graphCanvas.x - this.NodeWidth) / zoomLevel;
+                this.pasteSelection(this._copiedNodes, currentX, currentY);
             }
 
         }, false);
     }
 
+    reconnectNewNodes(nodeIndex: number, newNodes:GraphNode[], sourceNodes:GraphNode[], done: boolean[]) {
+        if (done[nodeIndex]) {
+            return;
+        }
+
+        const currentNode = newNodes[nodeIndex];
+        const block = currentNode.block;
+        const sourceNode = sourceNodes[nodeIndex];
+
+        for (var inputIndex = 0; inputIndex < sourceNode.block.inputs.length; inputIndex++) {
+            let sourceInput = sourceNode.block.inputs[inputIndex];
+            const currentInput = block.inputs[inputIndex];
+            if (!sourceInput.isConnected) {
+                continue;
+            }
+            const sourceBlock = sourceInput.connectedPoint!.ownerBlock;
+            const activeNodes = sourceNodes.filter(s => s.block === sourceBlock);
+
+            if (activeNodes.length > 0) {
+                const activeNode = activeNodes[0];
+                let indexInList = sourceNodes.indexOf(activeNode);
+
+                // First make sure to connect the other one
+                this.reconnectNewNodes(indexInList, newNodes, sourceNodes, done);
+
+                // Then reconnect
+                const outputIndex = sourceBlock.outputs.indexOf(sourceInput.connectedPoint!);
+                const newOutput = newNodes[indexInList].block.outputs[outputIndex];
+
+                newOutput.connectTo(currentInput);
+            } else {
+                // Connect with outside blocks
+                sourceInput._connectedPoint!.connectTo(currentInput);
+            }
+
+            this._graphCanvas.connectPorts(currentInput.connectedPoint!, currentInput);
+        }
+
+        currentNode.refresh();
+
+        done[nodeIndex] = true;
+    }
+
+    pasteSelection(copiedNodes: GraphNode[], currentX: number, currentY: number) {
+
+        let originalNode: Nullable<GraphNode> = null;
+
+        let newNodes:GraphNode[] = [];
+
+        // Create new nodes
+        for (var node of copiedNodes) {
+            let block = node.block;
+
+            if (!block) {
+                continue;
+            }
+
+            let clone = block.clone(this.props.globalState.nodeMaterial.getScene());
+
+            if (!clone) {
+                return;
+            }
+            
+            let newNode = this.createNodeFromObject(clone);
+
+            let x = 0;
+            let y = 0;
+            if (originalNode) {
+                x = currentX + node.x - originalNode.x;
+                y = currentY + node.y - originalNode.y;
+            } else {
+                originalNode = node;
+                x = currentX;
+                y = currentY;
+            }
+
+            newNode.x = x;
+            newNode.y = y;
+            newNode.cleanAccumulation();
+
+            newNodes.push(newNode);
+        }
+
+        // Relink
+        let done = new Array<boolean>(newNodes.length);
+        for (var index = 0; index < newNodes.length; index++) {
+            this.reconnectNewNodes(index, newNodes, copiedNodes, done);
+        }
+
+    }
+
     zoomToFit() {
         this._graphCanvas.zoomToFit();
     }