Browse Source

Added an example of how to add a custom inspector.

Johnny 9 years ago
parent
commit
c5529cb883
21 changed files with 892 additions and 1 deletions
  1. 5 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors.asset
  2. 82 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ExampleInspector.js
  3. 7 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ExampleInspector.js.asset
  4. 117 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ExampleInspector.ts
  5. 7 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ExampleInspector.ts.asset
  6. 167 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/InspectorUtils.js
  7. 7 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/InspectorUtils.js.asset
  8. 249 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/InspectorUtils.ts
  9. 7 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/InspectorUtils.ts.asset
  10. 48 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ScriptWidget.js
  11. 7 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ScriptWidget.js.asset
  12. 55 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ScriptWidget.ts
  13. 7 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ScriptWidget.ts.asset
  14. 43 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/InspectorBuilder.plugin.js
  15. 7 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/InspectorBuilder.plugin.js.asset
  16. 55 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/InspectorBuilder.plugin.ts
  17. 7 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/InspectorBuilder.plugin.ts.asset
  18. 4 0
      EditorPlugins/EditorPluginExample/Resources/EditorData/customEditor.html.asset
  19. 2 1
      EditorPlugins/EditorPluginExample/Resources/EditorData/tsconfig.json
  20. 5 0
      EditorPlugins/EditorPluginExample/Resources/InspectorExampleAsset.example
  21. 4 0
      EditorPlugins/EditorPluginExample/Resources/InspectorExampleAsset.example.asset

+ 5 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "abcb18a72a559441c0e9057e79cf75a6",
+	"FolderImporter": {}
+}

+ 82 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ExampleInspector.js

@@ -0,0 +1,82 @@
+//
+// Copyright (c) 2014-2016 THUNDERBEAST GAMES LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var ScriptWidget = require("./ScriptWidget");
+var InspectorUtils = require("./InspectorUtils");
+var AnimationBlenderInspector = (function (_super) {
+    __extends(AnimationBlenderInspector, _super);
+    function AnimationBlenderInspector() {
+        var _this = _super.call(this) || this;
+        var fd = _this.attrFontDesc = new Atomic.UIFontDescription();
+        fd.id = "Vera";
+        fd.size = 11;
+        var nlp = new Atomic.UILayoutParams();
+        nlp.width = 310;
+        var layout = _this.rootLayout = new Atomic.UILayout();
+        layout.spacing = 4;
+        layout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
+        layout.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
+        layout.layoutParams = nlp;
+        layout.axis = Atomic.UI_AXIS_Y;
+        _this.gravity = Atomic.UI_GRAVITY_ALL;
+        _this.addChild(layout);
+        _this.subscribeToEvent(_this, "WidgetEvent", function (data) { return _this.handleWidgetEvent(data); });
+        return _this;
+    }
+    AnimationBlenderInspector.prototype.inspect = function (asset) {
+        this.asset = asset;
+        this.exampleData = this.readJsonFile(asset.path);
+        // node attr layout
+        var rootLayout = this.rootLayout;
+        // Blender Section
+        var defaultLayout = InspectorUtils.createSection(rootLayout, "ExampleData: " + asset.name, 1);
+        this.populateInspector(defaultLayout);
+    };
+    AnimationBlenderInspector.prototype.populateInspector = function (layout) {
+        var NameEdit = InspectorUtils.createAttrEditField("Name", layout);
+        NameEdit.tooltip = "The name of your custom animaiton State.";
+        NameEdit.text = this.exampleData.Name;
+        var AgeEdit = InspectorUtils.createAttrEditField("Age", layout);
+        AgeEdit.tooltip = "The name of your custom animaiton State.";
+        AgeEdit.text = this.exampleData.Age;
+        var Identity = InspectorUtils.createAttrEditField("Age", layout);
+        Identity.tooltip = "The name of your custom animaiton State.";
+        Identity.text = this.exampleData.Identity.toString();
+    };
+    AnimationBlenderInspector.prototype.readJsonFile = function (pathName) {
+        var env = ToolCore.toolEnvironment;
+        this.file = new Atomic.File(pathName, Atomic.FILE_READWRITE);
+        if (!this.file.isOpen()) {
+            return null;
+        }
+        var json = JSON.parse(this.file.readText());
+        var projectTemplate = json;
+        return projectTemplate;
+    };
+    return AnimationBlenderInspector;
+}(ScriptWidget));
+module.exports = AnimationBlenderInspector;

