Преглед изворни кода

Refactored GUILayout and GUI space creation so layouts can be reparented and their creation is more alike other GUI elements

Marko Pintera пре 10 година
родитељ
комит
12c4c6b013
36 измењених фајлова са 406 додато и 461 уклоњено
  1. 3 2
      BansheeEditor/Source/BsGUIFieldBase.cpp
  2. 6 6
      BansheeEditor/Source/BsGUIMenuBar.cpp
  3. 3 2
      BansheeEditor/Source/BsGUITextField.cpp
  4. 5 3
      BansheeEditor/Source/BsGUIVector2Field.cpp
  5. 4 3
      BansheeEditor/Source/BsGUIVector3Field.cpp
  6. 4 3
      BansheeEditor/Source/BsGUIVector4Field.cpp
  7. 14 13
      BansheeEditor/Source/BsModalWindow.cpp
  8. 6 5
      BansheeEditor/Source/DbgEditorWidget1.cpp
  9. 16 16
      BansheeEditor/Source/DbgEditorWidget2.cpp
  10. 2 29
      BansheeEngine/Include/BsGUIElementBase.h
  11. 29 61
      BansheeEngine/Include/BsGUILayout.h
  12. 6 0
      BansheeEngine/Include/BsGUILayoutExplicit.h
  13. 6 0
      BansheeEngine/Include/BsGUILayoutX.h
  14. 6 0
      BansheeEngine/Include/BsGUILayoutY.h
  15. 20 0
      BansheeEngine/Include/BsGUISpace.h
  16. 2 0
      BansheeEngine/Include/BsProfilerOverlay.h
  17. 3 3
      BansheeEngine/Source/BsGUIDropDownBox.cpp
  18. 18 99
      BansheeEngine/Source/BsGUIElementBase.cpp
  19. 10 98
      BansheeEngine/Source/BsGUILayout.cpp
  20. 5 0
      BansheeEngine/Source/BsGUILayoutExplicit.cpp
  21. 5 0
      BansheeEngine/Source/BsGUILayoutX.cpp
  22. 5 0
      BansheeEngine/Source/BsGUILayoutY.cpp
  23. 3 2
      BansheeEngine/Source/BsGUIScrollArea.cpp
  24. 10 7
      BansheeEngine/Source/BsGUIScrollBar.cpp
  25. 20 0
      BansheeEngine/Source/BsGUISpace.cpp
  26. 64 71
      BansheeEngine/Source/BsProfilerOverlay.cpp
  27. 8 9
      ExampleProject/Main/Main.cpp
  28. 25 0
      MBansheeEditor/EditorBuiltin.cs
  29. 3 2
      SBansheeEditor/Source/BsGUIGameObjectField.cpp
  30. 3 2
      SBansheeEditor/Source/BsGUIResourceField.cpp
  31. 2 2
      SBansheeEngine/Include/BsScriptGUIFixedSpace.h
  32. 2 2
      SBansheeEngine/Include/BsScriptGUIFlexibleSpace.h
  33. 6 6
      SBansheeEngine/Source/BsScriptGUIFixedSpace.cpp
  34. 5 5
      SBansheeEngine/Source/BsScriptGUIFlexibleSpace.cpp
  35. 12 10
      SBansheeEngine/Source/BsScriptGUILayout.cpp
  36. 65 0
      TODO.txt

+ 3 - 2
BansheeEditor/Source/BsGUIFieldBase.cpp

@@ -1,6 +1,6 @@
 #include "BsGUIFieldBase.h"
 #include "BsGUIFieldBase.h"
 #include "BsGUILabel.h"
 #include "BsGUILabel.h"
-#include "BsGUILayout.h"
+#include "BsGUILayoutX.h"
 #include "BsGUIWidget.h"
 #include "BsGUIWidget.h"
 #include "BsGUISkin.h"
 #include "BsGUISkin.h"
 #include "BsGUILayoutUtility.h"
 #include "BsGUILayoutUtility.h"
