Selaa lähdekoodia

adding snippet server

msDestiny14 4 vuotta sitten
vanhempi
commit
2915bfa4fb

+ 26 - 44
guiEditor/src/components/propertyTab/propertyTabComponent.tsx

@@ -15,6 +15,9 @@ import { Engine } from 'babylonjs/Engines/engine';
 import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
 import { Observer } from 'babylonjs/Misc/observable';
 import { TextLineComponent } from "../../sharedUiComponents/lines/textLineComponent";
+import { StringTools } from "../../stringTools";
+import { AdvancedDynamicTexture } from "babylonjs-gui/2D/index";
+//import { SceneExplorerComponent } from "../sceneExplorer/sceneExplorerComponent";
 
 require("./propertyTab.scss");
 
@@ -72,18 +75,9 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
         }, undefined, true);
     }
 
-    loadFrame(file: File) {
-        Tools.ReadFile(file, (data) => {
-            // get Frame Data from file
-            //let decoder = new TextDecoder("utf-8");
-           // const frameData = JSON.parse(decoder.decode(data));
-           // SerializationTools.AddFrameToMaterial(frameData, this.props.globalState, this.props.globalState.nodeMaterial);
-        }, undefined, true);
-    }
-
     save() {
-        //let json = SerializationTools.Serialize(this.props.globalState.nodeMaterial, this.props.globalState);
-        //StringTools.DownloadAsFile(this.props.globalState.hostDocument, json, "nodeMaterial.json");
+        let json = JSON.stringify(this.props.globalState.guiTexture.serializeContent());
+        StringTools.DownloadAsFile(this.props.globalState.hostDocument, json, "guiTexture.json");
     }
 
     customSave() {
@@ -96,83 +90,70 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
     }
 
     saveToSnippetServer() {
-        /*const material = this.props.globalState.nodeMaterial;
-        const xmlHttp = new XMLHttpRequest();
-
-        let json = SerializationTools.Serialize(material, this.props.globalState);
+        var adt = this.props.globalState.guiTexture;
+        let content = JSON.stringify(adt.serializeContent());
 
+        var xmlHttp = new XMLHttpRequest();
         xmlHttp.onreadystatechange = () => {
             if (xmlHttp.readyState == 4) {
                 if (xmlHttp.status == 200) {
                     var snippet = JSON.parse(xmlHttp.responseText);
-                    const oldId = material.snippetId;
-                    material.snippetId = snippet.id;
+                    const oldId = adt.snippetId || "_BLANK";
+                    adt.snippetId = snippet.id;
                     if (snippet.version && snippet.version != "0") {
-                        material.snippetId += "#" + snippet.version;
+                        adt.snippetId += "#" + snippet.version;
                     }
-
                     this.forceUpdate();
                     if (navigator.clipboard) {
-                        navigator.clipboard.writeText(material.snippetId);
+                        navigator.clipboard.writeText(adt.snippetId);
                     }
 
                     let windowAsAny = window as any;
 
                     if (windowAsAny.Playground && oldId) {
                         windowAsAny.Playground.onRequestCodeChangeObservable.notifyObservers({
-                            regex: new RegExp(oldId, "g"),
-                            replace: material.snippetId
+                            regex: new RegExp(`parseFromSnippetAsync\\("${oldId}`, "g"),
+                            replace: `parseFromSnippetAsync("${adt.snippetId}`
                         });
                     }
 
-                    this.props.globalState.hostDocument.defaultView!.alert("NodeMaterial saved with ID: " + material.snippetId + " (please note that the id was also saved to your clipboard)");
-
+                    alert("GUI saved with ID: " + adt.snippetId + " (please note that the id was also saved to your clipboard)");
                 }
                 else {
-                    this.props.globalState.hostDocument.defaultView!.alert(`Unable to save your node material. It may be too large (${(dataToSend.payload.length / 1024).toFixed(2)} KB) because of embedded textures. Please reduce texture sizes or point to a specific url instead of embedding them and try again.`);
+                    alert("Unable to save your GUI");
                 }
             }
-        };
+        }
 
-        xmlHttp.open("POST", NodeMaterial.SnippetUrl + (material.snippetId ? "/" + material.snippetId : ""), true);
+        xmlHttp.open("POST", AdvancedDynamicTexture.SnippetUrl + (adt.snippetId ? "/" + adt.snippetId : ""), true);
         xmlHttp.setRequestHeader("Content-Type", "application/json");
 
         var dataToSend = {
             payload : JSON.stringify({
-                nodeMaterial: json
+                gui: content
             }),
             name: "",
             description: "",
             tags: ""
         };
 
-        xmlHttp.send(JSON.stringify(dataToSend));*/
+        xmlHttp.send(JSON.stringify(dataToSend));
     }
 
     loadFromSnippet() {
-        /*const material = this.props.globalState.nodeMaterial;
-        const scene = material.getScene();
 
         let snippedID = window.prompt("Please enter the snippet ID to use");
 
         if (!snippedID) {
             return;
         }
-
         this.props.globalState.onSelectionChangedObservable.notifyObservers(null);
-
-        NodeMaterial.ParseFromSnippetAsync(snippedID, scene, "", material).then(() => {
-            material.build();
-            if (!this.changeMode(this.props.globalState.nodeMaterial!.mode, true, false)) {
-                this.props.globalState.onResetRequiredObservable.notifyObservers();
-            }
-        }).catch((err) => {
-            this.props.globalState.hostDocument.defaultView!.alert("Unable to load your node material: " + err);
-        });*/
+        this.props.globalState.guiTexture.parseFromSnippetAsync(snippedID);
     }
 
