Skip to content

Commit

Permalink
Copy paste for frames
Browse files Browse the repository at this point in the history
  • Loading branch information
deltakosh committed Dec 11, 2019
1 parent cf3722c commit 9b3dd2e
Showing 1 changed file with 128 additions and 29 deletions.
157 changes: 128 additions & 29 deletions nodeEditor/src/graphEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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();
}
Expand Down

0 comments on commit 9b3dd2e

Please sign in to comment.