瀏覽代碼

Added GameObjectField C#

Marko Pintera 11 年之前
父節點
當前提交
1d5fdd56a3

+ 2 - 2
BansheeCore/Include/BsGameObjectHandle.h

@@ -263,7 +263,7 @@ namespace BansheeEngine
 		friend class GameObjectManager;
 		friend class GameObjectManager;
 
 
 		/**
 		/**
-		 * @brief	Creates a handle from a smart pointer.
+		 * @brief	Creates a GameObject handle from a smart pointer.
 		 */
 		 */
 		explicit GameObjectHandle(const std::shared_ptr<T> ptr)
 		explicit GameObjectHandle(const std::shared_ptr<T> ptr)
 			:GameObjectHandleBase(ptr)
 			:GameObjectHandleBase(ptr)
@@ -271,7 +271,7 @@ namespace BansheeEngine
 	};
 	};
 
 
 	/**
 	/**
-	 * @brief	Casts one handle type to another.
+	 * @brief	Casts one GameObject handle type to another.
 	 */
 	 */
 	template<class _Ty1, class _Ty2>
 	template<class _Ty1, class _Ty2>
 		GameObjectHandle<_Ty1> static_object_cast(const GameObjectHandle<_Ty2>& other)
 		GameObjectHandle<_Ty1> static_object_cast(const GameObjectHandle<_Ty2>& other)

+ 0 - 2
BansheeEditor/BansheeEditor.vcxproj

@@ -281,7 +281,6 @@
     <ClInclude Include="Include\BsGUIFieldBase.h" />
     <ClInclude Include="Include\BsGUIFieldBase.h" />
     <ClInclude Include="Include\BsGUIFloatField.h" />
     <ClInclude Include="Include\BsGUIFloatField.h" />
     <ClInclude Include="Include\BsGUIFoldout.h" />
     <ClInclude Include="Include\BsGUIFoldout.h" />
-    <ClInclude Include="Include\BsGUIGameObjectField.h" />
     <ClInclude Include="Include\BsGUIIntField.h" />
     <ClInclude Include="Include\BsGUIIntField.h" />
     <ClInclude Include="Include\BsGUIDropButton.h" />
     <ClInclude Include="Include\BsGUIDropButton.h" />
     <ClInclude Include="Include\BsGUITextField.h" />
     <ClInclude Include="Include\BsGUITextField.h" />
@@ -338,7 +337,6 @@
     <ClCompile Include="Source\BsGUIFieldBase.cpp" />
     <ClCompile Include="Source\BsGUIFieldBase.cpp" />
     <ClCompile Include="Source\BsGUIFloatField.cpp" />
     <ClCompile Include="Source\BsGUIFloatField.cpp" />
     <ClCompile Include="Source\BsGUIFoldout.cpp" />
     <ClCompile Include="Source\BsGUIFoldout.cpp" />
-    <ClCompile Include="Source\BsGUIGameObjectField.cpp" />
     <ClCompile Include="Source\BsGUIIntField.cpp" />
     <ClCompile Include="Source\BsGUIIntField.cpp" />
     <ClCompile Include="Source\BsGUIMenuBar.cpp" />
     <ClCompile Include="Source\BsGUIMenuBar.cpp" />
     <ClCompile Include="Source\BsGUIDropButton.cpp" />
     <ClCompile Include="Source\BsGUIDropButton.cpp" />

+ 0 - 6
BansheeEditor/BansheeEditor.vcxproj.filters

@@ -177,9 +177,6 @@
     <ClInclude Include="Include\BsGUIFoldout.h">
     <ClInclude Include="Include\BsGUIFoldout.h">
       <Filter>Header Files\Editor</Filter>
       <Filter>Header Files\Editor</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="Include\BsGUIGameObjectField.h">
-      <Filter>Header Files\Editor</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsGUIDropButton.h">
     <ClInclude Include="Include\BsGUIDropButton.h">
       <Filter>Header Files\Editor</Filter>
       <Filter>Header Files\Editor</Filter>
     </ClInclude>
     </ClInclude>
@@ -323,9 +320,6 @@
     <ClCompile Include="Source\BsGUIFoldout.cpp">
     <ClCompile Include="Source\BsGUIFoldout.cpp">
       <Filter>Source Files\Editor</Filter>
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
     </ClCompile>
-    <ClCompile Include="Source\BsGUIGameObjectField.cpp">
-      <Filter>Source Files\Editor</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsGUIDropButton.cpp">
     <ClCompile Include="Source\BsGUIDropButton.cpp">
       <Filter>Source Files\Editor</Filter>
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
     </ClCompile>

+ 6 - 1
BansheeEditor/Include/BsEditorGUI.h

