Browse Source

Add Copy/paste - #6012

David Catuhe 6 years ago
parent
commit
83959efd45

+ 1 - 1
nodeEditor/src/components/diagram/diagram.scss

@@ -88,7 +88,7 @@
         border-top-left-radius: 16px;
         font-size: 16px;
         text-align: center;
-        margin: -1px;
+        // margin: -1px;
         
         white-space: nowrap;
         text-overflow: ellipsis;

+ 37 - 0
nodeEditor/src/graphEditor.tsx

@@ -71,6 +71,8 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
 
     private _previewManager: PreviewManager;
 
+    private _copiedNode: Nullable<DefaultNodeModel> = null;
+
     /** @hidden */
     public _toAdd: LinkModel[] | null = [];
 
@@ -189,6 +191,41 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
             return this._nodes.filter(n => n.block === block)[0];
         }
 
+        this.props.globalState.hostDocument!.addEventListener("keyup", evt => {
+            if (!evt.ctrlKey) {
+                return;
+            }
+
+            if (evt.key === "c") {
+                let selectedItems = this._engine.diagramModel.getSelectedItems();
+                if (!selectedItems.length) {
+                    return;
+                }
+    
+                let selectedItem = selectedItems[0] as DefaultNodeModel;
+    
+                if (!selectedItem.block) {
+                    return;
+                }
+
+                this._copiedNode = selectedItem;
+            } else if (evt.key === "v") {
+                if (!this._copiedNode) {
+                    return;
+                }
+
+                let block = this._copiedNode.block;
+                let clone = block.clone(this.props.globalState.nodeMaterial.getScene());
+                let newNode = this.createNodeFromObject({ nodeMaterialBlock: clone });
+
+                newNode.x = this._copiedNode.x;
+                newNode.y = this._copiedNode.y + this._copiedNode.height + 10;
+
+                this._engine.repaintCanvas();
+            }
+
+        }, false);
+
         this.build(true);
     }
 

+ 21 - 0
src/Materials/Node/nodeMaterialBlock.ts

@@ -10,6 +10,7 @@ import { NodeMaterial, NodeMaterialDefines } from './nodeMaterial';
 import { InputBlock } from './Blocks/Input/inputBlock';
 import { UniqueIdGenerator } from '../../Misc/uniqueIdGenerator';
 import { Scene } from '../../scene';
+import { _TypeStore } from '../../Misc/typeStore';
 
 /**
  * Defines a block that can be used inside a node based material
@@ -497,6 +498,26 @@ export class NodeMaterialBlock {
     }
 
     /**
+     * Clone the current block to a new identical block
+     * @param scene defines the hosting scene
+     * @param rootUrl defines the root URL to use to load textures and relative dependencies
+     * @returns a copy of the current block
+     */
+    public clone(scene: Scene, rootUrl: string = "") {
+        let serializationObject = this.serialize();
+
+        let blockType = _TypeStore.GetClass(serializationObject.customType);
+        if (blockType) {
+            let block: NodeMaterialBlock = new blockType();
+            block._deserialize(serializationObject, scene, rootUrl);
+
+            return block;
+        }
+
+        return null;
+    }
+
+    /**
      * Serializes this block in a JSON representation
      * @returns the serialized block object
      */