@@ -13,7 +13,8 @@ namespace BansheeEngine
 		const String& style, const GUILayoutOptions& layoutOptions, bool withLabel)
 		const String& style, const GUILayoutOptions& layoutOptions, bool withLabel)
 		:GUIElementContainer(layoutOptions, style), mLabel(nullptr)
 		:GUIElementContainer(layoutOptions, style), mLabel(nullptr)
 	{
 	{
-		mLayout = &addLayoutXInternal(this);
+		mLayout = GUILayoutX::create();
+		_registerChildElement(mLayout);
 
 
 		if(withLabel)
 		if(withLabel)
 		{
 		{

+ 6 - 6
BansheeEditor/Source/BsGUIMenuBar.cpp

@@ -31,20 +31,20 @@ namespace BansheeEngine
 		GUILayout& mainLayout = mMainArea->getLayout();
 		GUILayout& mainLayout = mMainArea->getLayout();
 
 
 		mainLayout.addElement(mLogoTexture);
 		mainLayout.addElement(mLogoTexture);
-		mainLayout.addSpace(5);
-		mainLayout.addFlexibleSpace();
+		mainLayout.addNewElement<GUIFixedSpace>(5);
+		mainLayout.addNewElement<GUIFlexibleSpace>();
 
 
 		mMinBtn = GUIButton::create(HString(L""), "WinMinimizeBtn");
 		mMinBtn = GUIButton::create(HString(L""), "WinMinimizeBtn");
 		mMaxBtn = GUIButton::create(HString(L""), "WinMaximizeBtn");
 		mMaxBtn = GUIButton::create(HString(L""), "WinMaximizeBtn");
 		mCloseBtn = GUIButton::create(HString(L""), "WinCloseBtn");
 		mCloseBtn = GUIButton::create(HString(L""), "WinCloseBtn");
 
 
-		mainLayout.addSpace(3);
+		mainLayout.addNewElement<GUIFixedSpace>(3);
 		mainLayout.addElement(mMinBtn);
 		mainLayout.addElement(mMinBtn);
-		mainLayout.addSpace(3);
+		mainLayout.addNewElement<GUIFixedSpace>(3);
 		mainLayout.addElement(mMaxBtn);
 		mainLayout.addElement(mMaxBtn);
-		mainLayout.addSpace(3);
+		mainLayout.addNewElement<GUIFixedSpace>(3);
 		mainLayout.addElement(mCloseBtn);
 		mainLayout.addElement(mCloseBtn);
-		mainLayout.addSpace(3);
+		mainLayout.addNewElement<GUIFixedSpace>(3);
 
 
 		mMinBtn->onClick.connect(std::bind(&GUIMenuBar::onMinimizeClicked, this));
 		mMinBtn->onClick.connect(std::bind(&GUIMenuBar::onMinimizeClicked, this));
 		mMaxBtn->onClick.connect(std::bind(&GUIMenuBar::onMaximizeClicked, this));
 		mMaxBtn->onClick.connect(std::bind(&GUIMenuBar::onMaximizeClicked, this));

+ 3 - 2
BansheeEditor/Source/BsGUITextField.cpp

@@ -1,6 +1,6 @@
 #include "BsGUITextField.h"
 #include "BsGUITextField.h"
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
-#include "BsGUILayout.h"
+#include "BsGUILayoutX.h"
 #include "BsGUILabel.h"
 #include "BsGUILabel.h"
 #include "BsGUIInputBox.h"
 #include "BsGUIInputBox.h"
 #include "BsBuiltinResources.h"
 #include "BsBuiltinResources.h"
@@ -20,7 +20,8 @@ namespace BansheeEngine
 		:GUIElementContainer(layoutOptions, style),
 		:GUIElementContainer(layoutOptions, style),
 		mInputBox(nullptr), mValue(L""), mHasInputFocus(false), mLayout(nullptr), mLabel(nullptr)
 		mInputBox(nullptr), mValue(L""), mHasInputFocus(false), mLayout(nullptr), mLabel(nullptr)
 	{
 	{
-		mLayout = &addLayoutXInternal(this);
+		mLayout = GUILayoutX::create();
+		_registerChildElement(mLayout);
 
 
 		if (withLabel)
 		if (withLabel)
 		{
 		{

+ 5 - 3
BansheeEditor/Source/BsGUIVector2Field.cpp

@@ -1,6 +1,7 @@
 #include "BsGUIVector2Field.h"
 #include "BsGUIVector2Field.h"
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
-#include "BsGUILayout.h"
+#include "BsGUILayoutX.h"
+#include "BsGUILayoutY.h"
 #include "BsGUILabel.h"
 #include "BsGUILabel.h"
 #include "BsGUIFloatField.h"
 #include "BsGUIFloatField.h"
 #include "BsBuiltinResources.h"
 #include "BsBuiltinResources.h"
@@ -28,11 +29,12 @@ namespace BansheeEngine
 
 
 		mLayout->removeElement(mLabel);
 		mLayout->removeElement(mLabel);
 
 
-		GUILayout* layout = &mLayout->addLayoutY();
+		GUILayout* layout = mLayout->addNewElement<GUILayoutY>();
+
 		layout->addElement(mLabel);
 		layout->addElement(mLabel);
 		mLabel->setLayoutOptions(GUIOptions());
 		mLabel->setLayoutOptions(GUIOptions());
 
 
-		GUILayout* elementLayout = &layout->addLayoutX();
+		GUILayout* elementLayout = layout->addNewElement<GUILayoutX>();
 
 
 		elementLayout->addElement(mFieldX);
 		elementLayout->addElement(mFieldX);
 		elementLayout->addElement(mFieldY);
 		elementLayout->addElement(mFieldY);

+ 4 - 3
BansheeEditor/Source/BsGUIVector3Field.cpp

@@ -1,6 +1,7 @@
 #include "BsGUIVector3Field.h"
 #include "BsGUIVector3Field.h"
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
-#include "BsGUILayout.h"
+#include "BsGUILayoutX.h"
+#include "BsGUILayoutY.h"
 #include "BsGUILabel.h"
 #include "BsGUILabel.h"
 #include "BsGUIFloatField.h"
 #include "BsGUIFloatField.h"
 #include "BsBuiltinResources.h"
 #include "BsBuiltinResources.h"
@@ -30,11 +31,11 @@ namespace BansheeEngine
 
 
 		mLayout->removeElement(mLabel);
 		mLayout->removeElement(mLabel);
 
 
-		GUILayout* layout = &mLayout->addLayoutY();
+		GUILayout* layout = mLayout->addNewElement<GUILayoutY>();
 		layout->addElement(mLabel);
 		layout->addElement(mLabel);
 		mLabel->setLayoutOptions(GUIOptions());
 		mLabel->setLayoutOptions(GUIOptions());
 
 
-		GUILayout* elementLayout = &layout->addLayoutX();
+		GUILayout* elementLayout = layout->addNewElement<GUILayoutX>();
 
 
 		elementLayout->addElement(mFieldX);
 		elementLayout->addElement(mFieldX);
 		elementLayout->addElement(mFieldY);
 		elementLayout->addElement(mFieldY);

+ 4 - 3
BansheeEditor/Source/BsGUIVector4Field.cpp

@@ -1,6 +1,7 @@
 #include "BsGUIVector4Field.h"
 #include "BsGUIVector4Field.h"
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
-#include "BsGUILayout.h"
+#include "BsGUILayoutX.h"
+#include "BsGUILayoutY.h"
 #include "BsGUILabel.h"
 #include "BsGUILabel.h"
 #include "BsGUIFloatField.h"
 #include "BsGUIFloatField.h"
 #include "BsBuiltinResources.h"
 #include "BsBuiltinResources.h"
@@ -31,11 +32,11 @@ namespace BansheeEngine
 
 
 		mLayout->removeElement(mLabel);
 		mLayout->removeElement(mLabel);
 
 
-		GUILayout* layout = &mLayout->addLayoutY();
+		GUILayout* layout = mLayout->addNewElement<GUILayoutY>();
 		layout->addElement(mLabel);
 		layout->addElement(mLabel);
 		mLabel->setLayoutOptions(GUIOptions());
 		mLabel->setLayoutOptions(GUIOptions());
 
 
-		GUILayout* elementLayout = &layout->addLayoutX();
+		GUILayout* elementLayout = layout->addNewElement<GUILayoutX>();
 
 
 		elementLayout->addElement(mFieldX);
 		elementLayout->addElement(mFieldX);
 		elementLayout->addElement(mFieldY);
 		elementLayout->addElement(mFieldY);

+ 14 - 13
BansheeEditor/Source/BsModalWindow.cpp

@@ -4,6 +4,7 @@
 #include "BsPlatform.h"
 #include "BsPlatform.h"
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
 #include "BsGUILayoutX.h"
 #include "BsGUILayoutX.h"
+#include "BsGUILayoutY.h"
 #include "BsGUISpace.h"
 #include "BsGUISpace.h"
 #include "BsGUIButton.h"
 #include "BsGUIButton.h"
 #include "BsGUITexture.h"
 #include "BsGUITexture.h"
@@ -23,28 +24,28 @@ namespace BansheeEngine
 		mTitleBarBg = GUITexture::create(GUIOptions(GUIOption::flexibleWidth()), "TitleBarBackground");
 		mTitleBarBg = GUITexture::create(GUIOptions(GUIOption::flexibleWidth()), "TitleBarBackground");
 		mTitle = GUILabel::create(title);
 		mTitle = GUILabel::create(title);
 
 
-		GUILayout& bgLayout = mTitleBarBgArea->getLayout().addLayoutY();
-		bgLayout.addElement(mTitleBarBg);
-		bgLayout.addFlexibleSpace();
+		GUILayout* bgLayout = mTitleBarBgArea->getLayout().addNewElement<GUILayoutY>();
+		bgLayout->addElement(mTitleBarBg);
+		bgLayout->addNewElement<GUIFlexibleSpace>();
 
 
-		GUILayout& contentLayoutY = mTitleBarArea->getLayout().addLayoutY();
-		GUILayout& contentLayoutX = contentLayoutY.addLayoutX();
-		contentLayoutX.addFlexibleSpace();
-		GUILayout& titleLayout = contentLayoutX.addLayoutY();
-		titleLayout.addSpace(2);
-		titleLayout.addElement(mTitle);
-		titleLayout.addFlexibleSpace();
-		contentLayoutX.addFlexibleSpace();
+		GUILayout* contentLayoutY = mTitleBarArea->getLayout().addNewElement<GUILayoutY>();
+		GUILayout* contentLayoutX = contentLayoutY->addNewElement<GUILayoutX>();
+		contentLayoutX->addNewElement<GUIFlexibleSpace>();
+		GUILayout* titleLayout = contentLayoutX->addNewElement<GUILayoutY>();
+		titleLayout->addNewElement<GUIFixedSpace>(2);
+		titleLayout->addElement(mTitle);
+		titleLayout->addNewElement<GUIFlexibleSpace>();
+		contentLayoutX->addNewElement<GUIFlexibleSpace>();
 
 
 		if (hasCloseButton)
 		if (hasCloseButton)
 		{
 		{
 			mCloseButton = GUIButton::create(HString(L""), "WinCloseBtn");
 			mCloseButton = GUIButton::create(HString(L""), "WinCloseBtn");
-			contentLayoutX.addElement(mCloseButton);
+			contentLayoutX->addElement(mCloseButton);
 			
 			
 			mCloseButton->onClick.connect(std::bind(&ModalWindow::close, this));
 			mCloseButton->onClick.connect(std::bind(&ModalWindow::close, this));
 		}
 		}
 
 
-		contentLayoutY.addFlexibleSpace();
+		contentLayoutY->addNewElement<GUIFlexibleSpace>();
 		
 		
 		updateSize();
 		updateSize();
 	}
 	}

+ 6 - 5
BansheeEditor/Source/DbgEditorWidget1.cpp

@@ -6,6 +6,7 @@
 #include "BsGUIScrollArea.h"
 #include "BsGUIScrollArea.h"
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
 #include "BsGUILayout.h"
 #include "BsGUILayout.h"
+#include "BsGUILayoutY.h"
 #include "BsEditorWidgetManager.h"
 #include "BsEditorWidgetManager.h"
 #include "BsGUISceneTreeView.h"
 #include "BsGUISceneTreeView.h"
 #include "BsGUIResourceTreeView.h"
 #include "BsGUIResourceTreeView.h"
@@ -28,7 +29,7 @@ namespace BansheeEngine
 		GUIScrollArea* scrollArea = GUIScrollArea::create();
 		GUIScrollArea* scrollArea = GUIScrollArea::create();
 		layout.addElement(scrollArea);
 		layout.addElement(scrollArea);
 
 
-		GUILayout& treeViewLayout = scrollArea->getLayout().addLayoutY();
+		GUILayout* treeViewLayout = scrollArea->getLayout().addNewElement<GUILayoutY>();
 
 
 		//scrollLayout.addElement(GUIButton::create(*mGUI, L"Test A"));
 		//scrollLayout.addElement(GUIButton::create(*mGUI, L"Test A"));
 		//scrollLayout.addElement(GUIButton::create(*mGUI, L"Test B"));
 		//scrollLayout.addElement(GUIButton::create(*mGUI, L"Test B"));
@@ -46,11 +47,11 @@ namespace BansheeEngine
 		mSceneTreeView = GUISceneTreeView::create(GUIOptions(GUIOption::flexibleWidth(), GUIOption::flexibleHeight()));
 		mSceneTreeView = GUISceneTreeView::create(GUIOptions(GUIOption::flexibleWidth(), GUIOption::flexibleHeight()));
 		mResourceTreeView = GUIResourceTreeView::create(GUIOptions(GUIOption::flexibleWidth(), GUIOption::flexibleHeight()));
 		mResourceTreeView = GUIResourceTreeView::create(GUIOptions(GUIOption::flexibleWidth(), GUIOption::flexibleHeight()));
 
 
-		treeViewLayout.addElement(GUILabel::create(HString(L"<<<<<<<<<<<<<<SCENE VIEW>>>>>>>>>>>>>>")));
-		treeViewLayout.addElement(mSceneTreeView);
+		treeViewLayout->addElement(GUILabel::create(HString(L"<<<<<<<<<<<<<<SCENE VIEW>>>>>>>>>>>>>>")));
+		treeViewLayout->addElement(mSceneTreeView);
 
 
-		treeViewLayout.addElement(GUILabel::create(HString(L"<<<<<<<<<<<<<<RESOURCE VIEW>>>>>>>>>>>>>>")));
-		treeViewLayout.addElement(mResourceTreeView);
+		treeViewLayout->addElement(GUILabel::create(HString(L"<<<<<<<<<<<<<<RESOURCE VIEW>>>>>>>>>>>>>>")));
+		treeViewLayout->addElement(mResourceTreeView);
 
 
 		//GUIFlexibleSpace& space4 = otherLayout.addFlexibleSpace();
 		//GUIFlexibleSpace& space4 = otherLayout.addFlexibleSpace();
 		//otherLayout.addElement(mDbgLabel);
 		//otherLayout.addElement(mDbgLabel);

+ 16 - 16
BansheeEditor/Source/DbgEditorWidget2.cpp

@@ -3,7 +3,7 @@
 #include "BsGUIToggle.h"
 #include "BsGUIToggle.h"
 #include "BsGUIScrollArea.h"
 #include "BsGUIScrollArea.h"
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
-#include "BsGUILayout.h"
+#include "BsGUILayoutY.h"
 #include "BsGUIWidget.h"
 #include "BsGUIWidget.h"
 #include "BsGUISkin.h"
 #include "BsGUISkin.h"
 #include "BsGUIIntField.h"
 #include "BsGUIIntField.h"
@@ -49,7 +49,7 @@ namespace BansheeEngine
 	DbgEditorWidget2::DbgEditorWidget2(const ConstructPrivately& dummy, EditorWidgetContainer& parentContainer)
 	DbgEditorWidget2::DbgEditorWidget2(const ConstructPrivately& dummy, EditorWidgetContainer& parentContainer)
 		:EditorWidget<DbgEditorWidget2>(HString(L"DbgEditorWidget2"), parentContainer)
 		:EditorWidget<DbgEditorWidget2>(HString(L"DbgEditorWidget2"), parentContainer)
 	{
 	{
-		GUILayout& layout = mContent->getLayout().addLayoutY();
+		GUILayout* layout = mContent->getLayout().addNewElement<GUILayoutY>();
 
 
 		GUIIntField* intField = GUIIntField::create(GUIContent(HString(L"Int Field")), 100, GUIOptions(GUIOption::fixedWidth(200)));
 		GUIIntField* intField = GUIIntField::create(GUIContent(HString(L"Int Field")), 100, GUIOptions(GUIOption::fixedWidth(200)));
 		GUIFloatField* floatField = GUIFloatField::create(HString(L"Float Field"), GUIOptions(GUIOption::fixedWidth(200)));
 		GUIFloatField* floatField = GUIFloatField::create(HString(L"Float Field"), GUIOptions(GUIOption::fixedWidth(200)));
@@ -69,20 +69,20 @@ namespace BansheeEngine
 		GUIProgressBar* progressBar = GUIProgressBar::create(GUIOptions(GUIOption::fixedWidth(200)));
 		GUIProgressBar* progressBar = GUIProgressBar::create(GUIOptions(GUIOption::fixedWidth(200)));
 		progressBar->setPercent(0.33f);
 		progressBar->setPercent(0.33f);
 
 
-		layout.addElement(intField);
-		layout.addElement(floatField);
-		layout.addElement(textField);
-		layout.addElement(vec4Field);
-		layout.addElement(vec3Field);
-		layout.addElement(vec2Field);
-		layout.addElement(toggleField);
-		layout.addElement(colorField);
-		layout.addElement(foldout);
-		layout.addElement(button);
-		layout.addElement(slider);
-		layout.addElement(progressBar);
-
-		layout.addFlexibleSpace();
+		layout->addElement(intField);
+		layout->addElement(floatField);
+		layout->addElement(textField);
+		layout->addElement(vec4Field);
+		layout->addElement(vec3Field);
+		layout->addElement(vec2Field);
+		layout->addElement(toggleField);
+		layout->addElement(colorField);
+		layout->addElement(foldout);
+		layout->addElement(button);
+		layout->addElement(slider);
+		layout->addElement(progressBar);
+
+		layout->addNewElement<GUIFlexibleSpace>();
 	}
 	}
 
 
 	DbgEditorWidget2::~DbgEditorWidget2()
 	DbgEditorWidget2::~DbgEditorWidget2()

+ 2 - 29
BansheeEngine/Include/BsGUIElementBase.h

@@ -235,14 +235,14 @@ namespace BansheeEngine
 		 *
 		 *
 		 * @note	Internal method.
 		 * @note	Internal method.
 		 */
 		 */
-		void _registerChildElement(GUIElement* element);
+		void _registerChildElement(GUIElementBase* element);
 
 
 		/**
 		/**
 		 * @brief	Unregisters an existing child element.
 		 * @brief	Unregisters an existing child element.
 		 *
 		 *
 		 * @note	Internal method.
 		 * @note	Internal method.
 		 */
 		 */
-		void _unregisterChildElement(GUIElement* element);
+		void _unregisterChildElement(GUIElementBase* element);
 
 
 	protected:
 	protected:
 		/**
 		/**
@@ -256,33 +256,6 @@ namespace BansheeEngine
 		 */
 		 */
 		void markMeshAsDirty();
 		void markMeshAsDirty();
 
 
-		/**
-		 * @brief	Creates and adds a new horizontal layout to the specified "parent" element.
-		 */
-		GUILayout& addLayoutXInternal(GUIElementBase* parent);
-
-		/**
-		 * @brief	Creates and adds a new vertical layout to the specified "parent" element.
-		 */
-		GUILayout& addLayoutYInternal(GUIElementBase* parent);
-
-		/**
-		 * @brief	Removes an existing layout from this element.
-		 */
-		void removeLayoutInternal(GUILayout& layout);
-
-		/**
-		 * @brief	Creates and adds a new horizontal layout to the specified "parent" element,
-		 *			at a specific child index. Caller must ensure index is in valid range.
-		 */
-		GUILayout& insertLayoutXInternal(GUIElementBase* parent, UINT32 idx);
-
-		/**
-		 * @brief	Creates and adds a new vertical layout to the specified "parent" element,
-		 *			at a specific child index. Caller must ensure index is in valid range.
-		 */
-		GUILayout& insertLayoutYInternal(GUIElementBase* parent, UINT32 idx);
-
 		GUIWidget* mParentWidget;
 		GUIWidget* mParentWidget;
 		GUIElementBase* mParentElement;
 		GUIElementBase* mParentElement;
 		Vector<GUIElementBase*> mChildren;	
 		Vector<GUIElementBase*> mChildren;	

+ 29 - 61
BansheeEngine/Include/BsGUILayout.h

@@ -18,89 +18,52 @@ namespace BansheeEngine
 		virtual ~GUILayout();
 		virtual ~GUILayout();
 
 
 		/**
 		/**
-		 * @brief	Adds a new element to the layout after all existing elements.
-		 */
-		void addElement(GUIElement* element);
-
-		/**
-		 * @brief	Removes the specified element from the layout.
+		 * @brief	Creates a new element and adds it to the layout after all existing elements.
 		 */
 		 */
-		void removeElement(GUIElement* element);
+		template<class Type, class... Args>
+		Type* addNewElement(Args &&...args)
+		{
+			Type* elem = Type::create(std::forward<Args>(args)...);
+			addElement(elem);
+			return elem;
+		}
 
 
 		/**
 		/**
-		 * @brief	Inserts a GUI element before the element at the specified index.
+		 * @brief	Creates a new element and inserts it before the element at the specified index.
 		 */
 		 */
-		void insertElement(UINT32 idx, GUIElement* element);
+		template<class Type, class... Args>
+		Type* insertNewElement(UINT32 idx, Args &&...args)
+		{
+			Type* elem = Type::create(std::forward<Args>(args)...);
+			insertElement(idx, elem);
+			return elem;
+		}
 
 
 		/**
 		/**
-		 * @brief	Adds a new horizontal layout as a child of this layout.
-		 */
-		GUILayout& addLayoutX() { return addLayoutXInternal(this); }
-
-		/**
-		 * @brief	Adds a new vertical layout as a child of this layout.
-		 */
-		GUILayout& addLayoutY() { return addLayoutYInternal(this); }
-
-		/**
-		 * @brief	Removes the specified child layout.
-		 */
-		void removeLayout(GUILayout& layout) { removeLayoutInternal(layout); }
-
-		/**
-		 * @brief	Inserts a horizontal layout before the element at the specified index.
-		 */
-		GUILayout& insertLayoutX(UINT32 idx) { return insertLayoutXInternal(this, idx); }
-
-		/**
-		 * @brief	Inserts a vertical layout before the element at the specified index.
-		 */
-		GUILayout& insertLayoutY(UINT32 idx) { return insertLayoutYInternal(this, idx); }
-
-		/**
-		 * @brief	Adds a fixed space as a child of this layout. Size of space is specified in pixels.
-		 */
-		GUIFixedSpace& addSpace(UINT32 size);
-
-		/**
-		 * @brief	Removes an existing space from the layout.
-		 */
-		void removeSpace(GUIFixedSpace& space);
-
-		/**
-		 * @brief	Inserts a fixed space of "size" pixels before the element at the specified index.
+		 * @brief	Adds a new element to the layout after all existing elements.
 		 */
 		 */
-		GUIFixedSpace& insertSpace(UINT32 idx, UINT32 size);
+		void addElement(GUIElementBase* element);
 
 
 		/**
 		/**
-		 * @brief	Adds a flexible space as a child of this layout. Flexible space will grow/shrink
-		 *			depending on elements around it, but it will always allow elements to keep their
-		 *			optimal size.
+		 * @brief	Removes the specified element from the layout.
 		 */
 		 */
-		GUIFlexibleSpace& addFlexibleSpace();
+		void removeElement(GUIElementBase* element);
 
 
 		/**
 		/**
-		 * @brief	Removes an existing flexible space from the layout.
+		 * @brief	Removes a child element at the specified index.
 		 */
 		 */
-		void removeFlexibleSpace(GUIFlexibleSpace& space);
+		void removeElementAt(UINT32 idx);
 
 
 		/**
 		/**
-		 * @brief	Inserts a flexible space before an element at the specified index. Flexible space 
-		 *			will grow/shrink depending on elements around it, but it will always allow elements 
-		 *			to keep their optimal size.
+		 * @brief	Inserts a GUI element before the element at the specified index.
 		 */
 		 */
-		GUIFlexibleSpace& insertFlexibleSpace(UINT32 idx);
+		void insertElement(UINT32 idx, GUIElementBase* element);
 
 
 		/**
 		/**
 		 * @brief	Returns number of child elements in the layout.
 		 * @brief	Returns number of child elements in the layout.
 		 */
 		 */
 		UINT32 getNumChildren() const { return (UINT32)mChildren.size(); }
 		UINT32 getNumChildren() const { return (UINT32)mChildren.size(); }
 
 
-		/**
-		 * @brief	Removes a child element at the specified index.
-		 */
-		void removeChildAt(UINT32 idx);
-
 		/**
 		/**
 		 * @brief	Returns a size range that was cached during the last "_updateOptimalLayoutSizes" call.
 		 * @brief	Returns a size range that was cached during the last "_updateOptimalLayoutSizes" call.
 		 */
 		 */
@@ -156,6 +119,11 @@ namespace BansheeEngine
 		 */
 		 */
 		virtual Vector2I _calcActualSize(Rect2I* elementAreas, UINT32 numElements) const = 0;
 		virtual Vector2I _calcActualSize(Rect2I* elementAreas, UINT32 numElements) const = 0;
 
 
+		/**
+		 * @brief	Destroy the layout. Removes it from parent and widget, and deletes it.
+		 */	
+		static void destroy(GUILayout* layout);
+
 	protected:
 	protected:
 		GUIArea* mParentGUIArea;
 		GUIArea* mParentGUIArea;
 
 

+ 6 - 0
BansheeEngine/Include/BsGUILayoutExplicit.h

@@ -36,6 +36,12 @@ namespace BansheeEngine
 		 * @copydoc	GUILayout::_calcActualSize
 		 * @copydoc	GUILayout::_calcActualSize
 		 */
 		 */
 		virtual Vector2I _calcActualSize(Rect2I* elementAreas, UINT32 numElements) const;
 		virtual Vector2I _calcActualSize(Rect2I* elementAreas, UINT32 numElements) const;
+
+		/**
+		 * @brief	Creates a new GUI panel.
+		 */
+		static GUILayoutExplicit* create();
+
 	protected:
 	protected:
 		/**
 		/**
 		 * @brief	Positions/size all child layout elements based on the provided settings and their (previously calculated) optimal sizes.
 		 * @brief	Positions/size all child layout elements based on the provided settings and their (previously calculated) optimal sizes.

+ 6 - 0
BansheeEngine/Include/BsGUILayoutX.h

@@ -36,6 +36,12 @@ namespace BansheeEngine
 		 * @copydoc	GUILayout::_calcActualSize
 		 * @copydoc	GUILayout::_calcActualSize
 		 */
 		 */
 		virtual Vector2I _calcActualSize(Rect2I* elementAreas, UINT32 numElements) const;
 		virtual Vector2I _calcActualSize(Rect2I* elementAreas, UINT32 numElements) const;
+
+		/**
+		 * @brief	Creates a new horizontal layout.
+		 */
+		static GUILayoutX* create();
+
 	protected:
 	protected:
 		/**
 		/**
 		 * @brief	Positions/size all child layout elements based on the provided settings and their (previously calculated) optimal sizes.
 		 * @brief	Positions/size all child layout elements based on the provided settings and their (previously calculated) optimal sizes.

+ 6 - 0
BansheeEngine/Include/BsGUILayoutY.h

@@ -36,6 +36,12 @@ namespace BansheeEngine
 		 * @copydoc	GUILayout::_calcActualSize
 		 * @copydoc	GUILayout::_calcActualSize
 		 */
 		 */
 		virtual Vector2I _calcActualSize(Rect2I* elementAreas, UINT32 numElements) const;
 		virtual Vector2I _calcActualSize(Rect2I* elementAreas, UINT32 numElements) const;
+
+		/**
+		 * @brief	Creates a new vertical layout.
+		 */
+		static GUILayoutY* create();
+
 	protected:
 	protected:
 		/**
 		/**
 		 * @brief	Positions/size all child layout elements based on the provided settings and their (previously calculated) optimal sizes.
 		 * @brief	Positions/size all child layout elements based on the provided settings and their (previously calculated) optimal sizes.

+ 20 - 0
BansheeEngine/Include/BsGUISpace.h

@@ -63,6 +63,16 @@ namespace BansheeEngine
 			return padding;
 			return padding;
 		}
 		}
 
 
+		/**
+		 * @brief	Creates a new fixed space GUI element.
+		 */
+		static GUIFixedSpace* create(UINT32 size);
+
+		/**
+		 * @brief	Destroys the space and removes it from its parent.
+		 */
+		static void destroy(GUIFixedSpace* space);
+
 	protected:
 	protected:
 		UINT32 mSize;
 		UINT32 mSize;
 	};
 	};
@@ -119,5 +129,15 @@ namespace BansheeEngine
 
 
 			return padding;
 			return padding;
 		}
 		}
+
+		/**
+		 * @brief	Creates a new flexible space GUI element.
+		 */
+		static GUIFlexibleSpace* create();
+
+		/**
+		 * @brief	Destroys the space and removes it from its parent.
+		 */
+		static void destroy(GUIFlexibleSpace* space);
 	};
 	};
 }
 }