@@ -7,13 +7,18 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	class EditorGUI : public BansheeEngine::Module<EditorGUI>
+	class BS_ED_EXPORT EditorGUI : public BansheeEngine::Module<EditorGUI>
 	{
 	{
 	public:
 	public:
 		EditorGUI();
 		EditorGUI();
 
 
 		const GUISkin& getSkin() const { return mSkin; }
 		const GUISkin& getSkin() const { return mSkin; }
 
 
+		static const String ObjectFieldStyleName;
+		static const String ObjectFieldLabelStyleName;
+		static const String ObjectFieldDropBtnStyleName;
+		static const String ObjectFieldClearBtnStyleName;
+
 	private:
 	private:
 		GUISkin mSkin;
 		GUISkin mSkin;
 
 

+ 1 - 1
BansheeEditor/Include/BsGUIDropButton.h

@@ -10,7 +10,7 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	class GUIDropButton : public GUIButtonBase
+	class BS_ED_EXPORT GUIDropButton : public GUIButtonBase
 	{
 	{
 	public:
 	public:
 		static const String& getGUITypeName();
 		static const String& getGUITypeName();

+ 0 - 73
BansheeEditor/Include/BsGUIGameObjectField.h

@@ -1,73 +0,0 @@
-#pragma once
-
-#include "BsEditorPrerequisites.h"
-#include "BsGUIElementContainer.h"
-
-namespace BansheeEngine
-{
-	class BS_ED_EXPORT GUIGameObjectField : public GUIElementContainer
-	{
-		struct PrivatelyConstruct {};
-
-	public:
-		static const String& getGUITypeName();
-		static const String& getLabelStyleType();
-		static const String& getDropButtonStyleType();
-		static const String& getClearButtonStyleType();
-
-		static GUIGameObjectField* create(const GUIContent& labelContent, UINT32 labelWidth, const GUIOptions& layoutOptions, 
-			const String& style = StringUtil::BLANK);
-
-		static GUIGameObjectField* create(const GUIContent& labelContent, const GUIOptions& layoutOptions, 
-			const String& style = StringUtil::BLANK);
-
-		static GUIGameObjectField* create(const HString& labelText, UINT32 labelWidth, const GUIOptions& layoutOptions, 
-			const String& style = StringUtil::BLANK);
-
-		static GUIGameObjectField* create(const HString& labelText, const GUIOptions& layoutOptions, 
-			const String& style = StringUtil::BLANK);
-
-		static GUIGameObjectField* create(const GUIOptions& layoutOptions, const String& style = StringUtil::BLANK);
-
-		static GUIGameObjectField* create(const GUIContent& labelContent, UINT32 labelWidth, 
-			const String& style = StringUtil::BLANK);
-
-		static GUIGameObjectField* create(const GUIContent& labelContent, 
-			const String& style = StringUtil::BLANK);
-
-		static GUIGameObjectField* create(const HString& labelText, UINT32 labelWidth, 
-			const String& style = StringUtil::BLANK);
-
-		static GUIGameObjectField* create(const HString& labelText, 
-			const String& style = StringUtil::BLANK);
-
-		static GUIGameObjectField* create(const String& style = StringUtil::BLANK);
-
-		GUIGameObjectField(const PrivatelyConstruct& dummy, const GUIContent& labelContent, 
-			UINT32 labelWidth, const String& style, const GUILayoutOptions& layoutOptions, bool withLabel);
-
-		HGameObject getValue() const;
-		void setValue(const HGameObject& value);
-
-		void _updateLayoutInternal(INT32 x, INT32 y, UINT32 width, UINT32 height,
-			RectI clipRect, UINT8 widgetDepth, UINT16 areaDepth);
-
-		Vector2I _getOptimalSize() const;
-	private:
-		virtual ~GUIGameObjectField();
-
-		void styleUpdated();
-
-		void dataDropped(void* data);
-
-	private:
-		static const UINT32 DEFAULT_LABEL_WIDTH;
-
-		GUILayout* mLayout;
-		GUILabel* mLabel;
-		GUIDropButton* mDropButton;
-		GUIButton* mClearButton;
-
-		UINT64 mInstanceId;
-	};
-}

+ 11 - 7
BansheeEditor/Source/BsEditorGUI.cpp

@@ -18,7 +18,6 @@
 #include "BsGUIVector2Field.h"
 #include "BsGUIVector2Field.h"
 #include "BsGUIVector3Field.h"
 #include "BsGUIVector3Field.h"
 #include "BsGUIVector4Field.h"
 #include "BsGUIVector4Field.h"
-#include "BsGUIGameObjectField.h"
 
 
 #include "BsFont.h"
 #include "BsFont.h"
 #include "BsFontImportOptions.h"
 #include "BsFontImportOptions.h"
@@ -28,6 +27,11 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	const String EditorGUI::ObjectFieldStyleName = "GUIObjectField";
+	const String EditorGUI::ObjectFieldLabelStyleName = "EditorFieldLabel";
+	const String EditorGUI::ObjectFieldDropBtnStyleName = "DropButton";
+	const String EditorGUI::ObjectFieldClearBtnStyleName = "ObjectClearButton";
+
 	const WString EditorGUI::DefaultFontPath = L"arial.ttf";
 	const WString EditorGUI::DefaultFontPath = L"arial.ttf";
 	const UINT32 EditorGUI::DefaultFontSize = 10;
 	const UINT32 EditorGUI::DefaultFontSize = 10;
 
 
@@ -813,7 +817,7 @@ namespace BansheeEngine
 		objectDropStyle.textHorzAlign = THA_Center;
 		objectDropStyle.textHorzAlign = THA_Center;
 		objectDropStyle.textVertAlign = TVA_Center;
 		objectDropStyle.textVertAlign = TVA_Center;
 
 
-		mSkin.setStyle(GUIGameObjectField::getDropButtonStyleType(), objectDropStyle);
+		mSkin.setStyle(ObjectFieldDropBtnStyleName, objectDropStyle);
 
 
 		GUIElementStyle objectClearBtnStyle;
 		GUIElementStyle objectClearBtnStyle;
 		objectClearBtnStyle.normal.texture = getTexture(ObjectClearBtnNormalTex);
 		objectClearBtnStyle.normal.texture = getTexture(ObjectClearBtnNormalTex);
@@ -824,17 +828,17 @@ namespace BansheeEngine
 		objectClearBtnStyle.height = 15;
 		objectClearBtnStyle.height = 15;
 		objectClearBtnStyle.width = 13;
 		objectClearBtnStyle.width = 13;
 
 
-		mSkin.setStyle(GUIGameObjectField::getClearButtonStyleType(), objectClearBtnStyle);
+		mSkin.setStyle(ObjectFieldClearBtnStyleName, objectClearBtnStyle);
 
 
 		GUIElementStyle editorObjectFieldStyle;
 		GUIElementStyle editorObjectFieldStyle;
 		editorObjectFieldStyle.fixedHeight = true;
 		editorObjectFieldStyle.fixedHeight = true;
 		editorObjectFieldStyle.height = 15;
 		editorObjectFieldStyle.height = 15;
 		editorObjectFieldStyle.minWidth = 30;
 		editorObjectFieldStyle.minWidth = 30;
-		editorObjectFieldStyle.subStyles[GUIGameObjectField::getLabelStyleType()] = GUITextField::getLabelStyleType();
-		editorObjectFieldStyle.subStyles[GUIGameObjectField::getDropButtonStyleType()] = GUIGameObjectField::getDropButtonStyleType();
-		editorObjectFieldStyle.subStyles[GUIGameObjectField::getClearButtonStyleType()] = GUIGameObjectField::getClearButtonStyleType();
+		editorObjectFieldStyle.subStyles[ObjectFieldLabelStyleName] = GUITextField::getLabelStyleType();
+		editorObjectFieldStyle.subStyles[ObjectFieldDropBtnStyleName] = ObjectFieldDropBtnStyleName;
+		editorObjectFieldStyle.subStyles[ObjectFieldClearBtnStyleName] = ObjectFieldClearBtnStyleName;
 
 
-		mSkin.setStyle(GUIGameObjectField::getGUITypeName(), editorObjectFieldStyle);
+		mSkin.setStyle(ObjectFieldStyleName, editorObjectFieldStyle);
 
 
 		/************************************************************************/
 		/************************************************************************/
 		/* 								EDITOR FIELDS                      		*/
 		/* 								EDITOR FIELDS                      		*/

+ 0 - 228
BansheeEditor/Source/BsGUIGameObjectField.cpp

@@ -1,228 +0,0 @@
-#include "BsGUIGameObjectField.h"
-#include "BsGUIArea.h"
-#include "BsGUILayout.h"
-#include "BsGUILabel.h"
-#include "BsGUIDropButton.h"
-#include "BsGUIButton.h"
-#include "BsBuiltinResources.h"
-#include "BsGUIWidget.h"
-#include "BsGUIMouseEvent.h"
-#include "BsGUISceneTreeView.h"
-#include "BsGUIWidget.h"
-#include "BsGameObjectManager.h"
-
-using namespace std::placeholders;
-
-namespace BansheeEngine
-{
-	const UINT32 GUIGameObjectField::DEFAULT_LABEL_WIDTH = 100;
-
-	GUIGameObjectField::GUIGameObjectField(const PrivatelyConstruct& dummy, const GUIContent& labelContent, UINT32 labelWidth,
-		const String& style, const GUILayoutOptions& layoutOptions, bool withLabel)
-		:GUIElementContainer(layoutOptions, style), mLabel(nullptr), mClearButton(nullptr), mDropButton(nullptr), mInstanceId(0)
-	{
-		mLayout = &addLayoutXInternal(this);
-
-		if(withLabel)
-		{
-			mLabel = GUILabel::create(labelContent, GUIOptions(GUIOption::fixedWidth(labelWidth)), getSubStyleName(getLabelStyleType()));
-			mLayout->addElement(mLabel);
-		}
-
-		mDropButton = GUIDropButton::create((UINT32)DragAndDropType::SceneObject, GUIOptions(GUIOption::flexibleWidth()), getSubStyleName(getDropButtonStyleType()));
-		mClearButton = GUIButton::create(HString(L""), getSubStyleName(getClearButtonStyleType()));
-
-		mLayout->addElement(mDropButton);
-		mLayout->addElement(mClearButton);
-
-		mDropButton->onDataDropped.connect(std::bind(&GUIGameObjectField::dataDropped, this, _1));
-	}
-
-	GUIGameObjectField::~GUIGameObjectField()
-	{
-
-	}
-
-	GUIGameObjectField* GUIGameObjectField::create(const GUIContent& labelContent, UINT32 labelWidth, const GUIOptions& layoutOptions, 
-		const String& style)
-	{
-		const String* curStyle = &style;
-		if (*curStyle == StringUtil::BLANK)
-			curStyle = &getGUITypeName();
-
-		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), labelContent, labelWidth, *curStyle,
-			GUILayoutOptions::create(layoutOptions), true);
-	}
-
-	GUIGameObjectField* GUIGameObjectField::create(const GUIContent& labelContent, const GUIOptions& layoutOptions, 
-		const String& style)
-	{
-		const String* curStyle = &style;
-		if (*curStyle == StringUtil::BLANK)
-			curStyle = &getGUITypeName();
-
-		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), labelContent, DEFAULT_LABEL_WIDTH, *curStyle,
-			GUILayoutOptions::create(layoutOptions), true);
-	}
-
-	GUIGameObjectField* GUIGameObjectField::create(const HString& labelText, UINT32 labelWidth, const GUIOptions& layoutOptions, 
-		const String& style)
-	{
-		const String* curStyle = &style;
-		if (*curStyle == StringUtil::BLANK)
-			curStyle = &getGUITypeName();
-
-		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), GUIContent(labelText), labelWidth, *curStyle,
-			GUILayoutOptions::create(layoutOptions), true);
-	}
-
-	GUIGameObjectField* GUIGameObjectField::create(const HString& labelText, const GUIOptions& layoutOptions, 
-		const String& style)
-	{
-		const String* curStyle = &style;
-		if (*curStyle == StringUtil::BLANK)
-			curStyle = &getGUITypeName();
-
-		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), GUIContent(labelText), DEFAULT_LABEL_WIDTH, *curStyle,
-			GUILayoutOptions::create(layoutOptions), true);
-	}
-
-	GUIGameObjectField* GUIGameObjectField::create(const GUIOptions& layoutOptions, const String& style)
-	{
-		const String* curStyle = &style;
-		if (*curStyle == StringUtil::BLANK)
-			curStyle = &getGUITypeName();
-
-		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), GUIContent(), 0, *curStyle,
-			GUILayoutOptions::create(layoutOptions), false);
-	}
-
-	GUIGameObjectField* GUIGameObjectField::create(const GUIContent& labelContent, UINT32 labelWidth, 
-		const String& style)
-	{
-		const String* curStyle = &style;
-		if (*curStyle == StringUtil::BLANK)
-			curStyle = &getGUITypeName();
-
-		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), labelContent, labelWidth, *curStyle,
-			GUILayoutOptions::create(), true);
-	}
-
-	GUIGameObjectField* GUIGameObjectField::create(const GUIContent& labelContent, 
-		const String& style)
-	{
-		const String* curStyle = &style;
-		if (*curStyle == StringUtil::BLANK)
-			curStyle = &getGUITypeName();
-
-		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), labelContent, DEFAULT_LABEL_WIDTH, *curStyle,
-			GUILayoutOptions::create(), true);
-	}
-
-	GUIGameObjectField* GUIGameObjectField::create(const HString& labelText, UINT32 labelWidth, 
-		const String& style)
-	{
-		const String* curStyle = &style;
-		if (*curStyle == StringUtil::BLANK)
-			curStyle = &getGUITypeName();
-
-		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), GUIContent(labelText), labelWidth, *curStyle,
-			GUILayoutOptions::create(), true);
-	}
-
-	GUIGameObjectField* GUIGameObjectField::create(const HString& labelText, 
-		const String& style)
-	{
-		const String* curStyle = &style;
-		if (*curStyle == StringUtil::BLANK)
-			curStyle = &getGUITypeName();
-
-		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), GUIContent(labelText), DEFAULT_LABEL_WIDTH, *curStyle,
-			GUILayoutOptions::create(), true);
-	}
-
-	GUIGameObjectField* GUIGameObjectField::create(const String& style)
-	{
-		const String* curStyle = &style;
-		if (*curStyle == StringUtil::BLANK)
-			curStyle = &getGUITypeName();
-
-		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), GUIContent(), 0, *curStyle,
-			GUILayoutOptions::create(), false);
-	}
-
-	HGameObject GUIGameObjectField::getValue() const
-	{
-		HGameObject obj;
-
-		if(mInstanceId != 0)
-			GameObjectManager::instance().tryGetObject(mInstanceId, obj);
-
-		return obj;
-	}
-
-	void GUIGameObjectField::setValue(const HGameObject& value)
-	{
-		if(value)
-		{
-			mInstanceId = value->getInstanceId();
-			mDropButton->setContent(GUIContent(HString(toWString(value->getName()))));
-		}
-		else
-		{
-			mInstanceId = 0;
-			mDropButton->setContent(GUIContent(HString(L"None")));
-		}		
-	}
-
-	void GUIGameObjectField::_updateLayoutInternal(INT32 x, INT32 y, UINT32 width, UINT32 height,
-		RectI clipRect, UINT8 widgetDepth, UINT16 areaDepth)
-	{
-		mLayout->_updateLayoutInternal(x, y, width, height, clipRect, widgetDepth, areaDepth);
-	}
-
-	Vector2I GUIGameObjectField::_getOptimalSize() const
-	{
-		return mLayout->_getOptimalSize();
-	}
-
-	void GUIGameObjectField::dataDropped(void* data)
-	{
-		DraggedSceneObjects* draggedSceneObjects = reinterpret_cast<DraggedSceneObjects*>(data);
-
-		// TODO
-	}
-
-	void GUIGameObjectField::styleUpdated()
-	{
-		if (mLabel != nullptr)
-			mLabel->setStyle(getSubStyleName(getLabelStyleType()));
-
-		mDropButton->setStyle(getSubStyleName(getDropButtonStyleType()));
-		mClearButton->setStyle(getSubStyleName(getClearButtonStyleType()));
-	}
-
-	const String& GUIGameObjectField::getGUITypeName()
-	{
-		static String typeName = "GUIGameObjectField";
-		return typeName;
-	}
-
-	const String& GUIGameObjectField::getLabelStyleType()
-	{
-		static String STYLE_TYPE = "EditorFieldLabel";
-		return STYLE_TYPE;
-	}
-
-	const String& GUIGameObjectField::getDropButtonStyleType()
-	{
-		static String typeName = "DropButton";
-		return typeName;
-	}
-
-	const String& GUIGameObjectField::getClearButtonStyleType()
-	{
-		static String typeName = "ObjectClearButton";
-		return typeName;
-	}
-}

