Explorar o código

Adding resource selection modal, with support for selection of asset by import type, add selection buttons for models, materials, and components

Josh Engebretson %!s(int64=10) %!d(string=hai) anos
pai
achega
e4d1675c4d

+ 19 - 0
Resources/EditorData/AtomicEditor/editor/ui/resourceselection.tb.txt

@@ -0,0 +1,19 @@
+definitions
+	menubutton		
+		lp: height: 20
+		font: name: Vera, size: 11
+TBLayout: distribution: gravity, axis: y, id: resourceselectionframe
+	lp: min-width: 220
+	TBLayout: distribution: gravity
+		TBEditField
+			id filter
+			gravity left right
+			placeholder @search
+			type search	
+	TBWidget: gravity: all
+		TBLayout: distribution: gravity, id: resourcecontainer, gravity: all
+	TBLayout: 
+		TBButton: text: Select, id: select
+		TBButton: text: Cancel, id: cancel
+	
+

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

@@ -18,7 +18,6 @@ export interface SceneClosedEvent {
 
 }
 
-
 export const ContentFolderChanged = "ContentFolderChanged";
 export interface ContentFolderChangedEvent {
 

+ 1 - 0
Script/AtomicEditor/tsconfig.json

@@ -51,6 +51,7 @@
         "./ui/modal/ModalWindow.ts",
         "./ui/modal/NewProject.ts",
         "./ui/modal/ProgressModal.ts",
+        "./ui/modal/ResourceSelection.ts",
         "./ui/modal/UIResourceOps.ts",
         "./ui/playmode/PlayMode.ts"
     ]

+ 56 - 16
Script/AtomicEditor/ui/inspector/ComponentInspector.ts

@@ -2,6 +2,7 @@
 import ScriptWidget = require("../ScriptWidget");
 import DataBinding = require("./DataBinding");
 import InspectorUtils = require("./InspectorUtils");
