Browse Source

Add support for basic asset renaming (with import type overrides possible), add PrefabInspector with name + apply button

Josh Engebretson 10 years ago
parent
commit
fda4fa5d30

+ 28 - 9
Script/AtomicEditor/ui/frames/ProjectFrame.ts

@@ -49,6 +49,7 @@ class ProjectFrame extends ScriptWidget {
 
         this.subscribeToEvent("ResourceAdded", (ev: ToolCore.ResourceAddedEvent) => this.handleResourceAdded(ev));
         this.subscribeToEvent("ResourceRemoved", (ev: ToolCore.ResourceRemovedEvent) => this.handleResourceRemoved(ev));
+        this.subscribeToEvent("AssetRenamed", (ev: ToolCore.AssetRenamedEvent) => this.handleAssetRenamed(ev));
 
         // this.subscribeToEvent(EditorEvents.ResourceFolderCreated, (ev: EditorEvents.ResourceFolderCreatedEvent) => this.handleResourceFolderCreated(ev));
 
@@ -61,12 +62,29 @@ class ProjectFrame extends ScriptWidget {
 
     }
 
+    handleAssetRenamed(ev: ToolCore.AssetRenamedEvent) {
+
+        var container: Atomic.UILayout = <Atomic.UILayout>this.getWidget("contentcontainer");
+
+        for (var widget = container.firstChild; widget; widget = widget.next) {
+
+            if (widget.id == ev.asset.guid) {
+
+                if (widget['assetButton'])
+                    widget['assetButton'].text = ev.asset.name + ev.asset.extension;
+
+                break;
+            }
+        }
+
+    }
+
     handleResourceRemoved(ev: ToolCore.ResourceRemovedEvent) {
 
         var folderList = this.folderList;
         folderList.deleteItemByID(ev.guid);
 
-        var container: Atomic.UILayout = <Atomic.UILayout> this.getWidget("contentcontainer");
+        var container: Atomic.UILayout = <Atomic.UILayout>this.getWidget("contentcontainer");
 
         for (var widget = container.firstChild; widget; widget = widget.next) {
 
@@ -106,7 +124,7 @@ class ProjectFrame extends ScriptWidget {
 
         } else if (parent == this.currentFolder) {
 
-            var container: Atomic.UILayout = <Atomic.UILayout> this.getWidget("contentcontainer");
+            var container: Atomic.UILayout = <Atomic.UILayout>this.getWidget("contentcontainer");
             container.addChild(this.createButtonLayout(asset));
 
         }
@@ -161,7 +179,7 @@ class ProjectFrame extends ScriptWidget {
 
                 if (id == "folderList_") {
 
-                    var list = <Atomic.UISelectList> data.target;
+                    var list = <Atomic.UISelectList>data.target;
 
                     var selectedId = list.selectedItemID;
 
@@ -230,7 +248,7 @@ class ProjectFrame extends ScriptWidget {
 
         if (data.target) {
 
-            var container: Atomic.UILayout = <Atomic.UILayout> this.getWidget("contentcontainer");
+            var container: Atomic.UILayout = <Atomic.UILayout>this.getWidget("contentcontainer");
 
             if (data.target.id == "contentcontainerscroll" || container.isAncestorOf(data.target)) {
 
@@ -260,13 +278,13 @@ class ProjectFrame extends ScriptWidget {
         var dragObject = data.dragObject;
         if (dragObject.object && dragObject.object.typeName == "Node") {
 
-            var node = <Atomic.Node> dragObject.object;
+            var node = <Atomic.Node>dragObject.object;
 
-            var prefabComponent = <Atomic.PrefabComponent> node.getComponent("PrefabComponent");
+            var prefabComponent = <Atomic.PrefabComponent>node.getComponent("PrefabComponent");
 
             if (prefabComponent) {
 
-              prefabComponent.savePrefab();
+                prefabComponent.savePrefab();
 
             }
             else {
@@ -324,7 +342,7 @@ class ProjectFrame extends ScriptWidget {
         this.folderList.deleteAllItems();
         this.resourceFolder = null;
 
-        var container: Atomic.UILayout = <Atomic.UILayout> this.getWidget("contentcontainer");
+        var container: Atomic.UILayout = <Atomic.UILayout>this.getWidget("contentcontainer");
         container.deleteAllChildren();
 
     }
@@ -341,7 +359,7 @@ class ProjectFrame extends ScriptWidget {
 
         var db = ToolCore.getAssetDatabase();
 
-        var container: Atomic.UILayout = <Atomic.UILayout> this.getWidget("contentcontainer");
+        var container: Atomic.UILayout = <Atomic.UILayout>this.getWidget("contentcontainer");
         container.deleteAllChildren();
 
         var assets = db.getFolderAssets(folder.path);
@@ -411,6 +429,7 @@ class ProjectFrame extends ScriptWidget {
         button.fontDescription = fd;
         button.text = asset.name + asset.extension;
         button.skinBg = "TBButton.flat";
+        blayout['assetButton'] = button;
         blayout.addChild(button);
 
         return blayout;

+ 8 - 0
Script/AtomicEditor/ui/frames/inspector/InspectorFrame.ts

@@ -15,6 +15,7 @@ import MaterialInspector = require("./MaterialInspector");
 import ModelInspector = require("./ModelInspector");
 import NodeInspector = require("./NodeInspector");
 import AssemblyInspector = require("./AssemblyInspector");
+import PrefabInspector = require("./PrefabInspector");
 
 class InspectorFrame extends ScriptWidget {
 
@@ -124,6 +125,13 @@ class InspectorFrame extends ScriptWidget {
 
         }
 
+        if (asset.importerTypeName == "PrefabImporter") {
+
+            var prefabInspector = new PrefabInspector();
+            container.addChild(prefabInspector);
+            
+            prefabInspector.inspect(asset);
+        }
 
     }
 

+ 90 - 0
Script/AtomicEditor/ui/frames/inspector/PrefabInspector.ts

@@ -0,0 +1,90 @@
+//
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+// LICENSE: Atomic Game Engine Editor and Tools EULA
+// Please see LICENSE_ATOMIC_EDITOR_AND_TOOLS.md in repository root for
+// license information: https://github.com/AtomicGameEngine/AtomicGameEngine
+//
+
+import InspectorWidget = require("./InspectorWidget");
+import ArrayEditWidget = require("./ArrayEditWidget");
+import InspectorUtils = require("./InspectorUtils");
+
+class PrefabInspector extends InspectorWidget {
+
+    constructor() {
+
+        super();
+
+        this.fd.id = "Vera";
+        this.fd.size = 11;
+
+        this.subscribeToEvent(this, "WidgetEvent", (data) => this.handleWidgetEvent(data));
+
+    }
+
+    handleWidgetEvent(ev: Atomic.UIWidgetEvent) {
+
+    }
+
+    onApply() {
+
+        var nameText = this.nameEdit.text;
+        if (nameText != this.asset.name) {
+            if (!this.asset.rename(nameText)) {
+                this.nameEdit.text = this.asset.name;
+            }
+        }
+    }
+
+    inspect(asset: ToolCore.Asset) {
+
+        this.asset = asset;
+        this.importer = <ToolCore.PrefabImporter>asset.importer;
+
+        // node attr layout
+        var rootLayout = this.rootLayout;
+
+        // Assembly Section
+        var prefabLayout = this.createSection(rootLayout, "Prefab", 1);
+
+        var container = InspectorUtils.createContainer();
+        container.gravity = Atomic.UI_GRAVITY_ALL;
+        prefabLayout.addChild(container);
+
+        var panel = new Atomic.UILayout();
+        panel.axis = Atomic.UI_AXIS_Y;
+        panel.layoutSize = Atomic.UI_LAYOUT_SIZE_PREFERRED;
+        panel.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
+        container.addChild(panel);
+
+        // Name Edit
+        this.nameEdit = this.createAttrEditField("Name", panel);
+        this.nameEdit.text = this.asset.name;
+
+        var applyButton = this.createApplyButton();
+        panel.addChild(applyButton);
+
+        /*
+        var editButton = new Atomic.UIButton();
+        editButton.fontDescription = this.fd;
+        editButton.text = "Edit";
+
+        editButton.onClick = function() {
+
+        }.bind(this);
+
+        prefabLayout.addChild(editButton);
+        */
+
+
+    }
+
+    nameEdit: Atomic.UIEditField;
+
+    asset: ToolCore.Asset;
+    importer: ToolCore.PrefabImporter;
+    fd: Atomic.UIFontDescription = new Atomic.UIFontDescription();
+
+}
+
+export = PrefabInspector;

+ 16 - 10
Script/TypeScript/AtomicWork.d.ts

@@ -213,8 +213,8 @@ declare module AtomicNET {
 
     export interface CSComponentClassChangedEvent {
 
-      cscomponent: CSComponent;
-      classname: string;
+        cscomponent: CSComponent;
+        classname: string;
 
     }
 
@@ -242,30 +242,36 @@ declare module ToolCore {
 
     export interface AssetImportErrorEvent {
 
-        path:string;
-        guid:string;
+        path: string;
+        guid: string;
         error: string;
+    }
+
+    export interface AssetRenamedEvent {
+
+        asset: Asset;
 
     }
 
+
     export interface PlatformChangedEvent {
 
-        platform:ToolCore.Platform;
+        platform: ToolCore.Platform;
 
     }
 
     export interface BuildOutputEvent {
 
-        text:string;
+        text: string;
 
     }
 
     export interface BuildCompleteEvent {
 
-      platformID:number;
-      message:string;
-      success:boolean;
-      buildFolder:string;
+        platformID: number;
+        message: string;
+        success: boolean;
+        buildFolder: string;
 
     }
 

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

@@ -367,6 +367,23 @@ bool Asset::SetPath(const String& path)
 
 }
 
+bool Asset::Rename(const String& newName)
+{
+    if (importer_.Null())
+        return false;
+
+    bool result = importer_->Rename(newName);
+
+    if (result)
+    {
+        VariantMap eventData;
+        eventData[AssetRenamed::P_ASSET] = this;
+        SendEvent(E_ASSETRENAMED, eventData);
+    }
+
+    return result;
+}
+
 Resource* Asset::GetResource(const String &typeName)
 {
     if (importer_)

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

@@ -23,6 +23,7 @@ namespace ToolCore
 class Asset : public Object
 {
     friend class AssetDatabase;
+    friend class AssetImporter;
 
     OBJECT(Asset);
 
@@ -40,6 +41,7 @@ public:
     const String& GetGUID() const { return guid_; }
     const String& GetName() const { return name_; }
     const String& GetPath() const { return path_; }
+
     String GetExtension() const;
     /// Get the path relative to project
     String GetRelativePath();
@@ -68,6 +70,9 @@ public:
     // get the .asset filename
     String GetDotAssetFilename();
 
+    /// Rename the asset, which depending on the asset type may be nontrivial
+    bool Rename(const String& newName);
+
     bool IsFolder() const { return isFolder_; }
 
     // load .asset

+ 4 - 0
Source/ToolCore/Assets/AssetEvents.h

@@ -28,5 +28,9 @@ EVENT(E_ASSETIMPORTERROR, AssetImportError)
     PARAM(P_ERROR, Error);                  // string
 }
 
+EVENT(E_ASSETRENAMED, AssetRenamed)
+{
+    PARAM(P_ASSET, Asset);                  // asset ptr
+}
 
 }

+ 41 - 0
Source/ToolCore/Assets/AssetImporter.cpp

@@ -5,6 +5,7 @@
 // license information: https://github.com/AtomicGameEngine/AtomicGameEngine
 //
 
+#include <Atomic/IO/Log.h>
 #include <Atomic/IO/File.h>
 #include <Atomic/IO/FileSystem.h>
 #include "AssetDatabase.h"
@@ -52,5 +53,45 @@ bool AssetImporter::SaveSettingsInternal(JSONValue& jsonRoot)
     return true;
 }
 
+bool AssetImporter::Rename(const String& newName)
+{
+    String pathName, fileName, ext;
+
+    SplitPath(asset_->path_, pathName, fileName, ext);
+
+    String newPath = pathName + newName + ext;
+
+    FileSystem* fs = GetSubsystem<FileSystem>();
+
+    if (fs->FileExists(newPath) || fs->DirExists(newPath))
+        return false;
+
+    // rename asset first, ahead of the filesystem watcher
+    String oldPath = asset_->path_;
+
+    asset_->name_ = newName;
+    asset_->path_ = newPath;
+
+    // first rename the .asset file
+    if (!fs->Rename(oldPath + ".asset", newPath + ".asset"))
+    {
+        LOGERRORF("Unable to rename asset: %s to %s", GetNativePath(oldPath + ".asset").CString(), GetNativePath(newPath + ".asset").CString());
+        return false;
+    }
+
+    // now rename the asset file itself
+    if (!fs->Rename(oldPath, newPath))
+    {
+        // restore .asset
+        fs->Rename(newPath + ".asset", oldPath + ".asset");
+
+        LOGERRORF("Unable to rename: %s to %s", GetNativePath(oldPath).CString(), GetNativePath(newPath).CString());
+        return false;
+    }
+
+    return true;
+
+}
+
 
 }

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

@@ -48,6 +48,8 @@ public:
     /// Instantiate a node from the asset
     virtual Node* InstantiateNode(Node* parent, const String& name) { return 0; }
 
+    virtual bool Rename(const String& newName);
+
 protected:
 
     virtual bool Import() { return true; }