+ 0 - 3
BansheeEditor/Source/DbgEditorWidget2.cpp

@@ -14,7 +14,6 @@
 #include "BsGUIVector4Field.h"
 #include "BsGUIVector4Field.h"
 #include "BsGUIToggleField.h"
 #include "BsGUIToggleField.h"
 #include "BsGUIColorField.h"
 #include "BsGUIColorField.h"
-#include "BsGUIGameObjectField.h"
 #include "BsGUIButton.h"
 #include "BsGUIButton.h"
 #include "BsGUIFoldout.h"
 #include "BsGUIFoldout.h"
 #include "BsGUISpace.h"
 #include "BsGUISpace.h"
@@ -59,7 +58,6 @@ namespace BansheeEngine
 		GUIToggleField* toggleField = GUIToggleField::create(HString(L"Toggle Field"), GUIOptions(GUIOption::fixedWidth(200)));
 		GUIToggleField* toggleField = GUIToggleField::create(HString(L"Toggle Field"), GUIOptions(GUIOption::fixedWidth(200)));
 		GUIColorField* colorField = GUIColorField::create(HString(L"Color Field"), GUIOptions(GUIOption::fixedWidth(200)));
 		GUIColorField* colorField = GUIColorField::create(HString(L"Color Field"), GUIOptions(GUIOption::fixedWidth(200)));
 		GUIFoldout* foldout = GUIFoldout::create(HString(L"Test"), GUIOptions(GUIOption::fixedWidth(200)));
 		GUIFoldout* foldout = GUIFoldout::create(HString(L"Test"), GUIOptions(GUIOption::fixedWidth(200)));
