David Catuhe 5 anos atrás
pai
commit
0ba39aa4e3

+ 30 - 4
nodeEditor/src/components/propertyTab/propertyTabComponent.tsx

@@ -12,26 +12,31 @@ import { CheckBoxLineComponent } from '../../sharedComponents/checkBoxLineCompon
 import { DataStorage } from '../../dataStorage';
 import { DataStorage } from '../../dataStorage';
 import { GraphNode } from '../../diagram/graphNode';
 import { GraphNode } from '../../diagram/graphNode';
 import { SliderLineComponent } from '../../sharedComponents/sliderLineComponent';
 import { SliderLineComponent } from '../../sharedComponents/sliderLineComponent';
+import { GraphFrame } from '../../diagram/graphFrame';
+import { TextInputLineComponent } from '../../sharedComponents/textInputLineComponent';
+import { Color3LineComponent } from '../../sharedComponents/color3LineComponent';
 require("./propertyTab.scss");
 require("./propertyTab.scss");
 
 
 interface IPropertyTabComponentProps {
 interface IPropertyTabComponentProps {
     globalState: GlobalState;
     globalState: GlobalState;
 }
 }
 
 
-export class PropertyTabComponent extends React.Component<IPropertyTabComponentProps, { currentNode: Nullable<GraphNode> }> {
+export class PropertyTabComponent extends React.Component<IPropertyTabComponentProps, { currentNode: Nullable<GraphNode>, currentFrame: Nullable<GraphFrame> }> {
 
 
     constructor(props: IPropertyTabComponentProps) {
     constructor(props: IPropertyTabComponentProps) {
         super(props)
         super(props)
 
 
-        this.state = { currentNode: null };
+        this.state = { currentNode: null, currentFrame: null };
     }
     }
 
 
     componentDidMount() {
     componentDidMount() {
         this.props.globalState.onSelectionChangedObservable.add(selection => {
         this.props.globalState.onSelectionChangedObservable.add(selection => {
             if (selection instanceof GraphNode) {
             if (selection instanceof GraphNode) {
-                this.setState({ currentNode: selection });
+                this.setState({ currentNode: selection, currentFrame: null });
+            } else if (selection instanceof GraphFrame) {
+                this.setState({ currentNode: null, currentFrame: selection });
             } else {
             } else {
-                this.setState({ currentNode: null });
+                this.setState({ currentNode: null, currentFrame: null });
             }
             }
         });
         });
     }
     }
@@ -72,6 +77,27 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
                 </div>
                 </div>
             );
             );
         }
         }
+
+        if (this.state.currentFrame) {
+            return (
+                <div id="propertyTab">
+                    <div id="header">
+                        <img id="logo" src="https://www.babylonjs.com/Assets/logo-babylonjs-social-twitter.png" />
+                        <div id="title">
+                            NODE MATERIAL EDITOR
+                        </div>
+                    </div>
+                    <div>
+                        <LineContainerComponent title="GENERAL">
+                            <TextInputLineComponent globalState={this.props.globalState} label="Name" propertyName="name" target={this.state.currentFrame} />
+                            <Color3LineComponent label="Color" target={this.state.currentFrame} propertyName="color"></Color3LineComponent>
+                        </LineContainerComponent>
+                    </div>
+                </div>
+            );
+        }
+
+
         let gridSize = DataStorage.ReadNumber("GridSize", 20);
         let gridSize = DataStorage.ReadNumber("GridSize", 20);
 
 
         return (
         return (

+ 18 - 3
nodeEditor/src/diagram/graphCanvas.scss

@@ -46,16 +46,31 @@
             background: rgba(72, 72, 72, 0.7);
             background: rgba(72, 72, 72, 0.7);
             display: grid;
             display: grid;
             grid-template-rows: 40px calc(100% - 40px);
             grid-template-rows: 40px calc(100% - 40px);
-            grid-template-columns: 100%;
+            grid-template-columns: 100%;            
+            border: transparent solid 4px;
+            box-sizing: border-box;
 
 
             .group-box-header {
             .group-box-header {
                 grid-row: 1;
                 grid-row: 1;
                 grid-column: 1;
                 grid-column: 1;
-                background: rgba(72, 72, 72, 1);
+                background: rgba(72, 72, 72, 1);    
+                color: white;
+                font-size: 24px;
+                text-align: center;
+                display: grid;
+                align-content: center;
+                overflow: hidden;
+                margin: -4px;
+                border: rgba(72, 72, 72, 1) solid 4px;
+                border-bottom: 0;
             }
             }
 
 
             &.selected {
             &.selected {
-                border: white solid 4px;
+                border-color: white;
+
+                .group-box-header {
+                    border-color: white !important;
+                }
             }
             }
         }
         }
 
 