+ 7 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ExampleInspector.js.asset

@@ -0,0 +1,7 @@
+{
+	"version": 1,
+	"guid": "c38e0e6dac4f5a22cf0ae199ac416c6c",
+	"JavascriptImporter": {
+		"IsComponentFile": false
+	}
+}

+ 117 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ExampleInspector.ts

@@ -0,0 +1,117 @@
+//
+// Copyright (c) 2014-2016 THUNDERBEAST GAMES LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+import ScriptWidget = require("./ScriptWidget");
+import InspectorUtils = require("./InspectorUtils");
+
+class AnimationBlenderInspector extends ScriptWidget {
+
+    constructor() {
+
+        super();
+
+        var fd = this.attrFontDesc = new Atomic.UIFontDescription();
+        fd.id = "Vera";
+        fd.size = 11;
+
+        var nlp = new Atomic.UILayoutParams();
+        nlp.width = 310;
+
+        var layout = this.rootLayout = new Atomic.UILayout();
+        layout.spacing = 4;
+
+        layout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
+        layout.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
+        layout.layoutParams = nlp;
+        layout.axis = Atomic.UI_AXIS_Y;
+
+        this.gravity = Atomic.UI_GRAVITY_ALL;
+        this.addChild(layout);
+
+        this.subscribeToEvent(this, "WidgetEvent", (data) => this.handleWidgetEvent(data));
+
+    }
+
+    inspect(asset: ToolCore.Asset) {
+
+        this.asset = asset;
+
+        this.exampleData = this.readJsonFile(asset.path);
+
+        // node attr layout
+        var rootLayout = this.rootLayout;
+
+        // Blender Section
+        var defaultLayout = InspectorUtils.createSection(rootLayout, "ExampleData: " + asset.name, 1);
+
+        this.populateInspector(defaultLayout);
+
+    }
+
+    populateInspector(layout: Atomic.UILayout) {
+
+        var NameEdit = InspectorUtils.createAttrEditField("Name", layout);
+        NameEdit.tooltip = "The name of your custom animaiton State.";
+        NameEdit.text = this.exampleData.Name;
+
+        var AgeEdit = InspectorUtils.createAttrEditField("Age", layout);
+        AgeEdit.tooltip = "The name of your custom animaiton State.";
+        AgeEdit.text = this.exampleData.Age;
+
+        var Identity = InspectorUtils.createAttrEditField("Age", layout);
+        Identity.tooltip = "The name of your custom animaiton State.";
+        Identity.text = this.exampleData.Identity.toString();
+
+    }
+
+
+    readJsonFile(pathName: string): ExampleData {
+
+        var env = ToolCore.toolEnvironment;
+
+        this.file = new Atomic.File(pathName, Atomic.FILE_READWRITE);
+
+        if (!this.file.isOpen()) {
+            return null;
+        }
+
+        let json = JSON.parse(this.file.readText());
+
+        let projectTemplate = <ExampleData>json;
+
+        return projectTemplate;
+    }
+
+    asset: ToolCore.Asset;
+    rootLayout: Atomic.UILayout;
+    attrFontDesc: Atomic.UIFontDescription;
+    exampleData: ExampleData;
+    file: Atomic.File;
+}
+export = AnimationBlenderInspector;
+
+interface ExampleData {
+    Name: string;
+    Age: string;
+    Identity: number;
+}
+

+ 7 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ExampleInspector.ts.asset

@@ -0,0 +1,7 @@
+{
+	"version": 1,
+	"guid": "747af5243d35fc149d19d2f46b381b47",
+	"TypeScriptImporter": {
+		"IsComponentFile": false
+	}
+}

+ 167 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/InspectorUtils.js