-		GUIGameObjectField* gameObjectField = GUIGameObjectField::create(HString(L"Object Field"), GUIOptions(GUIOption::fixedWidth(200)));
 		colorField->setValue(Color::Red);
 		colorField->setValue(Color::Red);
 
 
 		GUIButton* button = GUIButton::create(HString(L"Testing"), GUIOptions(GUIOption::fixedWidth(100)));
 		GUIButton* button = GUIButton::create(HString(L"Testing"), GUIOptions(GUIOption::fixedWidth(100)));
@@ -75,7 +73,6 @@ namespace BansheeEngine
 		layout.addElement(colorField);
 		layout.addElement(colorField);
 		layout.addElement(foldout);
 		layout.addElement(foldout);
 		layout.addElement(button);
 		layout.addElement(button);
-		layout.addElement(gameObjectField);
 
 
 		layout.addFlexibleSpace();
 		layout.addFlexibleSpace();
 	}
 	}

+ 0 - 1
Inspector.txt

@@ -6,7 +6,6 @@ TODO:
     - Ensure int field isn't updated from app when in focus
     - Ensure int field isn't updated from app when in focus
  - Think about how to handle arrays, adding and deleting elements from them.
  - Think about how to handle arrays, adding and deleting elements from them.
    - Will likely need GUILayout::GetElementIndex()
    - Will likely need GUILayout::GetElementIndex()
- - I should add project and scene tree views to the main editor window to make inspector testing easier
  - Entire foldout should be clickable, not just the toggle button
  - Entire foldout should be clickable, not just the toggle button
  - Extend text field so it can be multi-line
  - Extend text field so it can be multi-line
  - Port to C#:
  - Port to C#:

+ 51 - 0
MBansheeEditor/GUI/GUIGameObjectField.cs

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

+ 1 - 0
MBansheeEditor/MBansheeEditor.csproj

@@ -45,6 +45,7 @@
     <Compile Include="Debug_Component2.cs" />
     <Compile Include="Debug_Component2.cs" />
     <Compile Include="EditorApplication.cs" />
     <Compile Include="EditorApplication.cs" />
     <Compile Include="EditorWindow.cs" />
     <Compile Include="EditorWindow.cs" />
+    <Compile Include="GUI\GUIGameObjectField.cs" />
     <Compile Include="GUI\GUIVector3Field.cs" />
     <Compile Include="GUI\GUIVector3Field.cs" />
     <Compile Include="GUI\GUIColorField.cs" />
     <Compile Include="GUI\GUIColorField.cs" />
     <Compile Include="GUI\GUIFloatField.cs" />
     <Compile Include="GUI\GUIFloatField.cs" />

+ 73 - 0
SBansheeEditor/Include/BsGUIGameObjectField.h

@@ -0,0 +1,73 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsGUIElementContainer.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT GUIGameObjectField : public GUIElementContainer
+	{
+		struct PrivatelyConstruct {};
+
+	public:
+		static const String& getGUITypeName();
+
+		static GUIGameObjectField* create(const String& type, const GUIContent& labelContent, UINT32 labelWidth, const GUIOptions& layoutOptions, 
+			const String& style = StringUtil::BLANK);
+
+		static GUIGameObjectField* create(const String& type, const GUIContent& labelContent, const GUIOptions& layoutOptions,
+			const String& style = StringUtil::BLANK);
+
+		static GUIGameObjectField* create(const String& type, const HString& labelText, UINT32 labelWidth, const GUIOptions& layoutOptions,
+			const String& style = StringUtil::BLANK);
+
+		static GUIGameObjectField* create(const String& type, const HString& labelText, const GUIOptions& layoutOptions,
+			const String& style = StringUtil::BLANK);
+
+		static GUIGameObjectField* create(const String& type, const GUIOptions& layoutOptions, const String& style = StringUtil::BLANK);
+
+		static GUIGameObjectField* create(const String& type, const GUIContent& labelContent, UINT32 labelWidth,
+			const String& style = StringUtil::BLANK);
+
+		static GUIGameObjectField* create(const String& type, const GUIContent& labelContent,
+			const String& style = StringUtil::BLANK);
+
+		static GUIGameObjectField* create(const String& type, const HString& labelText, UINT32 labelWidth,
+			const String& style = StringUtil::BLANK);
+
+		static GUIGameObjectField* create(const String& type, const HString& labelText,
+			const String& style = StringUtil::BLANK);
+
+		static GUIGameObjectField* create(const String& type, const String& style = StringUtil::BLANK);
+
+		GUIGameObjectField(const PrivatelyConstruct& dummy, const String& type, const GUIContent& labelContent,
+			UINT32 labelWidth, const String& style, const GUILayoutOptions& layoutOptions, bool withLabel);
+
+		HGameObject getValue() const;
+		void setValue(const HGameObject& value);
+
+		void _updateLayoutInternal(INT32 x, INT32 y, UINT32 width, UINT32 height,
+			RectI clipRect, UINT8 widgetDepth, UINT16 areaDepth);
+
+		Vector2I _getOptimalSize() const;
+
+		Event<void(const HGameObject&)> onValueChanged;
+	private:
+		virtual ~GUIGameObjectField();
+
+		void styleUpdated();
+
+		void dataDropped(void* data);
+
+	private:
+		static const UINT32 DEFAULT_LABEL_WIDTH;
+
+		GUILayout* mLayout;
+		GUILabel* mLabel;
+		GUIDropButton* mDropButton;
+		GUIButton* mClearButton;
+		String mType;
+
+		UINT64 mInstanceId;
+	};
+}

