Browse Source

implement renaming and re-ordering frame ports

Kyle Belfort 5 years ago
parent
commit
f0554232ea

+ 2 - 2
dist/preview release/what's new.md

@@ -14,7 +14,6 @@
 - Simplified code contributions by fully automating the dev setup with gitpod ([nisarhassan12](https://github.com/nisarhassan12))
 - Add a `CascadedShadowMap.IsSupported` method and log an error instead of throwing an exception when CSM is not supported ([Popov72](https://github.com/Popov72))
 
-- Can now rename NME frames inputs and outputs ([Kyle Belfort](https://github.com/belfortk)
 
 ### Engine
 
@@ -23,7 +22,8 @@
 
 ### NME
 
-- NME Frames are now resizable from the corners ([Kyle Belfort](https://github.com/belfortk)
+- Frames are now resizable from the corners ([Kyle Belfort](https://github.com/belfortk)
+- Can now rename and re-order frame inputs and outputs ([Kyle Belfort](https://github.com/belfortk)
 
 ### Inspector
 

+ 0 - 4
nodeEditor/src/diagram/graphCanvas.scss

@@ -221,10 +221,6 @@
                   border-color: white;
                 }
             }
-            
-            .handle{
-                z-index: 20;
-            }
 
             .right-handle {
                 grid-area: 1 / 2 / 3 / 2;

+ 8 - 4
nodeEditor/src/diagram/graphCanvas.tsx

@@ -14,7 +14,6 @@ import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
 import { DataStorage } from 'babylonjs/Misc/dataStorage';
 import { GraphFrame } from './graphFrame';
 import { IEditorData } from '../nodeLocationInfo';
-import { Observable } from 'babylonjs';
 
 require("./graphCanvas.scss");
 
@@ -186,11 +185,16 @@ export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentP
             this._candidatePort = port;
         });
 
-        props.globalState.onFrameNodeMoveUpObserver.add((nodePort: NodePort) => {
-            const frame = this._frames.find(frame => frame.id == nodePort.frameId);
-            frame?.moveFrameNodeUp(nodePort);
+        props.globalState.onFramePortMoveUpObserver.add((nodePort: NodePort) => {
+            const frame = this._frames.find(frame => frame.id === nodePort.frameId);
+            frame?.moveFramePortUp(nodePort);
         });
 
+        props.globalState.onFramePortMoveDownObserver.add((nodePort: NodePort) => {
+            const frame = this._frames.find(frame => frame.id === nodePort.frameId);
+            frame?.moveFramePortDown(nodePort);
+        })
+
         props.globalState.onGridSizeChanged.add(() => {
             this.gridSize = DataStorage.ReadNumber("GridSize", 20);
         });

+ 58 - 34
nodeEditor/src/diagram/graphFrame.ts

@@ -23,6 +23,7 @@ enum ResizingDirection {
 export class GraphFrame {
     private readonly CollapsedWidth = 200;
     private static _FrameCounter = 0;
+    private static _FramePortCounter = 0;
     private _name: string;
     private _color: Color3;
     private _x = 0;
@@ -72,7 +73,7 @@ export class GraphFrame {
     }
 
     private _createInputPort(port: NodePort, node: GraphNode) {
-        let localPort = NodePort.CreatePortElement(port.connectionPoint, node, this._inputPortContainer, null, this._ownerCanvas.globalState, true, this.id)
+        let localPort = NodePort.CreatePortElement(port.connectionPoint, node, this._inputPortContainer, null, this._ownerCanvas.globalState, true, this.id, GraphFrame._FramePortCounter++)
         this._ports.push(localPort);
 
         port.delegatedPort = localPort;
@@ -105,7 +106,7 @@ export class GraphFrame {
 
                                 if (!portAdded) {
                                     portAdded = true;
-                                    localPort = NodePort.CreatePortElement(port.connectionPoint, link.nodeB!, this._outputPortContainer, null, this._ownerCanvas.globalState, true, this.id);
+                                    localPort = NodePort.CreatePortElement(port.connectionPoint, link.nodeB!, this._outputPortContainer, null, this._ownerCanvas.globalState, false, this.id, GraphFrame._FramePortCounter++);
                                     this._ports.push(localPort);
                                 } else {
                                     localPort = this._ports.filter(p => p.connectionPoint === port.connectionPoint)[0];
@@ -113,11 +114,11 @@ export class GraphFrame {
 
                                 port.delegatedPort = localPort;
                                 this._controlledPorts.push(port);
-                                link.isVisible = true;
+                                link.isVisible = false;
                             }
                         }
                     } else {
-                        let localPort = NodePort.CreatePortElement(port.connectionPoint, node, this._outputPortContainer, null, this._ownerCanvas.globalState, true, this.id)
+                        let localPort = NodePort.CreatePortElement(port.connectionPoint, node, this._outputPortContainer, null, this._ownerCanvas.globalState, false, this.id, GraphFrame._FramePortCounter++)
                         this._ports.push(localPort);
                         port.delegatedPort = localPort;
                         this._controlledPorts.push(port);
@@ -481,36 +482,6 @@ export class GraphFrame {
         this.y = this._ownerCanvas.getGridPosition(this.y);   
     }
 
-    public moveFrameNodeUp(nodePort: NodePort){
-        console.log('moving node up: ', nodePort.portLabel);
-        if(nodePort.isInput) {
-            if(this._inputPortContainer.children.length < 2) {
-                return;
-            }
-            const elementsArray = Array.from(this._inputPortContainer.children);
-            const indexInContainer = (elementsArray as HTMLElement[]).findIndex(elem => elem.dataset.blockId === `${nodePort.node.block.uniqueId}`)
-            if(indexInContainer === 0){
-                return;
-            }
-            var b = elementsArray;
-            const elemA = elementsArray[indexInContainer];
-            const elemB =  elementsArray[indexInContainer -1];
-            
-        } else {
-            if(this._outputPortContainer.children.length < 2) {
-                return;
-            }
-            const elementsArray = Array.from(this._inputPortContainer.children);
-            console.log(elementsArray)
-        }
-
-    }
-    
-    public moveFrameNodeDown(blockUniqueId: number){
-        console.log('moving block down: ', blockUniqueId)
-        
-    }
-
     private _onDown(evt: PointerEvent) {
         evt.stopPropagation();
 
@@ -578,6 +549,59 @@ export class GraphFrame {
         evt.stopPropagation();
     }
 
+    public moveFramePortUp(nodePort: NodePort){
+        if(nodePort.isInput) {
+            if(this._inputPortContainer.children.length < 2) {
+                return;
+            }
+            const elementsArray = Array.from(this._inputPortContainer.childNodes);
+            this._moveFramePortUp(elementsArray, nodePort);
+        } else {
+            if(this._outputPortContainer.children.length < 2) {
+                return;
+            }
+            const elementsArray = Array.from(this._outputPortContainer.childNodes);
+            this._moveFramePortUp(elementsArray, nodePort);
+        }
+
+    }
+
+    private _moveFramePortUp(elementsArray: ChildNode[], nodePort: NodePort) {
+        const indexInContainer = (elementsArray as HTMLElement[]).findIndex(elem => elem.dataset.framePortId === `${nodePort.framePortId}`)
+        if(indexInContainer === 0){
+            return;
+        }
+        const secondPort = elementsArray[indexInContainer];
+        const firstPort =  elementsArray[indexInContainer -1];
+        firstPort.parentElement?.insertBefore(secondPort, firstPort);
+    }
+    
+    public moveFramePortDown(nodePort: NodePort){
+        if(nodePort.isInput) {
+            if(this._inputPortContainer.children.length < 2) {
+                return;
+            }
+            const elementsArray = Array.from(this._inputPortContainer.childNodes);
+            this._moveFramePortDown(elementsArray, nodePort);
+        } else {
+            if(this._outputPortContainer.children.length < 2) {
+                return;
+            }
+            const elementsArray = Array.from(this._outputPortContainer.childNodes);
+            this._moveFramePortDown(elementsArray, nodePort);
+        }
+    }
+
+    private _moveFramePortDown(elementsArray: ChildNode[], nodePort: NodePort) {
+        const indexInContainer = (elementsArray as HTMLElement[]).findIndex(elem => elem.dataset.framePortId === `${nodePort.framePortId}`)
+        if(indexInContainer === elementsArray.length -1){
+            return;
+        }
+        const firstPort = elementsArray[indexInContainer];
+        const secondPort =  elementsArray[indexInContainer + 1];
+        firstPort.parentElement?.insertBefore(secondPort, firstPort);
+    }
+
     private initResizing = (evt: PointerEvent) => {
         evt.stopPropagation();
         this._mouseStartPointX = evt.clientX;

+ 2 - 2
nodeEditor/src/diagram/graphNode.ts

@@ -407,11 +407,11 @@ export class GraphNode {
 
         // Connections
         for (var input of this.block.inputs) {
-            this._inputPorts.push(NodePort.CreatePortElement(input,  this, this._inputsContainer, this._displayManager, this._globalState, false, null));
+            this._inputPorts.push(NodePort.CreatePortElement(input,  this, this._inputsContainer, this._displayManager, this._globalState, true, null, undefined));
         }
 
         for (var output of this.block.outputs) {
-            this._outputPorts.push(NodePort.CreatePortElement(output,  this, this._outputsContainer, this._displayManager, this._globalState, false, null));
+            this._outputPorts.push(NodePort.CreatePortElement(output,  this, this._outputsContainer, this._displayManager, this._globalState, false, null, undefined));
         }
 
         this.refresh();

+ 14 - 5
nodeEditor/src/diagram/nodePort.ts

@@ -16,6 +16,7 @@ export class NodePort {
     private _portLabel: Element;
     private _frameId: Nullable<number>
     private _isInput: boolean;
+    private _framePortId: Nullable<number>;
 
     public delegatedPort: Nullable<NodePort> = null;
 
@@ -39,6 +40,10 @@ export class NodePort {
         return this._portLabel.innerHTML;
     }
 
+    public get framePortId() {
+        return this._framePortId;
+    }
+
     public set portLabel(newLabel: string) {
         this._portLabel.innerHTML = newLabel;
     }
@@ -72,7 +77,7 @@ export class NodePort {
         // this._globalState.onSelectionChangedObservable.notifyObservers(this);
     }
 
-    public constructor(portContainer: HTMLElement, public connectionPoint: NodeMaterialConnectionPoint, public node: GraphNode, globalState: GlobalState, isInput: boolean, frameId: Nullable<number>) {
+    public constructor(portContainer: HTMLElement, public connectionPoint: NodeMaterialConnectionPoint, public node: GraphNode, globalState: GlobalState, isInput: boolean, frameId: Nullable<number>, framePortId: number | undefined) {
         this._element = portContainer.ownerDocument!.createElement("div");
         this._element.classList.add("port");
         portContainer.appendChild(this._element);
@@ -81,6 +86,9 @@ export class NodePort {
         this._portLabel = portContainer.children[0];
         this._frameId = frameId
         this._isInput = isInput;
+        if(framePortId !== undefined) {
+            this._framePortId = framePortId;
+        }
 
         this._img = portContainer.ownerDocument!.createElement("img");
         this._element.appendChild(this._img );
@@ -91,7 +99,6 @@ export class NodePort {
         this._element.ondragstart= () => false;
 
         this._onCandidateLinkMovedObserver = globalState.onCandidateLinkMoved.add(coords => {
-            console.log('candidate link moved')
             const rect = this._element.getBoundingClientRect();
 
             if (!coords || rect.left > coords.x || rect.right < coords.x || rect.top > coords.y || rect.bottom < coords.y) {
@@ -111,12 +118,14 @@ export class NodePort {
     }
 
     public static CreatePortElement(connectionPoint: NodeMaterialConnectionPoint, node: GraphNode, root: HTMLElement, 
-            displayManager: Nullable<IDisplayManager>, globalState: GlobalState, isInput: boolean,  frameId:Nullable<number> = null) {
+            displayManager: Nullable<IDisplayManager>, globalState: GlobalState, isInput: boolean,  frameId: Nullable<number> = null, framePortId: number | undefined) {
         let portContainer = root.ownerDocument!.createElement("div");
         let block = connectionPoint.ownerBlock;
 
         portContainer.classList.add("portLine");
-        portContainer.dataset.blockId = `${node.block.uniqueId}`;
+        if(framePortId !== null) {
+            portContainer.dataset.framePortId = `${framePortId}`;
+        }
         root.appendChild(portContainer);
 
         if (!displayManager || displayManager.shouldDisplayPortLabels(block)) {
@@ -126,6 +135,6 @@ export class NodePort {
             portContainer.appendChild(portLabel);
         }
     
-        return new NodePort(portContainer, connectionPoint, node, globalState, isInput, frameId);
+        return new NodePort(portContainer, connectionPoint, node, globalState, isInput, frameId, framePortId);
     }
 }

+ 0 - 1
nodeEditor/src/diagram/properties/framePropertyComponent.tsx

@@ -8,7 +8,6 @@ import { TextInputLineComponent } from '../../sharedComponents/textInputLineComp
 import { ButtonLineComponent } from '../../sharedComponents/buttonLineComponent';
 import { Nullable } from 'babylonjs/types';
 import { Observer } from 'babylonjs/Misc/observable';
-import { NodePort } from '../nodePort';
 
 export interface IFramePropertyTabComponentProps {
     globalState: GlobalState

+ 2 - 48
nodeEditor/src/diagram/properties/nodePortPropertyComponent.tsx

@@ -1,13 +1,9 @@
 
 import * as React from "react";
 import { LineContainerComponent } from '../../sharedComponents/lineContainerComponent';
-import { GraphFrame } from '../graphFrame';
 import { GlobalState } from '../../globalState';
-import { Color3LineComponent } from '../../sharedComponents/color3LineComponent';
 import { TextInputLineComponent } from '../../sharedComponents/textInputLineComponent';
 import { ButtonLineComponent } from '../../sharedComponents/buttonLineComponent';
-import { Nullable } from 'babylonjs/types';
-import { Observer } from 'babylonjs/Misc/observable';
 import { NodePort } from '../nodePort';
 
 export interface INodePortPropertyTabComponentProps {
@@ -16,24 +12,11 @@ export interface INodePortPropertyTabComponentProps {
 }
 
 export class NodePortPropertyTabComponent extends React.Component<INodePortPropertyTabComponentProps> {
-    private onFrameExpandStateChangedObserver: Nullable<Observer<GraphFrame>>;
 
     constructor(props: INodePortPropertyTabComponentProps) {
         super(props)
     }
 
-
-    // componentDidMount() {
-    //     this.onFrameExpandStateChangedObserver = this.props.frame.onExpandStateChanged.add(() => this.forceUpdate());
-    // }
-
-    // componentWillUnmount() {
-    //     if (this.onFrameExpandStateChangedObserver) {
-    //         this.props.frame.onExpandStateChanged.remove(this.onFrameExpandStateChangedObserver);
-    //         this.onFrameExpandStateChangedObserver = null;
-    //     }
-    // }    
-
     render() {      
         return (
             <div id="propertyTab">
@@ -45,43 +28,14 @@ export class NodePortPropertyTabComponent extends React.Component<INodePortPrope
             </div>
             <div>
                 <LineContainerComponent title="GENERAL">
-                    <div>
-                        NodePortPropertyComponent
-                    </div>
                     <TextInputLineComponent globalState={this.props.globalState} label="Port Label" propertyName="portLabel" target={this.props.nodePort}/>
                     <ButtonLineComponent label="Move Node Up" onClick={() => {
-                                console.log('click on up')
-                                console.log(this.props.nodePort.frameId)
-                                console.log(this.props.nodePort.node.block.uniqueId)
-                                this.props.globalState.onFrameNodeMoveUpObserver.notifyObservers(this.props.nodePort);
+                                this.props.globalState.onFramePortMoveUpObserver.notifyObservers(this.props.nodePort);
                             }} />
 
                     <ButtonLineComponent label="Move Node Down" onClick={() => {
-                                console.log('click on down')
-                            }} />
-                    {/* <TextInputLineComponent globalState={this.props.globalState} label="Name" prop–ertyName="name" target={this.props.frame} /> */}
-                    {/* <Color3LineComponent globalState={this.props.globalState} label="Color" target={this.props.frame} propertyName="color"></Color3LineComponent>
-                    <TextInputLineComponent globalState={this.props.globalState} label="Comments" propertyName="comments" target={this.props.frame}
-                    />
-                    {
-                        this.props.frame.ports && this.props.frame.ports.map((port: NodePort) => 
-                        )
-                    }
-                    {
-                        !this.props.frame.isCollapsed &&
-                        <ButtonLineComponent label="Collapse" onClick={() => {
-                                this.props.frame!.isCollapsed = true;
-                            }} />
-                    }
-                    {
-                        this.props.frame.isCollapsed &&
-                        <ButtonLineComponent label="Expand" onClick={() => {
-                                this.props.frame!.isCollapsed = false;
+                                this.props.globalState.onFramePortMoveDownObserver.notifyObservers(this.props.nodePort);
                             }} />
-                    }
-                    {/* <ButtonLineComponent label="Export" onClick={() => {
-                                this.state.currentFrame!.export();
-                            }} /> */} 
                 </LineContainerComponent>
             </div>
         </div>

+ 2 - 1
nodeEditor/src/globalState.ts

@@ -37,7 +37,8 @@ export class GlobalState {
     onSelectionBoxMoved = new Observable<ClientRect | DOMRect>();
     onFrameCreated = new Observable<GraphFrame>();
     onCandidatePortSelected = new Observable<Nullable<NodePort>>();
-    onFrameNodeMoveUpObserver = new Observable<NodePort>();
+    onFramePortMoveUpObserver = new Observable<NodePort>();
+    onFramePortMoveDownObserver = new Observable<NodePort>();
     onGetNodeFromBlock: (block: NodeMaterialBlock) => GraphNode;
     onGridSizeChanged = new Observable<void>();
     previewMeshType: PreviewMeshType;