+ 2 - 0
BansheeEngine/Include/BsProfilerOverlay.h

@@ -30,6 +30,7 @@ namespace BansheeEngine
 		{
 		{
 			GUILayout* labelLayout;
 			GUILayout* labelLayout;
 			GUILayout* contentLayout;
 			GUILayout* contentLayout;
+			GUIFixedSpace* labelSpace;
 
 
 			Vector<GUIElement*> elements;
 			Vector<GUIElement*> elements;
 
 
@@ -51,6 +52,7 @@ namespace BansheeEngine
 		{
 		{
 			GUILayout* labelLayout;
 			GUILayout* labelLayout;
 			GUILayout* contentLayout;
 			GUILayout* contentLayout;
+			GUIFixedSpace* labelSpace;
 
 
 			Vector<GUIElement*> elements;
 			Vector<GUIElement*> elements;
 
 

+ 3 - 3
BansheeEngine/Source/BsGUIDropDownBox.cpp

@@ -1,6 +1,6 @@
 #include "BsGUIDropDownBox.h"
 #include "BsGUIDropDownBox.h"
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
-#include "BsGUILayout.h"
+#include "BsGUILayoutY.h"
 #include "BsGUILayoutX.h"
 #include "BsGUILayoutX.h"
 #include "BsGUITexture.h"
 #include "BsGUITexture.h"
 #include "BsGUILabel.h"
 #include "BsGUILabel.h"
@@ -217,7 +217,7 @@ namespace BansheeEngine
 		// Content area
 		// Content area
 		mContentArea = GUIArea::create(*mOwner, 0, 0, width, height);
 		mContentArea = GUIArea::create(*mOwner, 0, 0, width, height);
 		mContentArea->setDepth(100 - depthOffset * 2 - 1);
 		mContentArea->setDepth(100 - depthOffset * 2 - 1);
-		mContentLayout = &mContentArea->getLayout().addLayoutY();
+		mContentLayout = mContentArea->getLayout().addNewElement<GUILayoutY>();
 
 
 		// Background frame
 		// Background frame
 		mBackgroundArea = GUIArea::create(*mOwner, 0, 0, width, height);
 		mBackgroundArea = GUIArea::create(*mOwner, 0, 0, width, height);
@@ -379,7 +379,7 @@ namespace BansheeEngine
 	{
 	{
 		// Remove all elements from content layout
 		// Remove all elements from content layout
 		while(mContentLayout->getNumChildren() > 0)
 		while(mContentLayout->getNumChildren() > 0)
-			mContentLayout->removeChildAt(mContentLayout->getNumChildren() - 1);
+			mContentLayout->removeElementAt(mContentLayout->getNumChildren() - 1);
 
 
 		mContentLayout->addElement(mContent); // Note: Needs to be added first so that size calculations have proper skin to work with
 		mContentLayout->addElement(mContent); // Note: Needs to be added first so that size calculations have proper skin to work with
 
 

+ 18 - 99
BansheeEngine/Source/BsGUIElementBase.cpp

@@ -3,6 +3,7 @@
 #include "BsGUILayoutX.h"
 #include "BsGUILayoutX.h"
 #include "BsGUILayoutY.h"
 #include "BsGUILayoutY.h"
 #include "BsGUILayoutExplicit.h"
 #include "BsGUILayoutExplicit.h"
+#include "BsGUISpace.h"
 #include "BsGUIElement.h"
 #include "BsGUIElement.h"
 #include "BsException.h"
 #include "BsException.h"
 #include "BsGUIWidget.h"
 #include "BsGUIWidget.h"
@@ -22,19 +23,25 @@ namespace BansheeEngine
 		Vector<GUIElementBase*> childCopy = mChildren;
 		Vector<GUIElementBase*> childCopy = mChildren;
 		for (auto& child : childCopy)
 		for (auto& child : childCopy)
 		{
 		{
-			if (child->_getType() == GUIElementBase::Type::Element)
+			if (child->_getType() == Type::Element)
 			{
 			{
 				GUIElement* element = static_cast<GUIElement*>(child);
 				GUIElement* element = static_cast<GUIElement*>(child);
 				GUIElement::destroy(element);
 				GUIElement::destroy(element);
 			}
 			}
-			else
+			else if (child->_getType() == Type::Layout)
 			{
 			{
-				auto iterFind = std::find(mChildren.begin(), mChildren.end(), child);
-
-				if (iterFind != mChildren.end())
-					mChildren.erase(iterFind);
-
-				bs_delete(child);
+				GUILayout* layout = static_cast<GUILayout*>(child);
+				GUILayout::destroy(layout);
+			}
+			else if (child->_getType() == Type::FixedSpace)
+			{
+				GUIFixedSpace* space = static_cast<GUIFixedSpace*>(child);
+				GUIFixedSpace::destroy(space);
+			}
+			else if (child->_getType() == Type::FlexibleSpace)
+			{
+				GUIFlexibleSpace* space = static_cast<GUIFlexibleSpace*>(child);
+				GUIFlexibleSpace::destroy(space);
 			}
 			}
 		}
 		}
 	}
 	}
@@ -175,95 +182,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	GUILayout& GUIElementBase::addLayoutXInternal(GUIElementBase* parent)
-	{
-		GUILayoutX* entry = bs_new<GUILayoutX, PoolAlloc>();
-		entry->_setParent(parent);
-
-		mChildren.push_back(entry);
-		
-		if (mIsDisabled)
-			entry->disableRecursively();
-
-		markContentAsDirty();
-
-		return *entry;
-	}
-
-	GUILayout& GUIElementBase::addLayoutYInternal(GUIElementBase* parent)
-	{
-		GUILayoutY* entry = bs_new<GUILayoutY, PoolAlloc>();
-		entry->_setParent(parent);
-
-		mChildren.push_back(entry);
-
-		if (mIsDisabled)
-			entry->disableRecursively();
-
-		markContentAsDirty();
-
-		return *entry;
-	}
-
-	void GUIElementBase::removeLayoutInternal(GUILayout& layout)
-	{
-		bool foundElem = false;
-		for(auto iter = mChildren.begin(); iter != mChildren.end(); ++iter)
-		{
-			GUIElementBase* child = *iter;
-
-			if(child->_getType() == GUIElementBase::Type::Layout && child == &layout)
-			{
-				bs_delete<PoolAlloc>(child);
-
-				mChildren.erase(iter);
-				foundElem = true;
-				markContentAsDirty();
-				break;
-			}
-		}
-
-		if(!foundElem)
-			BS_EXCEPT(InvalidParametersException, "Provided element is not a part of this layout.");
-	}
-
-	GUILayout& GUIElementBase::insertLayoutXInternal(GUIElementBase* parent, UINT32 idx)
-	{
-		if(idx < 0 || idx > (UINT32)mChildren.size())
-			BS_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx) + ". Valid range: 0 .. " + toString((UINT32)mChildren.size()));
-
-		GUILayoutX* entry = bs_new<GUILayoutX, PoolAlloc>();
-		entry->_setParent(parent);
-
-		mChildren.insert(mChildren.begin() + idx, entry);
-
-		if (mIsDisabled)
-			entry->disableRecursively();
-
-		markContentAsDirty();
-
-		return *entry;
-	}
-
-	GUILayout& GUIElementBase::insertLayoutYInternal(GUIElementBase* parent, UINT32 idx)
-	{
-		if(idx < 0 || idx > (UINT32)mChildren.size())
-			BS_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx) + ". Valid range: 0 .. " + toString((UINT32)mChildren.size()));
-
-		GUILayoutY* entry = bs_new<GUILayoutY, PoolAlloc>();
-		entry->_setParent(parent);
-
-		mChildren.insert(mChildren.begin() + idx, entry);
-
-		if (mIsDisabled)
-			entry->disableRecursively();
-
-		markContentAsDirty();
-
-		return *entry;
-	}
-
-	void GUIElementBase::_registerChildElement(GUIElement* element)
+	void GUIElementBase::_registerChildElement(GUIElementBase* element)
 	{
 	{
 		GUIElementBase* parentElement = element->_getParent();
 		GUIElementBase* parentElement = element->_getParent();
 		if(parentElement != nullptr)
 		if(parentElement != nullptr)
@@ -280,14 +199,14 @@ namespace BansheeEngine
 		markContentAsDirty();
 		markContentAsDirty();
 	}
 	}
 
 