@@ -0,0 +1,167 @@
+//
+// Copyright (c) 2014-2016 THUNDERBEAST GAMES LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+"use strict";
+var InspectorUtils = (function () {
+    function InspectorUtils() {
+    }
+    InspectorUtils.createSeparator = function (parent) {
+        var sep = new Atomic.UISeparator();
+        sep.gravity = Atomic.UI_GRAVITY_LEFT_RIGHT;
+        sep.skinBg = "AESeparator";
+        parent.addChild(sep);
+        return sep;
+    };
+    InspectorUtils.createContainer = function () {
+        var container = new Atomic.UIContainer();
+        container.skinBg = "AEContainer";
+        return container;
+    };
+    InspectorUtils.createAttrName = function (name) {
+        var nameField = new Atomic.UITextField();
+        nameField.textAlign = Atomic.UI_TEXT_ALIGN_LEFT;
+        nameField.skinBg = "InspectorTextAttrName";
+        nameField.text = name;
+        nameField.fontDescription = InspectorUtils.attrFontDesc;
+        // atttribute name layout param
+        var atlp = new Atomic.UILayoutParams();
+        atlp.width = 120;
+        nameField.layoutParams = atlp;
+        return nameField;
+    };
+    InspectorUtils.createEditField = function () {
+        var edit = new Atomic.UIEditField();
+        edit.id = "editfield";
+        edit.textAlign = Atomic.UI_TEXT_ALIGN_LEFT;
+        edit.skinBg = "TBAttrEditorField";
+        edit.fontDescription = InspectorUtils.attrFontDesc;
+        var lp = new Atomic.UILayoutParams();
+        lp.width = 160;
+        lp.height = 24;
+        edit.layoutParams = lp;
+        return edit;
+    };
+    InspectorUtils.createColorWidget = function () {
+        var colorWidget = new Atomic.UIColorWidget();
+        colorWidget.id = "colorfield";
+        var lp = new Atomic.UILayoutParams();
+        lp.width = 160;
+        lp.height = 24;
+        colorWidget.layoutParams = lp;
+        return colorWidget;
+    };
+    InspectorUtils.createAttrEditField = function (name, parent) {
+        var attrLayout = new Atomic.UILayout();
+        attrLayout.layoutSize = Atomic.UI_LAYOUT_SIZE_AVAILABLE;
+        attrLayout.gravity = Atomic.UI_GRAVITY_LEFT_RIGHT;
+        attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
+        var _name = InspectorUtils.createAttrName(name);
+        attrLayout.addChild(_name);
+        var edit = InspectorUtils.createEditField();
+        attrLayout.addChild(edit);
+        parent.addChild(attrLayout);
+        return edit;
+    };
+    InspectorUtils.createAttrCheckBox = function (name, parent) {
+        var attrLayout = new Atomic.UILayout();
+        attrLayout.layoutSize = Atomic.UI_LAYOUT_SIZE_AVAILABLE;
+        attrLayout.gravity = Atomic.UI_GRAVITY_LEFT_RIGHT;
+        attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
+        var _name = InspectorUtils.createAttrName(name);
+        attrLayout.addChild(_name);
+        var checkBox = new Atomic.UICheckBox();
+        attrLayout.addChild(checkBox);
+        parent.addChild(attrLayout);
+        return { textField: _name, checkBox: checkBox };
+    };
+    InspectorUtils.createAttrEditFieldWithSelectButton = function (name, parent) {
+        var attrLayout = new Atomic.UILayout();
+        attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_POSITION_LEFT_TOP;
+        if (name) {
+            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 };
+    };
+    InspectorUtils.createAttrColorFieldWithSelectButton = function (name, parent) {
+        var attrLayout = new Atomic.UILayout();
+        attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_POSITION_LEFT_TOP;
+        if (name) {
+            var _name = InspectorUtils.createAttrName(name);
+            attrLayout.addChild(_name);
+        }
+        var fieldLayout = new Atomic.UILayout();
+        fieldLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_POSITION_LEFT_TOP;
+        var colorWidget = InspectorUtils.createColorWidget();
+        var selectButton = new Atomic.UIButton();
+        selectButton.text = "...";
+        selectButton.fontDescription = InspectorUtils.attrFontDesc;
+        fieldLayout.addChild(colorWidget);
+        fieldLayout.addChild(selectButton);
+        attrLayout.addChild(fieldLayout);
+        parent.addChild(attrLayout);
+        return { colorWidget: colorWidget, selectButton: selectButton };
+    };
+    InspectorUtils.createSection = function (parent, text, expanded) {
+        var section = new Atomic.UISection();
+        section.text = text;
+        section.value = expanded;
+        section.fontDescription = this.attrFontDesc;
+        var layout = this.createVerticalAttrLayout();
+        parent.addChild(section);
+        section.contentRoot.addChild(layout);
+        return layout;
+    };
+    InspectorUtils.createVerticalAttrLayout = function () {
+        var layout = new Atomic.UILayout(Atomic.UI_AXIS_Y);
+        layout.spacing = 3;
+        layout.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
+        layout.layoutSize = Atomic.UI_LAYOUT_SIZE_AVAILABLE;
+        return layout;
+    };
+    InspectorUtils.createApplyButton = function () {
+        var button = new Atomic.UIButton();
+        button.fontDescription = this.attrFontDesc;
+        button.gravity = Atomic.UI_GRAVITY_RIGHT;
+        button.text = "Apply";
+        button.onClick = function () {
+            this.onApply();
+        }.bind(this);
+        return button;
+    };
+    return InspectorUtils;
+}());
+InspectorUtils.Ctor = (function () {
+    var fd = InspectorUtils.attrFontDesc = new Atomic.UIFontDescription();
+    fd.id = "Vera";
+    fd.size = 11;
+})();
+module.exports = InspectorUtils;

