Browse Source

Merge remote-tracking branch 'upstream/master'

Eugene 9 years ago
parent
commit
57d4ee5e9d

+ 14 - 0
Script/AtomicEditor/editor/EditorEvents.ts

@@ -90,3 +90,17 @@ export interface SceneEditStateChangeEvent {
   serializable: Atomic.Serializable;
   serializable: Atomic.Serializable;
 
 
 }
 }
+
+export const InspectorProjectReference = "InspectorProjectReference";
+export interface InspectorProjectReferenceEvent {
+
+    // The full path to the resource to edit
+    path: string;
+
+}
+
+export const RemoveCurrentAssetAssigned = "RemoveCurrentAssetAssigned";
+export interface RemoveCurrentAssetAssignedEvent {
+
+}
+

+ 43 - 3
Script/AtomicEditor/ui/frames/ProjectFrame.ts

@@ -19,6 +19,10 @@ class ProjectFrame extends ScriptWidget {
     resourceFolder: ToolCore.Asset;
     resourceFolder: ToolCore.Asset;
     assetGUIDToItemID = {};
     assetGUIDToItemID = {};
     resourcesID: number = -1;
     resourcesID: number = -1;
+    assetReferencePath: string = null;
+    currentReferencedButton: Atomic.UIButton = null;
+    containerScrollToHeight: number;
+    containerScrollToHeightCounter: number;
 
 
     constructor(parent: Atomic.UIWidget) {
     constructor(parent: Atomic.UIWidget) {
 
 
@@ -50,6 +54,7 @@ class ProjectFrame extends ScriptWidget {
         this.subscribeToEvent("ResourceAdded", (ev: ToolCore.ResourceAddedEvent) => this.handleResourceAdded(ev));
         this.subscribeToEvent("ResourceAdded", (ev: ToolCore.ResourceAddedEvent) => this.handleResourceAdded(ev));
         this.subscribeToEvent("ResourceRemoved", (ev: ToolCore.ResourceRemovedEvent) => this.handleResourceRemoved(ev));
         this.subscribeToEvent("ResourceRemoved", (ev: ToolCore.ResourceRemovedEvent) => this.handleResourceRemoved(ev));
         this.subscribeToEvent("AssetRenamed", (ev: ToolCore.AssetRenamedEvent) => this.handleAssetRenamed(ev));
         this.subscribeToEvent("AssetRenamed", (ev: ToolCore.AssetRenamedEvent) => this.handleAssetRenamed(ev));
+        this.subscribeToEvent(EditorEvents.InspectorProjectReference, (ev: EditorEvents.InspectorProjectReferenceEvent) => { this.handleInspectorProjectReferenceHighlight(ev.path) });
 
 
         folderList.subscribeToEvent("UIListViewSelectionChanged", (event: Atomic.UIListViewSelectionChangedEvent) => this.handleFolderListSelectionChangedEvent(event));
         folderList.subscribeToEvent("UIListViewSelectionChanged", (event: Atomic.UIListViewSelectionChangedEvent) => this.handleFolderListSelectionChangedEvent(event));
 
 
@@ -213,13 +218,17 @@ class ProjectFrame extends ScriptWidget {
                     } else {
                     } else {
 
 
                         this.sendEvent(EditorEvents.EditResource, { "path": asset.path });
                         this.sendEvent(EditorEvents.EditResource, { "path": asset.path });
-
                     }
                     }
 
 
                 }
                 }
 
 
             }
             }
 
 
+            if (this.currentReferencedButton) {
+                this.currentReferencedButton.setState(4, false);
+                this.currentReferencedButton = null;
+            }
+
         }
         }
 
 
         return false;
         return false;
@@ -382,6 +391,18 @@ class ProjectFrame extends ScriptWidget {
 
 
     }
     }
 
 