-	void GUIElementBase::_unregisterChildElement(GUIElement* element)
+	void GUIElementBase::_unregisterChildElement(GUIElementBase* element)
 	{
 	{
 		bool foundElem = false;
 		bool foundElem = false;
 		for(auto iter = mChildren.begin(); iter != mChildren.end(); ++iter)
 		for(auto iter = mChildren.begin(); iter != mChildren.end(); ++iter)
 		{
 		{
 			GUIElementBase* child = *iter;
 			GUIElementBase* child = *iter;
 
 
-			if(child->_getType() == GUIElementBase::Type::Element && child == element)
+			if (child == element)
 			{
 			{
 				mChildren.erase(iter);
 				mChildren.erase(iter);
 				element->_setParent(nullptr);
 				element->_setParent(nullptr);

+ 10 - 98
BansheeEngine/Source/BsGUILayout.cpp

@@ -24,17 +24,17 @@ namespace BansheeEngine
 
 
 	}
 	}
 
 
-	void GUILayout::addElement(GUIElement* element)
+	void GUILayout::addElement(GUIElementBase* element)
 	{
 	{
 		_registerChildElement(element);
 		_registerChildElement(element);
 	}
 	}
 
 
-	void GUILayout::removeElement(GUIElement* element)
+	void GUILayout::removeElement(GUIElementBase* element)
 	{
 	{
 		_unregisterChildElement(element);
 		_unregisterChildElement(element);
 	}
 	}
 
 
-	void GUILayout::insertElement(UINT32 idx, GUIElement* element)
+	void GUILayout::insertElement(UINT32 idx, GUIElementBase* element)
 	{
 	{
 		if(idx < 0 || idx > (UINT32)mChildren.size())
 		if(idx < 0 || idx > (UINT32)mChildren.size())
 			BS_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx) + ". Valid range: 0 .. " + toString((UINT32)mChildren.size()));
 			BS_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx) + ". Valid range: 0 .. " + toString((UINT32)mChildren.size()));
@@ -54,7 +54,7 @@ namespace BansheeEngine
 		markContentAsDirty();
 		markContentAsDirty();
 	}
 	}
 
 
-	void GUILayout::removeChildAt(UINT32 idx)
+	void GUILayout::removeElementAt(UINT32 idx)
 	{
 	{
 		if(idx < 0 || idx >= (UINT32)mChildren.size())
 		if(idx < 0 || idx >= (UINT32)mChildren.size())
 			BS_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx) + ". Valid range: 0 .. " + toString((UINT32)mChildren.size()));
 			BS_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx) + ". Valid range: 0 .. " + toString((UINT32)mChildren.size()));
@@ -62,108 +62,20 @@ namespace BansheeEngine
 		GUIElementBase* child = mChildren[idx];
 		GUIElementBase* child = mChildren[idx];
 		mChildren.erase(mChildren.begin() + idx);
 		mChildren.erase(mChildren.begin() + idx);
 
 
-		if(child->_getType() == GUIElementBase::Type::Element)
-			child->_setParent(nullptr);
-		else
-			bs_delete<PoolAlloc>(child);
+		child->_setParent(nullptr);
 
 
 		markContentAsDirty();
 		markContentAsDirty();
 	}
 	}
 
 
-	GUIFixedSpace& GUILayout::addSpace(UINT32 size)
-	{
-		GUIFixedSpace* entry = bs_new<GUIFixedSpace, PoolAlloc>(size);
-
-		mChildren.push_back(entry);
-		markContentAsDirty();
-
-		return *entry;
-	}
-
-	void GUILayout::removeSpace(GUIFixedSpace& space)
-	{
-		bool foundElem = false;
-		for(auto iter = mChildren.begin(); iter != mChildren.end(); ++iter)
-		{
-			GUIElementBase* child = *iter;
-
-			if(child->_getType() == GUIElementBase::Type::FixedSpace && child == &space)
-			{
-				bs_delete<PoolAlloc>(child);
-
-				mChildren.erase(iter);
-				foundElem = true;
-				markContentAsDirty();
-				break;
-			}
-		}
-
-		if(!foundElem)
-			BS_EXCEPT(InvalidParametersException, "Provided element is not a part of this layout.");
-	}
-
-	GUIFixedSpace& GUILayout::insertSpace(UINT32 idx, UINT32 size)
-	{
-		if(idx < 0 || idx > (UINT32)mChildren.size())
-			BS_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx) + ". Valid range: 0 .. " + toString((UINT32)mChildren.size()));
-
-		GUIFixedSpace* entry = bs_new<GUIFixedSpace, PoolAlloc>(size);
-
-		mChildren.insert(mChildren.begin() + idx, entry);
-		markContentAsDirty();
-
-		return *entry;
-	}
-
-	GUIFlexibleSpace& GUILayout::addFlexibleSpace()
-	{
-		GUIFlexibleSpace* entry = bs_new<GUIFlexibleSpace, PoolAlloc>();
-
-		mChildren.push_back(entry);
-		markContentAsDirty();
-
-		return *entry;
-	}
-
-	void GUILayout::removeFlexibleSpace(GUIFlexibleSpace& space)
-	{
-		bool foundElem = false;
-		for(auto iter = mChildren.begin(); iter != mChildren.end(); ++iter)
-		{
-			GUIElementBase* child = *iter;
-
-			if(child->_getType() == GUIElementBase::Type::FlexibleSpace && child == &space)
-			{
-				bs_delete<PoolAlloc>(child);
-
-				mChildren.erase(iter);
-				foundElem = true;
-				markContentAsDirty();
-				break;
-			}
-		}
-
-		if(!foundElem)
-			BS_EXCEPT(InvalidParametersException, "Provided element is not a part of this layout.");
-	}
-
-	GUIFlexibleSpace& GUILayout::insertFlexibleSpace(UINT32 idx)
-	{
-		if(idx < 0 || idx > (UINT32)mChildren.size())
-			BS_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx) + ". Valid range: 0 .. " + toString((UINT32)mChildren.size()));
-
-		GUIFlexibleSpace* entry = bs_new<GUIFlexibleSpace, PoolAlloc>();
-
-		mChildren.insert(mChildren.begin() + idx, entry);
-		markContentAsDirty();
-
-		return *entry;
-	}
-
 	const RectOffset& GUILayout::_getPadding() const
 	const RectOffset& GUILayout::_getPadding() const
 	{
 	{
 		static RectOffset padding;
 		static RectOffset padding;
 
 
 		return padding;
 		return padding;
 	}
 	}
+
+	void GUILayout::destroy(GUILayout* layout)
+	{
+		bs_delete(layout);
+	}
 }
 }

+ 5 - 0
BansheeEngine/Source/BsGUILayoutExplicit.cpp

@@ -92,4 +92,9 @@ namespace BansheeEngine
 	{
 	{
 		return Vector2I(0, 0); // Not relevant
 		return Vector2I(0, 0); // Not relevant
 	}
 	}
+
+	GUILayoutExplicit* GUILayoutExplicit::create()
+	{
+		return bs_new<GUILayoutExplicit>();
+	}
 }
 }

+ 5 - 0
BansheeEngine/Source/BsGUILayoutX.cpp

@@ -466,4 +466,9 @@ namespace BansheeEngine
 
 
 		return actualArea;
 		return actualArea;
 	}
 	}
+
+	GUILayoutX* GUILayoutX::create()
+	{
+		return bs_new<GUILayoutX>();
+	}
 }
 }

+ 5 - 0
BansheeEngine/Source/BsGUILayoutY.cpp

@@ -462,4 +462,9 @@ namespace BansheeEngine
 
 
 		return actualArea;
 		return actualArea;
 	}
 	}
+
+	GUILayoutY* GUILayoutY::create()
+	{
+		return bs_new<GUILayoutY>();
+	}
 }
 }

+ 3 - 2
BansheeEngine/Source/BsGUIScrollArea.cpp

@@ -3,7 +3,7 @@
 #include "BsGUISkin.h"
 #include "BsGUISkin.h"
 #include "BsGUIWidget.h"
 #include "BsGUIWidget.h"
 #include "BsGUILayoutOptions.h"
 #include "BsGUILayoutOptions.h"
-#include "BsGUILayout.h"
+#include "BsGUILayoutY.h"
 #include "BsGUISkin.h"
 #include "BsGUISkin.h"
 #include "BsGUIScrollBarVert.h"
 #include "BsGUIScrollBarVert.h"
 #include "BsGUIScrollBarHorz.h"
 #include "BsGUIScrollBarHorz.h"
@@ -24,7 +24,8 @@ namespace BansheeEngine
 		:GUIElementContainer(layoutOptions), mVertScroll(nullptr), mHorzScroll(nullptr), mVertOffset(0), mHorzOffset(0),
 		:GUIElementContainer(layoutOptions), mVertScroll(nullptr), mHorzScroll(nullptr), mVertOffset(0), mHorzOffset(0),
 		mVertBarType(vertBarType), mHorzBarType(horzBarType), mScrollBarStyle(scrollBarStyle)
 		mVertBarType(vertBarType), mHorzBarType(horzBarType), mScrollBarStyle(scrollBarStyle)
 	{
 	{
-		mContentLayout = &addLayoutYInternal(this);
+		mContentLayout = GUILayoutY::create();
+		_registerChildElement(mContentLayout);
 
 
 		mHorzScroll = GUIScrollBarHorz::create(mScrollBarStyle);
 		mHorzScroll = GUIScrollBarHorz::create(mScrollBarStyle);
 		mVertScroll = GUIScrollBarVert::create(mScrollBarStyle);
 		mVertScroll = GUIScrollBarVert::create(mScrollBarStyle);

+ 10 - 7
BansheeEngine/Source/BsGUIScrollBar.cpp

@@ -4,7 +4,8 @@
 #include "BsGUISkin.h"
 #include "BsGUISkin.h"
 #include "BsGUIWidget.h"
 #include "BsGUIWidget.h"
 #include "BsGUILayoutOptions.h"
 #include "BsGUILayoutOptions.h"
-#include "BsGUILayout.h"
+#include "BsGUILayoutX.h"
+#include "BsGUILayoutY.h"
 #include "BsGUISkin.h"
 #include "BsGUISkin.h"
 #include "BsGUIButton.h"
 #include "BsGUIButton.h"
 #include "BsGUISliderHandle.h"
 #include "BsGUISliderHandle.h"
@@ -24,7 +25,8 @@ namespace BansheeEngine
 
 
 		if(mHorizontal)
 		if(mHorizontal)
 		{
 		{
-			mLayout = &addLayoutXInternal(this);
+			mLayout = GUILayoutX::create();
+			_registerChildElement(mLayout);
 
 
 			mUpBtn = GUIButton::create(HString(L""), "ScrollLeftBtn");
 			mUpBtn = GUIButton::create(HString(L""), "ScrollLeftBtn");
 			mDownBtn = GUIButton::create(HString(L""), "ScrollRightBtn");
 			mDownBtn = GUIButton::create(HString(L""), "ScrollRightBtn");
@@ -34,7 +36,8 @@ namespace BansheeEngine
 		}
 		}
 		else
 		else
 		{
 		{
-			mLayout = &addLayoutYInternal(this);
+			mLayout = GUILayoutY::create();
+			_registerChildElement(mLayout);
 
 
 			mUpBtn = GUIButton::create(HString(L""), "ScrollUpBtn");
 			mUpBtn = GUIButton::create(HString(L""), "ScrollUpBtn");
 			mDownBtn = GUIButton::create(HString(L""), "ScrollDownBtn");
 			mDownBtn = GUIButton::create(HString(L""), "ScrollDownBtn");
@@ -43,13 +46,13 @@ namespace BansheeEngine
 				GUIOptions(GUIOption::fixedWidth(6), GUIOption::flexibleHeight()), "ScrollBarVertBtn");
 				GUIOptions(GUIOption::fixedWidth(6), GUIOption::flexibleHeight()), "ScrollBarVertBtn");
 		}
 		}
 
 
