Răsfoiți Sursa

More work on Inspector
Fixed an issue where cursor wasn't reset when leaving window client area

Marko Pintera 11 ani în urmă
părinte
comite
c744997c1c

+ 1 - 0
BansheeEditor/Include/BsEditorPrerequisites.h

@@ -35,6 +35,7 @@ namespace BansheeEngine
 	class GUIFloatField;
 	class GUITextField;
 	class GUIColor;
+	class GUIFoldout;
 	class GUIDropButton;
 	class EditorWindowManager;
 	class DockManager;

+ 9 - 0
BansheeEngine/Source/BsGUIManager.cpp

@@ -1319,6 +1319,15 @@ namespace BansheeEngine
 		}
 
 		mElementsUnderPointer.swap(mNewElementsUnderPointer);
+
+		if(mDragState != DragState::Dragging)
+		{
+			if(mActiveCursor != CursorType::Arrow)
+			{
+				Cursor::instance().setCursor(CursorType::Arrow);
+				mActiveCursor = CursorType::Arrow;
+			}
+		}
 	}
 
 	void GUIManager::queueForDestroy(GUIElement* element)

+ 13 - 0
MBansheeEditor/Debug_Component1.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BansheeEngine
+{
+    public class Debug_Component1 : Component
+    {
+        public int value1;
+        public int value2;
+    }
+}

+ 13 - 0
MBansheeEditor/Debug_Component2.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BansheeEngine
+{
+    public class Debug_Component2 : Component
+    {
+        public int value4;
+        public int value55;
+    }
+}

+ 2 - 2
MBansheeEditor/EditorWindow.cs

@@ -11,9 +11,9 @@ namespace BansheeEditor
 
         protected GUIPanel GUI;
 
-        public static EditorWindow OpenWindow<T>() where T : EditorWindow
+        public static T OpenWindow<T>() where T : EditorWindow
         {
-            return Internal_CreateOrGetInstance(typeof(T).Namespace, typeof(T).Name);
+            return (T)Internal_CreateOrGetInstance(typeof(T).Namespace, typeof(T).Name);
         }
 
         protected EditorWindow()

+ 45 - 0
MBansheeEditor/GUIFoldout.cs

@@ -0,0 +1,45 @@
+using System;
+using System.Runtime.CompilerServices;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    public sealed class GUIFoldout : GUIElement
+    {
+        public delegate void OnToggledDelegate(bool expanded);
+
+        public event OnToggledDelegate OnToggled;
+
+        public GUIFoldout(GUIContent content, string style, params GUIOption[] options)
+        {
+            Internal_CreateInstance(this, content, style, options);
+        }
+
+        public GUIFoldout(GUIContent content, string style)
+        {
+            Internal_CreateInstance(this, content, style, new GUIOption[0]);
+        }
+
+        public GUIFoldout(GUIContent content, params GUIOption[] options)
+        {
+            Internal_CreateInstance(this, content, "", options);
+        }
+
+        public void SetContent(GUIContent content)
+        {
+            Internal_SetContent(mCachedPtr, content);
+        }
+
+        private void DoOnToggled(bool expanded)
+        {
+            if (OnToggled != null)
+                OnToggled(expanded);
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_CreateInstance(GUIFoldout instance, GUIContent content, string style, GUIOption[] options);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetContent(IntPtr nativeInstance, GUIContent content);
+    }
+}

+ 1 - 1
MBansheeEditor/Inspector/GenericInspector.cs

@@ -49,7 +49,7 @@ namespace BansheeEditor
 
         internal override int GetOptimalHeight()
         {
-            throw new NotImplementedException();
+            return 200; // TODO  - Implement properly
         }
     }
 }

+ 5 - 0
MBansheeEditor/Inspector/Inspector.cs

@@ -22,6 +22,11 @@ namespace BansheeEditor
             GUI.SetArea(x, y, width, height);
         }
 