+ 43 - 0
nodeEditor/src/diagram/graphCanvas.tsx

@@ -12,6 +12,7 @@ import { FragmentOutputBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/fr
 import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
 import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
 import { DataStorage } from '../dataStorage';
 import { DataStorage } from '../dataStorage';
 import { GraphFrame } from './graphFrame';
 import { GraphFrame } from './graphFrame';
+import { IEditorData } from '../nodeLocationInfo';
 
 
 require("./graphCanvas.scss");
 require("./graphCanvas.scss");
 
 
@@ -77,6 +78,10 @@ export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentP
         return this._links;
         return this._links;
     }
     }
 
 
+    public get frames() {
+        return this._frames;
+    }
+
     public get zoom() {
     public get zoom() {
         return this._zoom;
         return this._zoom;
     }
     }
@@ -191,6 +196,11 @@ export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentP
             editorData.zoom = this.zoom;
             editorData.zoom = this.zoom;
             editorData.x = this.x;
             editorData.x = this.x;
             editorData.y = this.y;
             editorData.y = this.y;
+
+            editorData.frames = [];
+            for (var frame of this._frames) {
+                editorData.frames.push(frame.serialize());
+            }
         }
         }
     }
     }
 
 
@@ -200,6 +210,14 @@ export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentP
 			return position;
 			return position;
 		}
 		}
 		return gridSize * Math.floor(position / gridSize);
 		return gridSize * Math.floor(position / gridSize);
+    }
+    
+    public getGridPositionCeil(position: number) {
+        let gridSize = this.gridSize;
+		if (gridSize === 0) {
+			return position;
+		}
+		return gridSize * Math.ceil(position / gridSize);
 	}
 	}
 
 
     updateTransform() {
     updateTransform() {
@@ -227,7 +245,13 @@ export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentP
         for (var node of this._nodes) {
         for (var node of this._nodes) {
             node.dispose();
             node.dispose();
         }
         }
+        
+        const frames = this._frames.splice(0);
+        for (var frame of frames) {
+            frame.dispose();
+        }
         this._nodes = [];
         this._nodes = [];
+        this._frames = [];
         this._links = [];
         this._links = [];
         this._graphCanvas.innerHTML = "";
         this._graphCanvas.innerHTML = "";
         this._svgCanvas.innerHTML = "";
         this._svgCanvas.innerHTML = "";
@@ -651,6 +675,25 @@ export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentP
 
 
         this.props.globalState.onRebuildRequiredObservable.notifyObservers();
         this.props.globalState.onRebuildRequiredObservable.notifyObservers();
     }
     }