-		mLayout->addSpace(2);
+		mLayout->addNewElement<GUIFixedSpace>(2);
 		mLayout->addElement(mUpBtn);
 		mLayout->addElement(mUpBtn);
-		mLayout->addSpace(2);
+		mLayout->addNewElement<GUIFixedSpace>(2);
 		mLayout->addElement(mHandleBtn);
 		mLayout->addElement(mHandleBtn);
-		mLayout->addSpace(2);
+		mLayout->addNewElement<GUIFixedSpace>(2);
 		mLayout->addElement(mDownBtn);
 		mLayout->addElement(mDownBtn);
-		mLayout->addSpace(2);
+		mLayout->addNewElement<GUIFixedSpace>(2);
 
 
 		mHandleBtn->onHandleMoved.connect(std::bind(&GUIScrollBar::handleMoved, this, _1));
 		mHandleBtn->onHandleMoved.connect(std::bind(&GUIScrollBar::handleMoved, this, _1));
 
 

+ 20 - 0
BansheeEngine/Source/BsGUISpace.cpp

@@ -12,6 +12,16 @@ namespace BansheeEngine
 		return range;
 		return range;
 	}
 	}
 
 
+	GUIFixedSpace* GUIFixedSpace::create(UINT32 size)
+	{
+		return bs_new<GUIFixedSpace>(size);
+	}
+
+	void GUIFixedSpace::destroy(GUIFixedSpace* space)
+	{
+		bs_delete(space);
+	}
+
 	LayoutSizeRange GUIFlexibleSpace::_calculateLayoutSizeRange() const
 	LayoutSizeRange GUIFlexibleSpace::_calculateLayoutSizeRange() const
 	{
 	{
 		LayoutSizeRange range;
 		LayoutSizeRange range;
@@ -21,4 +31,14 @@ namespace BansheeEngine
 
 
 		return range;
 		return range;
 	}
 	}
+
+	GUIFlexibleSpace* GUIFlexibleSpace::create()
+	{
+		return bs_new<GUIFlexibleSpace>();
+	}
+
+	void GUIFlexibleSpace::destroy(GUIFlexibleSpace* space)
+	{
+		bs_delete(space);
+	}
 }
 }

+ 64 - 71
BansheeEngine/Source/BsProfilerOverlay.cpp

@@ -3,6 +3,8 @@
 #include "BsGUIWidget.h"
 #include "BsGUIWidget.h"
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
 #include "BsGUILayout.h"
 #include "BsGUILayout.h"
+#include "BsGUILayoutX.h"
+#include "BsGUILayoutY.h"
 #include "BsGUIElement.h"
 #include "BsGUIElement.h"
 #include "BsGUILabel.h"
 #include "BsGUILabel.h"
 #include "BsGUISpace.h"
 #include "BsGUISpace.h"
@@ -32,13 +34,10 @@ namespace BansheeEngine
 			UINT32 excessEntries = (UINT32)rows.size() - curIdx;
 			UINT32 excessEntries = (UINT32)rows.size() - curIdx;
 			for(UINT32 i = 0; i < excessEntries; i++)
 			for(UINT32 i = 0; i < excessEntries; i++)
 			{
 			{
-				labelLayout.removeChildAt(labelLayout.getNumChildren() - 2); // -2 because last element is flexible space and we want to skip it
-				contentLayout.removeChildAt(contentLayout.getNumChildren() - 2); // -2 because last element is flexible space and we want to skip it
-
 				ProfilerOverlay::BasicRow& row = rows[curIdx + i];
 				ProfilerOverlay::BasicRow& row = rows[curIdx + i];
 
 
-				for(auto& element : row.elements)
-					GUIElement::destroy(element);
+				GUILayout::destroy(row.labelLayout);
+				GUILayout::destroy(row.contentLayout);
 			}
 			}
 
 
 			rows.resize(curIdx);
 			rows.resize(curIdx);
@@ -63,8 +62,8 @@ namespace BansheeEngine
 				newRow.avgTimeSelf = HString(L"{0}");
 				newRow.avgTimeSelf = HString(L"{0}");
 				newRow.totalTimeSelf = HString(L"{0}");
 				newRow.totalTimeSelf = HString(L"{0}");
 
 
-				newRow.labelLayout = &labelLayout.insertLayoutX(labelLayout.getNumChildren() - 1); // Insert before flexible space
-				newRow.contentLayout = &contentLayout.insertLayoutX(contentLayout.getNumChildren() - 1); // Insert before flexible space
+				newRow.labelLayout = labelLayout.insertNewElement<GUILayoutX>(labelLayout.getNumChildren() - 1); // Insert before flexible space
+				newRow.contentLayout = contentLayout.insertNewElement<GUILayoutX>(contentLayout.getNumChildren() - 1); // Insert before flexible space
 
 
 				GUILabel* name = GUILabel::create(newRow.name, GUIOptions(GUIOption::fixedWidth(200)));
 				GUILabel* name = GUILabel::create(newRow.name, GUIOptions(GUIOption::fixedWidth(200)));
 				GUILabel* pctOfParent = GUILabel::create(newRow.pctOfParent, GUIOptions(GUIOption::fixedWidth(50)));
 				GUILabel* pctOfParent = GUILabel::create(newRow.pctOfParent, GUIOptions(GUIOption::fixedWidth(50)));
@@ -76,7 +75,7 @@ namespace BansheeEngine
 				GUILabel* avgTimeSelf = GUILabel::create(newRow.avgTimeSelf, GUIOptions(GUIOption::fixedWidth(100)));
 				GUILabel* avgTimeSelf = GUILabel::create(newRow.avgTimeSelf, GUIOptions(GUIOption::fixedWidth(100)));
 				GUILabel* totalTimeSelf = GUILabel::create(newRow.totalTimeSelf, GUIOptions(GUIOption::fixedWidth(100)));
 				GUILabel* totalTimeSelf = GUILabel::create(newRow.totalTimeSelf, GUIOptions(GUIOption::fixedWidth(100)));
 
 
-				newRow.labelLayout->addSpace(0);
+				newRow.labelSpace = newRow.labelLayout->addNewElement<GUIFixedSpace>(0);
 				newRow.labelLayout->addElement(name);
 				newRow.labelLayout->addElement(name);
 
 
 				newRow.contentLayout->addElement(pctOfParent);
 				newRow.contentLayout->addElement(pctOfParent);
@@ -101,8 +100,8 @@ namespace BansheeEngine
 			
 			
 			ProfilerOverlay::BasicRow& row = rows[curIdx];
 			ProfilerOverlay::BasicRow& row = rows[curIdx];
 
 
-			row.labelLayout->removeChildAt(0);
-			row.labelLayout->insertSpace(0, depth * 20);
+			GUIFixedSpace::destroy(row.labelSpace);
+			row.labelSpace = row.labelLayout->insertNewElement<GUIFixedSpace>(0, depth * 20);
 
 
 			row.name.setParameter(0, toWString(name));
 			row.name.setParameter(0, toWString(name));
 			row.pctOfParent.setParameter(0, toWString(pctOfParent * 100.0f, 2, 0, ' ', std::ios::fixed));
 			row.pctOfParent.setParameter(0, toWString(pctOfParent * 100.0f, 2, 0, ' ', std::ios::fixed));
@@ -136,13 +135,10 @@ namespace BansheeEngine
 			UINT32 excessEntries = (UINT32)rows.size() - curIdx;
 			UINT32 excessEntries = (UINT32)rows.size() - curIdx;
 			for(UINT32 i = 0; i < excessEntries; i++)
 			for(UINT32 i = 0; i < excessEntries; i++)
 			{
 			{
-				labelLayout.removeChildAt(labelLayout.getNumChildren() - i - 1); // -1 because last element is flexible space and we want to skip it
-				contentLayout.removeChildAt(contentLayout.getNumChildren() - i - 1); // -1 because last element is flexible space and we want to skip it
-
 				ProfilerOverlay::PreciseRow& row = rows[curIdx + i];
 				ProfilerOverlay::PreciseRow& row = rows[curIdx + i];
 
 
-				for(auto& element : row.elements)
-					GUIElement::destroy(element);
+				GUILayout::destroy(row.labelLayout);
+				GUILayout::destroy(row.contentLayout);
 			}
 			}
 
 
 			rows.resize(curIdx);
 			rows.resize(curIdx);
@@ -167,8 +163,8 @@ namespace BansheeEngine
 				newRow.avgCyclesSelf = HString(L"{0}");
 				newRow.avgCyclesSelf = HString(L"{0}");
 				newRow.totalCyclesSelf = HString(L"{0}");
 				newRow.totalCyclesSelf = HString(L"{0}");
 
 
-				newRow.labelLayout = &labelLayout.insertLayoutX(labelLayout.getNumChildren() - 1); // Insert before flexible space
-				newRow.contentLayout = &contentLayout.insertLayoutX(contentLayout.getNumChildren() - 1); // Insert before flexible space
+				newRow.labelLayout = labelLayout.insertNewElement<GUILayoutX>(labelLayout.getNumChildren() - 1); // Insert before flexible space
+				newRow.contentLayout = contentLayout.insertNewElement<GUILayoutX>(contentLayout.getNumChildren() - 1); // Insert before flexible space
 
 
 				GUILabel* name = GUILabel::create(newRow.name, GUIOptions(GUIOption::fixedWidth(200)));
 				GUILabel* name = GUILabel::create(newRow.name, GUIOptions(GUIOption::fixedWidth(200)));
 				GUILabel* pctOfParent = GUILabel::create(newRow.pctOfParent, GUIOptions(GUIOption::fixedWidth(50)));
 				GUILabel* pctOfParent = GUILabel::create(newRow.pctOfParent, GUIOptions(GUIOption::fixedWidth(50)));
@@ -180,7 +176,7 @@ namespace BansheeEngine
 				GUILabel* avgCyclesSelf = GUILabel::create(newRow.avgCyclesSelf, GUIOptions(GUIOption::fixedWidth(100)));
 				GUILabel* avgCyclesSelf = GUILabel::create(newRow.avgCyclesSelf, GUIOptions(GUIOption::fixedWidth(100)));
 				GUILabel* totalCyclesSelf = GUILabel::create(newRow.totalCyclesSelf, GUIOptions(GUIOption::fixedWidth(100)));
 				GUILabel* totalCyclesSelf = GUILabel::create(newRow.totalCyclesSelf, GUIOptions(GUIOption::fixedWidth(100)));
 
 
-				newRow.labelLayout->addSpace(0);
+				newRow.labelSpace = newRow.labelLayout->addNewElement<GUIFixedSpace>(0);
 				newRow.labelLayout->addElement(name);
 				newRow.labelLayout->addElement(name);
 
 
 				newRow.contentLayout->addElement(pctOfParent);
 				newRow.contentLayout->addElement(pctOfParent);
@@ -205,8 +201,8 @@ namespace BansheeEngine
 
 
 			ProfilerOverlay::PreciseRow& row = rows[curIdx];
 			ProfilerOverlay::PreciseRow& row = rows[curIdx];
 
 
-			row.labelLayout->removeChildAt(0);
-			row.labelLayout->insertSpace(0, depth * 20);
+			GUIFixedSpace::destroy(row.labelSpace);
+			row.labelSpace = row.labelLayout->insertNewElement<GUIFixedSpace>(0, depth * 20);
 
 
 			row.name.setParameter(0, toWString(name));
 			row.name.setParameter(0, toWString(name));
 			row.pctOfParent.setParameter(0, toWString(pctOfParent * 100.0f, 2, 0, ' ', std::ios::fixed));
 			row.pctOfParent.setParameter(0, toWString(pctOfParent * 100.0f, 2, 0, ' ', std::ios::fixed));
@@ -239,12 +235,9 @@ namespace BansheeEngine
 			UINT32 excessEntries = (UINT32)rows.size() - curIdx;
 			UINT32 excessEntries = (UINT32)rows.size() - curIdx;
 			for (UINT32 i = 0; i < excessEntries; i++)
 			for (UINT32 i = 0; i < excessEntries; i++)
 			{
 			{
-				layout.removeChildAt(layout.getNumChildren() - i); 
-
 				ProfilerOverlay::GPUSampleRow& row = rows[curIdx + i];
 				ProfilerOverlay::GPUSampleRow& row = rows[curIdx + i];
 
 
-				for (auto& element : row.elements)
-					GUIElement::destroy(element);
+				GUILayout::destroy(row.layout);
 			}
 			}
 
 
 			rows.resize(curIdx);
 			rows.resize(curIdx);
@@ -261,7 +254,7 @@ namespace BansheeEngine
 				newRow.name = HString(L"{1}");
 				newRow.name = HString(L"{1}");
 				newRow.time = HString(L"{0}");
 				newRow.time = HString(L"{0}");
 
 
-				newRow.layout = &layout.insertLayoutX(layout.getNumChildren());
+				newRow.layout = layout.insertNewElement<GUILayoutX>(layout.getNumChildren());
 
 
 				GUILabel* nameLabel = GUILabel::create(newRow.name, GUIOptions(GUIOption::fixedWidth(100)));
 				GUILabel* nameLabel = GUILabel::create(newRow.name, GUIOptions(GUIOption::fixedWidth(100)));
 				GUILabel* timeLabel = GUILabel::create(newRow.time, GUIOptions(GUIOption::fixedWidth(100)));
 				GUILabel* timeLabel = GUILabel::create(newRow.time, GUIOptions(GUIOption::fixedWidth(100)));