+ 2 - 0
SBansheeEditor/Include/BsScriptEditorPrerequisites.h

@@ -22,6 +22,8 @@
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	class ScriptEditorWindow;
 	class ScriptEditorWindow;
+	class GUIGameObjectField;
+	class GUIResourceField;
 
 
 	static const char* BansheeEditorAssemblyName = "MBansheeEditor";
 	static const char* BansheeEditorAssemblyName = "MBansheeEditor";
 }
 }

+ 29 - 0
SBansheeEditor/Include/BsScriptGUIGameObjectField.h

@@ -0,0 +1,29 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsScriptGUIElement.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT ScriptGUIGameObjectField : public TScriptGUIElement<ScriptGUIGameObjectField>
+	{
+	public:
+		SCRIPT_OBJ(BansheeEditorAssemblyName, "BansheeEditor", "GUIGameObjectField")
+
+	private:
+		static void internal_createInstance(MonoObject* instance, MonoReflectionType* type, MonoObject* title, UINT32 titleWidth,
+			MonoString* style, MonoArray* guiOptions, bool withTitle);
+
+		static void internal_getValue(ScriptGUIGameObjectField* nativeInstance, MonoObject** output);
+		static void internal_setValue(ScriptGUIGameObjectField* nativeInstance, MonoObject* value);
+
+		static void onChanged(MonoObject* instance, const HGameObject& newValue);
+		static MonoObject* nativeToManagedGO(const HGameObject& instance);
+
+		ScriptGUIGameObjectField(MonoObject* instance, GUIGameObjectField* GOField);
+
+		typedef void(__stdcall *OnChangedThunkDef) (MonoObject*, MonoObject*, MonoException**);
+
+		static OnChangedThunkDef onChangedThunk;
+	};
+}

+ 4 - 0
SBansheeEditor/SBansheeEditor.vcxproj

@@ -226,12 +226,14 @@
     </Link>
     </Link>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <ItemGroup>
   <ItemGroup>
+    <ClInclude Include="Include\BsGUIGameObjectField.h" />
     <ClInclude Include="Include\BsGUIPanelContainer.h" />
     <ClInclude Include="Include\BsGUIPanelContainer.h" />
     <ClInclude Include="Include\BsScriptEditorPrerequisites.h" />
     <ClInclude Include="Include\BsScriptEditorPrerequisites.h" />
     <ClInclude Include="Include\BsScriptEditorWindow.h" />
     <ClInclude Include="Include\BsScriptEditorWindow.h" />
     <ClInclude Include="Include\BsScriptGUIColorField.h" />
     <ClInclude Include="Include\BsScriptGUIColorField.h" />
     <ClInclude Include="Include\BsScriptGUIFloatField.h" />
     <ClInclude Include="Include\BsScriptGUIFloatField.h" />
     <ClInclude Include="Include\BsScriptGUIFoldout.h" />
     <ClInclude Include="Include\BsScriptGUIFoldout.h" />
+    <ClInclude Include="Include\BsScriptGUIGameObjectField.h" />
     <ClInclude Include="Include\BsScriptGUIIntField.h" />
     <ClInclude Include="Include\BsScriptGUIIntField.h" />
     <ClInclude Include="Include\BsScriptGUIPanelContainer.h" />
     <ClInclude Include="Include\BsScriptGUIPanelContainer.h" />
     <ClInclude Include="Include\BsScriptGUITextField.h" />
     <ClInclude Include="Include\BsScriptGUITextField.h" />
@@ -241,12 +243,14 @@
     <ClInclude Include="Include\BsScriptGUIVector4Field.h" />
     <ClInclude Include="Include\BsScriptGUIVector4Field.h" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
+    <ClCompile Include="Source\BsGUIGameObjectField.cpp" />
     <ClCompile Include="Source\BsGUIPanelContainer.cpp" />
     <ClCompile Include="Source\BsGUIPanelContainer.cpp" />
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp" />
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp" />
     <ClCompile Include="Source\BsScriptEditorWindow.cpp" />
     <ClCompile Include="Source\BsScriptEditorWindow.cpp" />
     <ClCompile Include="Source\BsScriptGUIColorField.cpp" />
     <ClCompile Include="Source\BsScriptGUIColorField.cpp" />
     <ClCompile Include="Source\BsScriptGUIFloatField.cpp" />
     <ClCompile Include="Source\BsScriptGUIFloatField.cpp" />
     <ClCompile Include="Source\BsScriptGUIFoldout.cpp" />
     <ClCompile Include="Source\BsScriptGUIFoldout.cpp" />
+    <ClCompile Include="Source\BsScriptGUIGameObjectField.cpp" />
     <ClCompile Include="Source\BsScriptGUIIntField.cpp" />
     <ClCompile Include="Source\BsScriptGUIIntField.cpp" />
     <ClCompile Include="Source\BsScriptGUIPanelContainer.cpp" />
     <ClCompile Include="Source\BsScriptGUIPanelContainer.cpp" />
     <ClCompile Include="Source\BsScriptGUITextField.cpp" />
     <ClCompile Include="Source\BsScriptGUITextField.cpp" />

+ 12 - 0
SBansheeEditor/SBansheeEditor.vcxproj.filters

@@ -54,6 +54,12 @@
     <ClInclude Include="Include\BsScriptGUIVector4Field.h">
     <ClInclude Include="Include\BsScriptGUIVector4Field.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsGUIGameObjectField.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptGUIGameObjectField.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp">
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp">
@@ -95,5 +101,11 @@
     <ClCompile Include="Source\BsScriptGUIVector4Field.cpp">
     <ClCompile Include="Source\BsScriptGUIVector4Field.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\BsGUIGameObjectField.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsScriptGUIGameObjectField.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 245 - 0
SBansheeEditor/Source/BsGUIGameObjectField.cpp