+        internal void SetVisible(bool visible)
+        {
+            GUI.SetVisible(visible);
+        }
+
         internal void Destroy()
         {
             GUI.Destroy();

+ 33 - 16
MBansheeEditor/Inspector/InspectorWindow.cs

@@ -6,9 +6,15 @@ namespace BansheeEditor
 {
     internal sealed class InspectorWindow : EditorWindow
     {
-        private List<Inspector> inspectors = new List<Inspector>();
+        private class InspectorData
+        {
+            public GUIFoldout foldout;
+            public Inspector inspector;
+        }
+
+        private List<InspectorData> inspectorData = new List<InspectorData>();
 
-        internal void Initialize(SceneObject so)
+        internal void SetObjectToInspect(SceneObject so)
         {
             Clear();
 
@@ -17,23 +23,31 @@ namespace BansheeEditor
             Component[] allComponents = so.GetComponents();
             for (int i = 0; i < allComponents.Length; i++)
             {
-                // TODO
-                //  - Create component foldout
-                //  - Hook up the foldout so when clicked it will expand/collapse the custom inspector or child object
+                InspectorData data = new InspectorData();
+
+                data.foldout = new GUIFoldout(allComponents[i].GetType().Name);
+                GUI.layout.AddElement(data.foldout);
+
+                data.inspector = GetInspector(allComponents[i].GetType());
+                data.inspector.Initialize(CreatePanel(0, 0, 0, 0), allComponents[i]);
 
-                Inspector inspector = GetInspector(allComponents[i].GetType());
-                inspector.Initialize(CreatePanel(0, 0, 0, 0), allComponents[i]);
+                data.foldout.OnToggled += (bool expanded) => Foldout_OnToggled(data.inspector, expanded);
 
-                inspectors.Add(inspector);
+                inspectorData.Add(data);
             }
 
             RepositionInspectors();
         }
 
+        void Foldout_OnToggled(Inspector inspector, bool expanded)
+        {
+            inspector.SetVisible(expanded);
+        }
+
         internal void Refresh()
         {
-            for (int i = 0; i < inspectors.Count; i++)
-                inspectors[i].Refresh();
+            for (int i = 0; i < inspectorData.Count; i++)
+                inspectorData[i].inspector.Refresh();
         }
 
         internal void Destroy()
@@ -45,10 +59,13 @@ namespace BansheeEditor
 
         internal void Clear()
         {
-            for (int i = 0; i < inspectors.Count; i++)
-                inspectors[i].Destroy();
+            for (int i = 0; i < inspectorData.Count; i++)
+            {
+                inspectorData[i].foldout.Destroy();
+                inspectorData[i].inspector.Destroy();
+            }
 
-            inspectors.Clear();
+            inspectorData.Clear();
         }
 
         protected override void WindowResized(int width, int height)
@@ -59,11 +76,11 @@ namespace BansheeEditor
         private void RepositionInspectors()
         {
             int curPosition = 0;
-            for (int i = 0; i < inspectors.Count; i++)
+            for (int i = 0; i < inspectorData.Count; i++)
             {
-                int inspectorHeight = inspectors[i].GetOptimalHeight();
+                int inspectorHeight = inspectorData[i].inspector.GetOptimalHeight();
 
-                inspectors[i].SetArea(0, curPosition, width, inspectorHeight);
+                inspectorData[i].inspector.SetArea(0, curPosition, width, inspectorHeight);
                 curPosition += inspectorHeight;
             } 
         }

+ 3 - 0
MBansheeEditor/MBansheeEditor.csproj

@@ -41,8 +41,11 @@
   <ItemGroup>
     <Compile Include="DbgCustomInspector.cs" />
     <Compile Include="DbgEditorWindow.cs" />
+    <Compile Include="Debug_Component1.cs" />
+    <Compile Include="Debug_Component2.cs" />
     <Compile Include="EditorApplication.cs" />
     <Compile Include="EditorWindow.cs" />
+    <Compile Include="GUIFoldout.cs" />
     <Compile Include="Inspector\CustomInspector.cs" />
     <Compile Include="Inspector\GenericInspector.cs" />
     <Compile Include="Inspector\InspectableArray.cs" />

+ 13 - 0
MBansheeEditor/Program.cs

@@ -8,6 +8,19 @@ namespace BansheeEditor
     {
         static void Main()
         {
+            InspectorWindow window = EditorWindow.OpenWindow<InspectorWindow>();
+
+            //SceneObject newDbgObject = new SceneObject("NewDbgObject");
+            //newDbgObject.AddComponent<Debug_Component1>();
+            //newDbgObject.AddComponent<Debug_Component2>();
+
+            //window.SetObjectToInspect(newDbgObject);
+            //window.Refresh(); // TODO - This should be called N times per second
+
+
+
+
+
             // Starts main editor window with the specified width/height and render system
             // (Window position and sizes are stored internally. Restored upon StartUp and saved upon ShutDown)
             //EditorApplication.StartUp(RenderSystem.DX11, 1024, 800);

+ 6 - 0
MBansheeEngine/GUI/GUIPanel.cs

@@ -46,6 +46,12 @@ namespace BansheeEngine
             return area;
         }
 
+        public void SetVisible(bool visible)
+        {
+            for (int i = 0; i < childAreas.Count; i++)
+                childAreas[i].SetVisible(visible);
+        }
+
         internal void SetArea(int x, int y, int width, int height)
         {
             Internal_SetArea(mCachedPtr, x, y, width, height);

+ 39 - 0
SBansheeEditor/Include/BsScriptGUIFoldout.h

@@ -0,0 +1,39 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsScriptObject.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT ScriptGUIFoldout : public ScriptObject<ScriptGUIFoldout>
+	{
+	public:
+		static void initMetaData();
+
+		GUIFoldout* getInternalValue() const { return mFoldout; }
+
+	private:
+		static void internal_createInstance(MonoObject* instance, MonoObject* content, MonoString* style, MonoArray* guiOptions);
+		static void internal_destroyInstance(ScriptGUIFoldout* nativeInstance);
+		static void internal_setContent(ScriptGUIFoldout* nativeInstance, MonoObject* content);
+
+		static void internal_destroy(ScriptGUIFoldout* nativeInstance);
+		static void internal_setVisible(ScriptGUIFoldout* nativeInstance, bool visible);
+		static void internal_setParent(ScriptGUIFoldout* nativeInstance, MonoObject* parentLayout);
+
+		static void initRuntimeData();
+
+		static void onToggled(MonoObject* instance, bool expanded);
+
+		ScriptGUIFoldout(GUIFoldout* foldout);
+
+		void destroy();
+
+		GUIFoldout* mFoldout;
+		bool mIsDestroyed;
+
+		typedef void (__stdcall *OnToggledThunkDef) (MonoObject*, bool, MonoException**);
+
+		static OnToggledThunkDef onToggledThunk;
+	};
+}

+ 2 - 0
SBansheeEditor/SBansheeEditor.vcxproj

@@ -228,10 +228,12 @@
   <ItemGroup>
     <ClInclude Include="Include\BsScriptEditorPrerequisites.h" />
     <ClInclude Include="Include\BsScriptEditorWindow.h" />
+    <ClInclude Include="Include\BsScriptGUIFoldout.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp" />
     <ClCompile Include="Source\BsScriptEditorWindow.cpp" />
+    <ClCompile Include="Source\BsScriptGUIFoldout.cpp" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 6 - 0
SBansheeEditor/SBansheeEditor.vcxproj.filters

@@ -21,6 +21,9 @@
     <ClInclude Include="Include\BsScriptEditorWindow.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsScriptGUIFoldout.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp">
@@ -29,5 +32,8 @@
     <ClCompile Include="Source\BsScriptEditorWindow.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsScriptGUIFoldout.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 2 - 2
SBansheeEditor/Source/BsScriptEditorPlugin.cpp

@@ -18,10 +18,10 @@ namespace BansheeEngine
 		const String ASSEMBLY_ENTRY_POINT = "ProgramEd::Main";
 
 		MonoAssembly& assembly = MonoManager::instance().loadAssembly(ENGINE_ASSEMBLY_PATH, ENGINE_ASSEMBLY_NAME);
-		assembly.invoke(ASSEMBLY_ENTRY_POINT);
-
 		ScriptEditorWindow::registerManagedEditorWindows();
 
+		assembly.invoke(ASSEMBLY_ENTRY_POINT);
+
 		return nullptr;
 	}
 }

+ 122 - 0
SBansheeEditor/Source/BsScriptGUIFoldout.cpp

@@ -0,0 +1,122 @@
+#include "BsScriptGUIFoldout.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 "BsGUIFoldout.h"
+#include "BsGUIOptions.h"
+#include "BsGUIContent.h"
+#include "BsScriptGUIElementStyle.h"
+#include "BsScriptGUILayout.h"
+#include "BsScriptGUIArea.h"
+#include "BsScriptHString.h"
+#include "BsScriptGUIContent.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	ScriptGUIFoldout::OnToggledThunkDef ScriptGUIFoldout::onToggledThunk;
+
+	ScriptGUIFoldout::ScriptGUIFoldout(GUIFoldout* foldout)
+		:mFoldout(foldout), mIsDestroyed(false)
+	{
+
+	}
+
+	void ScriptGUIFoldout::initMetaData()
+	{
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUIFoldout", &ScriptGUIFoldout::initRuntimeData);
+
+		MonoManager::registerScriptType(&metaData);
+	}
+
+	void ScriptGUIFoldout::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptGUIFoldout::internal_createInstance);
+		metaData.scriptClass->addInternalCall("Internal_DestroyInstance", &ScriptGUIFoldout::internal_destroyInstance);
+		metaData.scriptClass->addInternalCall("Internal_SetContent", &ScriptGUIFoldout::internal_setContent);
+
+		metaData.scriptClass->addInternalCall("Internal_Destroy", &ScriptGUIFoldout::internal_destroy);
+		metaData.scriptClass->addInternalCall("Internal_SetVisible", &ScriptGUIFoldout::internal_setVisible);
+		metaData.scriptClass->addInternalCall("Internal_SetParent", &ScriptGUIFoldout::internal_setParent);
+
+		onToggledThunk = (OnToggledThunkDef)metaData.scriptClass->getMethod("DoOnToggled").getThunk();
+	}
+
+	void ScriptGUIFoldout::destroy()
+	{
+		if(!mIsDestroyed)
+		{
+			GUIElement::destroy(mFoldout);
+			mFoldout = nullptr;
+
+			mIsDestroyed = true;
+		}
+	}
+
+	void ScriptGUIFoldout::internal_createInstance(MonoObject* instance, MonoObject* content, MonoString* style, MonoArray* guiOptions)
+	{
+		GUIOptions options;
+
+		UINT32 arrayLen = (UINT32)mono_array_length(guiOptions);
+		for(UINT32 i = 0; i < arrayLen; i++)
+			options.addOption(mono_array_get(guiOptions, GUIOption, i));
+
+		GUIContent nativeContent(ScriptGUIContent::getText(content), ScriptGUIContent::getImage(content), ScriptGUIContent::getTooltip(content));
+		GUIFoldout* guiFoldout = GUIFoldout::create(options, toString(MonoUtil::monoToWString(style))); // TODO - Add label
+
+		guiFoldout->onStateChanged.connect(std::bind(&ScriptGUIFoldout::onToggled, instance, _1));
+
+		ScriptGUIFoldout* nativeInstance = new (cm_alloc<ScriptGUIFoldout>()) ScriptGUIFoldout(guiFoldout);
+		nativeInstance->createInstance(instance);
+
+		metaData.thisPtrField->setValue(instance, &nativeInstance);
+	}
+
+	void ScriptGUIFoldout::internal_setContent(ScriptGUIFoldout* nativeInstance, MonoObject* content)
+	{
+		GUIContent nativeContent(ScriptGUIContent::getText(content), ScriptGUIContent::getImage(content), ScriptGUIContent::getTooltip(content));
+		
+		// TODO - Update GUIFoldout once it has a label
+	}
+
+	void ScriptGUIFoldout::internal_destroy(ScriptGUIFoldout* nativeInstance)
+	{
+		nativeInstance->destroy();
+	}
+
+	void ScriptGUIFoldout::internal_destroyInstance(ScriptGUIFoldout* nativeInstance)
+	{
+		nativeInstance->destroy();
+		cm_delete(nativeInstance);
+	}
+
+	void ScriptGUIFoldout::internal_setVisible(ScriptGUIFoldout* nativeInstance, bool visible)
+	{
+		if(visible)
+			nativeInstance->getInternalValue()->enableRecursively();
+		else
+			nativeInstance->getInternalValue()->disableRecursively();
+	}
+
+	void ScriptGUIFoldout::internal_setParent(ScriptGUIFoldout* nativeInstance, MonoObject* parentLayout)
+	{
+		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
+
+		GUILayout* nativeLayout = scriptLayout->getInternalValue();
+		nativeLayout->addElement(nativeInstance->getInternalValue());
+	}
+
+	void ScriptGUIFoldout::onToggled(MonoObject* instance, bool expanded)
+	{
+		MonoException* exception = nullptr;
+		onToggledThunk(instance, expanded, &exception);
+
+		MonoUtil::throwIfException(exception);
+	}
+}