Marko Pintera 10 лет назад
Родитель
Сommit
62f37ceb7d

+ 10 - 0
BansheeEditor/Include/BsBuiltinEditorResources.h

@@ -100,6 +100,11 @@ namespace BansheeEngine
 		static const String ObjectFieldDropBtnStyleName;
 		static const String ObjectFieldClearBtnStyleName;
 
+		static const String TextureFieldStyleName;
+		static const String TextureFieldLabelStyleName;
+		static const String TextureFieldDropStyleName;
+		static const String TextureFieldClearBtnStyleName;
+
 		static const Path BuiltinDataFolder;
 		static const Path EditorSkinFolder;
 		static const Path EditorIconFolder;
@@ -309,6 +314,11 @@ namespace BansheeEngine
 
 		static const WString SelectionAreaTex;
 
+		static const WString TextureDropTex;
+
+		static const WString XButtonNormalTex;
+		static const WString XButtonHoverTex;
+
 		static const WString ShaderDockOverlayFile;
 		static const WString ShaderSceneGridFile;
 		static const WString ShaderPickingCullNoneFile;

+ 49 - 0
BansheeEditor/Source/BsBuiltinEditorResources.cpp

@@ -50,6 +50,11 @@ namespace BansheeEngine
 	const String BuiltinEditorResources::ObjectFieldDropBtnStyleName = "DropButton";
 	const String BuiltinEditorResources::ObjectFieldClearBtnStyleName = "ObjectClearButton";
 
+	const String BuiltinEditorResources::TextureFieldStyleName = "GUITextureField";
+	const String BuiltinEditorResources::TextureFieldLabelStyleName = "TextureFieldLabel";
+	const String BuiltinEditorResources::TextureFieldDropStyleName = "TextureDrop";
+	const String BuiltinEditorResources::TextureFieldClearBtnStyleName = "TextureClearButton";
+
 	const WString BuiltinEditorResources::DefaultFontFilename = L"arial.ttf";
 	const UINT32 BuiltinEditorResources::DefaultFontSize = 10;
 
@@ -212,6 +217,11 @@ namespace BansheeEngine
 
 	const WString BuiltinEditorResources::SelectionAreaTex = L"SelectionHighlight.psd";
 
+	const WString BuiltinEditorResources::TextureDropTex = L"TextureDrop.psd";
+
+	const WString BuiltinEditorResources::XButtonNormalTex = L"XButtonNormal.psd";
+	const WString BuiltinEditorResources::XButtonHoverTex = L"XButtonHover.psd";
+
 	/************************************************************************/
 	/* 									SHADERS                      		*/
 	/************************************************************************/
@@ -990,6 +1000,45 @@ namespace BansheeEngine
 
 		skin->setStyle(ObjectFieldStyleName, editorObjectFieldStyle);
 
+		/************************************************************************/
+		/* 						TEXTURE DROP FIELD                      		*/
+		/************************************************************************/
+		GUIElementStyle textureFieldStyle;
+		textureFieldStyle.minHeight = 15;
+		textureFieldStyle.minWidth = 15;
+		textureFieldStyle.subStyles[TextureFieldDropStyleName] = TextureFieldDropStyleName;
+		textureFieldStyle.subStyles[TextureFieldClearBtnStyleName] = TextureFieldClearBtnStyleName;
+		textureFieldStyle.subStyles[TextureFieldLabelStyleName] = GUITextField::getLabelStyleType();
+
+		skin->setStyle(TextureFieldStyleName, textureFieldStyle);
+
+		GUIElementStyle textureDropStyle;
+		textureDropStyle.font = font;
+		textureDropStyle.fontSize = DefaultFontSize;
+		textureDropStyle.textHorzAlign = THA_Center;
+		textureDropStyle.textVertAlign = TVA_Center;
+		textureDropStyle.normal.textColor = Color(95 / 255.0f, 95 / 255.0f, 95 / 255.0f, 1.0f);
+		textureDropStyle.normal.texture = getGUITexture(TextureDropTex);
+		textureDropStyle.minHeight = 15;
+		textureDropStyle.minWidth = 15;
+		textureDropStyle.border.left = 2;
+		textureDropStyle.border.right = 2;
+		textureDropStyle.border.top = 2;
+		textureDropStyle.border.bottom = 2;
+
+		skin->setStyle(TextureFieldDropStyleName, textureDropStyle);
+		
+		GUIElementStyle textureDropClearStyle;
+		textureDropClearStyle.normal.texture = getGUITexture(XButtonNormalTex);
+		textureDropClearStyle.hover.texture = getGUITexture(XButtonHoverTex);
+		textureDropClearStyle.active.texture = textureDropStyle.hover.texture;
+		textureDropClearStyle.fixedWidth = true;
+		textureDropClearStyle.fixedHeight = true;
+		textureDropClearStyle.height = 11;
+		textureDropClearStyle.width = 11;
+
+		skin->setStyle(TextureFieldClearBtnStyleName, textureDropClearStyle);
+
 		/************************************************************************/
 		/* 								EDITOR FIELDS                      		*/
 		/************************************************************************/