@@ -0,0 +1,245 @@
+#include "BsGUIGameObjectField.h"
+#include "BsGUIArea.h"
+#include "BsGUILayout.h"
+#include "BsGUILabel.h"
+#include "BsGUIDropButton.h"
+#include "BsGUIButton.h"
+#include "BsBuiltinResources.h"
+#include "BsGUIWidget.h"
+#include "BsGUIMouseEvent.h"
+#include "BsGUISceneTreeView.h"
+#include "BsGUIWidget.h"
+#include "BsGameObjectManager.h"
+#include "BsRuntimeScriptObjects.h"
+#include "BsMonoClass.h"
+#include "BsSceneObject.h"
+#include "BsManagedComponent.h"
+#include "BsEditorGUI.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	const UINT32 GUIGameObjectField::DEFAULT_LABEL_WIDTH = 100;
+
+	GUIGameObjectField::GUIGameObjectField(const PrivatelyConstruct& dummy, const String& type, const GUIContent& labelContent, UINT32 labelWidth,
+		const String& style, const GUILayoutOptions& layoutOptions, bool withLabel)
+		:GUIElementContainer(layoutOptions, style), mLabel(nullptr), mClearButton(nullptr), mDropButton(nullptr), mInstanceId(0), mType(type)
+	{
+		mLayout = &addLayoutXInternal(this);
+
+		if(withLabel)
+		{
+			mLabel = GUILabel::create(labelContent, GUIOptions(GUIOption::fixedWidth(labelWidth)), getSubStyleName(EditorGUI::ObjectFieldLabelStyleName));
+			mLayout->addElement(mLabel);
+		}
+
+		mDropButton = GUIDropButton::create((UINT32)DragAndDropType::SceneObject, GUIOptions(GUIOption::flexibleWidth()), getSubStyleName(EditorGUI::ObjectFieldDropBtnStyleName));
+		mClearButton = GUIButton::create(HString(L""), getSubStyleName(EditorGUI::ObjectFieldClearBtnStyleName));
+
+		mLayout->addElement(mDropButton);
+		mLayout->addElement(mClearButton);
+
+		mDropButton->onDataDropped.connect(std::bind(&GUIGameObjectField::dataDropped, this, _1));
+	}
+
+	GUIGameObjectField::~GUIGameObjectField()
+	{
+
+	}
+
+	GUIGameObjectField* GUIGameObjectField::create(const String& type, const GUIContent& labelContent, UINT32 labelWidth, const GUIOptions& layoutOptions,
+		const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &EditorGUI::ObjectFieldStyleName;
+
+		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), type, labelContent, labelWidth, *curStyle,
+			GUILayoutOptions::create(layoutOptions), true);
+	}
+
+	GUIGameObjectField* GUIGameObjectField::create(const String& type, const GUIContent& labelContent, const GUIOptions& layoutOptions,
+		const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &EditorGUI::ObjectFieldStyleName;
+
+		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), type, labelContent, DEFAULT_LABEL_WIDTH, *curStyle,
+			GUILayoutOptions::create(layoutOptions), true);
+	}
+
+	GUIGameObjectField* GUIGameObjectField::create(const String& type, const HString& labelText, UINT32 labelWidth, const GUIOptions& layoutOptions,
+		const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &EditorGUI::ObjectFieldStyleName;
+
+		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), type, GUIContent(labelText), labelWidth, *curStyle,
+			GUILayoutOptions::create(layoutOptions), true);
+	}
+
+	GUIGameObjectField* GUIGameObjectField::create(const String& type, const HString& labelText, const GUIOptions& layoutOptions,
+		const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &EditorGUI::ObjectFieldStyleName;
+
+		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), type, GUIContent(labelText), DEFAULT_LABEL_WIDTH, *curStyle,
+			GUILayoutOptions::create(layoutOptions), true);
+	}
+
+	GUIGameObjectField* GUIGameObjectField::create(const String& type, const GUIOptions& layoutOptions, const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &EditorGUI::ObjectFieldStyleName;
+
+		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), type, GUIContent(), 0, *curStyle,
+			GUILayoutOptions::create(layoutOptions), false);
+	}
+
+	GUIGameObjectField* GUIGameObjectField::create(const String& type, const GUIContent& labelContent, UINT32 labelWidth,
+		const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &EditorGUI::ObjectFieldStyleName;
+
+		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), type, labelContent, labelWidth, *curStyle,
+			GUILayoutOptions::create(), true);
+	}
+
+	GUIGameObjectField* GUIGameObjectField::create(const String& type, const GUIContent& labelContent,
+		const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &EditorGUI::ObjectFieldStyleName;
+
+		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), type, labelContent, DEFAULT_LABEL_WIDTH, *curStyle,
+			GUILayoutOptions::create(), true);
+	}
+
+	GUIGameObjectField* GUIGameObjectField::create(const String& type, const HString& labelText, UINT32 labelWidth,
+		const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &EditorGUI::ObjectFieldStyleName;
+
+		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), type, GUIContent(labelText), labelWidth, *curStyle,
+			GUILayoutOptions::create(), true);
+	}
+
+	GUIGameObjectField* GUIGameObjectField::create(const String& type, const HString& labelText,
+		const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &EditorGUI::ObjectFieldStyleName;
+
+		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), type, GUIContent(labelText), DEFAULT_LABEL_WIDTH, *curStyle,
+			GUILayoutOptions::create(), true);
+	}
+
+	GUIGameObjectField* GUIGameObjectField::create(const String& type, const String& style)
+	{
+		const String* curStyle = &style;
+		if (*curStyle == StringUtil::BLANK)
+			curStyle = &EditorGUI::ObjectFieldStyleName;
+
+		return bs_new<GUIGameObjectField>(PrivatelyConstruct(), type, GUIContent(), 0, *curStyle,
+			GUILayoutOptions::create(), false);
+	}
+
+	HGameObject GUIGameObjectField::getValue() const
+	{
+		HGameObject obj;
+
+		if(mInstanceId != 0)
+			GameObjectManager::instance().tryGetObject(mInstanceId, obj);
+
+		return obj;
+	}
+
+	void GUIGameObjectField::setValue(const HGameObject& value)
+	{
+		if(value)
+		{
+			mInstanceId = value->getInstanceId();
+			mDropButton->setContent(GUIContent(HString(toWString(value->getName()))));
+		}
+		else
+		{
+			mInstanceId = 0;
+			mDropButton->setContent(GUIContent(HString(L"None")));
+		}
+
+		onValueChanged(value);
+	}
+
+	void GUIGameObjectField::_updateLayoutInternal(INT32 x, INT32 y, UINT32 width, UINT32 height,
+		RectI clipRect, UINT8 widgetDepth, UINT16 areaDepth)
+	{
+		mLayout->_updateLayoutInternal(x, y, width, height, clipRect, widgetDepth, areaDepth);
+	}
+
+	Vector2I GUIGameObjectField::_getOptimalSize() const
+	{
+		return mLayout->_getOptimalSize();
+	}
+
+	void GUIGameObjectField::dataDropped(void* data)
+	{
+		DraggedSceneObjects* draggedSceneObjects = reinterpret_cast<DraggedSceneObjects*>(data);
+
+		if (draggedSceneObjects->numObjects <= 0)
+			return;
+
+		MonoClass* sceneObjectClass = RuntimeScriptObjects::instance().getSceneObjectClass();
+
+		if (mType == sceneObjectClass->getFullName()) // A scene object
+		{
+			setValue(draggedSceneObjects->objects[0]);
+		}
+		else // A component
+		{
+			for (UINT32 i = 0; i < draggedSceneObjects->numObjects; i++)
+			{
+				HSceneObject so = draggedSceneObjects->objects[i];
+
+				const Vector<HComponent>& components = so->getComponents();
+				for (auto& component : components)
+				{
+					if (component->getTypeId() == TID_ManagedComponent) // We only care about managed components
+					{
+						HManagedComponent managedComponent = static_object_cast<ManagedComponent>(component);
+						if (managedComponent->getManagedFullTypeName() == mType)
+						{
+							setValue(managedComponent);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	void GUIGameObjectField::styleUpdated()
+	{
+		if (mLabel != nullptr)
+			mLabel->setStyle(getSubStyleName(EditorGUI::ObjectFieldLabelStyleName));
+
+		mDropButton->setStyle(getSubStyleName(EditorGUI::ObjectFieldDropBtnStyleName));
+		mClearButton->setStyle(getSubStyleName(EditorGUI::ObjectFieldClearBtnStyleName));
+	}
+
+	const String& GUIGameObjectField::getGUITypeName()
+	{
+		static String typeName = "GUIGameObjectField";
+		return typeName;
+	}
+}

+ 123 - 0
SBansheeEditor/Source/BsScriptGUIGameObjectField.cpp

@@ -0,0 +1,123 @@
+#include "BsScriptGUIGameObjectField.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 "BsGUIGameObjectField.h"
+#include "BsGUIOptions.h"
+#include "BsGUIContent.h"
+#include "BsScriptGUIElementStyle.h"
+#include "BsScriptGUILayout.h"
+#include "BsScriptGUIArea.h"
+#include "BsScriptHString.h"
+#include "BsScriptGUIContent.h"
+#include "BsScriptGameObject.h"
+#include "BsScriptGameObjectManager.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	ScriptGUIGameObjectField::OnChangedThunkDef ScriptGUIGameObjectField::onChangedThunk;
+
+	ScriptGUIGameObjectField::ScriptGUIGameObjectField(MonoObject* instance, GUIGameObjectField* GOField)
+		:TScriptGUIElement(instance, GOField)
+	{
+
+	}
+
+	void ScriptGUIGameObjectField::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptGUIGameObjectField::internal_createInstance);
+		metaData.scriptClass->addInternalCall("Internal_GetValue", &ScriptGUIGameObjectField::internal_getValue);
+		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptGUIGameObjectField::internal_setValue);
+
+		onChangedThunk = (OnChangedThunkDef)metaData.scriptClass->getMethod("DoOnChanged", 1).getThunk();
+	}
+
+	void ScriptGUIGameObjectField::internal_createInstance(MonoObject* instance, MonoReflectionType* type, 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));
+
+		MonoType* monoType = mono_reflection_type_get_type(type);
+		::MonoClass* monoClass = mono_type_get_class(monoType);
+
+		String typeNamespace = mono_class_get_namespace(monoClass);
+		String typeName = mono_class_get_name(monoClass);
+
+		String fullTypeName = typeNamespace + "::" + typeName;
+
+		GUIGameObjectField* guiGameObjectField = nullptr;
+		if (withTitle)
+		{
+			GUIContent nativeContent(ScriptGUIContent::getText(title), ScriptGUIContent::getImage(title), ScriptGUIContent::getTooltip(title));
+			guiGameObjectField = GUIGameObjectField::create(fullTypeName, nativeContent, titleWidth, options, styleName);
+		}
+		else
+		{
+			guiGameObjectField = GUIGameObjectField::create(fullTypeName, options, styleName);
+		}
+
+		guiGameObjectField->onValueChanged.connect(std::bind(&ScriptGUIGameObjectField::onChanged, instance, _1));
+
+		ScriptGUIGameObjectField* nativeInstance = new (bs_alloc<ScriptGUIGameObjectField>()) ScriptGUIGameObjectField(instance, guiGameObjectField);
+	}
+
+	void ScriptGUIGameObjectField::internal_getValue(ScriptGUIGameObjectField* nativeInstance, MonoObject** output)
+	{
+		GUIGameObjectField* gameObjectField = static_cast<GUIGameObjectField*>(nativeInstance->getGUIElement());
+
+		HGameObject gameObject = gameObjectField->getValue();
+		*output = nativeToManagedGO(gameObject);
+	}
+
+	void ScriptGUIGameObjectField::internal_setValue(ScriptGUIGameObjectField* nativeInstance, MonoObject* value)
+	{
+		GUIGameObjectField* gameObjectField = static_cast<GUIGameObjectField*>(nativeInstance->getGUIElement());
+
+		if (value == nullptr)
+			gameObjectField->setValue(HGameObject());
+		else
+		{
+			ScriptGameObjectBase* scriptGO = ScriptGameObject::toNative(value);
+			gameObjectField->setValue(scriptGO->getNativeHandle());
+		}
+	}
+
+	void ScriptGUIGameObjectField::onChanged(MonoObject* instance, const HGameObject& newValue)
+	{
+		MonoException* exception = nullptr;
+		MonoObject* managedObj = nativeToManagedGO(newValue);
+
+		onChangedThunk(instance, managedObj, &exception);
+
+		MonoUtil::throwIfException(exception);
+	}
+
+	MonoObject* ScriptGUIGameObjectField::nativeToManagedGO(const HGameObject& instance)
+	{
+		if (instance == nullptr)
+		{
+			return nullptr;
+		}
+		else
+		{
+			ScriptGameObjectBase* scriptGO = ScriptGameObjectManager::instance().getScriptGameObject(instance->getInstanceId());
+			if (scriptGO == nullptr)
+				return nullptr;
+			else
+				return scriptGO->getManagedInstance();
+		}
+	}
+}