+ 7 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/InspectorUtils.js.asset

@@ -0,0 +1,7 @@
+{
+	"version": 1,
+	"guid": "1f95583e9d727b6d4fbdef8e65713b88",
+	"JavascriptImporter": {
+		"IsComponentFile": false
+	}
+}

+ 249 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/InspectorUtils.ts

@@ -0,0 +1,249 @@
+//
+// Copyright (c) 2014-2016 THUNDERBEAST GAMES LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+class InspectorUtils {
+
+  private static Ctor = (() => {
+
+    var fd = InspectorUtils.attrFontDesc = new Atomic.UIFontDescription();
+    fd.id = "Vera";
+    fd.size = 11;
+
+  })();
+
+  static createSeparator(parent:Atomic.UIWidget):Atomic.UISeparator {
+
+    var sep = new Atomic.UISeparator();
+
+    sep.gravity = Atomic.UI_GRAVITY_LEFT_RIGHT;
+    sep.skinBg = "AESeparator";
+
+    parent.addChild(sep);
+    return sep;
+
+  }
+
+  static createContainer():Atomic.UIContainer {
+
+    var container = new Atomic.UIContainer();
+
+    container.skinBg = "AEContainer";
+
+    return container;
+
+  }
+
+  static createAttrName(name:string):Atomic.UITextField {
+
+    var nameField = new Atomic.UITextField();
+    nameField.textAlign = Atomic.UI_TEXT_ALIGN_LEFT;
+    nameField.skinBg = "InspectorTextAttrName";
+    nameField.text = name;
+    nameField.fontDescription = InspectorUtils.attrFontDesc;
+
+    // atttribute name layout param
+    var atlp = new Atomic.UILayoutParams();
+    atlp.width = 120;
+    nameField.layoutParams = atlp;
+
+    return nameField;
+  }
+
+  static createEditField():Atomic.UIEditField {
+
+    var edit = new Atomic.UIEditField();
+    edit.id = "editfield";
+    edit.textAlign = Atomic.UI_TEXT_ALIGN_LEFT;
+    edit.skinBg = "TBAttrEditorField";
+    edit.fontDescription = InspectorUtils.attrFontDesc;
+    var lp = new Atomic.UILayoutParams();
+    lp.width = 160;
+    lp.height = 24;
+    edit.layoutParams = lp;
+
+    return edit;
+
+  }
+
+  static createColorWidget():Atomic.UIColorWidget {
+
+    var colorWidget = new Atomic.UIColorWidget();
+    colorWidget.id = "colorfield";
+
+    var lp = new Atomic.UILayoutParams();
+    lp.width = 160;
+    lp.height = 24;
+    colorWidget.layoutParams = lp;
+
+    return colorWidget;
+
+  }
+
+
+  static createAttrEditField(name:string, parent:Atomic.UIWidget):Atomic.UIEditField {
+
+    var attrLayout = new Atomic.UILayout();
+
+    attrLayout.layoutSize = Atomic.UI_LAYOUT_SIZE_AVAILABLE;
+    attrLayout.gravity = Atomic.UI_GRAVITY_LEFT_RIGHT;
+    attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
+
+    var _name = InspectorUtils.createAttrName(name);
+    attrLayout.addChild(_name);
+
+    var edit = InspectorUtils.createEditField();
+
+    attrLayout.addChild(edit);
+    parent.addChild(attrLayout);
+
+    return edit;
+
+  }
+
+  static createAttrCheckBox(name:string, parent:Atomic.UIWidget):{ textField:Atomic.UITextField, checkBox: Atomic.UICheckBox} {
+
+    var attrLayout = new Atomic.UILayout();
+
+    attrLayout.layoutSize = Atomic.UI_LAYOUT_SIZE_AVAILABLE;
+    attrLayout.gravity = Atomic.UI_GRAVITY_LEFT_RIGHT;
+    attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
+
+    var _name = InspectorUtils.createAttrName(name);
+    attrLayout.addChild(_name);
+
+    var checkBox = new Atomic.UICheckBox();
+
+    attrLayout.addChild(checkBox);
+    parent.addChild(attrLayout);
+
+    return {textField: _name, checkBox : checkBox};
+
+  }
+
+
+  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;
+
+    if (name) {
+      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 createAttrColorFieldWithSelectButton(name:string, parent:Atomic.UIWidget):{colorWidget:Atomic.UIColorWidget, selectButton:Atomic.UIButton} {
+
+    var attrLayout = new Atomic.UILayout();
+    attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_POSITION_LEFT_TOP;
+
+    if (name) {
+      var _name = InspectorUtils.createAttrName(name);
+      attrLayout.addChild(_name);
+    }
+
+    var fieldLayout = new Atomic.UILayout();
+    fieldLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_POSITION_LEFT_TOP;
+
+    var colorWidget = InspectorUtils.createColorWidget();
+
+    var selectButton = new Atomic.UIButton();
+    selectButton.text = "...";
+    selectButton.fontDescription = InspectorUtils.attrFontDesc;
+
+    fieldLayout.addChild(colorWidget);
+    fieldLayout.addChild(selectButton);
+
+    attrLayout.addChild(fieldLayout);
+    parent.addChild(attrLayout);
+
+    return {colorWidget:colorWidget, selectButton:selectButton};
+
+  }
+
+  static createSection(parent: Atomic.UIWidget, text: string, expanded: number): Atomic.UILayout {
+
+      var section = new Atomic.UISection();
+
+      section.text = text;
+      section.value = expanded;
+      section.fontDescription = this.attrFontDesc;
+
+      var layout = this.createVerticalAttrLayout();
+      parent.addChild(section);
+      section.contentRoot.addChild(layout);
+
+      return layout;
+
+  }
+
+  static createVerticalAttrLayout(): Atomic.UILayout {
+
+      var layout = new Atomic.UILayout(Atomic.UI_AXIS_Y);
+      layout.spacing = 3;
+      layout.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
+      layout.layoutSize = Atomic.UI_LAYOUT_SIZE_AVAILABLE;
+
+      return layout;
+
+  }
+
+  static createApplyButton(): Atomic.UIButton {
+
+      var button = new Atomic.UIButton();
+      button.fontDescription = this.attrFontDesc;
+      button.gravity = Atomic.UI_GRAVITY_RIGHT;
+      button.text = "Apply";
+
+      button.onClick = function () {
+
+          this.onApply();
+
+      }.bind(this);
+
+      return button;
+
+  }
+  // "static constructor"
+  static attrFontDesc:Atomic.UIFontDescription;
+
+}
+
+export = InspectorUtils;