+ 2 - 2
BansheeEngine/Source/BsGUIButtonBase.cpp

@@ -130,8 +130,8 @@ namespace BansheeEngine
 		{
 			IMAGE_SPRITE_DESC contentImgDesc;
 			contentImgDesc.texture = mContent.getImage().getInternalPtr();
-			contentImgDesc.width = mContent.getImage()->getWidth();
-			contentImgDesc.height = mContent.getImage()->getHeight();
+			contentImgDesc.width = std::min(mImageDesc.width, mContent.getImage()->getWidth());
+			contentImgDesc.height = std::min(mImageDesc.height, mContent.getImage()->getHeight());
 			contentImgDesc.color = mColor;
 
 			mContentImageSprite->update(contentImgDesc, (UINT64)_getParentWidget());

+ 59 - 0
MBansheeEditor/GUI/TextureField.cs

@@ -0,0 +1,59 @@
+using System;
+using System.Runtime.CompilerServices;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    public sealed class GUITextureField : GUIElement
+    {
+        public delegate void OnChangedDelegate(Texture newValue);
+
+        public event OnChangedDelegate OnChanged;
+
+        public Texture Value
+        {
+            get
+            {
+                Texture value;
+                Internal_GetValue(mCachedPtr, out value);
+                return value;
+            }
+
+            set { Internal_SetValue(mCachedPtr, value); }
+        }
+
+        public GUITextureField(GUIContent title, int titleWidth = 100, string style = "", params GUIOption[] options)
+        {
+            Internal_CreateInstance(this, title, titleWidth, style, options, true);
+        }
+
+        public GUITextureField(string style = "", params GUIOption[] options)
+        {
+            Internal_CreateInstance(this, null, 0, style, options, false);
+        }
+
+        public void SetTint(Color color)
+        {
+            Internal_SetTint(mCachedPtr, color);
+        }
+
+        private void Internal_DoOnChanged(Texture newValue)
+        {
+            if (OnChanged != null)
+                OnChanged(newValue);
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_CreateInstance(GUITextureField instance, GUIContent title, int titleWidth,
+            string style, GUIOption[] options, bool withTitle);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetValue(IntPtr nativeInstance, out Texture value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetValue(IntPtr nativeInstance, Texture value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetTint(IntPtr nativeInstance, Color color);
+    }
+}

+ 1 - 0
MBansheeEditor/MBansheeEditor.csproj

@@ -57,6 +57,7 @@
     <Compile Include="DropDownWindow.cs" />
     <Compile Include="FolderMonitor.cs" />
     <Compile Include="GUI\GUISceneTreeView.cs" />
+    <Compile Include="GUI\TextureField.cs" />
     <Compile Include="HierarchyWindow.cs" />
     <Compile Include="PrefabUtility.cs" />
     <Compile Include="ProjectDropTarget.cs" />

+ 79 - 0
SBansheeEditor/Include/BsGUITextureField.h

@@ -0,0 +1,79 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsGUIElementContainer.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT GUITextureField : public GUIElementContainer
+	{
+		struct PrivatelyConstruct {};
+
+	public:
+		static const String& getGUITypeName();
+
+		static GUITextureField* create(const GUIContent& labelContent, UINT32 labelWidth, const GUIOptions& options,
+			const String& style = StringUtil::BLANK);
+
+		static GUITextureField* create(const GUIContent& labelContent, const GUIOptions& options,
+			const String& style = StringUtil::BLANK);
+
+		static GUITextureField* create(const HString& labelText, UINT32 labelWidth, const GUIOptions& options,
+			const String& style = StringUtil::BLANK);
+
+		static GUITextureField* create(const HString& labelText, const GUIOptions& options,
+			const String& style = StringUtil::BLANK);
+
+		static GUITextureField* create(const GUIOptions& options, const String& style = StringUtil::BLANK);
+
+		static GUITextureField* create(const GUIContent& labelContent, UINT32 labelWidth,
+			const String& style = StringUtil::BLANK);
+
+		static GUITextureField* create(const GUIContent& labelContent,
+			const String& style = StringUtil::BLANK);
+
+		static GUITextureField* create(const HString& labelText, UINT32 labelWidth,
+			const String& style = StringUtil::BLANK);
+
+		static GUITextureField* create(const HString& labelText,
+			const String& style = StringUtil::BLANK);
+
+		static GUITextureField* create(const String& style = StringUtil::BLANK);
+
+		GUITextureField(const PrivatelyConstruct& dummy, const GUIContent& labelContent,
+			UINT32 labelWidth, const String& style, const GUIDimensions& dimensions, bool withLabel);
+
+		HTexture getValue() const;
+		void setValue(const HTexture& value);
+
+		String getUUID() const { return mUUID; }
+		void setUUID(const String& uuid);
+
+		/**
+		 * @copydoc	GUIElement::setTint
+		 */
+		virtual void setTint(const Color& color) override;
+
+		void _updateLayoutInternal(const GUILayoutData& data) override;
+
+		Vector2I _getOptimalSize() const override;
+
+		Event<void(const String&)> onValueChanged;
+	private:
+		virtual ~GUITextureField();
+
+		void styleUpdated() override;
+
+		void dataDropped(void* data);
+		void onClearButtonClicked();
+
+	private:
+		static const UINT32 DEFAULT_LABEL_WIDTH;
+
+		GUILayout* mLayout;
+		GUILabel* mLabel;
+		GUIDropButton* mDropButton;
+		GUIButton* mClearButton;
+		String mUUID;
+	};
+}

+ 1 - 0
SBansheeEditor/Include/BsScriptEditorPrerequisites.h

@@ -24,5 +24,6 @@ namespace BansheeEngine
 	class ScriptEditorWindow;
 	class GUIGameObjectField;
 	class GUIResourceField;
+	class GUITextureField;
 	class ScriptHandleSliderBase;
 }

+ 30 - 0
SBansheeEditor/Include/BsScriptGUITextureField.h

@@ -0,0 +1,30 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsScriptGUIElement.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT ScriptGUITextureField : public TScriptGUIElement <ScriptGUITextureField>
+	{
+	public:
+		SCRIPT_OBJ(EDITOR_ASSEMBLY, "BansheeEditor", "GUITextureField")
+
+	private:
+		static void internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,
+			MonoString* style, MonoArray* guiOptions, bool withTitle);
+
+		static void internal_getValue(ScriptGUITextureField* nativeInstance, MonoObject** output);
+		static void internal_setValue(ScriptGUITextureField* nativeInstance, MonoObject* value);
+		static void internal_setTint(ScriptGUITextureField* nativeInstance, Color color);
+
+		static void onChanged(MonoObject* instance, const HTexture& newValue);
+		static MonoObject* nativeToManagedResource(const HTexture& instance);
+
+		ScriptGUITextureField(MonoObject* instance, GUITextureField* textureField);
+
+		typedef void(__stdcall *OnChangedThunkDef) (MonoObject*, MonoObject*, MonoException**);
+
+		static OnChangedThunkDef onChangedThunk;
+	};
+}

