Browse Source

TextureImporter with thumbnail generation, adding UIScrollContainer, working on idiom for attr editing, MaterialEditor, TextureSelector

Josh Engebretson 10 years ago
parent
commit
984b66825d

+ 1 - 0
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/tsconfig.json

@@ -28,6 +28,7 @@
         "./ui/inspector/InspectorFrame.ts",
         "./ui/inspector/MaterialInspector.ts",
         "./ui/inspector/NodeInspector.ts",
+        "./ui/inspector/TextureSelector.ts",
         "./ui/modal/MessageModal.ts",
         "./ui/modal/ModalOps.ts"
     ]

+ 2 - 1
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/ui/inspector/InspectorFrame.ts

@@ -25,8 +25,9 @@ class InspectorFrame extends ScriptWidget {
         this.subscribeToEvent(UIEvents.EditResource, (data) => this.handleEditResource(data));
         this.subscribeToEvent("EditorActiveNodeChange", (data) => this.handleActiveNodeChange(data));
 
-    }
 
+    }
+    
     handleEditResource(ev: UIEvents.EditorResourceEvent) {
 
         var path = ev.path;

+ 87 - 16
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/ui/inspector/MaterialInspector.ts

@@ -1,5 +1,8 @@
 
 import ScriptWidget = require("../ScriptWidget");
+import UIEvents = require("../UIEvents");
+
+import TextureSelector = require("./TextureSelector");
 
 class MaterialInspector extends ScriptWidget {
 
@@ -9,8 +12,89 @@ class MaterialInspector extends ScriptWidget {
 
     }
 
+    createShaderParametersSection(): Atomic.UISection {
+
+        var section = new Atomic.UISection();
+        section.text = "Shader Paramaters";
+        section.value = 1;
+
+        return section;
+
+    }
+
+    createTextureSection(): Atomic.UISection {
+
+        var section = new Atomic.UISection();
+        section.text = "Textures";
+        section.value = 1;
+
+        var fd = new Atomic.UIFontDescription();
+        fd.id = "Vera";
+        fd.size = 11;
+
+        var attrsVerticalLayout = new Atomic.UILayout(Atomic.UI_AXIS_Y);
+        attrsVerticalLayout.spacing = 3;
+        attrsVerticalLayout.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
+        attrsVerticalLayout.layoutSize = Atomic.UI_LAYOUT_SIZE_AVAILABLE;
+
+        section.contentRoot.addChild(attrsVerticalLayout);
+
+        // TODO: Filter on technique
+        var textureUnits = [Atomic.TU_DIFFUSE, Atomic.TU_NORMAL, Atomic.TU_EMISSIVE, Atomic.TU_SPECULAR, Atomic.TU_ENVIRONMENT,
+            Atomic.TU_CUSTOM1, Atomic.TU_CUSTOM2];
+
+        for (var i in textureUnits) {
+
+            var tunit: Atomic.TextureUnit = textureUnits[i];
+
+            var tunitName = Atomic.Material.getTextureUnitName(tunit);
+
+            var attrLayout = new Atomic.UILayout();
+            attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
+
+            var name = new Atomic.UITextField();
+            name.textAlign = Atomic.UI_TEXT_ALIGN_LEFT;
+            name.skinBg = "InspectorTextAttrName";
+
+            name.text = tunitName;
+            name.fontDescription = fd;
+
+            attrLayout.addChild(name);
+
+            var textureWidget = new Atomic.UITextureWidget();
+            textureWidget.texture = this.material.getTexture(tunit);
+
+            var tlp = new Atomic.UILayoutParams();
+            tlp.width = 32;
+            tlp.height = 32;
+            textureWidget.layoutParams = tlp;
+
+            attrLayout.addChild(textureWidget);
+
+            attrsVerticalLayout.addChild(attrLayout);
+
+            var editInfo: { textureUnit: Atomic.TextureUnit } = { textureUnit: tunit };
+
+            var callback = function(ev: Atomic.UIWidgetEvent) {
+
+                var tselect = new TextureSelector(ev.target.view);
+
+                print("CALLBACK: ", ev.target.getTypeName(), this.textureUnit);
+
+            }.bind(editInfo);
+
+            textureWidget.subscribeToEvent(textureWidget, "WidgetEvent", callback);
+
+        }
+
+        return section;
+
+    }
+
     inspect(material: Atomic.Material) {
 
+        this.material = material;
+
         var fd = new Atomic.UIFontDescription();
         fd.id = "Vera";
         fd.size = 11;
@@ -51,7 +135,6 @@ class MaterialInspector extends ScriptWidget {
         attrLayout.addChild(name);
 
 
-        /*
         var field = new Atomic.UIEditField();
         field.textAlign = Atomic.UI_TEXT_ALIGN_LEFT;
         field.skinBg = "TBAttrEditorField";;
@@ -64,21 +147,6 @@ class MaterialInspector extends ScriptWidget {
 
         attrLayout.addChild(field);
 
-        */
-
-
-
-        var textureWidget = new Atomic.UITextureWidget();
-        textureWidget.texture = material.getTexture(Atomic.TU_DIFFUSE);
-
-        var tlp = new Atomic.UILayoutParams();
-        tlp.width = 64;
-        tlp.height = 64;
-        textureWidget.layoutParams = tlp;
-
-
-        attrLayout.addChild(textureWidget);
-
 
         attrsVerticalLayout.addChild(attrLayout);
 
@@ -102,6 +170,9 @@ class MaterialInspector extends ScriptWidget {
         }
         */
 
+        materialLayout.addChild(this.createTextureSection());
+        materialLayout.addChild(this.createShaderParametersSection());
+
         this.addChild(materialLayout);
 
     }

+ 1 - 1
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/ui/inspector/NodeInspector.ts

@@ -9,7 +9,7 @@ class NodeInspector extends ScriptWidget {
 
         super();
 
-        this.subscribeToEvent("WidgetEvent", (data) => this.handleWidgetEvent(data));
+        this.subscribeToEvent(this, "WidgetEvent", (data) => this.handleWidgetEvent(data));
 
     }
 

+ 40 - 0
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/ui/inspector/TextureSelector.ts

@@ -0,0 +1,40 @@
+
+class TextureSelector extends Atomic.UIWindow {
+
+    constructor(parent:Atomic.UIWidget) {
+
+        super();
+
+        this.text = "Select Texture";
+
+        this.rect = [0,0, 320, 512];
+
+        var mainLayout = new Atomic.UILayout();
+        mainLayout.gravity = Atomic.UI_GRAVITY_ALL;
+        mainLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_AVAILABLE;
+        mainLayout.axis = Atomic.UI_AXIS_Y;
+        this.contentRoot.addChild(mainLayout);
+
+        // really want a grid container
+        var scrollContainer = new Atomic.UIScrollContainer();
+        scrollContainer.gravity = Atomic.UI_GRAVITY_ALL;
+        scrollContainer.scrollMode = Atomic.UI_SCROLL_MODE_Y_AUTO;
+        scrollContainer.adaptContentSize = true;
+
+        var scrollLayout = new Atomic.UILayout();
+        scrollLayout.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
+        scrollLayout.axis = Atomic.UI_AXIS_Y;
+
+        scrollContainer.addChild(scrollLayout);
+
+        mainLayout.addChild(scrollContainer);
+
+        parent.addChild(this);
+
+        this.center();
+
+    }
+
+}
+
+export = TextureSelector;

+ 10 - 0
Source/Atomic/UI/UI.cpp

@@ -14,6 +14,7 @@
 #include <TurboBadger/tb_inline_select.h>
 #include <TurboBadger/tb_tab_container.h>
 #include <TurboBadger/tb_toggle_container.h>
+#include <TurboBadger/tb_scroll_container.h>
 #include <TurboBadger/image/tb_image_widget.h>
 
 void register_tbbf_font_renderer();
@@ -50,6 +51,7 @@ using namespace tb;
 #include "UIContainer.h"
 #include "UISection.h"
 #include "UIInlineSelect.h"
+#include "UIScrollContainer.h"
 
 namespace tb
 {
@@ -468,6 +470,14 @@ UIWidget* UI::WrapWidget(tb::TBWidget* widget)
 
     // this is order dependent as we're using IsOfType which also works if a base class
 
+    if (widget->IsOfType<TBScrollContainer>())
+    {
+        UIScrollContainer* container = new UIScrollContainer(context_, false);
+        container->SetWidget(widget);
+        widgetWrap_[widget] = container;
+        return container;
+    }
+
     if (widget->IsOfType<TBInlineSelect>())
     {
         UIInlineSelect* select = new UIInlineSelect(context_, false);

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

@@ -0,0 +1,92 @@
+
+#include <TurboBadger/tb_widgets.h>
+#include <TurboBadger/tb_widgets_common.h>
+#include <Atomic/IO/Log.h>
+
+#include "UIEvents.h"
+#include "UI.h"
+#include "UIScrollContainer.h"
+
+using namespace tb;
+
+namespace Atomic
+{
+
+UIScrollContainer::UIScrollContainer(Context* context, bool createWidget) : UIWidget(context, false)
+{
+    if (createWidget)
+    {
+        widget_ = new TBScrollContainer();
+        widget_->SetDelegate(this);
+        GetSubsystem<UI>()->WrapWidget(this, widget_);
+    }
+}
+
+UIScrollContainer::~UIScrollContainer()
+{
+
+}
+
+void UIScrollContainer::SetScrollMode(UI_SCROLL_MODE mode)
+{
+    if (!widget_)
+        return;
+
+    ((TBScrollContainer*) widget_)->SetScrollMode((tb::SCROLL_MODE) mode);
+
+}
+
+void UIScrollContainer::SetAdaptToContentSize(bool adapt)
+{
+    if (!widget_)
+        return;
+
+    ((TBScrollContainer*) widget_)->SetAdaptToContentSize(adapt);
+
+}
+
+bool UIScrollContainer::GetAdaptToContentSize()
+{
+    if (!widget_)
+        return false;
+
+    return ((TBScrollContainer*) widget_)->GetAdaptToContentSize();
+
+}
+
+void UIScrollContainer::SetAdaptContentSize(bool adapt)
+{
+    if (!widget_)
+        return;
+
+    ((TBScrollContainer*) widget_)->SetAdaptContentSize(adapt);
+
+}
+
+bool UIScrollContainer::GetAdaptContentSize()
+{
+    if (!widget_)
+        return false;
+
+    return ((TBScrollContainer*) widget_)->GetAdaptContentSize();
+
+}
+
+
+UI_SCROLL_MODE UIScrollContainer::GetScrollMode()
+{
+    if (!widget_)
+        return UI_SCROLL_MODE_OFF;
+
+
+    return (UI_SCROLL_MODE) ((TBScrollContainer*) widget_)->GetScrollMode();
+
+}
+
+
+bool UIScrollContainer::OnEvent(const tb::TBWidgetEvent &ev)
+{
+    return UIWidget::OnEvent(ev);
+}
+
+}

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

@@ -0,0 +1,54 @@
+
+#pragma once
+
+#include <TurboBadger/tb_scroll_container.h>
+
+#include "UIWidget.h"
+
+namespace Atomic
+{
+
+enum UI_SCROLL_MODE {
+    ///< X and Y always			scroll-mode: xy
+    UI_SCROLL_MODE_X_Y = tb::SCROLL_MODE_X_Y,
+    ///< Y always (X never)		scroll-mode: y
+    UI_SCROLL_MODE_Y = tb::SCROLL_MODE_Y,
+    ///< Y auto (X never)		scroll-mode: y-auto
+    UI_SCROLL_MODE_Y_AUTO = tb::SCROLL_MODE_Y_AUTO,
+    ///< X auto, Y auto			scroll-mode: auto
+    UI_SCROLL_MODE_X_AUTO_Y_AUTO = tb::SCROLL_MODE_X_AUTO_Y_AUTO,
+    ///< X any Y never			scroll-mode: off
+    UI_SCROLL_MODE_OFF = tb::SCROLL_MODE_OFF
+};
+
+
+class UIScrollContainer : public UIWidget
+{
+    OBJECT(UIScrollContainer)
+
+public:
+
+    UIScrollContainer(Context* context, bool createWidget = true);
+    virtual ~UIScrollContainer();
+
+    void SetScrollMode(UI_SCROLL_MODE mode);
+    UI_SCROLL_MODE GetScrollMode();
+
+    /// Set to true if the preferred size of this container should adapt to the preferred size of the content. This is disabled by default.
+    void SetAdaptToContentSize(bool adapt);
+    bool GetAdaptToContentSize();
+
+    /// Set to true if the content should adapt to the available size of this container when it's larger than the preferred size. */
+    void SetAdaptContentSize(bool adapt);
+    bool GetAdaptContentSize();
+
+
+protected:
+
+    virtual bool OnEvent(const tb::TBWidgetEvent &ev);
+
+private:
+
+};
+
+}

+ 24 - 0
Source/Atomic/UI/UIWidget.cpp

@@ -8,6 +8,7 @@
 #include "UIWidget.h"
 #include "UILayout.h"
 #include "UIFontDescription.h"
+#include "UIView.h"
 
 using namespace tb;
 
@@ -465,7 +466,30 @@ void UIWidget::SetStateRaw(/*WIDGET_STATE*/ unsigned state)
 
 }
 
+UIView* UIWidget::GetView()
+{
+    if (!widget_)
+        return 0;
 
+    if (GetType() == UIView::GetTypeStatic())
+        return (UIView*) this;
+
+    TBWidget* tbw = widget_->GetParent();
+    while(tbw)
+    {
+        TBWidgetDelegate* delegate = tbw->GetDelegate();
+        if (delegate)
+        {
+            UIWidget* d = (UIWidget*) delegate;
+            if (d->GetType() == UIView::GetTypeStatic())
+                return (UIView*) d;
+        }
+
+        tbw = tbw->GetParent();
+    }
+
+    return 0;
+}
 
 bool UIWidget::OnEvent(const tb::TBWidgetEvent &ev)
 {

+ 3 - 1
Source/Atomic/UI/UIWidget.h

@@ -96,6 +96,7 @@ enum UI_EVENT_TYPE {
 };
 
 
+class UIView;
 class UILayoutParams;
 class UIFontDescription;
 
@@ -166,10 +167,11 @@ public:
 
     void SetIsFocusable(bool value);
 
-
     // get this or child widget with id
     UIWidget* GetWidget(const String& id);
 
+    UIView* GetView();
+
     virtual void AddChild(UIWidget* child);
 
     tb::TBWidget* GetInternalWidget() { return widget_; }

+ 7 - 0
Source/AtomicJS/Javascript/JSAPI.cpp

@@ -35,6 +35,13 @@ void js_class_get_prototype(duk_context* ctx, const char* package, const char *c
     duk_remove(ctx, -2); // remove Atomic object
 }
 
+void js_class_get_constructor(duk_context* ctx, const char* package, const char *classname)
+{
+    duk_get_global_string(ctx, package);
+    duk_get_prop_string(ctx, -1, classname);
+    duk_remove(ctx, -2); // remove package
+}
+
 void js_constructor_basecall(duk_context* ctx, const char* package, const char* baseclass)
 {
     int top = duk_get_top(ctx);

+ 1 - 0
Source/AtomicJS/Javascript/JSAPI.h

@@ -35,6 +35,7 @@ void js_constructor_basecall(duk_context* ctx, const char* package, const char*
 void js_setup_prototype(JSVM* vm, const char* package, const char* classname, const char* basePackage, const char* basename, bool hasProperties = false);
 void js_class_push_propertyobject(JSVM* vm, const char* package, const char* classname);
 void js_class_get_prototype(duk_context* ctx, const char* package, const char *classname);
+void js_class_get_constructor(duk_context* ctx, const char* package, const char *classname);
 
 /// Pushes variant value or undefined if can't be pushed
 void js_push_variant(duk_context* ctx, const Variant &v);

+ 14 - 2
Source/AtomicJS/Javascript/JSGraphics.cpp

@@ -54,7 +54,7 @@ static int Light_SetShadowBias(duk_context* ctx)
 
 // Material
 
-static int Material_GetShaderParamaters(duk_context* ctx)
+static int Material_GetShaderParameters(duk_context* ctx)
 {
     duk_push_this(ctx);
     Material* material = js_to_class_instance<Material>(ctx, -1, 0);
@@ -89,6 +89,12 @@ static int Material_GetShaderParamaters(duk_context* ctx)
     return 1;
 }
 
+static int Material_GetTextureUnitName(duk_context* ctx)
+{
+    duk_push_string(ctx, Material::GetTextureUnitName((TextureUnit) duk_get_number(ctx, 0)).CString());
+    return 1;
+}
+
 
 void jsapi_init_graphics(JSVM* vm)
 {
@@ -102,10 +108,16 @@ void jsapi_init_graphics(JSVM* vm)
     duk_pop(ctx);
 
     js_class_get_prototype(ctx, "Atomic", "Material");
-    duk_push_c_function(ctx, Material_GetShaderParamaters, 0);
+    duk_push_c_function(ctx, Material_GetShaderParameters, 0);
     duk_put_prop_string(ctx, -2, "getShaderParameters");
     duk_pop(ctx);
 
+    // static methods
+    js_class_get_constructor(ctx, "Atomic", "Material");
+    duk_push_c_function(ctx, Material_GetTextureUnitName, 1);
+    duk_put_prop_string(ctx, -2, "getTextureUnitName");
+    duk_pop(ctx);
+
 }
 
 }

+ 1 - 0
Source/AtomicJS/Javascript/JSUI.cpp

@@ -56,6 +56,7 @@ JSUI::JSUI(Context* context) : Object(context),
     uiTypes_["UISection"] = true;
     uiTypes_["UIInlineSelect"] = true;
     uiTypes_["UITextureWidget"] = true;
+    uiTypes_["UIScrollContainer"] = true;
 
 }
 

+ 6 - 0
Source/AtomicJS/Packages/Atomic/Graphics.json

@@ -17,6 +17,12 @@
 			"SetOrthoSize" : ["float"]
 		}
 
+	},
+	"typescript_decl" : {
+
+		"Material" : [
+			"static getTextureUnitName(unit:TextureUnit):string;"
+		]
 	}
 
 }

+ 2 - 1
Source/AtomicJS/Packages/Atomic/UI.json

@@ -8,7 +8,8 @@
 								"UIImageWidget", "UIClickLabel", "UICheckBox", "UIMenuItem", "UIMenuItemSource",
 								"UISelectList", "UIListView", "UIMessageWindow", "UILayoutParams", "UIFontDescription",
 								"UISkinImage", "UITabContainer", "UISceneView", "UIPreferredSize", "UIDragObject",
-								"UIContainer", "UISection", "UIInlineSelect", "UITextureWidget"],
+								"UIContainer", "UISection", "UIInlineSelect", "UITextureWidget",
+								"UIScrollContainer"],
 	"overloads" : {
 	}
 }

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