+ 7 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/InspectorUtils.ts.asset

@@ -0,0 +1,7 @@
+{
+	"version": 1,
+	"guid": "a2b7853bab793b06d8fd6629265b274a",
+	"TypeScriptImporter": {
+		"IsComponentFile": false
+	}
+}

+ 48 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ScriptWidget.js

@@ -0,0 +1,48 @@
+//
+// Copyright (c) 2014-2016 THUNDERBEAST GAMES LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var ScriptWidget = (function (_super) {
+    __extends(ScriptWidget, _super);
+    function ScriptWidget() {
+        var _this = _super.call(this) || this;
+        // JS way of binding method
+        // this.subscribeToEvent(this, "WidgetEvent", this.handleWidgetEvent.bind(this));
+        // TypeScript-ey
+        _this.subscribeToEvent(_this, "WidgetEvent", function (data) { return _this.handleWidgetEvent(data); });
+        return _this;
+    }
+    ScriptWidget.prototype.onEventClick = function (target, refid) {
+        return false;
+    };
+    ScriptWidget.prototype.handleWidgetEvent = function (ev) {
+        if (ev.type == Atomic.UI_EVENT_TYPE_CLICK) {
+            return this.onEventClick(ev.target, ev.refid);
+        }
+    };
+    return ScriptWidget;
+}(Atomic.UIWidget));
+module.exports = ScriptWidget;