+ 4 - 0
SBansheeEditor/SBansheeEditor.vcxproj

@@ -235,6 +235,7 @@
     <ClInclude Include="Include\BsEditorScriptManager.h" />
     <ClInclude Include="Include\BsGUIGameObjectField.h" />
     <ClInclude Include="Include\BsGUIResourceField.h" />
+    <ClInclude Include="Include\BsGUITextureField.h" />
     <ClInclude Include="Include\BsMenuItemManager.h" />
     <ClInclude Include="Include\BsScriptBrowseDialog.h" />
     <ClInclude Include="Include\BsScriptBuildManager.h" />
@@ -244,6 +245,7 @@
     <ClInclude Include="Include\BsScriptEditorTestSuite.h" />
     <ClInclude Include="Include\BsScriptFolderMonitor.h" />
     <ClInclude Include="Include\BsScriptGUISceneTreeView.h" />
+    <ClInclude Include="Include\BsScriptGUITextureField.h" />
     <ClInclude Include="Include\BsScriptOSDropTarget.h" />
     <ClInclude Include="Include\BsScriptEditorApplication.h" />
     <ClInclude Include="Include\BsScriptEditorBuiltin.h" />
@@ -282,6 +284,7 @@
     <ClInclude Include="Include\BsScriptUnitTests.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="Source\BsGUITextureField.cpp" />
     <ClCompile Include="Source\BsMenuItemManager.cpp" />
     <ClCompile Include="Source\BsScriptBuildManager.cpp" />
     <ClCompile Include="Source\BsScriptCodeEditor.cpp" />
