Browse Source

Adding UITextureWidget which can render a Texture without duplicating in TB memory, material editor work

Josh Engebretson 10 years ago
parent
commit
0dca42c81d

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

@@ -37,7 +37,7 @@ class ProjectFrame extends ScriptWidget {
 
     handleWidgetEvent(data): boolean {
 
-        if (data.type == Atomic.UI.EVENT_TYPE_CLICK) {
+        if (data.type == Atomic.UI_EVENT_TYPE_CLICK) {
 
             var db = ToolCore.getAssetDatabase();
 
@@ -58,6 +58,7 @@ class ProjectFrame extends ScriptWidget {
                     if (selectedId != "0") {
 
                         var asset = db.getAssetByGUID(selectedId);
+
                         if (asset.isFolder)
                             this.refreshContent(asset);
                     }

+ 9 - 3
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/ui/inspector/ComponentInspector.ts

@@ -14,14 +14,20 @@ class ComponentInspector extends Atomic.UISection {
 
     handleWidgetEvent(ev: Atomic.UIWidgetEvent) {
 
+        var handled = false;
+
         for (var i = 0; i < this.bindings.length; i++) {
 
-          this.bindings[i].handleWidgetEvent(ev);
+          if (this.bindings[i].handleWidgetEvent(ev)) {
+
+            handled = true;
+
+          }
 
         }
 
-        // return handled
-        return true;
+        // return if handled
+        return handled;
 
     }
 

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

@@ -92,7 +92,7 @@ class DataBinding {
 
     }
 
-    handleWidgetEvent(ev: Atomic.UIWidgetEvent) {
+    handleWidgetEvent(ev: Atomic.UIWidgetEvent) : boolean {
 
       if (this.objectLocked)
           return false;
@@ -102,9 +102,12 @@ class DataBinding {
           if (this.widget == ev.target || this.widget.isAncestorOf(ev.target))
           {
               this.setObjectValueFromWidget(ev.target);
+              return true;
           }
       }
 
+      return false;
+
     }
 
     object: Atomic.Serializable;

+ 20 - 6
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/ui/inspector/InspectorFrame.ts

@@ -22,9 +22,6 @@ class InspectorFrame extends ScriptWidget {
 
         var container = this.getWidget("inspectorcontainer");
 
-        // this.materialInspector = new MaterialInspector();
-        // container.addChild(this.materialInspector);
-
         this.subscribeToEvent(UIEvents.EditResource, (data) => this.handleEditResource(data));
         this.subscribeToEvent("EditorActiveNodeChange", (data) => this.handleActiveNodeChange(data));
 
@@ -60,9 +57,24 @@ class InspectorFrame extends ScriptWidget {
 
     inspectAsset(asset: ToolCore.Asset) {
 
-        //if (asset.importerTypeName == "MaterialImporter") {
-        //this.materialInspector.inspect(asset);
-        //}
+        if (asset.importerTypeName == "MaterialImporter") {
+
+          var cache = Atomic.getResourceCache();
+
+          var material = <Atomic.Material> cache.getResource("Material", asset.path);
+
+          if (!material)
+              return;
+
+          var container = this.getWidget("inspectorcontainer");
+          container.deleteAllChildren();
+
+          var inspector = new MaterialInspector();
+          container.addChild(inspector);
+
+          inspector.inspect(material);
+
+        }
 
     }
 
@@ -71,6 +83,8 @@ class InspectorFrame extends ScriptWidget {
         if (!node) return;
 
         var container = this.getWidget("inspectorcontainer");
+        container.deleteAllChildren();
+
         var inspector = new NodeInspector();
         container.addChild(inspector);
 

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

@@ -1,52 +1,114 @@
 
 import ScriptWidget = require("../ScriptWidget");
 
-var UI = Atomic.UI;
-
 class MaterialInspector extends ScriptWidget {
 
-  constructor() {
+    constructor() {
+
+        super();
 
-    super();
+    }
 
-    var text = this.nameTextField = new Atomic.UITextField();
-    text.gravity = UI.GRAVITY_ALL;
+    inspect(material: Atomic.Material) {
 
-    //this.gravity = UI.GRAVITY_ALL;
+        var fd = new Atomic.UIFontDescription();
+        fd.id = "Vera";
+        fd.size = 11;
 
-    this.addChild(text)
+        var mlp = new Atomic.UILayoutParams();
+        mlp.width = 304;
 
-  }
+        var materialLayout = new Atomic.UILayout();
+        materialLayout.spacing = 4;
 
-  inspect(asset:ToolCore.Asset) {
+        materialLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
+        materialLayout.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
+        materialLayout.layoutParams = mlp;
+        materialLayout.axis = Atomic.UI_AXIS_Y;
 
-    //this.material = mat;
+        // node attr layout
 
-    var cache = Atomic.getResourceCache();
+        var materialSection = new Atomic.UISection();
+        materialSection.text = "Material";
+        materialSection.value = 1;
+        materialLayout.addChild(materialSection);
 
-    var material = <Atomic.Material> cache.getResource("Material", asset.path);
+        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;
 
-    if (!material)
-      return;
+        var attrLayout = new Atomic.UILayout();
+        attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
 
-    // TODO: support quality level and lod for techniques  
-    var technique = material.getTechnique(0);
+        var name = new Atomic.UITextField();
+        name.textAlign = Atomic.UI_TEXT_ALIGN_LEFT;
+        name.skinBg = "InspectorTextAttrName";
 
-    this.nameTextField.text = technique.name;
+        name.text = "Name";
+        name.fontDescription = fd;
 
-    var params = material.getShaderParameters();
+        attrLayout.addChild(name);
 
-    for (var i in params) {
 
-      print(params[i].name, " : ", params[i].value, " : ", params[i].type);
+        /*
+        var field = new Atomic.UIEditField();
+        field.textAlign = Atomic.UI_TEXT_ALIGN_LEFT;
+        field.skinBg = "TBAttrEditorField";;
+        field.fontDescription = fd;
+        var lp = new Atomic.UILayoutParams();
+        lp.width = 140;
+        field.layoutParams = lp;
+
+        field.text = material.getTexture(Atomic.TU_DIFFUSE).name;
+
+        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);
+
+
+        materialSection.contentRoot.addChild(attrsVerticalLayout);
+
+
+        /*
+
+        // TODO: support quality level and lod for techniques
+        var technique = material.getTechnique(0);
+
+        this.nameTextField.text = technique.name;
+
+        var params = material.getShaderParameters();
+
+        for (var i in params) {
+
+          print(params[i].name, " : ", params[i].value, " : ", params[i].type);
+
+        }
+        */
+
+        this.addChild(materialLayout);
+
+    }
 
-  material:Atomic.Material;
+    material: Atomic.Material;
 
-  nameTextField:Atomic.UITextField;
+    nameTextField: Atomic.UITextField;
 
 
 }

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

@@ -15,14 +15,20 @@ class NodeInspector extends ScriptWidget {
 
     handleWidgetEvent(ev: Atomic.UIWidgetEvent) {
 
+        var handled = false;
+
         for (var i = 0; i < this.bindings.length; i++) {
 
-          this.bindings[i].handleWidgetEvent(ev);
+          if (this.bindings[i].handleWidgetEvent(ev)) {
+
+            handled = true;
+
+          }
 
         }
 
         // return handled
-        return true;
+        return handled;
 
     }
 

+ 119 - 0
Source/Atomic/UI/UITextureWidget.cpp

@@ -0,0 +1,119 @@
+
+#include <TurboBadger/tb_widgets.h>
+#include <TurboBadger/tb_widgets_common.h>
+
+#include <Atomic/IO/Log.h>
+#include <Atomic/Graphics/Texture.h>
+
+#include "UIEvents.h"
+#include "UI.h"
+#include "UITextureWidget.h"
+
+using namespace tb;
+
+namespace Atomic
+{
+
+// internal wiget, as we need to override paint
+class TBTextureWidget : public tb::TBWidget
+{
+    friend class UITextureWidget;
+
+public:
+    // For safe typecasting
+    TBOBJECT_SUBCLASS(UITextureWidget, tb::TBWidget);
+
+    TBTextureWidget();
+
+    virtual void OnPaint(const PaintProps &paint_props);
+
+private:
+
+    WeakPtr<UITextureWidget> uiTextureWidget_;
+    PODVector<float> vertexData_;
+
+};
+
+
+UITextureWidget::UITextureWidget(Context* context, bool createWidget) : UIWidget(context, false)
+{
+    if (createWidget)
+    {
+        widget_ = new TBTextureWidget();
+        ((TBTextureWidget*)widget_)->uiTextureWidget_ = this;
+        widget_->SetDelegate(this);
+        GetSubsystem<UI>()->WrapWidget(this, widget_);
+    }
+}
+
+UITextureWidget::~UITextureWidget()
+{
+
+}
+
+void UITextureWidget::SetTexture(Texture *texture)
+{
+    texture_ = texture;
+}
+
+Texture* UITextureWidget::GetTexture()
+{
+    return texture_;
+}
+
+bool UITextureWidget::OnEvent(const tb::TBWidgetEvent &ev)
+{
+    return UIWidget::OnEvent(ev);
+}
+
+TBTextureWidget::TBTextureWidget()
+{
+    vertexData_.Resize(6 * UI_VERTEX_SIZE);
+    float color;
+    ((unsigned&)color) = 0xFFFFFFFF;
+
+    float* data = &vertexData_[0];
+
+    data[2] = 0; data[3] = color; data[4] = 0; data[5] = 0;
+    data[8] = 0; data[9] = color; data[10] = 1; data[11] = 0;
+    data[14] = 0; data[15] = color; data[16] = 1; data[17] = 1;
+    data[20] = 0; data[21] = color; data[22] = 0; data[23] = 0;
+    data[26] = 0; data[27] = color; data[28] = 1; data[29] = 1;
+    data[32] = 0; data[33] = color; data[34] = 0; data[35] = 1;
+}
+
+
+void TBTextureWidget::OnPaint(const PaintProps &paint_props)
+{
+    if (uiTextureWidget_.Null() || !uiTextureWidget_->GetTexture())
+        return;
+
+    TBRect rect = GetRect();
+    rect.x = rect.y = 0;
+    ConvertToRoot(rect.x, rect.y);
+
+    float* data = &vertexData_[0];
+
+    data[0] = rect.x;
+    data[1] = rect.y;
+
+    data[6] = rect.x + rect.w;
+    data[7] =  rect.y;
+
+    data[12] = rect.x + rect.w;
+    data[13] = rect.y + rect.h;
+
+    data[18] = rect.x;
+    data[19] = rect.y;
+
+    data[24] = rect.x + rect.w;
+    data[25] = rect.y + rect.h;
+
+    data[30] = rect.x;
+    data[31] = rect.y + rect.h;
+
+    uiTextureWidget_->GetSubsystem<UI>()->SubmitBatchVertexData(uiTextureWidget_->GetTexture(), vertexData_);
+
+}
+
+}

+ 35 - 0
Source/Atomic/UI/UITextureWidget.h

@@ -0,0 +1,35 @@
+
+#pragma once
+
+#include "UIWidget.h"
+
+namespace Atomic
+{
+
+class Texture;
+
+/// A widget that can render a Texture2D, so the image data
+/// doesn't need to be loaded 2x (once for Texture2D and once for say a UIImageWidget)
+class UITextureWidget : public UIWidget
+{
+    OBJECT(UITextureWidget)
+
+public:
+
+    UITextureWidget(Context* context, bool createWidget = true);
+    virtual ~UITextureWidget();
+
+    void SetTexture(Texture *texture);
+    Texture* GetTexture();
+
+protected:
+
+    virtual bool OnEvent(const tb::TBWidgetEvent &ev);
+
+private:
+
+    SharedPtr<Texture> texture_;
+
+};
+
+}

+ 8 - 6
Source/AtomicEditorWork/Editors/SceneEditor3D/SceneView3D.cpp

@@ -365,11 +365,6 @@ void SceneView3D::HandleUpdate(StringHash eventType, VariantMap& eventData)
             {
                 dragNode_->LoadXML(xml->GetRoot());
                 UpdateDragNode(0, 0);
-
-                VariantMap neventData;
-                neventData[EditorActiveNodeChange::P_NODE] = dragNode_;
-                SendEvent(E_EDITORACTIVENODECHANGE, neventData);
-
             }
 
             preloadResourceScene_ = 0;
@@ -485,13 +480,20 @@ void SceneView3D::HandleDragExitWidget(StringHash eventType, VariantMap& eventDa
         SendEvent(E_EDITORACTIVENODECHANGE, neventData);
     }
 
-    dragAssetGUID_ = 0;
+    dragAssetGUID_ = "";
     dragNode_ = 0;
 }
 
 
 void SceneView3D::HandleDragEnded(StringHash eventType, VariantMap& eventData)
 {
+    if (dragNode_.NotNull())
+    {
+        VariantMap neventData;
+        neventData[EditorActiveNodeChange::P_NODE] = dragNode_;
+        SendEvent(E_EDITORACTIVENODECHANGE, neventData);
+    }
+    dragAssetGUID_ = "";
     dragNode_ = 0;
 }
 

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

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

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

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