+import EditorUI = require("../EditorUI");
 
 class ComponentInspector extends Atomic.UISection {
 
@@ -47,6 +48,11 @@ class ComponentInspector extends Atomic.UISection {
         var nlp = new Atomic.UILayoutParams();
         nlp.width = 304;
 
+        // atttribute name layout param
+        var atlp = new Atomic.UILayoutParams();
+        atlp.width = 100;
+
+
         var attrsVerticalLayout = new Atomic.UILayout(Atomic.UI_AXIS_Y);
         attrsVerticalLayout.spacing = 3;
         attrsVerticalLayout.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
@@ -75,6 +81,7 @@ class ComponentInspector extends Atomic.UISection {
             var name = new Atomic.UITextField();
             name.textAlign = Atomic.UI_TEXT_ALIGN_LEFT;
             name.skinBg = "InspectorTextAttrName";
+            name.layoutParams = atlp;
 
             if (attr.type == Atomic.VAR_VECTOR3 || attr.type == Atomic.VAR_COLOR ||
                 attr.type == Atomic.VAR_QUATERNION) {
@@ -195,10 +202,23 @@ class ComponentInspector extends Atomic.UISection {
         var staticModel = <Atomic.StaticModel> this.component;
         var cacheModel = staticModel.model;
 
-        // MODEL FIELD
-        var field = InspectorUtils.createAttrEditField("Model", layout);
+        var o = InspectorUtils.createAttrEditFieldWithSelectButton("Model", layout);
+        var field = o.editField;
         field.readOnly = true;
 
+        var select = o.selectButton;
+
+        select.onClick = () => {
+
+            EditorUI.getModelOps().showResourceSelection("Select Model", "ModelImporter", function(asset: ToolCore.Asset) {
+
+                staticModel.model = <Atomic.Model> Atomic.cache.getResource("Model", asset.cachePath + ".mdl");
+                field.text = asset.name;
+
+            });
+
+        }
+
         if (cacheModel) {
 
             var asset = ToolCore.assetDatabase.getAssetByCachePath(cacheModel.name);
@@ -239,9 +259,27 @@ class ComponentInspector extends Atomic.UISection {
 
         // MATERIAL FIELD (single material, not multimaterial for now)
 
-        var materialField = InspectorUtils.createAttrEditField("Material", layout);
+        o = InspectorUtils.createAttrEditFieldWithSelectButton("Material", layout);
+        var materialField = o.editField;
         materialField.readOnly = true;
 
+        select = o.selectButton;
+
+        select.onClick = () => {
+
+            EditorUI.getModelOps().showResourceSelection("Select Material", "MaterialImporter", function(asset: ToolCore.Asset) {
+
+                staticModel.setMaterial(<Atomic.Material> Atomic.cache.getResource("Material", asset.path));
+
+                if (staticModel.getMaterial())
+                    materialField.text = staticModel.getMaterial().name;
+                else
+                    materialField.text = "";
+
+            });
+
+        }
+
         var material = staticModel.getMaterial();
 
         if (material) {
@@ -285,22 +323,25 @@ class ComponentInspector extends Atomic.UISection {
         // expand prefab
         this.value = 1;
 
-        var fd = new Atomic.UIFontDescription();
-        fd.id = "Vera";
-        fd.size = 11;
+        var o = InspectorUtils.createAttrEditFieldWithSelectButton("Script", layout);
+        var field = o.editField;
+        field.readOnly = true;
+        field.text = js.componentFile ? js.componentFile.name : "";
 
-        var selectButton = new Atomic.UIButton();
-        selectButton.text = "Select Script";
-        selectButton.fontDescription = fd;
+        var select = o.selectButton;
 
-        selectButton.onClick = () => {
+        select.onClick = () => {
 
-            return true;
-        }
+            EditorUI.getModelOps().showResourceSelection("Select JSComponent Script", "JavascriptImporter", function(asset: ToolCore.Asset) {
 
-        var field = InspectorUtils.createAttrEditField("Script", layout);
-        field.readOnly = true;
-        field.text = js.componentFile ? js.componentFile.name : "";
+                js.componentFile = <Atomic.JSComponentFile> Atomic.cache.getResource("JSComponentFile", asset.path);
+
+                if (js.componentFile)
+                    field.text = js.componentFile.name;
+
+            });
+
+        }
 
         // handle dropping of component on field
         field.subscribeToEvent(field, "DragEnded", (ev: Atomic.DragEndedEvent) => {
@@ -326,7 +367,6 @@ class ComponentInspector extends Atomic.UISection {
 
         });
 
-        layout.addChild(selectButton);
 
     }
 

+ 34 - 0
Script/AtomicEditor/ui/inspector/InspectorUtils.ts

@@ -38,6 +38,12 @@ class InspectorUtils {
     nameField.skinBg = "InspectorTextAttrName";
     nameField.text = name;
     nameField.fontDescription = InspectorUtils.attrFontDesc;
+
+    // atttribute name layout param
+    var atlp = new Atomic.UILayoutParams();
+    atlp.width = 100;
+    nameField.layoutParams = atlp;
+
     return nameField;
   }
 
@@ -73,6 +79,34 @@ class InspectorUtils {
 
   }
 
+  static createAttrEditFieldWithSelectButton(name:string, parent:Atomic.UIWidget):{editField:Atomic.UIEditField, selectButton:Atomic.UIButton} {
+
+    var attrLayout = new Atomic.UILayout();
+    attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_POSITION_LEFT_TOP;
+
+    var _name = InspectorUtils.createAttrName(name);
+    attrLayout.addChild(_name);
+
+    var fieldLayout = new Atomic.UILayout();
+    fieldLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_POSITION_LEFT_TOP;
+
+    var edit = InspectorUtils.createEditField();
+
+    var selectButton = new Atomic.UIButton();
+    selectButton.text = "...";
+    selectButton.fontDescription = InspectorUtils.attrFontDesc;
+
+    fieldLayout.addChild(edit);
+    fieldLayout.addChild(selectButton);
+
+    attrLayout.addChild(fieldLayout);
+    parent.addChild(attrLayout);
+
+    return {editField:edit, selectButton:selectButton};
+
+  }
+
+
   // "static constructor"
   private static attrFontDesc:Atomic.UIFontDescription;
 

+ 0 - 2
Script/AtomicEditor/ui/modal/MessageModal.ts

@@ -17,7 +17,6 @@ export class MessageModal extends Atomic.ScriptObject
 
     super();
 
-    // Subscribe to graphics subsystems screen mode switching, so we can adjust the widget size
     this.subscribeToEvent(UIEvents.MessageModalEvent, (data) => {
 
       if (data.type == "error") {
@@ -28,7 +27,6 @@ export class MessageModal extends Atomic.ScriptObject
 
     });
 
-
   }
 
 }

+ 12 - 0
Script/AtomicEditor/ui/modal/ModalOps.ts

@@ -7,6 +7,8 @@ import EULAWindow = require("../license/EULAWindow");
 import ActivationWindow = require("../license/ActivationWindow");
 import ActivationSuccessWindow = require("../license/ActivationSuccessWindow");
 
+import ResourceSelection = require("./ResourceSelection");
+
 import UIResourceOps = require("./UIResourceOps");
 
 class ModalOps extends Atomic.ScriptObject {
@@ -69,6 +71,16 @@ class ModalOps extends Atomic.ScriptObject {
 
     }
 
+    showResourceSelection(windowText:string, importerType:string, callback: (asset: ToolCore.Asset) => any) {
+
+      if (this.show()) {
+
+          this.opWindow = new ResourceSelection(windowText, importerType, callback);
+
+      }
+
+    }
+
     showNewProject() {
 
         if (this.show()) {

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

@@ -0,0 +1,91 @@
+
+import EditorUI = require("../EditorUI");
+import EditorEvents = require("../../editor/EditorEvents");
+import ModalWindow = require("./ModalWindow");
+
+class ResourceSelection extends ModalWindow {
+
+    folderList: Atomic.UIListView;
+    callback: (asset: ToolCore.Asset) => any;
+
+    populate(importerType: string) {
+
+        var db = ToolCore.assetDatabase;
+        var assets = db.getAssetsByImporterType(importerType);
+
+        for (var i in assets) {
+
+            var asset = assets[i];
+
+            if (importerType == "JavascriptImporter") {
+                if (!(<ToolCore.JavascriptImporter> asset.importer).isComponentFile())
+                    continue;
+            }
+
+            this.folderList.addRootItem(asset.relativePath, "", asset.guid);
+
+        }
+
+    }
+
+    constructor(windowText: string, importerType: string, callback: (asset: ToolCore.Asset) => any) {
+
+        super();
+
+        this.callback = callback;
+
+        this.load("AtomicEditor/editor/ui/resourceselection.tb.txt");
+
+        var foldercontainer = this.getWidget("resourcecontainer");
+
+        var folderList = this.folderList = new Atomic.UIListView();
+
+        folderList.rootList.id = "resourceList_";
+
+        foldercontainer.addChild(folderList);
+
+        this.populate(importerType);
+
+        this.text = windowText;
+        this.setSize(800, 600);
+        this.center();
+
+    }
+
+    handleWidgetEvent(ev: Atomic.UIWidgetEvent) {
+
+        if (ev.type == Atomic.UI_EVENT_TYPE_CLICK) {
+
+            var id = ev.target.id;
+
+            if (id == "select") {
+
+                var id = this.folderList.selectedItemID;
+
+                if (id.length) {
+
+                  this.callback(ToolCore.assetDatabase.getAssetByGUID(id));
+
+                }
+
+
+                this.hide();
+
+                return true;
+
+            }
+
+            if (id == "cancel") {
+
+                this.hide();
+
+                return true;
+            }
+
+        }
+
+    }
+}
+
+
+export = ResourceSelection;

+ 3 - 0
Script/TypeScript/ToolCore.d.ts

@@ -234,6 +234,7 @@ declare module ToolCore {
       guid: string;
       name: string;
       path: string;
+      relativePath: string;
       cachePath: string;
       timestamp: number;
       importerType: string;
@@ -252,6 +253,8 @@ declare module ToolCore {
       getGUID(): string;
       getName(): string;
       getPath(): string;
+      // Get the path relative to project
+      getRelativePath(): string;
       getCachePath(): string;
       getTimestamp(): number;
       getImporterType(): string;

+ 15 - 0
Source/ToolCore/Assets/Asset.cpp

@@ -3,6 +3,9 @@
 #include <Atomic/IO/File.h>
 #include <Atomic/IO/FileSystem.h>
 
+#include "../ToolSystem.h"
+#include "../Project/Project.h"
+
 #include "AssetDatabase.h"
 #include "ModelImporter.h"
 #include "FolderImporter.h"
@@ -44,6 +47,18 @@ Asset* Asset::GetParent()
 
 }
 
+String Asset::GetRelativePath()
+{
+    Project* project =GetSubsystem<ToolSystem>()->GetProject();
+
+    String path = path_;
+
+    path.Replace(project->GetResourcePath(), "", false);
+
+    return path;
+
+}
+
 bool Asset::CheckCacheFile()
 {
     if (importer_.Null() || !importer_->RequiresCacheFile())

+ 2 - 0
Source/ToolCore/Assets/Asset.h

@@ -32,6 +32,8 @@ public:
     const String& GetGUID() const { return guid_; }
     const String& GetName() const { return name_; }
     const String& GetPath() const { return path_; }
+    /// Get the path relative to project
+    String GetRelativePath();
     String GetCachePath() const;
     unsigned GetTimestamp() const { return timestamp_; }