@@ -294,6 +297,7 @@
     <ClCompile Include="Source\BsScriptEditorTestSuite.cpp" />
     <ClCompile Include="Source\BsScriptFolderMonitor.cpp" />
     <ClCompile Include="Source\BsScriptGUISceneTreeView.cpp" />
+    <ClCompile Include="Source\BsScriptGUITextureField.cpp" />
     <ClCompile Include="Source\BsScriptOSDropTarget.cpp" />
     <ClCompile Include="Source\BsScriptEditorApplication.cpp" />
     <ClCompile Include="Source\BsScriptEditorBuiltin.cpp" />

+ 12 - 0
SBansheeEditor/SBansheeEditor.vcxproj.filters

@@ -159,6 +159,12 @@
     <ClInclude Include="Include\BsScriptPrefabUtility.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsGUITextureField.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptGUITextureField.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp">
@@ -305,5 +311,11 @@
     <ClCompile Include="Source\BsScriptPrefabUtility.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsGUITextureField.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsScriptGUITextureField.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 264 - 0
SBansheeEditor/Source/BsGUITextureField.cpp

@@ -0,0 +1,264 @@
+#include "BsGUITextureField.h"
+#include "BsGUILayoutX.h"
+#include "BsGUILayoutY.h"
+#include "BsGUILabel.h"
+#include "BsGUIDropButton.h"
+#include "BsGUIButton.h"
+#include "BsGUIPanel.h"
+#include "BsResources.h"
+#include "BsProjectLibrary.h"
+#include "BsBuiltinEditorResources.h"
+#include "BsGUIResourceTreeView.h"
+#include "BsGUISpace.h"
+#include "BsProjectResourceMeta.h"
+#include "BsSpriteTexture.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	const UINT32 GUITextureField::DEFAULT_LABEL_WIDTH = 100;
+
+	GUITextureField::GUITextureField(const PrivatelyConstruct& dummy, const GUIContent& labelContent, UINT32 labelWidth,
+		const String& style, const GUIDimensions& dimensions, bool withLabel)
+		:GUIElementContainer(dimensions, style), mLabel(nullptr), mClearButton(nullptr), mDropButton(nullptr)
+	{
+		mLayout = GUILayoutX::create();
+		_registerChildElement(mLayout);
+
+		if (withLabel)
+		{
+			mLabel = GUILabel::create(labelContent, GUIOptions(GUIOption::fixedWidth(labelWidth)), getSubStyleName(BuiltinEditorResources::TextureFieldLabelStyleName));
+			mLayout->addElement(mLabel);
+		}
+
+		mDropButton = GUIDropButton::create((UINT32)DragAndDropType::Resources, GUIOptions(GUIOption::flexibleWidth()), getSubStyleName(BuiltinEditorResources::TextureFieldDropStyleName));
+		mClearButton = GUIButton::create(HString(L""), getSubStyleName(BuiltinEditorResources::TextureFieldClearBtnStyleName));
+		mClearButton->onClick.connect(std::bind(&GUITextureField::onClearButtonClicked, this));
+
+		GUIPanel* dropTargetPanel = mLayout->addNewElement<GUIPanel>();
+		dropTargetPanel->addElement(mDropButton);
+
+		GUIPanel* closeBtnPanel = mLayout->addNewElement<GUIPanel>();
+		GUILayoutY* closeBtnLayoutY = closeBtnPanel->addNewElement<GUILayoutY>();
+		closeBtnLayoutY->addNewElement<GUIFixedSpace>(5);
+		GUILayoutX* closeBtnLayoutX = closeBtnLayoutY->addNewElement<GUILayoutX>();
+		closeBtnLayoutY->addNewElement<GUIFlexibleSpace>();
+		closeBtnLayoutX->addNewElement<GUIFlexibleSpace>();
+		closeBtnLayoutX->addElement(mClearButton);
+		closeBtnLayoutX->addNewElement<GUIFixedSpace>(5);
+
+		mDropButton->onDataDropped.connect(std::bind(&GUITextureField::dataDropped, this, _1));
+	}
+
+	GUITextureField::~GUITextureField()
+	{
+
+	}
+
+	GUITextureField* GUITextureField::create(const GUIContent& labelContent, UINT32 labelWidth, const GUIOptions& options,
+		const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &BuiltinEditorResources::TextureFieldStyleName;
+
+		return bs_new<GUITextureField>(PrivatelyConstruct(), labelContent, labelWidth, *curStyle,
+			GUIDimensions::create(options), true);
+	}
+
+	GUITextureField* GUITextureField::create(const GUIContent& labelContent, const GUIOptions& options,
+		const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &BuiltinEditorResources::TextureFieldStyleName;
+
+		return bs_new<GUITextureField>(PrivatelyConstruct(), labelContent, DEFAULT_LABEL_WIDTH, *curStyle,
+			GUIDimensions::create(options), true);
+	}
+
+	GUITextureField* GUITextureField::create(const HString& labelText, UINT32 labelWidth, const GUIOptions& options,
+		const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &BuiltinEditorResources::TextureFieldStyleName;
+
+		return bs_new<GUITextureField>(PrivatelyConstruct(), GUIContent(labelText), labelWidth, *curStyle,
+			GUIDimensions::create(options), true);
+	}
+
+	GUITextureField* GUITextureField::create( const HString& labelText, const GUIOptions& options,
+		const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &BuiltinEditorResources::TextureFieldStyleName;
+
+		return bs_new<GUITextureField>(PrivatelyConstruct(), GUIContent(labelText), DEFAULT_LABEL_WIDTH, *curStyle,
+			GUIDimensions::create(options), true);
+	}
+
+	GUITextureField* GUITextureField::create(const GUIOptions& options, const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &BuiltinEditorResources::TextureFieldStyleName;
+
+		return bs_new<GUITextureField>(PrivatelyConstruct(), GUIContent(), 0, *curStyle,
+			GUIDimensions::create(options), false);
+	}
+
+	GUITextureField* GUITextureField::create(const GUIContent& labelContent, UINT32 labelWidth,
+		const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &BuiltinEditorResources::TextureFieldStyleName;
+
+		return bs_new<GUITextureField>(PrivatelyConstruct(), labelContent, labelWidth, *curStyle,
+			GUIDimensions::create(), true);
+	}
+
+	GUITextureField* GUITextureField::create(const GUIContent& labelContent, const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &BuiltinEditorResources::TextureFieldStyleName;
+
+		return bs_new<GUITextureField>(PrivatelyConstruct(), labelContent, DEFAULT_LABEL_WIDTH, *curStyle,
+			GUIDimensions::create(), true);
+	}
+
+	GUITextureField* GUITextureField::create(const HString& labelText, UINT32 labelWidth, const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &BuiltinEditorResources::TextureFieldStyleName;
+
+		return bs_new<GUITextureField>(PrivatelyConstruct(), GUIContent(labelText), labelWidth, *curStyle,
+			GUIDimensions::create(), true);
+	}
+
+	GUITextureField* GUITextureField::create(const HString& labelText, const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &BuiltinEditorResources::TextureFieldStyleName;
+
+		return bs_new<GUITextureField>(PrivatelyConstruct(), GUIContent(labelText), DEFAULT_LABEL_WIDTH, *curStyle,
+			GUIDimensions::create(), true);
+	}
+
+	GUITextureField* GUITextureField::create(const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &BuiltinEditorResources::TextureFieldStyleName;
+
+		return bs_new<GUITextureField>(PrivatelyConstruct(), GUIContent(), 0, *curStyle, GUIDimensions::create(), false);
+	}
+
+	HTexture GUITextureField::getValue() const
+	{
+		return static_resource_cast<Texture>(Resources::instance().loadFromUUID(mUUID));
+	}
+
+	void GUITextureField::setValue(const HTexture& value)
+	{
+		if (value)
+			setUUID(value.getUUID());
+		else
+			setUUID("");
+	}
+
+	void GUITextureField::setUUID(const String& uuid)
+	{
+		mUUID = uuid;
+
+		HTexture texture;
+
+		Path filePath;
+		if (Resources::instance().getFilePathFromUUID(mUUID, filePath))
+			texture = Resources::instance().load<Texture>(filePath);
+		
+		if (texture != nullptr)
+		{
+			HSpriteTexture sprite = SpriteTexture::create(texture);
+			mDropButton->setContent(GUIContent(sprite));
+			mClearButton->enableRecursively();
+		}
+		else
+		{
+			mDropButton->setContent(GUIContent(HString(L"(None)")));
+			mClearButton->disableRecursively();
+		}
+
+		onValueChanged(mUUID);
+	}
+
+	void GUITextureField::setTint(const Color& color)
+	{
+		if (mLabel != nullptr)
+			mLabel->setTint(color);
+
+		mDropButton->setTint(color);
+		mClearButton->setTint(color);
+	}
+
+	void GUITextureField::_updateLayoutInternal(const GUILayoutData& data)
+	{
+		mLayout->_setLayoutData(data);
+		mLayout->_updateLayoutInternal(data);
+	}
+
+	Vector2I GUITextureField::_getOptimalSize() const
+	{
+		return mLayout->_getOptimalSize();
+	}
+
+	void GUITextureField::dataDropped(void* data)
+	{
+		DraggedResources* draggedResources = reinterpret_cast<DraggedResources*>(data);
+		UINT32 numResources = (UINT32)draggedResources->resourcePaths.size();
+
+		if (numResources <= 0)
+			return;
+
+		for (UINT32 i = 0; i < numResources; i++)
+		{
+			Path path = draggedResources->resourcePaths[i];
+
+			String uuid;
+			if (!gResources().getUUIDFromFilePath(draggedResources->resourcePaths[i], uuid))
+				continue;
+
+			ProjectResourceMetaPtr meta = ProjectLibrary::instance().findResourceMeta(uuid);
+			if (meta == nullptr || meta->getTypeId() != TID_Texture)
+				continue;
+
+			setUUID(uuid);
+			break;
+		}
+	}
+
+	void GUITextureField::styleUpdated()
+	{
+		if (mLabel != nullptr)
+			mLabel->setStyle(getSubStyleName(BuiltinEditorResources::TextureFieldLabelStyleName));
+
+		mDropButton->setStyle(getSubStyleName(BuiltinEditorResources::TextureFieldDropStyleName));
+		mClearButton->setStyle(getSubStyleName(BuiltinEditorResources::TextureFieldClearBtnStyleName));
+	}
+
+	void GUITextureField::onClearButtonClicked()
+	{
+		setValue(HTexture());
+	}
+
+	const String& GUITextureField::getGUITypeName()
+	{
+		return BuiltinEditorResources::TextureFieldStyleName;
+	}
+}