+ 1 - 1
SBansheeEngine/Include/BsScriptComponent.h

@@ -7,7 +7,7 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	class BS_SCR_BE_EXPORT ScriptComponent : public ScriptObject<ScriptComponent, ScriptGameObject>
+	class BS_SCR_BE_EXPORT ScriptComponent : public ScriptObject<ScriptComponent, ScriptGameObjectBase>
 	{
 	{
 	public:
 	public:
 		SCRIPT_OBJ(BansheeEngineAssemblyName, "BansheeEngine", "Component")
 		SCRIPT_OBJ(BansheeEngineAssemblyName, "BansheeEngine", "Component")

+ 3 - 1
SBansheeEngine/Include/BsScriptEnginePrerequisites.h

@@ -31,7 +31,7 @@ namespace BansheeEngine
 	class ScriptGUIArea;
 	class ScriptGUIArea;
 	class ScriptGUILayout;
 	class ScriptGUILayout;
 	class ScriptGUILabel;
 	class ScriptGUILabel;
-	class ScriptGameObject;
+	class ScriptGameObjectBase;
 	class ScriptSceneObject;
 	class ScriptSceneObject;
 	class ScriptComponent;
 	class ScriptComponent;
 	class ManagedComponent;
 	class ManagedComponent;
@@ -52,6 +52,8 @@ namespace BansheeEngine
 	class ManagedSerializableObjectInfo;
 	class ManagedSerializableObjectInfo;
 	class ManagedSerializableFieldInfo;
 	class ManagedSerializableFieldInfo;
 
 
+	typedef GameObjectHandle<ManagedComponent> HManagedComponent;
+
 	enum TypeID_BansheeScript
 	enum TypeID_BansheeScript
 	{
 	{
 		TID_ManagedComponent = 50000,
 		TID_ManagedComponent = 50000,

+ 17 - 3
SBansheeEngine/Include/BsScriptGameObject.h

@@ -5,15 +5,29 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	class BS_SCR_BE_EXPORT ScriptGameObject : public ScriptObjectBase
+	class BS_SCR_BE_EXPORT ScriptGameObjectBase : public ScriptObjectBase
 	{
 	{
 	public:
 	public:
-		ScriptGameObject(MonoObject* instance)
+		ScriptGameObjectBase(MonoObject* instance)
 			:ScriptObjectBase(instance)
 			:ScriptObjectBase(instance)
 		{ }
 		{ }
-		virtual ~ScriptGameObject() { }
+		virtual ~ScriptGameObjectBase() { }
 
 
 		virtual HGameObject getNativeHandle() const = 0;
 		virtual HGameObject getNativeHandle() const = 0;
 		virtual void setNativeHandle(const HGameObject& gameObject) = 0;
 		virtual void setNativeHandle(const HGameObject& gameObject) = 0;
 	};
 	};
+
+	class BS_SCR_BE_EXPORT ScriptGameObject : public ScriptObject<ScriptGameObject, ScriptGameObjectBase>
+	{
+	public:
+		static String getAssemblyName() { return BansheeEngineAssemblyName; }
+		static String getNamespace() { return "BansheeEngine"; }
+		static String getTypeName() { return "GameObject"; }
+		static void initRuntimeData() { }
+
+	private:
+		ScriptGameObject(MonoObject* instance)
+			:ScriptObject(instance)
+		{ }
+	};
 }
 }

+ 5 - 4
SBansheeEngine/Include/BsScriptGameObjectManager.h

@@ -15,13 +15,14 @@ namespace BansheeEngine
 		ScriptSceneObject* createScriptSceneObject(const HSceneObject& sceneObject);
 		ScriptSceneObject* createScriptSceneObject(const HSceneObject& sceneObject);
 		ScriptSceneObject* createScriptSceneObject(MonoObject* existingInstance, const HSceneObject& sceneObject);
 		ScriptSceneObject* createScriptSceneObject(MonoObject* existingInstance, const HSceneObject& sceneObject);
 
 
-		ScriptComponent* getScriptComponent(const GameObjectHandle<ManagedComponent>& component);
-		ScriptSceneObject* getScriptSceneObject(const HSceneObject& sceneObject);
+		ScriptComponent* getScriptComponent(const GameObjectHandle<ManagedComponent>& component) const;
+		ScriptSceneObject* getScriptSceneObject(const HSceneObject& sceneObject) const;
+		ScriptGameObjectBase* getScriptGameObject(UINT64 instanceId) const;
 
 
-		void destroyScriptGameObject(ScriptGameObject* gameObject);
+		void destroyScriptGameObject(ScriptGameObjectBase* gameObject);
 
 
 	private:
 	private:
-		UnorderedMap<UINT64, ScriptGameObject*> mScriptGameObjects;
+		UnorderedMap<UINT64, ScriptGameObjectBase*> mScriptGameObjects;
 
 
 		MonoClass* mSceneObjectClass;
 		MonoClass* mSceneObjectClass;
 	};
 	};