+ 7 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ScriptWidget.js.asset

@@ -0,0 +1,7 @@
+{
+	"version": 1,
+	"guid": "25c5e5012050bf7b61b9a41d8dc5177b",
+	"JavascriptImporter": {
+		"IsComponentFile": false
+	}
+}

+ 55 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ScriptWidget.ts

@@ -0,0 +1,55 @@
+//
+// Copyright (c) 2014-2016 THUNDERBEAST GAMES LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+class ScriptWidget extends Atomic.UIWidget {
+
+    constructor() {
+
+        super();
+
+        // JS way of binding method
+        // this.subscribeToEvent(this, "WidgetEvent", this.handleWidgetEvent.bind(this));
+
+        // TypeScript-ey
+        this.subscribeToEvent(this, "WidgetEvent", (data) => this.handleWidgetEvent(data));
+
+    }
+
+    onEventClick(target: Atomic.UIWidget, refid: string): boolean {
+
+        return false;
+
+    }
+
+    handleWidgetEvent(ev: Atomic.UIWidgetEvent): boolean {
+
+        if (ev.type == Atomic.UI_EVENT_TYPE_CLICK) {
+
+            return this.onEventClick(ev.target, ev.refid);
+
+        }
+
+    }
+
+}
+
+export = ScriptWidget;

+ 7 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/ExampleInspectors/ScriptWidget.ts.asset

@@ -0,0 +1,7 @@
+{
+	"version": 1,
+	"guid": "62804739b599c9f5f575d867d569b1e2",
+	"TypeScriptImporter": {
+		"IsComponentFile": false
+	}
+}

+ 43 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/InspectorBuilder.plugin.js

@@ -0,0 +1,43 @@
+/// <reference path="../../typings/Atomic/Atomic.d.ts" />
+/// <reference path="../../typings/Atomic/EditorWork.d.ts" />
+"use strict";
+var InspectorBuilderServiceUILabel = "Inspector Builder";
+//Add custom inspectors here
+var ExampleInspector = require("./ExampleInspectors/ExampleInspector");
+var InspectorBuilderService = (function () {
+    function InspectorBuilderService() {
+        this.name = "InspectorBuilderService";
+        this.description = "This service provides custom inspector functionality.";
+        this.serviceLocator = null;
+    }
+    InspectorBuilderService.prototype.initialize = function (serviceLoader) {
+        Atomic.print("InspectorBuilder.initialize");
+        this.serviceLocator = (serviceLoader);
+        if (this.serviceLocator) {
+            this.serviceLocator.projectServices.register(this);
+            this.serviceLocator.uiServices.register(this);
+        }
+    };
+    InspectorBuilderService.prototype.projectUnloaded = function () {
+        this.serviceLocator.uiServices.removePluginMenuItemSource(InspectorBuilderServiceUILabel);
+        Atomic.print("InspectorBuilder.projectUnloaded");
+        if (this.serviceLocator) {
+            this.serviceLocator.projectServices.unregister(this);
+            this.serviceLocator.uiServices.unregister(this);
+        }
+    };
+    InspectorBuilderService.prototype.projectAssetClicked = function (asset) {
+        Atomic.print("Inspector.projectAssetClicked with extension: " + asset.extension);
+        if (asset.extension == ".example") {
+            var exampleInspector = new ExampleInspector();
+            this.serviceLocator.uiServices.loadCustomInspector(exampleInspector);
+            exampleInspector.inspect(asset);
+            return true;
+        }
+        return false;
+    };
+    return InspectorBuilderService;
+}());
+var inspectorBuilderService = new InspectorBuilderService();
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = inspectorBuilderService;