-
     render() {
+
+        //var myScene=this.props.globalState.guiTexture.getScene();
         if (this.state.currentNode) {
             return (
                 <div id="propertyTab">
@@ -182,6 +163,8 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
                             GUI EDITOR
                         </div>
                     </div>
+                    {//myScene && <SceneExplorerComponent globalState={this.props.globalState} scene={myScene}></SceneExplorerComponent>
+                    }
                     {this.state.currentNode?.renderProperties()}
                 </div>
             );
@@ -248,10 +231,9 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
                                 this.customSave();
                             }} />
                         }
-                        <FileButtonLineComponent label="Load Frame" onClick={(file) => this.loadFrame(file)} accept=".json" />
                     </LineContainerComponent>
                     {
-                        !this.props.globalState.customSave &&
+                        
                         <LineContainerComponent title="SNIPPET">
                             <ButtonLineComponent label="Load from snippet server" onClick={() => this.loadFromSnippet()} />
                             <ButtonLineComponent label="Save to snippet server" onClick={() => {

+ 30 - 1
guiEditor/src/diagram/guiNode.ts

@@ -7,6 +7,8 @@ import * as React from 'react';
 import { GenericPropertyComponent } from './properties/genericNodePropertyComponent';
 import { Control } from 'babylonjs-gui/2D/controls/control';
 import { Vector2 } from 'babylonjs/Maths/math.vector';
+import { Container } from 'babylonjs-gui/2D/controls/container';
+import { _ThinInstanceDataStorage } from 'babylonjs';
 
 export class GUINode {
     private _x = 0;
@@ -21,7 +23,7 @@ export class GUINode {
     private _isSelected: boolean;
     private _isVisible = true;
     private _enclosingFrameId = -1;
-
+    private _isContainer = false;
     public get isVisible() {
         return this._isVisible;
     }
@@ -104,6 +106,8 @@ export class GUINode {
     public constructor(globalState: GlobalState, public guiNode: Control) {
         this._globalState = globalState;
         this._ownerCanvas = this._globalState.workbench;
+        this.x = guiNode.leftInPixels;
+        this.y = guiNode.topInPixels;
         
         guiNode.onPointerUpObservable.add(evt => {
             this.clicked = false;
@@ -129,6 +133,8 @@ export class GUINode {
         }
         );
 
+        this._isContainer = this.isContainer();
+
         //TODO: Implement
         this._onSelectionBoxMovedObserver = this._globalState.onSelectionBoxMoved.add(rect1 => {
         });
@@ -177,6 +183,29 @@ export class GUINode {
         this.guiNode.topInPixels = this.y;
     }
 
+    private isContainer() {
+        switch (this.guiNode.typeName) {
+            case "Button":
+            case "StackPanel":
+            case "Rectangle":
+                return true;
+            default:
+                return false;
+        }
+    }
+
+
+    public addGui(childNode: GUINode)
+    {
+        if(!this._isContainer) return;
+        
+        (this.guiNode as Container).addControl(childNode.guiNode);
+        
+        //adjust the position to be relative
+        childNode.x = this.x - childNode.x;
+        childNode.y = this.y - childNode.y;
+    }
+
     public dispose() {
         // notify frame observers that this node is being deleted
         this._globalState.onGraphNodeRemovalObservable.notifyObservers(this);

+ 13 - 1
guiEditor/src/diagram/workbench.tsx

@@ -203,7 +203,7 @@ export class WorkbenchComponent extends React.Component<IWorkbenchComponentProps
         }
 		return gridSize * Math.floor(position / gridSize);
     }
-    
+
     public getGridPositionCeil(position: number) {
         let gridSize = this.gridSize;
 		if (gridSize === 0) {
@@ -212,6 +212,18 @@ export class WorkbenchComponent extends React.Component<IWorkbenchComponentProps
 		return gridSize * Math.ceil(position / gridSize);
 	}
 
+    loadFromGuiTexture(serializationObject: any) {
+        this.globalState.onSelectionChangedObservable.notifyObservers(null);
+        this._guiNodes = [];
+        this.globalState.guiTexture.parseContent(serializationObject);
+        var children = this.globalState.guiTexture.getChildren();
+
+        children[0].children.forEach(guiElement => {
+            var newGuiNode = new GUINode(this.props.globalState, guiElement);
+            this._guiNodes.push(newGuiNode);
+        });
+    }
+
     updateTransform() {
         this._rootContainer.style.transform = `translate(${this._x}px, ${this._y}px) scale(${this._zoom})`;
 

+ 1 - 1
guiEditor/src/serializationTools.ts

@@ -31,7 +31,7 @@ export class SerializationTools {
 
     public static Deserialize(serializationObject: any, globalState: GlobalState) {
         globalState.onIsLoadingChanged.notifyObservers(true);
-
+        globalState.workbench.loadFromGuiTexture(serializationObject);
     }
 
     public static AddFrameToMaterial(serializationObject: any, globalState: GlobalState, currentMaterial: NodeMaterial) {

+ 87 - 0
guiEditor/src/stringTools.ts

@@ -0,0 +1,87 @@
+export class StringTools {
+    /*
+     * Based on FileSaver.js
+     * A saveAs() FileSaver implementation.
+     *
+     * By Eli Grey, http://eligrey.com
+     *
+     * License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
+     * source  : http://purl.eligrey.com/github/FileSaver.js
+     */
+    private static _SaveAs(blob: Blob, name: string, document: HTMLDocument) {
+        if ('download' in HTMLAnchorElement.prototype) {
+            var URL = window.URL || window.webkitURL;
+            var a = document.createElement('a');
+        
+            a.download = name;
+            a.rel = 'noopener'; // tabnabbing
+
+            a.href = URL.createObjectURL(blob)
+            setTimeout(() => { URL.revokeObjectURL(a.href) }, 4E4) // 40s
+            setTimeout(() => { this._Click(a, document) }, 0);
+            return;
+        }
+
+        // Open a popup immediately do go around popup blocker
+        // Mostly only available on user interaction and the fileReader is async so...
+        var popup = open('', '_blank');
+        if (popup) {
+            popup.document.title = popup.document.body.innerText = 'downloading...';
+        }
+
+        var force = blob.type === 'application/octet-stream';
+        var isSafari = /constructor/i.test((window as any).HTMLElement) || (window as any).safari;
+        var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
+
+        if ((isChromeIOS || (force && isSafari)) && typeof FileReader !== 'undefined') {
+            // Safari doesn't allow downloading of blob URLs
+            var reader = new FileReader();
+            reader.onloadend = () => {
+                var url:any = reader.result;
+                url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;');
+                if (popup) {
+                    popup.location.href = url;
+                }
+                else {
+                    location = url;
+                }
+                popup = null;
+            }
+            reader.readAsDataURL(blob);
+        } else {
+            var URL = window.URL || window.webkitURL
+            var url = URL.createObjectURL(blob)
+            if (popup) {
+                popup.location.href = url;
+            }
+            else {
+                location.href = url;
+            }
+            popup = null;
+            setTimeout(function () { URL.revokeObjectURL(url) }, 4E4);
+        }
+    }
+
+    private static _Click(node: HTMLElement, document: HTMLDocument) {
+        try {
+            node.dispatchEvent(new MouseEvent('click'))
+        } catch (e) {
+            var evt = document.createEvent('MouseEvents');
+            evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
+            node.dispatchEvent(evt);
+        }
+    }
+
+    /**
+     * Download a string into a file that will be saved locally by the browser
+     * @param content defines the string to download locally as a file
+     */
+    public static DownloadAsFile(document: HTMLDocument, content: string, filename: string) {
+        let blob = new Blob([content],
+            {
+                type: "application/octet-stream"
+            });
+
+        this._SaveAs(blob, filename, document);        
+    }
+}