+ 117 - 0
SBansheeEditor/Source/BsScriptGUITextureField.cpp

@@ -0,0 +1,117 @@
+#include "BsScriptGUITextureField.h"
+#include "BsScriptMeta.h"
+#include "BsMonoField.h"
+#include "BsMonoClass.h"
+#include "BsMonoManager.h"
+#include "BsMonoMethod.h"
+#include "BsSpriteTexture.h"
+#include "BsMonoUtil.h"
+#include "BsGUILayout.h"
+#include "BsGUITextureField.h"
+#include "BsGUIOptions.h"
+#include "BsGUIContent.h"
+#include "BsScriptGUIElementStyle.h"
+#include "BsScriptGUILayout.h"
+#include "BsScriptHString.h"
+#include "BsScriptGUIContent.h"
+#include "BsScriptTexture.h"
+#include "BsScriptResourceManager.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	ScriptGUITextureField::OnChangedThunkDef ScriptGUITextureField::onChangedThunk;
+
+	ScriptGUITextureField::ScriptGUITextureField(MonoObject* instance, GUITextureField* resourceField)
+		:TScriptGUIElement(instance, resourceField)
+	{
+
+	}
+
+	void ScriptGUITextureField::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptGUITextureField::internal_createInstance);
+		metaData.scriptClass->addInternalCall("Internal_GetValue", &ScriptGUITextureField::internal_getValue);
+		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUITextureField::internal_setValue);
+		metaData.scriptClass->addInternalCall("Internal_SetTint", &ScriptGUITextureField::internal_setTint);
+
+		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnChanged", 1)->getThunk();
+	}
+
+	void ScriptGUITextureField::internal_createInstance(MonoObject* instance, MonoObject* title, UINT32 titleWidth,
+		MonoString* style, MonoArray* guiOptions, bool withTitle)
+	{
+		GUIOptions options;
+
+		UINT32 arrayLen = (UINT32)mono_array_length(guiOptions);
+		for (UINT32 i = 0; i < arrayLen; i++)
+			options.addOption(mono_array_get(guiOptions, GUIOption, i));
+
+		String styleName = toString(MonoUtil::monoToWString(style));
+
+		GUITextureField* guiTextureField = nullptr;
+		if (withTitle)
+		{
+			GUIContent nativeContent(ScriptGUIContent::getText(title), ScriptGUIContent::getImage(title), ScriptGUIContent::getTooltip(title));
+			guiTextureField = GUITextureField::create(nativeContent, titleWidth, options, styleName);
+		}
+		else
+		{
+			guiTextureField = GUITextureField::create(options, styleName);
+		}
+
+		guiTextureField->onValueChanged.connect(std::bind(&ScriptGUITextureField::onChanged, instance, _1));
+
+		ScriptGUITextureField* nativeInstance = new (bs_alloc<ScriptGUITextureField>()) ScriptGUITextureField(instance, guiTextureField);
+	}
+
+	void ScriptGUITextureField::internal_getValue(ScriptGUITextureField* nativeInstance, MonoObject** output)
+	{
+		GUITextureField* textureField = static_cast<GUITextureField*>(nativeInstance->getGUIElement());
+
+		HTexture resource = textureField->getValue();
+		*output = nativeToManagedResource(resource);
+	}
+
+	void ScriptGUITextureField::internal_setValue(ScriptGUITextureField* nativeInstance, MonoObject* value)
+	{
+		GUITextureField* textureField = static_cast<GUITextureField*>(nativeInstance->getGUIElement());
+
+		if (value == nullptr)
+			textureField->setValue(HTexture());
+		else
+		{
+			ScriptTextureBase* scriptTexture = ScriptTexture::toNative(value);
+			textureField->setValue(static_resource_cast<Texture>(scriptTexture->getNativeHandle()));
+		}
+	}
+
+	void ScriptGUITextureField::internal_setTint(ScriptGUITextureField* nativeInstance, Color color)
+	{
+		GUITextureField* textureField = (GUITextureField*)nativeInstance->getGUIElement();
+		textureField->setTint(color);
+	}
+
+	void ScriptGUITextureField::onChanged(MonoObject* instance, const HTexture& newValue)
+	{
+		MonoObject* managedObj = nativeToManagedResource(newValue);
+		MonoUtil::invokeThunk(onChangedThunk, instance, managedObj);
+	}
+
+	MonoObject* ScriptGUITextureField::nativeToManagedResource(const HTexture& instance)
+	{
+		if (instance == nullptr)
+		{
+			return nullptr;
+		}
+		else
+		{
+			ScriptResourceBase* scriptResource = ScriptResourceManager::instance().getScriptResource(instance.getUUID());
+			if (scriptResource == nullptr)
+				return nullptr;
+			else
+				return scriptResource->getManagedInstance();
+		}
+	}
+}