+ 1 - 1
SBansheeEngine/Include/BsScriptSceneObject.h

@@ -7,7 +7,7 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	class BS_SCR_BE_EXPORT ScriptSceneObject : public ScriptObject<ScriptSceneObject, ScriptGameObject>
+	class BS_SCR_BE_EXPORT ScriptSceneObject : public ScriptObject<ScriptSceneObject, ScriptGameObjectBase>
 	{
 	{
 	public:
 	public:
 		SCRIPT_OBJ(BansheeEngineAssemblyName, "BansheeEngine", "SceneObject")
 		SCRIPT_OBJ(BansheeEngineAssemblyName, "BansheeEngine", "SceneObject")

+ 12 - 3
SBansheeEngine/Source/BsScriptGameObjectManager.cpp

@@ -56,7 +56,7 @@ namespace BansheeEngine
 		return nativeInstance;
 		return nativeInstance;
 	}
 	}
 
 
-	ScriptComponent* ScriptGameObjectManager::getScriptComponent(const GameObjectHandle<ManagedComponent>& component)
+	ScriptComponent* ScriptGameObjectManager::getScriptComponent(const GameObjectHandle<ManagedComponent>& component) const
 	{
 	{
 		auto findIter = mScriptGameObjects.find(component->getInstanceId());
 		auto findIter = mScriptGameObjects.find(component->getInstanceId());
 		if(findIter != mScriptGameObjects.end())
 		if(findIter != mScriptGameObjects.end())
@@ -65,7 +65,7 @@ namespace BansheeEngine
 		return nullptr;
 		return nullptr;
 	}
 	}
 
 
-	ScriptSceneObject* ScriptGameObjectManager::getScriptSceneObject(const HSceneObject& sceneObject)
+	ScriptSceneObject* ScriptGameObjectManager::getScriptSceneObject(const HSceneObject& sceneObject) const
 	{
 	{
 		auto findIter = mScriptGameObjects.find(sceneObject->getInstanceId());
 		auto findIter = mScriptGameObjects.find(sceneObject->getInstanceId());
 		if(findIter != mScriptGameObjects.end())
 		if(findIter != mScriptGameObjects.end())
@@ -74,7 +74,16 @@ namespace BansheeEngine
 		return nullptr;
 		return nullptr;
 	}
 	}
 
 
-	void ScriptGameObjectManager::destroyScriptGameObject(ScriptGameObject* gameObject)
+	ScriptGameObjectBase* ScriptGameObjectManager::getScriptGameObject(UINT64 instanceId) const
+	{
+		auto findIter = mScriptGameObjects.find(instanceId);
+		if (findIter != mScriptGameObjects.end())
+			return static_cast<ScriptSceneObject*>(findIter->second);
+
+		return nullptr;
+	}
+
+	void ScriptGameObjectManager::destroyScriptGameObject(ScriptGameObjectBase* gameObject)
 	{
 	{
 		UINT64 idx = gameObject->getNativeHandle()->getInstanceId();
 		UINT64 idx = gameObject->getNativeHandle()->getInstanceId();
 		mScriptGameObjects.erase(idx);
 		mScriptGameObjects.erase(idx);