+    // Shows referenced file in projectframe
+    handleInspectorProjectReferenceHighlight(path: string): void {
+        this.assetReferencePath = path;
+        var db = ToolCore.getAssetDatabase();
+        var asset = db.getAssetByPath(this.resourceFolder.getPath() + "/" + path);
+
+        this.folderList.selectAllItems(false);
+        this.folderList.selectItemByID(asset.parent.guid, true);
+        this.refreshContent(asset.parent);
+        this.folderList.scrollToSelectedItem();
+    }
+
     private refreshContent(folder: ToolCore.Asset) {
     private refreshContent(folder: ToolCore.Asset) {
 
 
         if (this.currentFolder != folder) {
         if (this.currentFolder != folder) {
@@ -399,12 +420,17 @@ class ProjectFrame extends ScriptWidget {
 
 
         var assets = db.getFolderAssets(folder.path);
         var assets = db.getFolderAssets(folder.path);
 
 
+        this.containerScrollToHeightCounter = 0;
+
         for (var i in assets) {
         for (var i in assets) {
 
 
             var asset = assets[i];
             var asset = assets[i];
-
             container.addChild(this.createButtonLayout(asset));
             container.addChild(this.createButtonLayout(asset));
+            this.containerScrollToHeightCounter++;
         }
         }
+       
+        var containerScroll: Atomic.UIScrollContainer = <Atomic.UIScrollContainer>this.getWidget("contentcontainerscroll");
+        containerScroll.scrollTo(0, this.containerScrollToHeight);
 
 
     }
     }
 
 
@@ -442,11 +468,25 @@ class ProjectFrame extends ScriptWidget {
 
 
         var button = new Atomic.UIButton();
         var button = new Atomic.UIButton();
 
 
+
+
         // setup the drag object
         // setup the drag object
         button.dragObject = new Atomic.UIDragObject(asset, asset.name);
         button.dragObject = new Atomic.UIDragObject(asset, asset.name);
 
 
         var lp = new Atomic.UILayoutParams;
         var lp = new Atomic.UILayoutParams;
-        lp.height = 20;
+        var buttonHeight = lp.height = 20;
+        
+        //Get the path of the button and compare it to the asset's path to highlight 
+        var resourcePath = this.resourceFolder.getPath() + "/" + this.assetReferencePath;
+
+        //Highlight Button UI
+        if (resourcePath == asset.path) {
+
+            button.setState(4, true);
+            this.currentReferencedButton = button;
+            this.containerScrollToHeight = this.containerScrollToHeightCounter * buttonHeight;
+
+        }
 
 
         var fd = new Atomic.UIFontDescription();
         var fd = new Atomic.UIFontDescription();
         fd.id = "Vera";
         fd.id = "Vera";

+ 32 - 0
Script/AtomicEditor/ui/frames/inspector/AttributeInfoEdit.ts

@@ -8,6 +8,7 @@
 import EditorUI = require("ui/EditorUI");
 import EditorUI = require("ui/EditorUI");
 import InspectorUtils = require("./InspectorUtils");
 import InspectorUtils = require("./InspectorUtils");
 import SerializableEditType = require("./SerializableEditType");
 import SerializableEditType = require("./SerializableEditType");
+import EditorEvents = require("editor/EditorEvents");
 
 
 class AttributeInfoEdit extends Atomic.UILayout {
 class AttributeInfoEdit extends Atomic.UILayout {
 
 
@@ -700,6 +701,37 @@ class ResourceRefAttributeEdit extends AttributeInfoEdit {
                     }
                     }
                 }
                 }
                 this.editField.text = text;
                 this.editField.text = text;
+
+                this.editField.subscribeToEvent(this.editField, "WidgetEvent", (ev: Atomic.UIWidgetEvent) => {
+
+                    if (ev.type == Atomic.UI_EVENT_TYPE_POINTER_DOWN) {
+
+                        resource = <Atomic.Resource>object.getAttribute(this.attrInfo.name);
+
+                        if (resource instanceof Atomic.JSComponentFile) {
+
+                            var pathName = resource.name;
+                            this.sendEvent(EditorEvents.InspectorProjectReference, { "path": pathName });
+
+                        } else if (resource instanceof Atomic.Model) {
+
+                            var asset = ToolCore.assetDatabase.getAssetByCachePath(resource.name);
+                            this.sendEvent(EditorEvents.InspectorProjectReference, { "path": asset.getRelativePath() });
+
+                        } else if (resource instanceof Atomic.Animation) {
+
+                             var animCacheReferenceName = resource.name.replace("_"+(<Atomic.Animation>resource).animationName, "");
+                             var asset = ToolCore.assetDatabase.getAssetByCachePath(animCacheReferenceName);
+                             this.sendEvent(EditorEvents.InspectorProjectReference, { "path": asset.getRelativePath() });
+
+                        } else {
+
+                            //Unknown Resource
+
+                        }
+                    }
+
+                });
             }
             }
 
 
 
 

+ 56 - 19
Script/AtomicEditor/ui/frames/inspector/ComponentAttributeUI.ts

@@ -9,6 +9,7 @@ import EditorUI = require("ui/EditorUI");
 import InspectorUtils = require("./InspectorUtils");
 import InspectorUtils = require("./InspectorUtils");
 import AttributeInfoEdit = require("./AttributeInfoEdit");
 import AttributeInfoEdit = require("./AttributeInfoEdit");
 import SerializableEditType = require("./SerializableEditType");
 import SerializableEditType = require("./SerializableEditType");
+import EditorEvents = require("editor/EditorEvents");
 
 
 class LightCascadeAttributeEdit extends AttributeInfoEdit {
 class LightCascadeAttributeEdit extends AttributeInfoEdit {
 
 
@@ -106,6 +107,7 @@ class LightCascadeAttributeEdit extends AttributeInfoEdit {
 interface MaterialEdit {
 interface MaterialEdit {
 
 
     index: number;
     index: number;
+    pathReference: string;
     editField: Atomic.UIEditField;
     editField: Atomic.UIEditField;
     selectButton: Atomic.UIButton;
     selectButton: Atomic.UIButton;
 
 
@@ -121,12 +123,47 @@ class SubmeshAttributeEdit extends AttributeInfoEdit {
     enabledCheckBox: Atomic.UICheckBox;
     enabledCheckBox: Atomic.UICheckBox;
     nameField: Atomic.UITextField;
     nameField: Atomic.UITextField;
     name: string;
     name: string;
+    matIndex: number;
 
 
     constructor(name: string) {
     constructor(name: string) {
 
 
         super();
         super();
         this.name = name;
         this.name = name;
         this.hideName = true;
         this.hideName = true;
+
+        this.subscribeToEvent(EditorEvents.RemoveCurrentAssetAssigned, (ev: EditorEvents.RemoveCurrentAssetAssignedEvent) => {
+
+            this.editType.onAttributeInfoEdited(this.attrInfo, null, this.matIndex);
+            this.refresh();
+        });
+
+
+    }
+
+    openResourceSelectionBox(materialIndex: number, resourceTypeName: string, importerName: string) {
+
+        this.matIndex = materialIndex;
+
+        EditorUI.getModelOps().showResourceSelection("Select " + resourceTypeName + " Resource", importerName, resourceTypeName, function (retObject: any) {
+
+            var resource: Atomic.Resource = null;
+
+            if (retObject instanceof ToolCore.Asset) {
+
+                resource = (<ToolCore.Asset>retObject).getResource(resourceTypeName);
+
+            } else if (retObject instanceof Atomic.Resource) {
+
+                resource = <Atomic.Resource>retObject;
+
+            }
+
+            this.sendEvent(EditorEvents.InspectorProjectReference, { "path": resource.name });
+            this.editType.onAttributeInfoEdited(this.attrInfo, resource, materialIndex);
+            this.refresh();
+
+        }.bind(this));
+
     }
     }
 
 
     createMaterialEdit(materialIndex: number) {
     createMaterialEdit(materialIndex: number) {
@@ -141,32 +178,18 @@ class SubmeshAttributeEdit extends AttributeInfoEdit {
 
 
         var selectButton = o.selectButton;
         var selectButton = o.selectButton;
 
 
-        var materialEdit: MaterialEdit = { index: materialIndex, editField: o.editField, selectButton: selectButton };
+        var materialEdit: MaterialEdit = { index: materialIndex, pathReference: "" , editField: o.editField, selectButton: selectButton };
         this.materialEdits[materialIndex] = materialEdit;
         this.materialEdits[materialIndex] = materialEdit;
 
 
         var resourceTypeName = "Material";
         var resourceTypeName = "Material";
         var importerName = ToolCore.assetDatabase.getResourceImporterName(resourceTypeName);
         var importerName = ToolCore.assetDatabase.getResourceImporterName(resourceTypeName);
 
 
-        selectButton.onClick = () => {
-
-            EditorUI.getModelOps().showResourceSelection("Select " + resourceTypeName + " Resource", importerName, resourceTypeName, function(retObject: any) {
-
-                var resource: Atomic.Resource = null;
-
-                if (retObject instanceof ToolCore.Asset) {
 
 
-                    resource = (<ToolCore.Asset>retObject).getResource(resourceTypeName);
-
-                } else if (retObject instanceof Atomic.Resource) {
-
-                    resource = <Atomic.Resource>retObject;
-
-                }
+        selectButton.onClick = () => {
 
 
-                this.editType.onAttributeInfoEdited(this.attrInfo, resource, materialIndex);
-                this.refresh();
+            this.openResourceSelectionBox(materialIndex, resourceTypeName, importerName);
+           // this.sendEvent(EditorEvents.InspectorProjectReference, { "path": pathName });
 
 
-            }.bind(this));
         };
         };
 
 
         // handle dropping of component on field
         // handle dropping of component on field
@@ -191,7 +214,7 @@ class SubmeshAttributeEdit extends AttributeInfoEdit {
                 if (importer) {
                 if (importer) {
 
 
                     var resource = asset.getResource(resourceTypeName);
                     var resource = asset.getResource(resourceTypeName);
-
+                    this.sendEvent(EditorEvents.InspectorProjectReference, { "path": resource.name });
                     this.editType.onAttributeInfoEdited(this.attrInfo, resource, materialIndex);
                     this.editType.onAttributeInfoEdited(this.attrInfo, resource, materialIndex);
                     this.refresh();
                     this.refresh();
                 }
                 }
@@ -199,6 +222,19 @@ class SubmeshAttributeEdit extends AttributeInfoEdit {
 
 
         });
         });
 
 
+        o.editField.subscribeToEvent(o.editField, "WidgetEvent", (ev: Atomic.UIWidgetEvent) => {
+
+            if (ev.type == Atomic.UI_EVENT_TYPE_POINTER_DOWN && o.editField.text != "") {
+
+                var pathName = materialEdit.pathReference;
+                this.sendEvent(EditorEvents.InspectorProjectReference, { "path": pathName });
+
+            } else if (o.editField.text == "") {
+
+                this.openResourceSelectionBox(materialIndex, resourceTypeName, importerName);
+            }
+
+        });
     }
     }
 
 
     createEditWidget() {
     createEditWidget() {
@@ -332,6 +368,7 @@ class SubmeshAttributeEdit extends AttributeInfoEdit {
 
 
                     var pathinfo = Atomic.splitPath(text);
                     var pathinfo = Atomic.splitPath(text);
                     matEdit.editField.text = pathinfo.fileName;
                     matEdit.editField.text = pathinfo.fileName;
+                    matEdit.pathReference = text;
                 }
                 }
 
 
 
 

+ 58 - 8
Script/AtomicEditor/ui/frames/inspector/MaterialInspector.ts

@@ -8,6 +8,7 @@
 import ScriptWidget = require("ui/ScriptWidget");
 import ScriptWidget = require("ui/ScriptWidget");
 import UIEvents = require("ui/UIEvents");
 import UIEvents = require("ui/UIEvents");
 import EditorUI = require("ui/EditorUI");
 import EditorUI = require("ui/EditorUI");
+import EditorEvents = require("editor/EditorEvents");
 
 
 import TextureSelector = require("./TextureSelector");
 import TextureSelector = require("./TextureSelector");
 
 
@@ -73,6 +74,10 @@ for (var key in techniqueLookup) {
 
 
 class MaterialInspector extends ScriptWidget {
 class MaterialInspector extends ScriptWidget {
 
 
+    currentTexture: Atomic.UITextureWidget = null;
+    tunit: number;
+    textureWidget: Atomic.UITextureWidget 
+
     constructor() {
     constructor() {
 
 
         super();
         super();
@@ -80,7 +85,7 @@ class MaterialInspector extends ScriptWidget {
         this.fd.id = "Vera";
         this.fd.id = "Vera";
         this.fd.size = 11;
         this.fd.size = 11;
 
 
-
+        this.subscribeToEvent(EditorEvents.RemoveCurrentAssetAssigned, (ev: EditorEvents.RemoveCurrentAssetAssignedEvent) => this.createTextureRemoveButtonCallback(this.tunit, this.textureWidget));
     }
     }
 
 
     createShaderParametersSection(): Atomic.UISection {
     createShaderParametersSection(): Atomic.UISection {
@@ -237,22 +242,38 @@ class MaterialInspector extends ScriptWidget {
 
 
     }
     }
 
 
-    createTextureButtonCallback(textureUnit:number, textureWidget:Atomic.UITextureWidget) {
 
 
-      return  () => {
+    openTextureSelectionBox(textureUnit: number, textureWidget: Atomic.UITextureWidget) {
 
 
         var inspector = this;
         var inspector = this;
+        
+        EditorUI.getModelOps().showResourceSelection("Select Texture", "TextureImporter", "Texture2D", function (asset: ToolCore.Asset, args: any) {
 
 
-        EditorUI.getModelOps().showResourceSelection("Select Texture", "TextureImporter", "Texture2D", function(asset: ToolCore.Asset, args: any) {
-
-            var texture = <Atomic.Texture2D> Atomic.cache.getResource("Texture2D", asset.path);
+            var texture = <Atomic.Texture2D>Atomic.cache.getResource("Texture2D", asset.path);
 
 
             if (texture) {
             if (texture) {
                 inspector.material.setTexture(textureUnit, texture);
                 inspector.material.setTexture(textureUnit, texture);
                 textureWidget.texture = inspector.getTextureThumbnail(texture);
                 textureWidget.texture = inspector.getTextureThumbnail(texture);
+
+                this.sendEvent(EditorEvents.InspectorProjectReference, { "path": texture.getName() });
             }
             }
 
 
         });
         });
+        
+    }
+    
+     // Big Texture Button(referenced texture file path in project frame)
+    createTextureButtonCallback(textureUnit:number, textureWidget:Atomic.UITextureWidget) {
+        
+        return () => {
+
+            var texture = this.material.getTexture(textureUnit);
+
+            if (textureWidget.getTexture() != null) {
+                this.sendEvent(EditorEvents.InspectorProjectReference, { "path": texture.getName() });
+            } else {
+                this.openTextureSelectionBox(textureUnit, textureWidget);
+            }
 
 
         return true;
         return true;
 
 
@@ -260,6 +281,27 @@ class MaterialInspector extends ScriptWidget {
 
 
     }
     }
 
 
+   // Small Texture Button (Opens texture selection window)
+    createTextureReferenceButtonCallback(textureUnit: number, textureWidget: Atomic.UITextureWidget) {
+
+        return () => {
+            this.tunit = textureUnit;
+            this.textureWidget = textureWidget;
+            this.openTextureSelectionBox(textureUnit, textureWidget);
+            return true;
+        };
+    }
+
+    //Remove Texture Button
+    createTextureRemoveButtonCallback(textureUnit: number, textureWidget: Atomic.UITextureWidget) {
+
+            var texture = this.material.getTexture(textureUnit);
+
+            if (texture != null && textureWidget != null) {
+                textureWidget.setTexture(null);
+            }
+
+    }
 
 
     createTextureSection(): Atomic.UISection {
     createTextureSection(): Atomic.UISection {
 
 
@@ -276,8 +318,7 @@ class MaterialInspector extends ScriptWidget {
         section.contentRoot.addChild(attrsVerticalLayout);
         section.contentRoot.addChild(attrsVerticalLayout);
 
 
         // TODO: Filter on technique
         // TODO: Filter on technique
-        var textureUnits = [Atomic.TU_DIFFUSE, Atomic.TU_NORMAL, Atomic.TU_SPECULAR ,Atomic.TU_EMISSIVE];//, Atomic.TU_ENVIRONMENT,
-        //Atomic.TU_CUSTOM1, Atomic.TU_CUSTOM2];
+        var textureUnits = [ Atomic.TU_DIFFUSE, Atomic.TU_NORMAL, Atomic.TU_SPECULAR, Atomic.TU_EMISSIVE ];
 
 
         for (var i in textureUnits) {
         for (var i in textureUnits) {
 
 
@@ -310,11 +351,19 @@ class MaterialInspector extends ScriptWidget {
             textureButton["tunit"] = tunit;
             textureButton["tunit"] = tunit;
             textureButton["textureWidget"] = textureWidget;
             textureButton["textureWidget"] = textureWidget;
 
 
+            //Create drop-down buttons to open Texture Selection Dialog Box
+            var textureRefButton = new Atomic.UIButton();
+            textureRefButton.skinBg = "arrow.down";
+            textureRefButton["tunit"] = tunit;
+            textureRefButton["textureWidget"] = textureWidget;
+
             textureButton.onClick = this.createTextureButtonCallback(tunit, textureWidget);
             textureButton.onClick = this.createTextureButtonCallback(tunit, textureWidget);
+            textureRefButton.onClick = this.createTextureReferenceButtonCallback(tunit, textureWidget);
 
 
             textureButton.contentRoot.addChild(textureWidget);
             textureButton.contentRoot.addChild(textureWidget);
 
 
             attrLayout.addChild(textureButton);
             attrLayout.addChild(textureButton);
+            attrLayout.addChild(textureRefButton);
 
 
             attrsVerticalLayout.addChild(attrLayout);
             attrsVerticalLayout.addChild(attrLayout);
 
 
@@ -335,6 +384,7 @@ class MaterialInspector extends ScriptWidget {
                         this.material.setTexture(ev.target["tunit"], texture);
                         this.material.setTexture(ev.target["tunit"], texture);
                         (<Atomic.UITextureWidget>ev.target["textureWidget"]).texture = this.getTextureThumbnail(texture);
                         (<Atomic.UITextureWidget>ev.target["textureWidget"]).texture = this.getTextureThumbnail(texture);
 
 
+                        this.sendEvent("InspectorProjectReference", { "path": texture.getName(), "ButtonID": texture.getName() });
                     }
                     }
                 }
                 }
             });
             });

+ 10 - 0
Script/AtomicEditor/ui/frames/inspector/ModelInspector.ts

@@ -8,6 +8,7 @@
 import InspectorWidget = require("./InspectorWidget");
 import InspectorWidget = require("./InspectorWidget");
 import ArrayEditWidget = require("./ArrayEditWidget");
 import ArrayEditWidget = require("./ArrayEditWidget");
 import InspectorUtils = require("./InspectorUtils");
 import InspectorUtils = require("./InspectorUtils");
+import EditorEvents = require("editor/EditorEvents");
 
 
 class ModelInspector extends InspectorWidget {
 class ModelInspector extends InspectorWidget {
 
 
@@ -75,6 +76,15 @@ class ModelInspector extends InspectorWidget {
         editField.readOnly = true;
         editField.readOnly = true;
         editField.text = asset.name;
         editField.text = asset.name;
 
 
+        //This should preferably be onClick
+        editField.subscribeToEvent(editField, "UIWidgetFocusChanged", (ev: Atomic.UIWidgetFocusChangedEvent) => {
+
+            if (ev.widget == editField && editField.focus) {
+                this.sendEvent(EditorEvents.InspectorProjectReference, { "path": asset.getRelativePath() });
+            }
+
+        });
+
         this.scaleEdit = InspectorUtils.createAttrEditField("Scale", modelLayout);
         this.scaleEdit = InspectorUtils.createAttrEditField("Scale", modelLayout);
         this.scaleEdit.text = this.importer.scale.toString();
         this.scaleEdit.text = this.importer.scale.toString();
 
 

+ 1 - 1
Script/AtomicEditor/ui/frames/menus/ProjectFrameMenu.ts

@@ -152,7 +152,7 @@ else if (Atomic.platform == "MacOSX") {
 var assetGeneralContextItems = {
 var assetGeneralContextItems = {
     "Rename": ["rename_asset", undefined, ""],
     "Rename": ["rename_asset", undefined, ""],
     "Force Reimport": ["force_reimport", undefined, ""],
     "Force Reimport": ["force_reimport", undefined, ""],
-    [showInFs]: ["reveal_folder", undefined, ""], 
+    [showInFs]: ["reveal_folder", undefined, ""],
     "-1": null,
     "-1": null,
     "Delete": ["delete_asset", undefined, ""]
     "Delete": ["delete_asset", undefined, ""]
 };
 };

+ 8 - 0
Script/AtomicEditor/ui/modal/ResourceSelection.ts

@@ -21,6 +21,8 @@ class ResourceSelection extends ModalWindow {
         var db = ToolCore.assetDatabase;
         var db = ToolCore.assetDatabase;
         var assets = db.getAssetsByImporterType(importerType, resourceType);
         var assets = db.getAssetsByImporterType(importerType, resourceType);
 
 
+        this.folderList.addRootItem("None", "", "");
+
         for (var i in assets) {
         for (var i in assets) {
 
 
             var asset = assets[i];
             var asset = assets[i];
@@ -116,6 +118,12 @@ class ResourceSelection extends ModalWindow {
 
 
         var id = this.folderList.selectedItemID;
         var id = this.folderList.selectedItemID;
 
 
+        if (id == "") {
+            this.sendEvent(EditorEvents.RemoveCurrentAssetAssigned);
+            this.hide();
+            return true;
+        }
+
         if (this.resourceType == "Animation") {
         if (this.resourceType == "Animation") {
 
 
           if (id.length) {
           if (id.length) {

+ 43 - 42
Script/AtomicWebViewEditor/interop.ts

@@ -4,56 +4,57 @@ import * as editorConfig from "./editor/editorConfig";
 
 
 export function saveCode() {
 export function saveCode() {
 
 
-    const data = {
-        message: "saveCode",
-        payload: editor.session.getValue()
-    };
-
-    window.atomicQuery({
-        request: JSON.stringify(data),
-        persistent: false,
-        onSuccess: function(response) {/**/ },
-        onFailure: function(error_code, error_message) {
-            console.log("Error getting code");
-        }
-    });
+  const data = {
+    message: "saveCode",
+    payload: editor.session.getValue()
+  };
+
+  window.atomicQuery({
+    request: JSON.stringify(data),
+    persistent: false,
+    onSuccess: function(response) {/**/ },
+    onFailure: function(error_code, error_message) {
+      console.log("Error getting code");
+    }
+  });
 }
 }
 
 
 export function codeLoaded(value: string, fileExt: string) {
 export function codeLoaded(value: string, fileExt: string) {
-    editor.session.setValue(value);
-    editor.gotoLine(0);
-
-    editor.getSession().on("change", function(e) {
-        window.atomicQuery({
-            request: "change",
-            persistent: false,
-            onSuccess: (response) => {/**/ },
-            onFailure: (error_code, error_message) => {
-                console.log("Error on change");
-            }
-        });
+  editor.session.setValue(value);
+  editor.gotoLine(0);
+
+  editor.getSession().on("change", function(e) {
+    window.atomicQuery({
+      request: "change",
+      persistent: false,
+      onSuccess: (response) => {/**/ },
+      onFailure: (error_code, error_message) => {
+        console.log("Error on change");
+      }
     });
     });
+  });
 }
 }
 
 
 export function loadCode(codeUrl: string) {
 export function loadCode(codeUrl: string) {
-    const fileExt = codeUrl.split(".").pop();
-
-    // go ahead and set the theme prior to pulling the file across
-    editorConfig.configure(fileExt);
-
-    const p = new Promise(function(resolve, reject) {
-        const xmlHttp = new XMLHttpRequest();
-        xmlHttp.onreadystatechange = () => {
-            if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
-                resolve(xmlHttp.responseText);
-            }
-        };
-        xmlHttp.open("GET", codeUrl, true); // true for asynchronous
-        xmlHttp.send(null);
-    }).then(function(src: string) {
-        codeLoaded(src, fileExt);
-    });
+  const fileExt = codeUrl.split(".").pop();
+
+  // go ahead and set the theme prior to pulling the file across
+  editorConfig.configure(fileExt);
+
+  const p = new Promise(function(resolve, reject) {
+    const xmlHttp = new XMLHttpRequest();
+    xmlHttp.onreadystatechange = () => {
+      if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
+        resolve(xmlHttp.responseText);
+      }
+    };
+    xmlHttp.open("GET", codeUrl, true); // true for asynchronous
+    xmlHttp.send(null);
+  }).then(function(src: string) {
+    codeLoaded(src, fileExt);
+  });
 }
 }
 
 
 // Set up the window object so the host can call into it
 // Set up the window object so the host can call into it
 window.loadCode = loadCode;
 window.loadCode = loadCode;
+window.saveCode = saveCode;

+ 1 - 0
Script/AtomicWebViewEditor/typings/AtomicQuery.d.ts

@@ -1,4 +1,5 @@
 interface Window {
 interface Window {
     atomicQuery: any;
     atomicQuery: any;
     loadCode: (codeUrl) => void;
     loadCode: (codeUrl) => void;
+    saveCode: () => void;
 }
 }

+ 13 - 8
Source/Atomic/UI/UIDragDrop.cpp

@@ -95,7 +95,7 @@ void UIDragDrop::DragEnd()
     dragSourceWidget_ = 0;
     dragSourceWidget_ = 0;
     dragLayout_->SetVisibility(UI_WIDGET_VISIBILITY_GONE);
     dragLayout_->SetVisibility(UI_WIDGET_VISIBILITY_GONE);
 
 
-    if (currentTargetWidget.Null() || dragSourceWidget == currentTargetWidget)
+    if (currentTargetWidget.Null())
     {
     {
         return;
         return;
     }
     }
@@ -146,6 +146,7 @@ void UIDragDrop::HandleMouseDown(StringHash eventType, VariantMap& eventData)
 
 
         currentTargetWidget_ = widget;
         currentTargetWidget_ = widget;
         dragSourceWidget_ = widget;
         dragSourceWidget_ = widget;
+        mouseDownPosition_ = input->GetMousePosition();
 
 
     }
     }
 
 
@@ -171,8 +172,6 @@ void UIDragDrop::HandleMouseUp(StringHash eventType, VariantMap& eventData)
 
 
 void UIDragDrop::HandleMouseMove(StringHash eventType, VariantMap& eventData)
 void UIDragDrop::HandleMouseMove(StringHash eventType, VariantMap& eventData)
 {
 {
-    Input* input = GetSubsystem<Input>();
-
     if (dragObject_.Null() && dragSourceWidget_.Null())
     if (dragObject_.Null() && dragSourceWidget_.Null())
         return;
         return;
 
 
@@ -188,6 +187,17 @@ void UIDragDrop::HandleMouseMove(StringHash eventType, VariantMap& eventData)
 
 
     }
     }
 
 
+    using namespace MouseMove;
+
+    int x = eventData[P_X].GetInt();
+    int y = eventData[P_Y].GetInt();
+
+    // tolerance to 8 pixels to start drag/drop operation
+    IntVector2 mousePos(x, y);
+    mousePos -= mouseDownPosition_;
+    if (Abs(mousePos.x_) < 8 && Abs(mousePos.y_) < 8)
+        return;
+
     // initialize if necessary
     // initialize if necessary
     if (dragLayout_->GetVisibility() == UI_WIDGET_VISIBILITY_GONE)
     if (dragLayout_->GetVisibility() == UI_WIDGET_VISIBILITY_GONE)
     {
     {
@@ -199,11 +209,6 @@ void UIDragDrop::HandleMouseMove(StringHash eventType, VariantMap& eventData)
         dragLayout_->SetRect(IntRect(0, 0, sz->GetMinWidth(), sz->GetMinHeight()));
         dragLayout_->SetRect(IntRect(0, 0, sz->GetMinWidth(), sz->GetMinHeight()));
     }
     }
 
 
-    using namespace MouseMove;
-
-    int x = eventData[P_X].GetInt();
-    int y = eventData[P_Y].GetInt();
-
     // see if we have a widget
     // see if we have a widget
     TBWidget* tbw = TBWidget::hovered_widget;
     TBWidget* tbw = TBWidget::hovered_widget;
 
 

+ 2 - 1
Source/Atomic/UI/UIDragDrop.h

@@ -69,7 +69,8 @@ private:
 
 
     SharedPtr<UIDragObject> dragObject_;
     SharedPtr<UIDragObject> dragObject_;
 
 
-
+    // initial mouse down position to handle whether or not to start a drag operation
+    IntVector2 mouseDownPosition_;
 
 
 };
 };
 
 

+ 44 - 11
Source/Atomic/UI/UIListView.cpp

@@ -852,6 +852,13 @@ void UIListView::SendItemSelectedChanged(ListViewItem* item)
 
 
 }
 }
 
 
+void UIListView::SelectItem(ListViewItem* item, bool select)
+{
+    item->SetSelected(select);
+    UpdateItemVisibility();
+    SendItemSelectedChanged(item);
+}
+
 bool UIListView::OnEvent(const tb::TBWidgetEvent &ev)
 bool UIListView::OnEvent(const tb::TBWidgetEvent &ev)
 {
 {
     if (ev.type == EVENT_TYPE_KEY_UP )
     if (ev.type == EVENT_TYPE_KEY_UP )
@@ -883,25 +890,51 @@ bool UIListView::OnEvent(const tb::TBWidgetEvent &ev)
             if (item->id == ev.target->GetID())
             if (item->id == ev.target->GetID())
             {
             {
                 bool multi = false;
                 bool multi = false;
-                if (multiSelect_ && (ev.modifierkeys & TB_SHIFT || ev.modifierkeys & TB_CTRL || ev.modifierkeys & TB_SUPER))
+                if (multiSelect_ && (ev.modifierkeys & TB_CTRL || ev.modifierkeys & TB_SUPER))
                     multi = true;
                     multi = true;
 
 
-                if (multi)
+                bool shiftMulti = false;
+                if (multiSelect_ && (ev.modifierkeys & TB_SHIFT))
+                    shiftMulti = true;
+
+                if (shiftMulti)
+                {
+                    int first = rootList_->GetValue();
+
+                    if (i > first)
+                    {
+                        for (int j = first + 1; j < i; j++)
+                        {
+                            ListViewItem* itemSelect = source_->GetItem(j);
+                            SelectItem(itemSelect, true);
+                            SetValueFirstSelected();
+                        }
+
+                        SelectItem(item, true);
+                        SetValueFirstSelected();
+                    }
+                    else if (i < first)
+                    {
+                        for (int j = first - 1; j > i; j--)
+                        {
+                            ListViewItem* itemSelect = source_->GetItem(j);
+                            SelectItem(itemSelect, true);
+                            SetValueFirstSelected();
+                        }
+
+                        SelectItem(item, true);
+                        SetValueFirstSelected();
+                    }
+                }
+                else if (multi)
                 {
                 {
                     if (item->GetSelected())
                     if (item->GetSelected())
                     {
                     {
-                        item->SetSelected(false);
-                        UpdateItemVisibility();
-
-                        SendItemSelectedChanged(item);
+                        SelectItem(item, false);
                     }
                     }
                     else
                     else
                     {
                     {
-
-                        item->SetSelected(true);
-                        UpdateItemVisibility();
-
-                        SendItemSelectedChanged(item);
+                        SelectItem(item, true);
                     }
                     }
 
 
                     SetValueFirstSelected();
                     SetValueFirstSelected();

+ 2 - 0
Source/Atomic/UI/UIListView.h

@@ -96,6 +96,8 @@ private:
 
 
     unsigned itemLookupId_;
     unsigned itemLookupId_;
 
 
+    void SelectItem(ListViewItem* item, bool select);
+
 };
 };
 
 
 }
 }

+ 7 - 0
Source/Atomic/UI/UIScrollContainer.cpp

@@ -104,6 +104,13 @@ UI_SCROLL_MODE UIScrollContainer::GetScrollMode()
 
 
 }
 }
 
 
+void UIScrollContainer::ScrollTo(int x, int y)
+{
+    if (!widget_)
+        return;
+
+    return ((TBScrollContainer *)widget_)->ScrollTo(x, y);
+}
 
 
 bool UIScrollContainer::OnEvent(const tb::TBWidgetEvent &ev)
 bool UIScrollContainer::OnEvent(const tb::TBWidgetEvent &ev)
 {
 {

+ 2 - 0
Source/Atomic/UI/UIScrollContainer.h

@@ -63,6 +63,8 @@ public:
     void SetAdaptContentSize(bool adapt);
     void SetAdaptContentSize(bool adapt);
     bool GetAdaptContentSize();
     bool GetAdaptContentSize();
 
 
+    void ScrollTo(int x, int y);
+
 
 
 protected:
 protected:
 
 

+ 18 - 14
Source/AtomicEditor/Editors/SceneEditor3D/SceneEditor3D.cpp

@@ -29,6 +29,7 @@
 #include <ToolCore/Project/ProjectUserPrefs.h>
 #include <ToolCore/Project/ProjectUserPrefs.h>
 #include <ToolCore/Assets/AssetDatabase.h>
 #include <ToolCore/Assets/AssetDatabase.h>
 #include <ToolCore/Assets/Asset.h>
 #include <ToolCore/Assets/Asset.h>
+#include <ToolCore/Assets/SceneImporter.h>
 
 
 
 
 #include "../../EditorMode/AEEditorEvents.h"
 #include "../../EditorMode/AEEditorEvents.h"
@@ -71,24 +72,19 @@ SceneEditor3D::SceneEditor3D(Context* context, const String &fullpath, UITabCont
     sceneView_ = new SceneView3D(context_, this);
     sceneView_ = new SceneView3D(context_, this);
     editHistory_ = new SceneEditHistory(context, this);
     editHistory_ = new SceneEditHistory(context, this);
 
 
-    // EARLY ACCESS
-    if (fullpath.Find(String("ToonTown")) != String::NPOS)
+    AssetDatabase* assetDB = GetSubsystem<AssetDatabase>();
+    Asset* sceneAsset = assetDB->GetAssetByPath(fullpath);
+
+    if (sceneAsset)
     {
     {
-        sceneView_->GetCameraNode()->SetWorldPosition(Vector3(-119.073f, 76.1121f, 16.47763f));
-        Quaternion q(0.55f, 0.14f,  0.8f, -0.2f);
-        sceneView_->SetYaw(q.YawAngle());
-        sceneView_->SetPitch(q.PitchAngle());
-        sceneView_->GetCameraNode()->SetWorldRotation(q);
+        sceneImporter_ = static_cast<SceneImporter*>(sceneAsset->GetImporter());
+        sceneView_->GetCameraNode()->SetWorldPosition(sceneImporter_->GetSceneCamPosition());
+        sceneView_->SetPitch(sceneImporter_->GetSceneCamRotation().PitchAngle());
+        sceneView_->SetYaw(sceneImporter_->GetSceneCamRotation().YawAngle());
     }
     }
     else
     else
     {
     {
-        Node* playerSpawn = scene_->GetChild("PlayerInfoStart", true);
-        if (playerSpawn)
-        {
-            sceneView_->GetCameraNode()->SetPosition(playerSpawn->GetPosition());
-            sceneView_->SetYaw(playerSpawn->GetRotation().EulerAngles().y_);
-        }
-
+        LOGERRORF("SceneEditor3D::SceneEditor3D - Unable to get scene asset");
     }
     }
 
 
     sceneView_->SetGravity(UI_GRAVITY_ALL);
     sceneView_->SetGravity(UI_GRAVITY_ALL);
@@ -237,6 +233,14 @@ void SceneEditor3D::Close(bool navigateToAvailableResource)
     data["Scene"] = scene_;
     data["Scene"] = scene_;
     SendEvent("EditorSceneClosed", data);
     SendEvent("EditorSceneClosed", data);
 
 
+    if (sceneImporter_.NotNull())
+    {
+        sceneImporter_->SetSceneCamPosition(sceneView_->GetCameraNode()->GetWorldPosition());
+        sceneImporter_->SetSceneCamRotation(sceneView_->GetCameraNode()->GetWorldRotation());
+        sceneImporter_->GetAsset()->Save();
+        sceneImporter_ = nullptr;
+    }
+
     ResourceEditor::Close(navigateToAvailableResource);
     ResourceEditor::Close(navigateToAvailableResource);
 }
 }
 
 

+ 2 - 0
Source/AtomicEditor/Editors/SceneEditor3D/SceneEditor3D.h

@@ -30,6 +30,7 @@ class Octree;
 namespace ToolCore
 namespace ToolCore
 {
 {
     class ProjectUserPrefs;
     class ProjectUserPrefs;
+    class SceneImporter;
 }
 }
 
 
 using namespace ToolCore;
 using namespace ToolCore;
@@ -110,6 +111,7 @@ private:
 
 
     SharedPtr<SceneSelection> selection_;
     SharedPtr<SceneSelection> selection_;
     SharedPtr<SceneEditHistory> editHistory_;
     SharedPtr<SceneEditHistory> editHistory_;
+    SharedPtr<SceneImporter> sceneImporter_;
 
 
     SharedPtr<Node> clipboardNode_;
     SharedPtr<Node> clipboardNode_;
 
 

+ 2 - 0
Source/ThirdParty/TurboBadger/tb_editfield.cpp

@@ -232,6 +232,8 @@ bool TBEditField::OnEvent(const TBWidgetEvent &ev)
         {
         {
             // Post a message to start selection scroll
             // Post a message to start selection scroll
             PostMessageDelayed(TBIDC("selscroll"), nullptr, SELECTION_SCROLL_DELAY);
             PostMessageDelayed(TBIDC("selscroll"), nullptr, SELECTION_SCROLL_DELAY);
+            // forward to delegate, if any
+            TBWidget::OnEvent(ev);
             return true;
             return true;
         }
         }
     }
     }

+ 19 - 2
Source/ToolCore/Assets/SceneImporter.cpp

@@ -5,6 +5,8 @@
 // license information: https://github.com/AtomicGameEngine/AtomicGameEngine
 // license information: https://github.com/AtomicGameEngine/AtomicGameEngine
 //
 //
 
 
+#include <Atomic/Core/StringUtils.h>
+
 #include "Asset.h"
 #include "Asset.h"
 #include "AssetDatabase.h"
 #include "AssetDatabase.h"
 #include "SceneImporter.h"
 #include "SceneImporter.h"
@@ -25,6 +27,9 @@ SceneImporter::~SceneImporter()
 void SceneImporter::SetDefaults()
 void SceneImporter::SetDefaults()
 {
 {
     AssetImporter::SetDefaults();
     AssetImporter::SetDefaults();
+
+    sceneCamRotation_ = Quaternion::IDENTITY;
+    sceneCamPosition_ = Vector3::ZERO;
 }
 }
 
 
 bool SceneImporter::Import()
 bool SceneImporter::Import()
@@ -39,6 +44,14 @@ bool SceneImporter::LoadSettingsInternal(JSONValue& jsonRoot)
 
 
     JSONValue import = jsonRoot.Get("SceneImporter");
     JSONValue import = jsonRoot.Get("SceneImporter");
 
 
+    SetDefaults();
+
+    if (import.Get("sceneCamRotation").IsString())
+        sceneCamRotation_ = ToQuaternion(import.Get("sceneCamRotation").GetString());
+
+    if (import.Get("sceneCamPosition").IsString())
+        sceneCamPosition_ = ToVector3(import.Get("sceneCamPosition").GetString());
+
     return true;
     return true;
 }
 }
 
 
@@ -47,8 +60,12 @@ bool SceneImporter::SaveSettingsInternal(JSONValue& jsonRoot)
     if (!AssetImporter::SaveSettingsInternal(jsonRoot))
     if (!AssetImporter::SaveSettingsInternal(jsonRoot))
         return false;
         return false;
 
 
-    JSONValue import(JSONValue::emptyObject);
-    jsonRoot.Set("SceneImporter", import);
+    JSONValue save;
+
+    save.Set("sceneCamRotation", sceneCamRotation_.ToString());
+    save.Set("sceneCamPosition", sceneCamPosition_.ToString());
+
+    jsonRoot.Set("SceneImporter", save);
 
 
     return true;
     return true;
 }
 }

+ 13 - 0
Source/ToolCore/Assets/SceneImporter.h

@@ -23,6 +23,16 @@ public:
 
 
     virtual void SetDefaults();
     virtual void SetDefaults();
 
 
+    /// Set the scene camera's rotation
+    void SetSceneCamRotation(const Quaternion& rotation) { sceneCamRotation_ = rotation; }
+    /// Set the scene camera's position
+    void SetSceneCamPosition(const Vector3& position) { sceneCamPosition_ = position; }
+
+    /// Get the scene camera's rotation
+    const Quaternion& GetSceneCamRotation() const { return sceneCamRotation_; }
+    /// Get the scene camera's position
+    const Vector3& GetSceneCamPosition() const { return sceneCamPosition_; }
+
 protected:
 protected:
 
 
     bool Import();
     bool Import();
@@ -30,6 +40,9 @@ protected:
     virtual bool LoadSettingsInternal(JSONValue& jsonRoot);
     virtual bool LoadSettingsInternal(JSONValue& jsonRoot);
     virtual bool SaveSettingsInternal(JSONValue& jsonRoot);
     virtual bool SaveSettingsInternal(JSONValue& jsonRoot);
 
 
+    Quaternion sceneCamRotation_;
+    Vector3 sceneCamPosition_;
+
 };
 };
 
 
 }
 }

+ 5 - 1
Source/ToolCore/JSBind/JSBDoc.cpp

@@ -50,7 +50,11 @@ static String GetScriptType(JSBFunctionType* ftype)
 
 
 void JSBDoc::Begin()
 void JSBDoc::Begin()
 {
 {
-    source_ += "//Atomic JSDoc Definitions\n\n\n";
+    source_ += "//////////////////////////////////////////////////////////\n";
+    source_ += "// IMPORTANT: THIS FILE IS GENERATED, CHANGES WILL BE LOST\n";
+    source_ += "//////////////////////////////////////////////////////////\n\n";
+
+    source_ += "//Atomic JSDoc Definitions\n\n";
 
 
     source_ += "/**\n * Atomic Game Engine\n * @namespace\n*/\n var " + package_->GetName() + " = {}\n\n";
     source_ += "/**\n * Atomic Game Engine\n * @namespace\n*/\n var " + package_->GetName() + " = {}\n\n";
 }
 }

+ 4 - 1
Source/ToolCore/JSBind/JSBTypeScript.cpp

@@ -75,8 +75,11 @@ String JSBTypeScript::GetScriptType(JSBFunctionType* ftype)
 
 
 void JSBTypeScript::Begin()
 void JSBTypeScript::Begin()
 {
 {
-    source_ += "//Atomic TypeScript Definitions\n\n\n";
+    source_ += "//////////////////////////////////////////////////////////\n";
+    source_ += "// IMPORTANT: THIS FILE IS GENERATED, CHANGES WILL BE LOST\n";
+    source_ += "//////////////////////////////////////////////////////////\n\n";
 
 
+    source_ += "// Atomic TypeScript Definitions\n\n";
 
 
     if (package_->GetName() != "Atomic")
     if (package_->GetName() != "Atomic")
     {
     {