+
+    processEditorData(editorData: IEditorData) {
+        const frames = this._frames.splice(0);
+        for (var frame of frames) {
+            frame.dispose();
+        }
+
+        this._frames = [];
+
+        this.x = editorData.x || 0;
+        this.y = editorData.y || 0;
+        this.zoom = editorData.zoom || 1;
+
+        // Frames
+        for (var frameData of editorData.frames) {
+            var frame = GraphFrame.Parse(frameData, this);
+            this._frames.push(frame);
+        }
+    }
  
  
     render() {
     render() {
         return (
         return (

+ 86 - 21
nodeEditor/src/diagram/graphFrame.ts

@@ -3,15 +3,18 @@ import { GraphCanvasComponent } from './graphCanvas';
 import { Nullable } from 'babylonjs/types';
 import { Nullable } from 'babylonjs/types';
 import { Observer } from 'babylonjs/Misc/observable';
 import { Observer } from 'babylonjs/Misc/observable';
 import { NodeLink } from './nodeLink';
 import { NodeLink } from './nodeLink';
+import { Color3 } from 'babylonjs';
+import { IFrameData } from '../nodeLocationInfo';
 
 
 export class GraphFrame {
 export class GraphFrame {
     private _name: string;
     private _name: string;
+    private _color: Color3;
     private _x = 0;
     private _x = 0;
     private _y = 0;
     private _y = 0;
     private _gridAlignedX = 0;
     private _gridAlignedX = 0;
     private _gridAlignedY = 0;    
     private _gridAlignedY = 0;    
-    public width: number;
-    public height: number;
+    private _width: number;
+    private _height: number;
     public element: HTMLDivElement;   
     public element: HTMLDivElement;   
     private _headerElement: HTMLDivElement;    
     private _headerElement: HTMLDivElement;    
     private _nodes: GraphNode[] = [];
     private _nodes: GraphNode[] = [];
@@ -24,14 +27,6 @@ export class GraphFrame {
         return this._nodes;
         return this._nodes;
     }
     }
 
 
-    public get gridAlignedX() {
-        return this._gridAlignedX;
-    }
-
-    public get gridAlignedY() {
-        return this._gridAlignedY;
-    }
-
     public get name() {
     public get name() {
         return this._name;
         return this._name;
     }
     }
@@ -41,6 +36,17 @@ export class GraphFrame {
         this._headerElement.innerHTML = value;
         this._headerElement.innerHTML = value;
     }
     }
 
 
+    public get color() {
+        return this._color;
+    }
+
+    public set color(value: Color3) {
+        this._color = value;
+        this._headerElement.style.background = `rgba(${value.r * 255}, ${value.g * 255}, ${value.b * 255}, 1)`;
+        this._headerElement.style.borderColor = `rgba(${value.r * 255}, ${value.g * 255}, ${value.b * 255}, 1)`;
+        this.element.style.background = `rgba(${value.r * 255}, ${value.g * 255}, ${value.b * 255}, 0.7)`;
+    }    
+
     public get x() {
     public get x() {
         return this._x;
         return this._x;
     }
     }
@@ -68,9 +74,39 @@ export class GraphFrame {
 
 
         this._gridAlignedY = this._ownerCanvas.getGridPosition(value);
         this._gridAlignedY = this._ownerCanvas.getGridPosition(value);
         this.element.style.top = `${this._gridAlignedY}px`;
         this.element.style.top = `${this._gridAlignedY}px`;
-    }    
+    }   
+    
+    public get width() {
+        return this._width;
+    }
+
+    public set width(value: number) {
+        if (this._width === value) {
+            return;
+        }
+        this._width = value;
+        
+        var gridAlignedRight = this._ownerCanvas.getGridPositionCeil(value + this._gridAlignedX);
+
+        this.element.style.width = `${gridAlignedRight - this._gridAlignedX}px`;
+    }
+
+    public get height() {
+        return this._height;
+    }
+
+    public set height(value: number) {
+        if (this._height === value) {
+            return;
+        }
+        this._height = value;
+        
+        var gridAlignedBottom = this._ownerCanvas.getGridPositionCeil(value + this._gridAlignedY);
 
 
-    public constructor(candidate: HTMLDivElement, canvas: GraphCanvasComponent) {
+        this.element.style.height = `${gridAlignedBottom - this._gridAlignedY}px`;
+    }
+
+    public constructor(candidate: Nullable<HTMLDivElement>, canvas: GraphCanvasComponent) {
         this._ownerCanvas = canvas;
         this._ownerCanvas = canvas;
         const root = canvas.groupContainer;
         const root = canvas.groupContainer;
         this.element = root.ownerDocument!.createElement("div");        
         this.element = root.ownerDocument!.createElement("div");        
@@ -81,15 +117,17 @@ export class GraphFrame {
         this._headerElement.classList.add("group-box-header");
         this._headerElement.classList.add("group-box-header");
         this.element.appendChild(this._headerElement);
         this.element.appendChild(this._headerElement);
 
 
-        this.x = parseFloat(candidate.style.left!.replace("px", ""));
-        this.y = parseFloat(candidate.style.top!.replace("px", ""));
-        this.width = parseFloat(candidate.style.width!.replace("px", ""));
-        this.height = parseFloat(candidate.style.height!.replace("px", ""));
+        this.name = "Frame";
+        this.color = Color3.FromInts(72, 72, 72);
 
 
-        this.cleanAccumulation();        
+        if (candidate) {
+            this.x = parseFloat(candidate.style.left!.replace("px", ""));
+            this.y = parseFloat(candidate.style.top!.replace("px", ""));
+            this.width = parseFloat(candidate.style.width!.replace("px", ""));
+            this.height = parseFloat(candidate.style.height!.replace("px", ""));
 
 
-        this.element.style.width = `${this.width}px`;
-        this.element.style.height = `${this.height}px`;
+            this.cleanAccumulation();        
+        }
         
         
         this._headerElement.addEventListener("pointerdown", evt => this._onDown(evt));
         this._headerElement.addEventListener("pointerdown", evt => this._onDown(evt));
         this._headerElement.addEventListener("pointerup", evt => this._onUp(evt));
         this._headerElement.addEventListener("pointerup", evt => this._onUp(evt));
@@ -105,8 +143,8 @@ export class GraphFrame {
     }
     }
 
 
     public cleanAccumulation() {
     public cleanAccumulation() {
-        this.x = this.gridAlignedX;
-        this.y = this.gridAlignedY;
+        this.x = this._gridAlignedX;
+        this.y = this._gridAlignedY;
     }
     }
 
 
     private _onDown(evt: PointerEvent) {
     private _onDown(evt: PointerEvent) {
@@ -164,5 +202,32 @@ export class GraphFrame {
         }
         }
 
 
         this.element.parentElement!.removeChild(this.element);
         this.element.parentElement!.removeChild(this.element);
+
+        
+        this._ownerCanvas.frames.splice(this._ownerCanvas.frames.indexOf(this), 1);
+    }
+
+    public serialize(): IFrameData {
+        return {
+            x: this._x,
+            y: this._y,
+            width: this._width,
+            height: this._height,
+            color: this._color.asArray(),
+            name: this.name
+        }
+    }
+
+    public static Parse(serializationData: IFrameData, canvas: GraphCanvasComponent) {
+        let newFrame = new GraphFrame(null, canvas);
+
+        newFrame.x = serializationData.x;
+        newFrame.y = serializationData.y;
+        newFrame.width = serializationData.width;
+        newFrame.height = serializationData.height;
+        newFrame.name = serializationData.name;
+        newFrame.color = Color3.FromArray(serializationData.color);
+
+        return newFrame;
     }
     }
 }
 }

+ 3 - 3
nodeEditor/src/graphEditor.tsx

@@ -303,9 +303,9 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
         if (!editorData || !editorData.locations) {
         if (!editorData || !editorData.locations) {
             this._graphCanvas.distributeGraph();
             this._graphCanvas.distributeGraph();
         } else {
         } else {
-            this._graphCanvas.x = editorData.x || 0;
-            this._graphCanvas.y = editorData.y || 0;
-            this._graphCanvas.zoom = editorData.zoom || 1;
+            this._graphCanvas.processEditorData(editorData);
+
+            // Locations
             for (var location of editorData.locations) {
             for (var location of editorData.locations) {
                 for (var node of this._graphCanvas.nodes) {
                 for (var node of this._graphCanvas.nodes) {
                     if (node.block && node.block.uniqueId === location.blockId) {
                     if (node.block && node.block.uniqueId === location.blockId) {

+ 10 - 0
nodeEditor/src/nodeLocationInfo.ts

@@ -4,9 +4,19 @@ export interface INodeLocationInfo {
     y: number;
     y: number;
 }
 }
 
 
+export interface IFrameData {
+    x: number;
+    y: number;
+    width: number;
+    height: number;
+    color: number[];
+    name: string
+}
+
 export interface IEditorData {
 export interface IEditorData {
     locations: INodeLocationInfo[];
     locations: INodeLocationInfo[];
     x: number;
     x: number;
     y: number;
     y: number;
     zoom: number;
     zoom: number;
+    frames: IFrameData[];
 }
 }