@@ -8,6 +8,7 @@
 #include "FolderImporter.h"
 #include "SceneImporter.h"
 #include "MaterialImporter.h"
+#include "TextureImporter.h"
 #include "Asset.h"
 
 namespace ToolCore
@@ -166,6 +167,11 @@ bool Asset::CreateImporter()
 
         name_ = GetFileName(path_);
 
+        Vector<String> textureFormats;
+        textureFormats.Push(".jpg");
+        textureFormats.Push(".png");
+        textureFormats.Push(".tga");
+
         // todo, externalize recognizers
         if (ext == ".fbx")
         {
@@ -179,6 +185,10 @@ bool Asset::CreateImporter()
         {
             importer_ = new MaterialImporter(context_);
         }
+        else if (textureFormats.Contains(ext))
+        {
+            importer_ = new TextureImporter(context_);
+        }
 
     }
 

+ 77 - 0
Source/ToolCore/Assets/TextureImporter.cpp

@@ -0,0 +1,77 @@
+
+#include <Atomic/Resource/ResourceCache.h>
+#include <Atomic/Resource/Image.h>
+
+#include "Asset.h"
+#include "AssetDatabase.h"
+#include "TextureImporter.h"
+
+namespace ToolCore
+{
+
+TextureImporter::TextureImporter(Context* context) : AssetImporter(context)
+{
+
+}
+
+TextureImporter::~TextureImporter()
+{
+
+}
+
+void TextureImporter::SetDefaults()
+{
+    AssetImporter::SetDefaults();
+}
+
+bool TextureImporter::Import(const String& guid)
+{
+    AssetDatabase* db = GetSubsystem<AssetDatabase>();
+    Asset* asset = db->GetAssetByGUID(guid);
+
+    if (!asset)
+        return false;
+
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    SharedPtr<Image> image = cache->GetTempResource<Image>(asset->GetPath());
+
+    if (image.Null())
+        return false;
+
+    // todo, proper proportions
+    image->Resize(64, 64);
+
+    String cachePath = db->GetCachePath();
+
+    // not sure entirely what we want to do here, though if the cache file doesn't exist
+    // will reimport
+    image->SavePNG(cachePath + asset->GetGUID());
+
+    // save thumbnail
+    image->SavePNG(cachePath + asset->GetGUID() + "_thumbnail.png");
+
+    return true;
+}
+
+bool TextureImporter::LoadSettingsInternal()
+{
+    if (!AssetImporter::LoadSettingsInternal())
+        return false;
+
+    JSONValue import = jsonRoot_.GetChild("TextureImporter", JSON_OBJECT);
+
+    return true;
+}
+
+bool TextureImporter::SaveSettingsInternal()
+{
+    if (!AssetImporter::SaveSettingsInternal())
+        return false;
+
+    JSONValue import = jsonRoot_.CreateChild("TextureImporter");
+
+    return true;
+}
+
+
+}

+ 29 - 0
Source/ToolCore/Assets/TextureImporter.h

@@ -0,0 +1,29 @@
+
+#pragma once
+
+#include "AssetImporter.h"
+
+namespace ToolCore
+{
+
+class TextureImporter : public AssetImporter
+{
+    OBJECT(TextureImporter);
+
+public:
+    /// Construct.
+    TextureImporter(Context* context);
+    virtual ~TextureImporter();
+
+    virtual void SetDefaults();
+
+    bool Import(const String& guid);
+
+protected:
+
+    virtual bool LoadSettingsInternal();
+    virtual bool SaveSettingsInternal();
+
+};
+
+}