+ 7 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/InspectorBuilder.plugin.js.asset

@@ -0,0 +1,7 @@
+{
+	"version": 1,
+	"guid": "9faf62608b45ad4b365704e7a4adfc62",
+	"JavascriptImporter": {
+		"IsComponentFile": false
+	}
+}

+ 55 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/InspectorBuilder.plugin.ts

@@ -0,0 +1,55 @@
+/// <reference path="../../typings/Atomic/Atomic.d.ts" />
+/// <reference path="../../typings/Atomic/EditorWork.d.ts" />
+
+const InspectorBuilderServiceUILabel = "Inspector Builder";
+
+//Add custom inspectors here
+import ExampleInspector = require("./ExampleInspectors/ExampleInspector");
+
+class InspectorBuilderService implements
+    Editor.HostExtensions.HostEditorService,
+    Editor.HostExtensions.ProjectServicesEventListener,
+    Editor.HostExtensions.UIServicesEventListener{
+
+    name: string = "InspectorBuilderService";
+    description: string = "This service provides custom inspector functionality.";
+
+    private serviceLocator: Editor.HostExtensions.HostServiceLocator = null;
+
+    initialize(serviceLoader: Editor.Extensions.ServiceLoader) {
+        Atomic.print("InspectorBuilder.initialize");
+        this.serviceLocator = <Editor.HostExtensions.HostServiceLocator>(serviceLoader);
+        if (this.serviceLocator) {
+            this.serviceLocator.projectServices.register(this);
+            this.serviceLocator.uiServices.register(this);
+
+        }
+    }
+
+    projectUnloaded() {
+        this.serviceLocator.uiServices.removePluginMenuItemSource(InspectorBuilderServiceUILabel);
+
+        Atomic.print("InspectorBuilder.projectUnloaded");
+        if (this.serviceLocator) {
+            this.serviceLocator.projectServices.unregister(this);
+            this.serviceLocator.uiServices.unregister(this);
+        }
+    }
+
+    projectAssetClicked(asset: ToolCore.Asset): boolean {
+        Atomic.print("Inspector.projectAssetClicked with extension: " + asset.extension);
+
+        if (asset.extension == ".example") {
+            
+            var exampleInspector = new ExampleInspector();
+            this.serviceLocator.uiServices.loadCustomInspector(<Atomic.UIWidget>exampleInspector);
+
+            exampleInspector.inspect(asset);
+            return true;
+        }
+        return false;
+    }
+
+}
+const inspectorBuilderService = new InspectorBuilderService();
+export default inspectorBuilderService;

+ 7 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/InspectorBuilder.plugin.ts.asset

@@ -0,0 +1,7 @@
+{
+	"version": 1,
+	"guid": "ace47c5687169ff00214c7a156584226",
+	"TypeScriptImporter": {
+		"IsComponentFile": false
+	}
+}

+ 4 - 0
EditorPlugins/EditorPluginExample/Resources/EditorData/customEditor.html.asset

@@ -0,0 +1,4 @@
+{
+	"version": 1,
+	"guid": "aad90df43299bc182790e7b1ad77d336"
+}

+ 2 - 1
EditorPlugins/EditorPluginExample/Resources/EditorData/tsconfig.json

@@ -12,6 +12,7 @@
         "experimentalDecorators": true
         "experimentalDecorators": true
     },
     },
     "files": [
     "files": [
-        "./TSExample.plugin.ts"
+      "./TSExample.plugin.ts",
+      "./InspectorBuilder.plugin.ts"
     ]
     ]
 }
 }

+ 5 - 0
EditorPlugins/EditorPluginExample/Resources/InspectorExampleAsset.example

@@ -0,0 +1,5 @@
+{
+	"Name": "Jeremy",
+	"Age": "29",
+	"Identity" : 6523489
+}

+ 4 - 0
EditorPlugins/EditorPluginExample/Resources/InspectorExampleAsset.example.asset

@@ -0,0 +1,4 @@
+{
+	"version": 1,
+	"guid": "3a1d6a740f24d7bb13bffbda0174f660"
+}