@@ -321,10 +314,10 @@ namespace BansheeEngine
 		mCPUBasicAreaContents = GUIArea::create(*mWidget, 0, 0);
 		mCPUBasicAreaContents = GUIArea::create(*mWidget, 0, 0);
 		mCPUPreciseAreaContents = GUIArea::create(*mWidget, 0, 0);
 		mCPUPreciseAreaContents = GUIArea::create(*mWidget, 0, 0);
 
 
-		mBasicLayoutLabels = &mCPUBasicAreaLabels->getLayout().addLayoutY();
-		mPreciseLayoutLabels = &mCPUPreciseAreaLabels->getLayout().addLayoutY();
-		mBasicLayoutContents = &mCPUBasicAreaContents->getLayout().addLayoutY();
-		mPreciseLayoutContents = &mCPUPreciseAreaContents->getLayout().addLayoutY();
+		mBasicLayoutLabels = mCPUBasicAreaLabels->getLayout().addNewElement<GUILayoutY>();
+		mPreciseLayoutLabels = mCPUPreciseAreaLabels->getLayout().addNewElement<GUILayoutY>();
+		mBasicLayoutContents = mCPUBasicAreaContents->getLayout().addNewElement<GUILayoutY>();
+		mPreciseLayoutContents = mCPUPreciseAreaContents->getLayout().addNewElement<GUILayoutY>();
 
 
 		// Set up CPU sample title bars
 		// Set up CPU sample title bars
 		mTitleBasicName = GUILabel::create(HString(L"Name"), GUIOptions(GUIOption::fixedWidth(200)));
 		mTitleBasicName = GUILabel::create(HString(L"Name"), GUIOptions(GUIOption::fixedWidth(200)));
@@ -347,58 +340,58 @@ namespace BansheeEngine
 		mTitlePreciseAvgCyclesSelf = GUILabel::create(HString(L"Avg. self cycles"), GUIOptions(GUIOption::fixedWidth(100)));
 		mTitlePreciseAvgCyclesSelf = GUILabel::create(HString(L"Avg. self cycles"), GUIOptions(GUIOption::fixedWidth(100)));
 		mTitlePreciseTotalCyclesSelf = GUILabel::create(HString(L"Total self cycles"), GUIOptions(GUIOption::fixedWidth(100)));
 		mTitlePreciseTotalCyclesSelf = GUILabel::create(HString(L"Total self cycles"), GUIOptions(GUIOption::fixedWidth(100)));
 
 
-		GUILayout& basicTitleLabelLayout = mBasicLayoutLabels->addLayoutX();
-		GUILayout& preciseTitleLabelLayout = mPreciseLayoutLabels->addLayoutX();
-		GUILayout& basicTitleContentLayout = mBasicLayoutContents->addLayoutX();
-		GUILayout& preciseTitleContentLayout = mPreciseLayoutContents->addLayoutX();
-
-		basicTitleLabelLayout.addElement(mTitleBasicName);
-		basicTitleContentLayout.addElement(mTitleBasicPctOfParent);
-		basicTitleContentLayout.addElement(mTitleBasicNumCalls);
-		basicTitleContentLayout.addElement(mTitleBasicNumAllocs);
-		basicTitleContentLayout.addElement(mTitleBasicNumFrees);
-		basicTitleContentLayout.addElement(mTitleBasicAvgTime);
-		basicTitleContentLayout.addElement(mTitleBasicTotalTime);
-		basicTitleContentLayout.addElement(mTitleBasicAvgTitleSelf);
-		basicTitleContentLayout.addElement(mTitleBasicTotalTimeSelf);
-
-		preciseTitleLabelLayout.addElement(mTitlePreciseName);
-		preciseTitleContentLayout.addElement(mTitlePrecisePctOfParent);
-		preciseTitleContentLayout.addElement(mTitlePreciseNumCalls);
-		preciseTitleContentLayout.addElement(mTitlePreciseNumAllocs);
-		preciseTitleContentLayout.addElement(mTitlePreciseNumFrees);
-		preciseTitleContentLayout.addElement(mTitlePreciseAvgCycles);
-		preciseTitleContentLayout.addElement(mTitlePreciseTotalCycles);
-		preciseTitleContentLayout.addElement(mTitlePreciseAvgCyclesSelf);
-		preciseTitleContentLayout.addElement(mTitlePreciseTotalCyclesSelf);
-
-		mBasicLayoutLabels->addFlexibleSpace();
-		mPreciseLayoutLabels->addFlexibleSpace();
-		mBasicLayoutContents->addFlexibleSpace();
-		mPreciseLayoutContents->addFlexibleSpace();
+		GUILayout* basicTitleLabelLayout = mBasicLayoutLabels->addNewElement<GUILayoutX>();
+		GUILayout* preciseTitleLabelLayout = mPreciseLayoutLabels->addNewElement<GUILayoutX>();
+		GUILayout* basicTitleContentLayout = mBasicLayoutContents->addNewElement<GUILayoutX>();
+		GUILayout* preciseTitleContentLayout = mPreciseLayoutContents->addNewElement<GUILayoutX>();
+
+		basicTitleLabelLayout->addElement(mTitleBasicName);
+		basicTitleContentLayout->addElement(mTitleBasicPctOfParent);
+		basicTitleContentLayout->addElement(mTitleBasicNumCalls);
+		basicTitleContentLayout->addElement(mTitleBasicNumAllocs);
+		basicTitleContentLayout->addElement(mTitleBasicNumFrees);
+		basicTitleContentLayout->addElement(mTitleBasicAvgTime);
+		basicTitleContentLayout->addElement(mTitleBasicTotalTime);
+		basicTitleContentLayout->addElement(mTitleBasicAvgTitleSelf);
+		basicTitleContentLayout->addElement(mTitleBasicTotalTimeSelf);
+
+		preciseTitleLabelLayout->addElement(mTitlePreciseName);
+		preciseTitleContentLayout->addElement(mTitlePrecisePctOfParent);
+		preciseTitleContentLayout->addElement(mTitlePreciseNumCalls);
+		preciseTitleContentLayout->addElement(mTitlePreciseNumAllocs);
+		preciseTitleContentLayout->addElement(mTitlePreciseNumFrees);
+		preciseTitleContentLayout->addElement(mTitlePreciseAvgCycles);
+		preciseTitleContentLayout->addElement(mTitlePreciseTotalCycles);
+		preciseTitleContentLayout->addElement(mTitlePreciseAvgCyclesSelf);
+		preciseTitleContentLayout->addElement(mTitlePreciseTotalCyclesSelf);
+
+		mBasicLayoutLabels->addNewElement<GUIFlexibleSpace>();
+		mPreciseLayoutLabels->addNewElement<GUIFlexibleSpace>();
+		mBasicLayoutContents->addNewElement<GUIFlexibleSpace>();
+		mPreciseLayoutContents->addNewElement<GUIFlexibleSpace>();
 
 
 		// Set up GPU sample areas
 		// Set up GPU sample areas
 		mGPUAreaFrameContents = GUIArea::create(*mWidget, 0, 0);
 		mGPUAreaFrameContents = GUIArea::create(*mWidget, 0, 0);
 		mGPUAreaFrameSamples = GUIArea::create(*mWidget, 0, 0);
 		mGPUAreaFrameSamples = GUIArea::create(*mWidget, 0, 0);
-		mGPULayoutFrameContentsLeft = &mGPUAreaFrameContents->getLayout().addLayoutY();
-		mGPULayoutFrameContentsRight = &mGPUAreaFrameContents->getLayout().addLayoutY();
+		mGPULayoutFrameContentsLeft = mGPUAreaFrameContents->getLayout().addNewElement<GUILayoutY>();
+		mGPULayoutFrameContentsRight = mGPUAreaFrameContents->getLayout().addNewElement<GUILayoutY>();
 
 
-		GUILayout& gpuSamplesMain = mGPUAreaFrameSamples->getLayout().addLayoutY();
+		GUILayout* gpuSamplesMain = mGPUAreaFrameSamples->getLayout().addNewElement<GUILayoutY>();
 
 
-		GUILayout& gpuSampleTitle = gpuSamplesMain.addLayoutY();
-		mGPULayoutSamples = &gpuSamplesMain.addLayoutY();
-		gpuSamplesMain.addFlexibleSpace();
+		GUILayout* gpuSampleTitle = gpuSamplesMain->addNewElement<GUILayoutY>();
+		mGPULayoutSamples = gpuSamplesMain->addNewElement<GUILayoutY>();
+		gpuSamplesMain->addNewElement<GUIFlexibleSpace>();
 
 
 		HString gpuSamplesStr(L"__ProfOvGPUSamples", L"Samples");
 		HString gpuSamplesStr(L"__ProfOvGPUSamples", L"Samples");
-		gpuSampleTitle.addElement(GUILabel::create(gpuSamplesStr));
-		gpuSampleTitle.addSpace(20);
+		gpuSampleTitle->addElement(GUILabel::create(gpuSamplesStr));
+		gpuSampleTitle->addNewElement<GUIFixedSpace>(20);
 
 
-		GUILayout& gpuSampleTitleRow = gpuSampleTitle.addLayoutX();
+		GUILayout* gpuSampleTitleRow = gpuSampleTitle->addNewElement<GUILayoutX>();
 
 
 		HString gpuSamplesNameStr(L"__ProfOvGPUSampName", L"Name");
 		HString gpuSamplesNameStr(L"__ProfOvGPUSampName", L"Name");
 		HString gpuSamplesTimeStr(L"__ProfOvGPUSampTime", L"Time");
 		HString gpuSamplesTimeStr(L"__ProfOvGPUSampTime", L"Time");
-		gpuSampleTitleRow.addElement(GUILabel::create(gpuSamplesNameStr, GUIOptions(GUIOption::fixedWidth(100))));
-		gpuSampleTitleRow.addElement(GUILabel::create(gpuSamplesTimeStr, GUIOptions(GUIOption::fixedWidth(100))));
+		gpuSampleTitleRow->addElement(GUILabel::create(gpuSamplesNameStr, GUIOptions(GUIOption::fixedWidth(100))));
+		gpuSampleTitleRow->addElement(GUILabel::create(gpuSamplesTimeStr, GUIOptions(GUIOption::fixedWidth(100))));
 
 
 		mGPUFrameNumStr = HString(L"__ProfOvFrame", L"Frame #{0}");
 		mGPUFrameNumStr = HString(L"__ProfOvFrame", L"Frame #{0}");
 		mGPUTimeStr = HString(L"__ProfOvTime", L"Time: {0}ms");
 		mGPUTimeStr = HString(L"__ProfOvTime", L"Time: {0}ms");
@@ -436,7 +429,7 @@ namespace BansheeEngine
 		mGPULayoutFrameContentsLeft->addElement(GUILabel::create(mGPUBlendStateChangesStr, GUIOptions(GUIOption::fixedWidth(200))));
 		mGPULayoutFrameContentsLeft->addElement(GUILabel::create(mGPUBlendStateChangesStr, GUIOptions(GUIOption::fixedWidth(200))));
 		mGPULayoutFrameContentsLeft->addElement(GUILabel::create(mGPURasterStateChangesStr, GUIOptions(GUIOption::fixedWidth(200))));
 		mGPULayoutFrameContentsLeft->addElement(GUILabel::create(mGPURasterStateChangesStr, GUIOptions(GUIOption::fixedWidth(200))));
 		mGPULayoutFrameContentsLeft->addElement(GUILabel::create(mGPUDepthStencilStateChangesStr, GUIOptions(GUIOption::fixedWidth(200))));
 		mGPULayoutFrameContentsLeft->addElement(GUILabel::create(mGPUDepthStencilStateChangesStr, GUIOptions(GUIOption::fixedWidth(200))));
-		mGPULayoutFrameContentsLeft->addFlexibleSpace();
+		mGPULayoutFrameContentsLeft->addNewElement<GUIFlexibleSpace>();
 
 
 		mGPULayoutFrameContentsRight->addElement(GUILabel::create(mGPUObjectsCreatedStr, GUIOptions(GUIOption::fixedWidth(200))));
 		mGPULayoutFrameContentsRight->addElement(GUILabel::create(mGPUObjectsCreatedStr, GUIOptions(GUIOption::fixedWidth(200))));
 		mGPULayoutFrameContentsRight->addElement(GUILabel::create(mGPUObjectsDestroyedStr, GUIOptions(GUIOption::fixedWidth(200))));
 		mGPULayoutFrameContentsRight->addElement(GUILabel::create(mGPUObjectsDestroyedStr, GUIOptions(GUIOption::fixedWidth(200))));
@@ -448,7 +441,7 @@ namespace BansheeEngine
 		mGPULayoutFrameContentsRight->addElement(GUILabel::create(mGPUIndexBufferBindsStr, GUIOptions(GUIOption::fixedWidth(200))));
 		mGPULayoutFrameContentsRight->addElement(GUILabel::create(mGPUIndexBufferBindsStr, GUIOptions(GUIOption::fixedWidth(200))));
 		mGPULayoutFrameContentsRight->addElement(GUILabel::create(mGPUGPUProgramBufferBindsStr, GUIOptions(GUIOption::fixedWidth(200))));
 		mGPULayoutFrameContentsRight->addElement(GUILabel::create(mGPUGPUProgramBufferBindsStr, GUIOptions(GUIOption::fixedWidth(200))));
 		mGPULayoutFrameContentsRight->addElement(GUILabel::create(mGPUGPUProgramBindsStr, GUIOptions(GUIOption::fixedWidth(200))));
 		mGPULayoutFrameContentsRight->addElement(GUILabel::create(mGPUGPUProgramBindsStr, GUIOptions(GUIOption::fixedWidth(200))));
-		mGPULayoutFrameContentsRight->addFlexibleSpace();
+		mGPULayoutFrameContentsRight->addNewElement<GUIFlexibleSpace>();
 
 
 		updateCPUSampleAreaSizes();
 		updateCPUSampleAreaSizes();
 		updateGPUSampleAreaSizes();
 		updateGPUSampleAreaSizes();

+ 8 - 9
ExampleProject/Main/Main.cpp

@@ -2,7 +2,6 @@
 
 
 #include "BsApplication.h"
 #include "BsApplication.h"
 #include "BsImporter.h"
 #include "BsImporter.h"
-#include "BsGpuProgramImportOptions.h"
 #include "BsTextureImportOptions.h"
 #include "BsTextureImportOptions.h"
 #include "BsMaterial.h"
 #include "BsMaterial.h"
 #include "BsShader.h"
 #include "BsShader.h"
@@ -336,30 +335,30 @@ namespace BansheeEngine
 		GUIArea* bottomArea = GUIArea::createStretchedXY(*gui, 0, 0, 0, 0);
 		GUIArea* bottomArea = GUIArea::createStretchedXY(*gui, 0, 0, 0, 0);
 
 
 		// Add a vertical layout that will automatically position any child elements top to bottom.
 		// Add a vertical layout that will automatically position any child elements top to bottom.
-		GUILayout& bottomLayout = bottomArea->getLayout().addLayoutY();
+		GUILayout* bottomLayout = bottomArea->getLayout().addNewElement<GUILayoutY>();
 
 
 		// Add a flexible space that fills up any remaining area in the layout, making the two labels above be aligned
 		// Add a flexible space that fills up any remaining area in the layout, making the two labels above be aligned
 		// to the bottom of the GUI widget (and the screen).
 		// to the bottom of the GUI widget (and the screen).
-		bottomLayout.addFlexibleSpace();
+		bottomLayout->addNewElement<GUIFlexibleSpace>();
 
 
 		// Add a couple of labels to the layout with the needed messages. Labels expect a HString object that
 		// Add a couple of labels to the layout with the needed messages. Labels expect a HString object that
 		// maps into a string table and allows for easily localization. 
 		// maps into a string table and allows for easily localization. 
-		bottomLayout.addElement(GUILabel::create(HString(L"Press F1 to toggle CPU profiler overlay")));
-		bottomLayout.addElement(GUILabel::create(HString(L"Press F2 to toggle GPU profiler overlay")));
+		bottomLayout->addElement(GUILabel::create(HString(L"Press F1 to toggle CPU profiler overlay")));
+		bottomLayout->addElement(GUILabel::create(HString(L"Press F2 to toggle GPU profiler overlay")));
 
 
 		// Create a GUI area that is used for displaying resolution and fullscreen options.
 		// Create a GUI area that is used for displaying resolution and fullscreen options.
 		GUIArea* rightArea = GUIArea::createStretchedXY(*gui, 30, 30, 30, 30);
 		GUIArea* rightArea = GUIArea::createStretchedXY(*gui, 30, 30, 30, 30);
 
 
 		// We want all the GUI elements be right aligned, so we add a flexible space first.
 		// We want all the GUI elements be right aligned, so we add a flexible space first.
-		rightArea->getLayout().addFlexibleSpace();
+		rightArea->getLayout().addNewElement<GUIFlexibleSpace>();
 
 
 		// And we want the elements to be vertically placed, top to bottom
 		// And we want the elements to be vertically placed, top to bottom
-		GUILayout& rightLayout = rightArea->getLayout().addLayoutY();
+		GUILayout* rightLayout = rightArea->getLayout().addNewElement<GUILayoutY>();
 
 
 		// Add a button that will trigger a callback when clicked
 		// Add a button that will trigger a callback when clicked
 		toggleFullscreenButton = GUIButton::create(HString(L"Toggle fullscreen"));
 		toggleFullscreenButton = GUIButton::create(HString(L"Toggle fullscreen"));
 		toggleFullscreenButton->onClick.connect(&toggleFullscreen);
 		toggleFullscreenButton->onClick.connect(&toggleFullscreen);
-		rightLayout.addElement(toggleFullscreenButton);
+		rightLayout->addElement(toggleFullscreenButton);
 
 
 		// Add a profiler overlay object that is resposible for displaying CPU and GPU profiling GUI
 		// Add a profiler overlay object that is resposible for displaying CPU and GPU profiling GUI
 		profilerOverlay = guiSO->addComponent<ProfilerOverlay>(guiCamera->getViewport());
 		profilerOverlay = guiSO->addComponent<ProfilerOverlay>(guiCamera->getViewport());
@@ -396,7 +395,7 @@ namespace BansheeEngine
 
 
 		// Create the list box
 		// Create the list box
 		GUIListBox* videoModeListBox = GUIListBox::create(videoModeLabels);
 		GUIListBox* videoModeListBox = GUIListBox::create(videoModeLabels);
-		rightLayout.addElement(videoModeListBox);
+		rightLayout->addElement(videoModeListBox);
 
 
 		// Select the default (desktop) video mode
 		// Select the default (desktop) video mode
 		videoModeListBox->selectElement(selectedVideoModeIdx);
 		videoModeListBox->selectElement(selectedVideoModeIdx);

+ 25 - 0
MBansheeEditor/EditorBuiltin.cs

@@ -0,0 +1,25 @@
+using System.Runtime.CompilerServices;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    public static class EditorBuiltin
+    {
+        public static SpriteTexture FolderIcon { get { return Internal_GetFolderIcon(); } }
+        public static SpriteTexture MeshIcon { get { return Internal_GetMeshIcon(); } }
+        public static SpriteTexture FontIcon { get { return Internal_GetFontIcon(); } }
+        public static SpriteTexture TextureIcon { get { return Internal_GetTextureIcon(); } }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern SpriteTexture Internal_GetFolderIcon();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern SpriteTexture Internal_GetMeshIcon();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern SpriteTexture Internal_GetFontIcon();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern SpriteTexture Internal_GetTextureIcon();
+    }
+}

+ 3 - 2
SBansheeEditor/Source/BsGUIGameObjectField.cpp

@@ -1,6 +1,6 @@
 #include "BsGUIGameObjectField.h"
 #include "BsGUIGameObjectField.h"
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
-#include "BsGUILayout.h"
+#include "BsGUILayoutX.h"
 #include "BsGUILabel.h"
 #include "BsGUILabel.h"
 #include "BsGUIDropButton.h"
 #include "BsGUIDropButton.h"
 #include "BsGUIButton.h"
 #include "BsGUIButton.h"
@@ -27,7 +27,8 @@ namespace BansheeEngine
 		const String& style, const GUILayoutOptions& layoutOptions, bool withLabel)
 		const String& style, const GUILayoutOptions& layoutOptions, bool withLabel)
 		:GUIElementContainer(layoutOptions, style), mLabel(nullptr), mClearButton(nullptr), mDropButton(nullptr), mInstanceId(0), mType(type), mNamespace(typeNamespace)
 		:GUIElementContainer(layoutOptions, style), mLabel(nullptr), mClearButton(nullptr), mDropButton(nullptr), mInstanceId(0), mType(type), mNamespace(typeNamespace)
 	{
 	{
-		mLayout = &addLayoutXInternal(this);
+		mLayout = GUILayoutX::create();
+		_registerChildElement(mLayout);
 
 
 		if(withLabel)
 		if(withLabel)
 		{
 		{

+ 3 - 2
SBansheeEditor/Source/BsGUIResourceField.cpp

@@ -1,6 +1,6 @@
 #include "BsGUIResourceField.h"
 #include "BsGUIResourceField.h"
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
-#include "BsGUILayout.h"
+#include "BsGUILayoutX.h"
 #include "BsGUILabel.h"
 #include "BsGUILabel.h"
 #include "BsGUIDropButton.h"
 #include "BsGUIDropButton.h"
 #include "BsGUIButton.h"
 #include "BsGUIButton.h"
@@ -29,7 +29,8 @@ namespace BansheeEngine
 		const String& style, const GUILayoutOptions& layoutOptions, bool withLabel)
 		const String& style, const GUILayoutOptions& layoutOptions, bool withLabel)
 		:GUIElementContainer(layoutOptions, style), mLabel(nullptr), mClearButton(nullptr), mDropButton(nullptr), mType(type), mNamespace(typeNamespace)
 		:GUIElementContainer(layoutOptions, style), mLabel(nullptr), mClearButton(nullptr), mDropButton(nullptr), mType(type), mNamespace(typeNamespace)
 	{
 	{
-		mLayout = &addLayoutXInternal(this);
+		mLayout = GUILayoutX::create();
+		_registerChildElement(mLayout);
 
 
 		if (withLabel)
 		if (withLabel)
 		{
 		{

+ 2 - 2
SBansheeEngine/Include/BsScriptGUIFixedSpace.h

@@ -15,11 +15,11 @@ namespace BansheeEngine
 		static void internal_createInstanceInsert(MonoObject* instance, MonoObject* parentLayout, UINT32 index, UINT32 size);
 		static void internal_createInstanceInsert(MonoObject* instance, MonoObject* parentLayout, UINT32 index, UINT32 size);
 		static void internal_setSize(ScriptGUIFixedSpace* nativeInstance, UINT32 size);
 		static void internal_setSize(ScriptGUIFixedSpace* nativeInstance, UINT32 size);
 
 
-		ScriptGUIFixedSpace(MonoObject* instance, GUIFixedSpace& fixedSpace, GUILayout* parentLayout);
+		ScriptGUIFixedSpace(MonoObject* instance, GUIFixedSpace* fixedSpace, GUILayout* parentLayout);
 
 
 		void destroy();
 		void destroy();
 
 
-		GUIFixedSpace& mFixedSpace;
+		GUIFixedSpace* mFixedSpace;
 		GUILayout* mParentLayout;
 		GUILayout* mParentLayout;
 		bool mIsDestroyed;
 		bool mIsDestroyed;
 	};
 	};

+ 2 - 2
SBansheeEngine/Include/BsScriptGUIFlexibleSpace.h

@@ -14,11 +14,11 @@ namespace BansheeEngine
 		static void internal_createInstanceAdd(MonoObject* instance, MonoObject* parentLayout);
 		static void internal_createInstanceAdd(MonoObject* instance, MonoObject* parentLayout);
 		static void internal_createInstanceInsert(MonoObject* instance, MonoObject* parentLayout, UINT32 index);
 		static void internal_createInstanceInsert(MonoObject* instance, MonoObject* parentLayout, UINT32 index);
 
 
-		ScriptGUIFlexibleSpace(MonoObject* instance, GUIFlexibleSpace& flexibleSpace, GUILayout* parentLayout);
+		ScriptGUIFlexibleSpace(MonoObject* instance, GUIFlexibleSpace* flexibleSpace, GUILayout* parentLayout);
 
 
 		void destroy();
 		void destroy();
 
 
-		GUIFlexibleSpace& mFlexibleSpace;
+		GUIFlexibleSpace* mFlexibleSpace;
 		GUILayout* mParentLayout;
 		GUILayout* mParentLayout;
 		bool mIsDestroyed;
 		bool mIsDestroyed;
 	};
 	};

+ 6 - 6
SBansheeEngine/Source/BsScriptGUIFixedSpace.cpp

@@ -11,8 +11,8 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	ScriptGUIFixedSpace::ScriptGUIFixedSpace(MonoObject* instance, GUIFixedSpace& fixedSpace, GUILayout* parentLayout)
-		:TScriptGUIElementBase(instance, &fixedSpace), mFixedSpace(fixedSpace), mParentLayout(parentLayout), mIsDestroyed(false)
+	ScriptGUIFixedSpace::ScriptGUIFixedSpace(MonoObject* instance, GUIFixedSpace* fixedSpace, GUILayout* parentLayout)
+		:TScriptGUIElementBase(instance, fixedSpace), mFixedSpace(fixedSpace), mParentLayout(parentLayout), mIsDestroyed(false)
 	{
 	{
 
 
 	}
 	}
@@ -28,7 +28,7 @@ namespace BansheeEngine
 	{
 	{
 		if (!mIsDestroyed)
 		if (!mIsDestroyed)
 		{
 		{
-			mParentLayout->removeSpace(mFixedSpace);
+			GUIFixedSpace::destroy(mFixedSpace);
 			mParentLayout = nullptr;
 			mParentLayout = nullptr;
 
 
 			mIsDestroyed = true;
 			mIsDestroyed = true;
@@ -39,7 +39,7 @@ namespace BansheeEngine
 	{
 	{
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
-		GUIFixedSpace& space = nativeLayout->addSpace(size);
+		GUIFixedSpace* space = nativeLayout->addNewElement<GUIFixedSpace>(size);
 
 
 		ScriptGUIFixedSpace* nativeInstance = new (bs_alloc<ScriptGUIFixedSpace>()) ScriptGUIFixedSpace(instance, space, nativeLayout);
 		ScriptGUIFixedSpace* nativeInstance = new (bs_alloc<ScriptGUIFixedSpace>()) ScriptGUIFixedSpace(instance, space, nativeLayout);
 	}
 	}
@@ -48,13 +48,13 @@ namespace BansheeEngine
 	{
 	{
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
-		GUIFixedSpace& space = nativeLayout->insertSpace(index, size);
+		GUIFixedSpace* space = nativeLayout->insertNewElement<GUIFixedSpace>(index, size);
 
 
 		ScriptGUIFixedSpace* nativeInstance = new (bs_alloc<ScriptGUIFixedSpace>()) ScriptGUIFixedSpace(instance, space, nativeLayout);
 		ScriptGUIFixedSpace* nativeInstance = new (bs_alloc<ScriptGUIFixedSpace>()) ScriptGUIFixedSpace(instance, space, nativeLayout);
 	}
 	}
 
 
 	void ScriptGUIFixedSpace::internal_setSize(ScriptGUIFixedSpace* nativeInstance, UINT32 size)
 	void ScriptGUIFixedSpace::internal_setSize(ScriptGUIFixedSpace* nativeInstance, UINT32 size)
 	{
 	{
-		nativeInstance->mFixedSpace.setSize(size);
+		nativeInstance->mFixedSpace->setSize(size);
 	}
 	}
 }
 }

+ 5 - 5
SBansheeEngine/Source/BsScriptGUIFlexibleSpace.cpp

@@ -11,8 +11,8 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	ScriptGUIFlexibleSpace::ScriptGUIFlexibleSpace(MonoObject* instance, GUIFlexibleSpace& flexibleSpace, GUILayout* parentLayout)
-		:TScriptGUIElementBase(instance, &flexibleSpace), mFlexibleSpace(flexibleSpace), mParentLayout(parentLayout), mIsDestroyed(false)
+	ScriptGUIFlexibleSpace::ScriptGUIFlexibleSpace(MonoObject* instance, GUIFlexibleSpace* flexibleSpace, GUILayout* parentLayout)
+		:TScriptGUIElementBase(instance, flexibleSpace), mFlexibleSpace(flexibleSpace), mParentLayout(parentLayout), mIsDestroyed(false)
 	{
 	{
 
 
 	}
 	}
@@ -27,7 +27,7 @@ namespace BansheeEngine
 	{
 	{
 		if(!mIsDestroyed)
 		if(!mIsDestroyed)
 		{
 		{
-			mParentLayout->removeFlexibleSpace(mFlexibleSpace);
+			GUIFlexibleSpace::destroy(mFlexibleSpace);
 			mParentLayout = nullptr;
 			mParentLayout = nullptr;
 
 
 			mIsDestroyed = true;
 			mIsDestroyed = true;
@@ -38,7 +38,7 @@ namespace BansheeEngine
 	{
 	{
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
-		GUIFlexibleSpace& space = nativeLayout->addFlexibleSpace();
+		GUIFlexibleSpace* space = nativeLayout->addNewElement<GUIFlexibleSpace>();
 
 
 		ScriptGUIFlexibleSpace* nativeInstance = new (bs_alloc<ScriptGUIFlexibleSpace>()) ScriptGUIFlexibleSpace(instance, space, nativeLayout);
 		ScriptGUIFlexibleSpace* nativeInstance = new (bs_alloc<ScriptGUIFlexibleSpace>()) ScriptGUIFlexibleSpace(instance, space, nativeLayout);
 	}
 	}
@@ -47,7 +47,7 @@ namespace BansheeEngine
 	{
 	{
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
-		GUIFlexibleSpace& space = nativeLayout->insertFlexibleSpace(index);
+		GUIFlexibleSpace* space = nativeLayout->insertNewElement<GUIFlexibleSpace>(index);
 
 
 		ScriptGUIFlexibleSpace* nativeInstance = new (bs_alloc<ScriptGUIFlexibleSpace>()) ScriptGUIFlexibleSpace(instance, space, nativeLayout);
 		ScriptGUIFlexibleSpace* nativeInstance = new (bs_alloc<ScriptGUIFlexibleSpace>()) ScriptGUIFlexibleSpace(instance, space, nativeLayout);
 	}
 	}

+ 12 - 10
SBansheeEngine/Source/BsScriptGUILayout.cpp

@@ -7,6 +7,9 @@
 #include "BsScriptGUIScrollArea.h"
 #include "BsScriptGUIScrollArea.h"
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
 #include "BsGUILayout.h"
 #include "BsGUILayout.h"
+#include "BsGUILayoutX.h"
+#include "BsGUILayoutY.h"
+#include "BsGUILayoutExplicit.h"
 #include "BsGUIScrollArea.h"
 #include "BsGUIScrollArea.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
@@ -33,8 +36,7 @@ namespace BansheeEngine
 	{
 	{
 		if(!mIsDestroyed)
 		if(!mIsDestroyed)
 		{
 		{
-			if(mParentLayout != nullptr)
-				mParentLayout->removeLayout(*mLayout);
+			GUILayout::destroy(mLayout);
 
 
 			mLayout = nullptr;
 			mLayout = nullptr;
 			mParentLayout = nullptr;
 			mParentLayout = nullptr;
@@ -56,40 +58,40 @@ namespace BansheeEngine
 	{
 	{
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
-		GUILayout& layout = nativeLayout->addLayoutX();
+		GUILayout* layout = nativeLayout->addNewElement<GUILayoutX>();
 
 
 		ScriptGUILayout* nativeInstance = new (bs_alloc<ScriptGUILayout>()) 
 		ScriptGUILayout* nativeInstance = new (bs_alloc<ScriptGUILayout>()) 
-			ScriptGUILayout(instance, &layout, nativeLayout);
+			ScriptGUILayout(instance, layout, nativeLayout);
 	}
 	}
 
 
 	void ScriptGUILayout::internal_createInstanceYFromLayoutAdd(MonoObject* instance, MonoObject* parentLayout)
 	void ScriptGUILayout::internal_createInstanceYFromLayoutAdd(MonoObject* instance, MonoObject* parentLayout)
 	{
 	{
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
-		GUILayout& layout = nativeLayout->addLayoutY();
+		GUILayout* layout = nativeLayout->addNewElement<GUILayoutY>();
 
 
 		ScriptGUILayout* nativeInstance = new (bs_alloc<ScriptGUILayout>()) 
 		ScriptGUILayout* nativeInstance = new (bs_alloc<ScriptGUILayout>()) 
-			ScriptGUILayout(instance, &layout, nativeLayout);
+			ScriptGUILayout(instance, layout, nativeLayout);
 	}
 	}
 
 
 	void ScriptGUILayout::internal_createInstanceXFromLayoutInsert(MonoObject* instance, MonoObject* parentLayout, UINT32 index)
 	void ScriptGUILayout::internal_createInstanceXFromLayoutInsert(MonoObject* instance, MonoObject* parentLayout, UINT32 index)
 	{
 	{
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
-		GUILayout& layout = nativeLayout->insertLayoutX(index);
+		GUILayout* layout = nativeLayout->insertNewElement<GUILayoutX>(index);
 
 
 		ScriptGUILayout* nativeInstance = new (bs_alloc<ScriptGUILayout>())
 		ScriptGUILayout* nativeInstance = new (bs_alloc<ScriptGUILayout>())
-			ScriptGUILayout(instance, &layout, nativeLayout);
+			ScriptGUILayout(instance, layout, nativeLayout);
 	}
 	}
 
 
 	void ScriptGUILayout::internal_createInstanceYFromLayoutInsert(MonoObject* instance, MonoObject* parentLayout, UINT32 index)
 	void ScriptGUILayout::internal_createInstanceYFromLayoutInsert(MonoObject* instance, MonoObject* parentLayout, UINT32 index)
 	{
 	{
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		ScriptGUILayout* scriptLayout = ScriptGUILayout::toNative(parentLayout);
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
 		GUILayout* nativeLayout = scriptLayout->getInternalValue();
-		GUILayout& layout = nativeLayout->insertLayoutY(index);
+		GUILayout* layout = nativeLayout->insertNewElement<GUILayoutY>(index);
 
 
 		ScriptGUILayout* nativeInstance = new (bs_alloc<ScriptGUILayout>())
 		ScriptGUILayout* nativeInstance = new (bs_alloc<ScriptGUILayout>())
-			ScriptGUILayout(instance, &layout, nativeLayout);
+			ScriptGUILayout(instance, layout, nativeLayout);
 	}
 	}
 
 
 	void ScriptGUILayout::internal_createInstanceYFromScrollArea(MonoObject* instance, MonoObject* parentScrollArea)
 	void ScriptGUILayout::internal_createInstanceYFromScrollArea(MonoObject* instance, MonoObject* parentScrollArea)

+ 65 - 0
TODO.txt

@@ -14,6 +14,69 @@ Almost all of PRojectLibrary functionality is completely untested
 My GUID generation is screwed up. If multiple GUIDs are generated in succession then the timestamp will remain
 My GUID generation is screwed up. If multiple GUIDs are generated in succession then the timestamp will remain
 the same and the only variable will be the 4byte random number, which can sometimes end up identical to the previous number.
 the same and the only variable will be the 4byte random number, which can sometimes end up identical to the previous number.
 
 
+----------------------------------------------------------------------
+GUIArea refactor:
+
+Revert all changes and start from scratch:
+ 1. Get all layouts to use pointers and be reparentable. Compile/commit
+    - Make GUIElementBase::addElement return a ptr to the element so I don't need to use two lines to init and add an element
+ 2. Add new GUILayoutOption (offset) and ensure it works. Add GUILayoutOptions to layouts as well, and ensure parent layouts respect them (when it makes sense).
+ 3. Remove normal position/size from GUIElementBase and move it to GUIElement
+ 4. Move to the new positioning/size system (get rid of GUIOptions) and add support for offset size type
+   - Also ensure these options work with layouts and that GUILayoutExplicit respects child layout positions same as it does elements
+ 5. Rename GUiLayoutExplicit to GUIPanel. Add default layout to it. Make coordinates relative
+     and ensure ColorPicker window works looks fine. (And refactor elements so they contain relative size.)
+ 6. Change how GUIArea depth works. Allow GUIPanel to have a depth range (keep at the depth on GUIArea for now as well)
+ 7. Modify C# so it no longer uses GUIPanel or GUIPanelContainer and uses GUILayoutExplicit (now GUIPanel) instead
+ 8. Remove GUIArea and replace with GUILayoutExplicit in C++ and C#
+
+GUIPanel (ex GUILayoutExplicit)
+ - When creating a GUIPanel allow certain size to be specified. When layout is positioned that size is used as if it was fixed GUI element size.
+ - Should have a default layout as its child. This layout acts as it was parented by a GUIArea (it tries to cover the entire size of GUILayout)
+  - But it also has standard AddElement methods which will allow elements to be positioned directly.
+ - When calculating bounds I need to return them relative to the parent GUIPanel
+   - When specifying bounds they should be relative to parent GUIPanel
+   - This will require updating GUILayoutUtility
+
+Replace current GUIOption::fixedWidth/etc. system and implement something new that also works for layouts
+ - Also it deals with the issue of relative coordinates
+ - setPosition(GUIPosition x, GUIPosition y) <- used only if direct parent of GUIPanel
+   - GUIPosition::fixed(int value) <- position in pixels offset from parent GUIPanel
+ - setWidth(GUISize size), setHeight(GUISize size)
+   - GUISize::fixed(int value) <- fixed size in pixels
+   - GUISize::flexible(int min, int max) <- flexible size in pixels with minimum and maximum value (0 means inifinite)
+   - GUISize::offset(int offset) <- size that is determined by the distance from the edge from its parent
+ - setAnchor(Vector2 min, Vector2 max)
+   - anchor + specifiying size as an offset is weird but I can't think of a way around it
+ - Need to modify layout updates so they properly handle these new settings. Most importantly for layouts as they don't support layout 
+   options right now. And GUI elements don't support float versions of position/size methods.
+
+TODO - Better way to handle layout depth?
+  - Specify layout depth as offset + range. Then just add the depths and clamp if outside the range
+TODO - Will I need a separate set of coordinates to properly handle relative coordinates?
+  - Yes, most likely. Other option is somehow storing a reference to the parent but I don't think
+    that's a good solution. Rename current position/size to cached position/size and make current
+	getter/setters point to the new relative position/size instead. Cached should only be available
+	to internal methods.
+
+OPTIONAL - Consider making coordinates/size be GUIElement only
+
+Use cases:
+InspectorWindow:
+ - It has a scroll area that will have a GUIPanel as its child. User can then add custom GUIPanels as children to the root GUIPanels main layout.
+
+ColorPicker
+ - This should work fine as long as I ensure that I add explicit elements to the root GUIPanel (one that has the main layout with all other elements)
+
+ProjectWindow
+ - ScrollArea would have a GUIPanel child and then it would work similarly to InspectorWindow
+
+Three child GUIPanels in a widget, title-bar, contents and background
+ - Add three GUIPanels to the root panel, each with its own depth
+ - Title GUIPanel: Add GUISpaces for padding, GUIFlexibleSpace to anchor to the top, specify GUIPanel height but leave width at 0 for flexible expand
+ - Content GUIPanel: Similar as title, but leave both width and height as 0, add GUISpace as padding
+ - Background GUIPanel: Leave as is
+
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 Project window
 Project window
 
 
@@ -23,6 +86,8 @@ When working with scroll areas I cannot create multiple child areas of different
 Simple tasks:
 Simple tasks:
  - Add GUI button as overlay. Hook up its input event to select (click) + enter directory (double click) + context (right click, for later)
  - Add GUI button as overlay. Hook up its input event to select (click) + enter directory (double click) + context (right click, for later)
  - Add element highlights: ping (blue bg), selection (orange bg), cut (fade out icon/label)
  - Add element highlights: ping (blue bg), selection (orange bg), cut (fade out icon/label)
+ - Add C# ContextMenu
+ - Add DropDownWindow type
 
 
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 Resources
 Resources