Quellcode durchsuchen

Added a common base for GUILayout and GUIElement

Marko Pintera vor 12 Jahren
Ursprung
Commit
6d4bed822a

+ 2 - 0
BansheeEngine/BansheeEngine.vcxproj

@@ -152,6 +152,7 @@
     <ClInclude Include="Include\BsGUIArea.h" />
     <ClInclude Include="Include\BsGUIArea.h" />
     <ClInclude Include="Include\BsGUIButton.h" />
     <ClInclude Include="Include\BsGUIButton.h" />
     <ClInclude Include="Include\BsGUICommandEvent.h" />
     <ClInclude Include="Include\BsGUICommandEvent.h" />
+    <ClInclude Include="Include\BsGUIElementBase.h" />
     <ClInclude Include="Include\BsGUIInputTool.h" />
     <ClInclude Include="Include\BsGUIInputTool.h" />
     <ClInclude Include="Include\BsGUIInputBox.h" />
     <ClInclude Include="Include\BsGUIInputBox.h" />
     <ClInclude Include="Include\BsGUIButtonEvent.h" />
     <ClInclude Include="Include\BsGUIButtonEvent.h" />
@@ -199,6 +200,7 @@
     <ClCompile Include="Source\BsGUIArea.cpp" />
     <ClCompile Include="Source\BsGUIArea.cpp" />
     <ClCompile Include="Source\BsGUIButton.cpp" />
     <ClCompile Include="Source\BsGUIButton.cpp" />
     <ClCompile Include="Source\BsGUIElement.cpp" />
     <ClCompile Include="Source\BsGUIElement.cpp" />
+    <ClCompile Include="Source\BsGUIElementBase.cpp" />
     <ClCompile Include="Source\BsGUIInputBox.cpp" />
     <ClCompile Include="Source\BsGUIInputBox.cpp" />
     <ClCompile Include="Source\BsGUIButtonEvent.cpp" />
     <ClCompile Include="Source\BsGUIButtonEvent.cpp" />
     <ClCompile Include="Source\BsGUIInputCaret.cpp" />
     <ClCompile Include="Source\BsGUIInputCaret.cpp" />

+ 6 - 0
BansheeEngine/BansheeEngine.vcxproj.filters

@@ -171,6 +171,9 @@
     <ClInclude Include="Include\BsGUIInputTool.h">
     <ClInclude Include="Include\BsGUIInputTool.h">
       <Filter>Header Files\GUI</Filter>
       <Filter>Header Files\GUI</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsGUIElementBase.h">
+      <Filter>Header Files\GUI</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsGUIElement.cpp">
     <ClCompile Include="Source\BsGUIElement.cpp">
@@ -287,5 +290,8 @@
     <ClCompile Include="Source\BsGUIInputTool.cpp">
     <ClCompile Include="Source\BsGUIInputTool.cpp">
       <Filter>Source Files\GUI</Filter>
       <Filter>Source Files\GUI</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\BsGUIElementBase.cpp">
+      <Filter>Source Files\GUI</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 2 - 22
BansheeEngine/Include/BsGUIElement.h

@@ -1,13 +1,14 @@
 #pragma once
 #pragma once
 
 
 #include "BsPrerequisites.h"
 #include "BsPrerequisites.h"
+#include "BsGUIElementBase.h"
 #include "BsGUILayoutOptions.h"
 #include "BsGUILayoutOptions.h"
 #include "CmRect.h"
 #include "CmRect.h"
 #include "CmInt2.h"
 #include "CmInt2.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	class BS_EXPORT GUIElement
+	class BS_EXPORT GUIElement : public GUIElementBase
 	{
 	{
 	public:
 	public:
 		GUIElement(GUIWidget& parent, const GUIElementStyle* style, const GUILayoutOptions& layoutOptions, bool acceptsKeyboardFocus = false);
 		GUIElement(GUIWidget& parent, const GUIElementStyle* style, const GUILayoutOptions& layoutOptions, bool acceptsKeyboardFocus = false);
@@ -83,30 +84,22 @@ namespace BansheeEngine
 		/* 							INTERNAL METHODS                      		*/
 		/* 							INTERNAL METHODS                      		*/
 		/************************************************************************/
 		/************************************************************************/
 
 
-		GUILayout* _getParentLayout() const { return mParentLayout; }
-		void _setParentLayout(GUILayout* layout) { mParentLayout = layout; }
-
 		void _setWidgetDepth(CM::UINT8 depth);
 		void _setWidgetDepth(CM::UINT8 depth);
 		void _setAreaDepth(CM::UINT16 depth);
 		void _setAreaDepth(CM::UINT16 depth);
 		void _setOffset(const CM::Int2& offset);
 		void _setOffset(const CM::Int2& offset);
 		void _setWidth(CM::UINT32 width);
 		void _setWidth(CM::UINT32 width);
 		void _setHeight(CM::UINT32 height);
 		void _setHeight(CM::UINT32 height);
 		void _setClipRect(const CM::Rect& clipRect);
 		void _setClipRect(const CM::Rect& clipRect);
-		void _markAsClean() { mIsDirty = 0; }
 		virtual void _setFocus(bool focus) {}
 		virtual void _setFocus(bool focus) {}
 
 
 		CM::UINT32 _getWidth() const { return mWidth; }
 		CM::UINT32 _getWidth() const { return mWidth; }
 		CM::UINT32 _getHeight() const { return mHeight; }
 		CM::UINT32 _getHeight() const { return mHeight; }
 		CM::Int2 _getOffset() const { return mOffset; }
 		CM::Int2 _getOffset() const { return mOffset; }
-		virtual CM::UINT32 _getOptimalWidth() const = 0;
-		virtual CM::UINT32 _getOptimalHeight() const = 0;
 		virtual CM::UINT32 _getRenderElementDepth(CM::UINT32 renderElementIdx) const { return _getDepth(); }
 		virtual CM::UINT32 _getRenderElementDepth(CM::UINT32 renderElementIdx) const { return _getDepth(); }
 
 
 		const CM::Rect& _getBounds() const { return mBounds; }
 		const CM::Rect& _getBounds() const { return mBounds; }
 		CM::UINT32 _getDepth() const { return mDepth; }
 		CM::UINT32 _getDepth() const { return mDepth; }
 		GUIWidget& _getParentWidget() const { return mParent; }
 		GUIWidget& _getParentWidget() const { return mParent; }
-		bool _isContentDirty() const;
-		bool _isMeshDirty() const; 
 		virtual bool _isInBounds(const CM::Int2 position) const;
 		virtual bool _isInBounds(const CM::Int2 position) const;
 		bool _acceptsKeyboardFocus() const { return mAcceptsKeyboardFocus; }
 		bool _acceptsKeyboardFocus() const { return mAcceptsKeyboardFocus; }
 
 
@@ -119,28 +112,15 @@ namespace BansheeEngine
 
 
 		void setLayoutOptions(const GUILayoutOptions& layoutOptions);
 		void setLayoutOptions(const GUILayoutOptions& layoutOptions);
 		
 		
-		/**
-		 * @brief	Marks the elements contents as dirty, which causes the sprite meshes to be recreated from scratch.
-		 */
-		void markContentAsDirty();
-
-		/**
-		 * @brief	Mark only the elements that operate directly on the sprite mesh without requiring the mesh
-		 * 			to be recreated as dirty. This includes position, depth and clip rectangle.
-		 */
-		void markMeshAsDirty();
-
 		CM::Rect getVisibleBounds() const;
 		CM::Rect getVisibleBounds() const;
 		CM::Rect getContentBounds() const;
 		CM::Rect getContentBounds() const;
 
 
 		static GUILayoutOptions getDefaultLayoutOptions(const GUIElementStyle* style);
 		static GUILayoutOptions getDefaultLayoutOptions(const GUIElementStyle* style);
 
 
 		GUIWidget& mParent;
 		GUIWidget& mParent;
-		GUILayout* mParentLayout;
 		GUILayoutOptions mLayoutOptions;
 		GUILayoutOptions mLayoutOptions;
 		CM::Rect mBounds;
 		CM::Rect mBounds;
 
 
-		CM::UINT8 mIsDirty;
 		bool mAcceptsKeyboardFocus;
 		bool mAcceptsKeyboardFocus;
 		CM::UINT32 mDepth;
 		CM::UINT32 mDepth;
 		CM::Int2 mOffset;
 		CM::Int2 mOffset;

+ 106 - 0
BansheeEngine/Include/BsGUIElementBase.h

@@ -0,0 +1,106 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "BsGUILayoutOptions.h"
+#include "CmRect.h"
+#include "CmInt2.h"
+
+namespace BansheeEngine
+{
+	class BS_EXPORT GUIElementBase
+	{
+	protected:
+		enum class Type
+		{
+			Layout,
+			Element,
+			FixedSpace,
+			FlexibleSpace
+		};
+
+		struct GUILayoutEntry
+		{
+			union
+			{
+				GUIElement* element;
+				GUILayout* layout;
+				GUIFixedSpace* space;
+				GUIFlexibleSpace* flexibleSpace;
+			};
+
+			bool isElement() const { return mType == Type::Element; }
+			bool isLayout() const { return mType == Type::Layout; }
+			bool isFixedSpace() const { return mType == Type::FixedSpace; }
+			bool isFlexibleSpace() const { return mType == Type::FlexibleSpace; }
+
+			void setElement(GUIElement* _element)
+			{
+				element = _element;
+				mType = Type::Element;
+			}
+
+			void setLayout(GUILayout* _layout)
+			{
+				layout = _layout;
+				mType = Type::Layout;
+			}
+
+			void setSpace(GUIFixedSpace* _space)
+			{
+				space = _space;
+				mType = Type::FixedSpace;
+			}
+
+			void setFlexibleSpace(GUIFlexibleSpace* _space)
+			{
+				flexibleSpace = _space;
+				mType = Type::FlexibleSpace;
+			}
+
+			Type mType;
+		};
+
+	public:
+		GUIElementBase();
+		virtual ~GUIElementBase() {}
+
+		/************************************************************************/
+		/* 							INTERNAL METHODS                      		*/
+		/************************************************************************/
+
+		/**
+		 * @brief	Re-arranges the elements to fit the layout. (Internal use only)
+		 */
+		virtual void _updateLayout(CM::UINT32 x, CM::UINT32 y, CM::UINT32 width, CM::UINT32 height, CM::UINT8 widgetDepth, CM::UINT16 areaDepth);
+		virtual void _updateOptimalLayoutSizes();
+		virtual void _updateLayoutInternal(CM::UINT32 x, CM::UINT32 y, CM::UINT32 width, CM::UINT32 height, CM::UINT8 widgetDepth, CM::UINT16 areaDepth);
+
+		virtual CM::UINT32 _getOptimalWidth() const = 0;
+		virtual CM::UINT32 _getOptimalHeight() const = 0;
+
+		GUILayout* _getParentLayout() const { return mParentLayout; }
+		void _setParentLayout(GUILayout* layout) { mParentLayout = layout; }
+
+		void _markAsClean() { mIsDirty = 0; }
+		virtual void _setFocus(bool focus) {}
+
+		bool _isContentDirty() const;
+		bool _isMeshDirty() const; 
+
+	protected:
+		/**
+		 * @brief	Marks the elements contents as dirty, which causes the sprite meshes to be recreated from scratch.
+		 */
+		void markContentAsDirty();
+
+		/**
+		 * @brief	Mark only the elements that operate directly on the sprite mesh without requiring the mesh
+		 * 			to be recreated as dirty. This includes position, depth and clip rectangle.
+		 */
+		void markMeshAsDirty();
+
+		GUILayout* mParentLayout;
+		CM::Vector<GUILayoutEntry>::type mChildren;	
+		CM::UINT8 mIsDirty;
+	};
+}

+ 3 - 66
BansheeEngine/Include/BsGUILayout.h

@@ -1,62 +1,13 @@
 #pragma once
 #pragma once
 
 
 #include "BsPrerequisites.h"
 #include "BsPrerequisites.h"
+#include "BsGUIElementBase.h"
 #include "CmInt2.h"
 #include "CmInt2.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	class BS_EXPORT GUILayout
+	class BS_EXPORT GUILayout : public GUIElementBase
 	{
 	{
-		enum class Type
-		{
-			Layout,
-			Element,
-			FixedSpace,
-			FlexibleSpace
-		};
-
-		struct GUILayoutEntry
-		{
-			union
-			{
-				GUIElement* element;
-				GUILayout* layout;
-				GUIFixedSpace* space;
-				GUIFlexibleSpace* flexibleSpace;
-			};
-
-			bool isElement() const { return mType == Type::Element; }
-			bool isLayout() const { return mType == Type::Layout; }
-			bool isFixedSpace() const { return mType == Type::FixedSpace; }
-			bool isFlexibleSpace() const { return mType == Type::FlexibleSpace; }
-
-			void setElement(GUIElement* _element)
-			{
-				element = _element;
-				mType = Type::Element;
-			}
-
-			void setLayout(GUILayout* _layout)
-			{
-				layout = _layout;
-				mType = Type::Layout;
-			}
-
-			void setSpace(GUIFixedSpace* _space)
-			{
-				space = _space;
-				mType = Type::FixedSpace;
-			}
-
-			void setFlexibleSpace(GUIFlexibleSpace* _space)
-			{
-				flexibleSpace = _space;
-				mType = Type::FlexibleSpace;
-			}
-
-			Type mType;
-		};
-
 	public:
 	public:
 		GUILayout();
 		GUILayout();
 		virtual ~GUILayout();
 		virtual ~GUILayout();
@@ -80,30 +31,16 @@ namespace BansheeEngine
 		GUIFlexibleSpace& insertFlexibleSpace(CM::UINT32 idx);
 		GUIFlexibleSpace& insertFlexibleSpace(CM::UINT32 idx);
 
 
 		/**
 		/**
-		 * @brief	Returns a combined number of child elements and layouts.
+		 * @brief	Returns a number of all child elements
 		 */
 		 */
 		CM::UINT32 getNumChildren() const;
 		CM::UINT32 getNumChildren() const;
 
 
-		/**
-		 * @brief	Re-arranges the elements to fit the layout. (Internal use only)
-		 */
-		void _update(CM::UINT32 x, CM::UINT32 y, CM::UINT32 width, CM::UINT32 height, CM::UINT8 widgetDepth, CM::UINT16 areaDepth);
-
 		CM::UINT32 _getOptimalWidth() const { return mOptimalWidth; }
 		CM::UINT32 _getOptimalWidth() const { return mOptimalWidth; }
 		CM::UINT32 _getOptimalHeight() const { return mOptimalHeight; }
 		CM::UINT32 _getOptimalHeight() const { return mOptimalHeight; }
 
 
-		void _markAsDirty() { mIsDirty = true; }
-		bool _isDirty();
-
-		virtual void _updateOptimalSizes() = 0;
 	protected:
 	protected:
-		CM::Vector<GUILayoutEntry>::type mChildren;	
 		CM::Vector<CM::Int2>::type mOptimalSizes;
 		CM::Vector<CM::Int2>::type mOptimalSizes;
 		CM::UINT32 mOptimalWidth;
 		CM::UINT32 mOptimalWidth;
 		CM::UINT32 mOptimalHeight;
 		CM::UINT32 mOptimalHeight;
-
-		bool mIsDirty;
-
-		virtual void updateInternal(CM::UINT32 x, CM::UINT32 y, CM::UINT32 width, CM::UINT32 height, CM::UINT8 widgetDepth, CM::UINT16 areaDepth) = 0;
 	};
 	};
 }
 }

+ 2 - 2
BansheeEngine/Include/BsGUILayoutX.h

@@ -11,8 +11,8 @@ namespace BansheeEngine
 		GUILayoutX() {};
 		GUILayoutX() {};
 		~GUILayoutX() {};
 		~GUILayoutX() {};
 
 
-		void _updateOptimalSizes();
+		void _updateOptimalLayoutSizes();
 	protected:
 	protected:
-		void updateInternal(CM::UINT32 x, CM::UINT32 y, CM::UINT32 width, CM::UINT32 height, CM::UINT8 widgetDepth, CM::UINT16 areaDepth);
+		void _updateLayoutInternal(CM::UINT32 x, CM::UINT32 y, CM::UINT32 width, CM::UINT32 height, CM::UINT8 widgetDepth, CM::UINT16 areaDepth);
 	};
 	};
 }
 }

+ 2 - 2
BansheeEngine/Include/BsGUILayoutY.h

@@ -11,8 +11,8 @@ namespace BansheeEngine
 		GUILayoutY() {};
 		GUILayoutY() {};
 		~GUILayoutY() {};
 		~GUILayoutY() {};
 
 
-		void _updateOptimalSizes();
+		void _updateOptimalLayoutSizes();
 	protected:
 	protected:
-		void updateInternal(CM::UINT32 x, CM::UINT32 y, CM::UINT32 width, CM::UINT32 height, CM::UINT8 widgetDepth, CM::UINT16 areaDepth);
+		void _updateLayoutInternal(CM::UINT32 x, CM::UINT32 y, CM::UINT32 width, CM::UINT32 height, CM::UINT8 widgetDepth, CM::UINT16 areaDepth);
 	};
 	};
 }
 }

+ 2 - 2
BansheeEngine/Source/BsGUIArea.cpp

@@ -54,7 +54,7 @@ namespace BansheeEngine
 	{
 	{
 		if(isDirty())
 		if(isDirty())
 		{
 		{
-			mLayout->_update(mX, mY, mWidth, mHeight, mWidget.getDepth(), mDepth);
+			mLayout->_updateLayout(mX, mY, mWidth, mHeight, mWidget.getDepth(), mDepth);
 			mIsDirty = false;
 			mIsDirty = false;
 		}
 		}
 	}
 	}
@@ -64,7 +64,7 @@ namespace BansheeEngine
 		if(mIsDirty)
 		if(mIsDirty)
 			return true;
 			return true;
 
 
-		return mLayout->_isDirty();
+		return mLayout->_isContentDirty();
 	}
 	}
 
 
 	void GUIArea::notifyWindowResized(UINT32 newWidth, UINT32 newHeight)
 	void GUIArea::notifyWindowResized(UINT32 newWidth, UINT32 newHeight)

+ 1 - 27
BansheeEngine/Source/BsGUIElement.cpp

@@ -9,7 +9,7 @@ using namespace CamelotFramework;
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	GUIElement::GUIElement(GUIWidget& parent, const GUIElementStyle* style, const GUILayoutOptions& layoutOptions, bool acceptsKeyboardFocus)
 	GUIElement::GUIElement(GUIWidget& parent, const GUIElementStyle* style, const GUILayoutOptions& layoutOptions, bool acceptsKeyboardFocus)
-		:mParent(parent), mIsDirty(true), mParentLayout(nullptr), mLayoutOptions(layoutOptions), mWidth(0), mHeight(0), mDepth(0), mStyle(style),
+		:mParent(parent), mLayoutOptions(layoutOptions), mWidth(0), mHeight(0), mDepth(0), mStyle(style),
 		mAcceptsKeyboardFocus(acceptsKeyboardFocus)
 		mAcceptsKeyboardFocus(acceptsKeyboardFocus)
 	{
 	{
 		mParent.registerElement(this);
 		mParent.registerElement(this);
@@ -137,32 +137,6 @@ namespace BansheeEngine
 		return contentBounds.contains(position);
 		return contentBounds.contains(position);
 	}
 	}
 
 
-	bool GUIElement::_isContentDirty() const
-	{
-		return (mIsDirty & 0x01) != 0;
-	}
-
-	bool GUIElement::_isMeshDirty() const
-	{
-		return (mIsDirty & 0x02) != 0;
-	}
-
-	void GUIElement::markContentAsDirty() 
-	{ 
-		if(!_isContentDirty())
-		{
-			if(mParentLayout != nullptr)
-				mParentLayout->_markAsDirty();
-
-			mIsDirty |= 0x01; 
-		}
-	}
-
-	void GUIElement::markMeshAsDirty()
-	{
-		mIsDirty |= 0x02;
-	}
-
 	GUILayoutOptions GUIElement::getDefaultLayoutOptions(const GUIElementStyle* style)
 	GUILayoutOptions GUIElement::getDefaultLayoutOptions(const GUIElementStyle* style)
 	{
 	{
 		GUILayoutOptions layoutOptions;
 		GUILayoutOptions layoutOptions;

+ 75 - 0
BansheeEngine/Source/BsGUIElementBase.cpp

@@ -0,0 +1,75 @@
+#include "BsGUIElementBase.h"
+#include "BsGUILayout.h"
+
+using namespace CamelotFramework;
+
+namespace BansheeEngine
+{
+	GUIElementBase::GUIElementBase()
+		:mIsDirty(true), mParentLayout(nullptr)
+	{
+
+	}
+
+	bool GUIElementBase::_isContentDirty() const
+	{
+		if((mIsDirty & 0x01) != 0)
+			return true;
+
+		for(auto& child : mChildren)
+		{
+			if(child.isLayout())
+			{
+				if(child.layout->_isContentDirty())
+					return true;
+			}
+		}
+
+		return false;
+	}
+
+	bool GUIElementBase::_isMeshDirty() const
+	{
+		return (mIsDirty & 0x02) != 0;
+	}
+
+	void GUIElementBase::markContentAsDirty() 
+	{ 
+		if(!_isContentDirty())
+		{
+			if(mParentLayout != nullptr)
+				mParentLayout->markContentAsDirty();
+
+			mIsDirty |= 0x01; 
+		}
+	}
+
+	void GUIElementBase::markMeshAsDirty()
+	{
+		mIsDirty |= 0x02;
+	}
+
+	void GUIElementBase::_updateLayout(UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT8 widgetDepth, UINT16 areaDepth)
+	{
+		_updateOptimalLayoutSizes(); // We calculate optimal sizes of all layouts as a pre-processing step, as they are requested often during update
+		_updateLayoutInternal(x, y, width, height, widgetDepth, areaDepth);
+	}
+
+	void GUIElementBase::_updateOptimalLayoutSizes()
+	{
+		for(auto& child : mChildren)
+		{
+			if(child.isLayout())
+				child.layout->_updateOptimalLayoutSizes();
+		}
+	}
+
+	void GUIElementBase::_updateLayoutInternal(CM::UINT32 x, CM::UINT32 y, CM::UINT32 width, CM::UINT32 height, CM::UINT8 widgetDepth, CM::UINT16 areaDepth)
+	{
+		for(auto& child : mChildren)
+		{
+			if(child.isLayout())
+				child.layout->_updateLayout(x, y, width, height, widgetDepth, areaDepth);
+		}
+	}
+}

+ 18 - 39
BansheeEngine/Source/BsGUILayout.cpp

@@ -10,7 +10,7 @@ using namespace CamelotFramework;
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	GUILayout::GUILayout()
 	GUILayout::GUILayout()
-		:mIsDirty(false), mOptimalWidth(0), mOptimalHeight(0)
+		:mOptimalWidth(0), mOptimalHeight(0)
 	{
 	{
 
 
 	}
 	}
@@ -49,7 +49,8 @@ namespace BansheeEngine
 
 
 		element->_setParentLayout(this);
 		element->_setParentLayout(this);
 		mChildren.push_back(entry);
 		mChildren.push_back(entry);
-		mIsDirty = true;
+
+		markContentAsDirty();
 	}
 	}
 
 
 	void GUILayout::removeElement(GUIElement* element)
 	void GUILayout::removeElement(GUIElement* element)
@@ -63,7 +64,8 @@ namespace BansheeEngine
 			{
 			{
 				mChildren.erase(iter);
 				mChildren.erase(iter);
 				foundElem = true;
 				foundElem = true;
-				mIsDirty = true;
+				
+				markContentAsDirty();
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -85,7 +87,8 @@ namespace BansheeEngine
 
 
 		element->_setParentLayout(this);
 		element->_setParentLayout(this);
 		mChildren.insert(mChildren.begin() + idx, entry);
 		mChildren.insert(mChildren.begin() + idx, entry);
-		mIsDirty = true;
+		
+		markContentAsDirty();
 	}
 	}
 
 
 	GUILayout& GUILayout::addLayoutX()
 	GUILayout& GUILayout::addLayoutX()
@@ -94,7 +97,7 @@ namespace BansheeEngine
 		entry.setLayout(cm_new<GUILayoutX, PoolAlloc>());
 		entry.setLayout(cm_new<GUILayoutX, PoolAlloc>());
 
 
 		mChildren.push_back(entry);
 		mChildren.push_back(entry);
-		mIsDirty = true;
+		markContentAsDirty();
 
 
 		return *entry.layout;
 		return *entry.layout;
 	}
 	}
@@ -105,7 +108,7 @@ namespace BansheeEngine
 		entry.setLayout(cm_new<GUILayoutY, PoolAlloc>());
 		entry.setLayout(cm_new<GUILayoutY, PoolAlloc>());
 
 
 		mChildren.push_back(entry);
 		mChildren.push_back(entry);
-		mIsDirty = true;
+		markContentAsDirty();
 
 
 		return *entry.layout;
 		return *entry.layout;
 	}
 	}
@@ -123,7 +126,7 @@ namespace BansheeEngine
 
 
 				mChildren.erase(iter);
 				mChildren.erase(iter);
 				foundElem = true;
 				foundElem = true;
-				mIsDirty = true;
+				markContentAsDirty();
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -141,7 +144,7 @@ namespace BansheeEngine
 		entry.setLayout(cm_new<GUILayoutX, PoolAlloc>());
 		entry.setLayout(cm_new<GUILayoutX, PoolAlloc>());
 
 
 		mChildren.insert(mChildren.begin() + idx, entry);
 		mChildren.insert(mChildren.begin() + idx, entry);
-		mIsDirty = true;
+		markContentAsDirty();
 
 
 		return *entry.layout;
 		return *entry.layout;
 	}
 	}
@@ -155,7 +158,7 @@ namespace BansheeEngine
 		entry.setLayout(cm_new<GUILayoutY, PoolAlloc>());;
 		entry.setLayout(cm_new<GUILayoutY, PoolAlloc>());;
 
 
 		mChildren.insert(mChildren.begin() + idx, entry);
 		mChildren.insert(mChildren.begin() + idx, entry);
-		mIsDirty = true;
+		markContentAsDirty();
 
 
 		return *entry.layout;
 		return *entry.layout;
 	}
 	}
@@ -166,7 +169,7 @@ namespace BansheeEngine
 		entry.setSpace(cm_new<GUIFixedSpace, PoolAlloc>(size));
 		entry.setSpace(cm_new<GUIFixedSpace, PoolAlloc>(size));
 
 
 		mChildren.push_back(entry);
 		mChildren.push_back(entry);
-		mIsDirty = true;
+		markContentAsDirty();
 
 
 		return *entry.space;
 		return *entry.space;
 	}
 	}
@@ -184,7 +187,7 @@ namespace BansheeEngine
 
 
 				mChildren.erase(iter);
 				mChildren.erase(iter);
 				foundElem = true;
 				foundElem = true;
-				mIsDirty = true;
+				markContentAsDirty();
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -202,7 +205,7 @@ namespace BansheeEngine
 		entry.setSpace(cm_new<GUIFixedSpace, PoolAlloc>(size));
 		entry.setSpace(cm_new<GUIFixedSpace, PoolAlloc>(size));
 
 
 		mChildren.insert(mChildren.begin() + idx, entry);
 		mChildren.insert(mChildren.begin() + idx, entry);
-		mIsDirty = true;
+		markContentAsDirty();
 
 
 		return *entry.space;
 		return *entry.space;
 	}
 	}
@@ -213,7 +216,7 @@ namespace BansheeEngine
 		entry.setFlexibleSpace(cm_new<GUIFlexibleSpace, PoolAlloc>());
 		entry.setFlexibleSpace(cm_new<GUIFlexibleSpace, PoolAlloc>());
 
 
 		mChildren.push_back(entry);
 		mChildren.push_back(entry);
-		mIsDirty = true;
+		markContentAsDirty();
 
 
 		return *entry.flexibleSpace;
 		return *entry.flexibleSpace;
 	}
 	}
@@ -231,7 +234,7 @@ namespace BansheeEngine
 
 
 				mChildren.erase(iter);
 				mChildren.erase(iter);
 				foundElem = true;
 				foundElem = true;
-				mIsDirty = true;
+				markContentAsDirty();
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -249,7 +252,7 @@ namespace BansheeEngine
 		entry.setFlexibleSpace(cm_new<GUIFlexibleSpace, PoolAlloc>());
 		entry.setFlexibleSpace(cm_new<GUIFlexibleSpace, PoolAlloc>());
 
 
 		mChildren.insert(mChildren.begin() + idx, entry);
 		mChildren.insert(mChildren.begin() + idx, entry);
-		mIsDirty = true;
+		markContentAsDirty();
 
 
 		return *entry.flexibleSpace;
 		return *entry.flexibleSpace;
 	}
 	}
@@ -258,28 +261,4 @@ namespace BansheeEngine
 	{
 	{
 		return (UINT32)mChildren.size();
 		return (UINT32)mChildren.size();
 	}
 	}
-
-	void GUILayout::_update(UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT8 widgetDepth, UINT16 areaDepth)
-	{
-		_updateOptimalSizes(); // We calculate optimal sizes of all layouts as a pre-processing step, as they are requested often during update
-		updateInternal(x, y, width, height, widgetDepth, areaDepth);
-		mIsDirty = false;
-	}
-
-	bool GUILayout::_isDirty()
-	{
-		if(mIsDirty)
-			return true;
-
-		for(auto& child : mChildren)
-		{
-			if(child.isLayout())
-			{
-				if(child.layout->_isDirty())
-					return true;
-			}
-		}
-
-		return false;
-	}
 }
 }

+ 4 - 4
BansheeEngine/Source/BsGUILayoutX.cpp

@@ -8,13 +8,13 @@ using namespace CamelotFramework;
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	void GUILayoutX::_updateOptimalSizes()
+	void GUILayoutX::_updateOptimalLayoutSizes()
 	{
 	{
 		// Update all children first, otherwise we can't determine out own optimal size
 		// Update all children first, otherwise we can't determine out own optimal size
 		for(auto& child : mChildren)
 		for(auto& child : mChildren)
 		{
 		{
 			if(child.isLayout())
 			if(child.isLayout())
-				child.layout->_updateOptimalSizes();
+				child.layout->_updateOptimalLayoutSizes();
 		}
 		}
 
 
 		if(mChildren.size() != mOptimalSizes.size())
 		if(mChildren.size() != mOptimalSizes.size())
@@ -80,7 +80,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void GUILayoutX::updateInternal(UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT8 widgetDepth, UINT16 areaDepth)
+	void GUILayoutX::_updateLayoutInternal(UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT8 widgetDepth, UINT16 areaDepth)
 	{
 	{
 		UINT32 totalOptimalSize = _getOptimalWidth();
 		UINT32 totalOptimalSize = _getOptimalWidth();
 		UINT32 totalNonClampedSize = 0;
 		UINT32 totalNonClampedSize = 0;
@@ -362,7 +362,7 @@ namespace BansheeEngine
 			}
 			}
 			else if(child.isLayout())
 			else if(child.isLayout())
 			{
 			{
-				child.layout->_update(x + xOffset, y, elementWidth, height, widgetDepth, areaDepth);
+				child.layout->_updateLayout(x + xOffset, y, elementWidth, height, widgetDepth, areaDepth);
 			}
 			}
 
 
 			xOffset += elementWidth;
 			xOffset += elementWidth;

+ 4 - 4
BansheeEngine/Source/BsGUILayoutY.cpp

@@ -8,13 +8,13 @@ using namespace CamelotFramework;
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	void GUILayoutY::_updateOptimalSizes()
+	void GUILayoutY::_updateOptimalLayoutSizes()
 	{
 	{
 		// Update all children first, otherwise we can't determine out own optimal size
 		// Update all children first, otherwise we can't determine out own optimal size
 		for(auto& child : mChildren)
 		for(auto& child : mChildren)
 		{
 		{
 			if(child.isLayout())
 			if(child.isLayout())
-				child.layout->_updateOptimalSizes();
+				child.layout->_updateOptimalLayoutSizes();
 		}
 		}
 
 
 		if(mChildren.size() != mOptimalSizes.size())
 		if(mChildren.size() != mOptimalSizes.size())
@@ -80,7 +80,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void GUILayoutY::updateInternal(UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT8 widgetDepth, UINT16 areaDepth)
+	void GUILayoutY::_updateLayoutInternal(UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT8 widgetDepth, UINT16 areaDepth)
 	{
 	{
 		UINT32 totalOptimalSize = _getOptimalHeight();
 		UINT32 totalOptimalSize = _getOptimalHeight();
 		UINT32 totalNonClampedSize = 0;
 		UINT32 totalNonClampedSize = 0;
@@ -361,7 +361,7 @@ namespace BansheeEngine
 			}
 			}
 			else if(child.isLayout())
 			else if(child.isLayout())
 			{
 			{
-				child.layout->_update(x, y + yOffset, width, elementHeight, widgetDepth, areaDepth);
+				child.layout->_updateLayout(x, y + yOffset, width, elementHeight, widgetDepth, areaDepth);
 			}
 			}
 
 
 			yOffset += elementHeight;
 			yOffset += elementHeight;

+ 1 - 7
TODO.txt

@@ -12,6 +12,7 @@ I call waitUntilLoaded too many times. Sometimes 5-6 times in a single function.
 GUIWidget::updateMeshes leaks. If I leave the game running I can see memory continously going up
 GUIWidget::updateMeshes leaks. If I leave the game running I can see memory continously going up
  - Resizing from the top doesn't work
  - Resizing from the top doesn't work
  - Resizing from the left actually resizes the right side
  - Resizing from the left actually resizes the right side
+ - Clipping areas outside of a widget (or GUIArea for that matter) are not set up at all
 
 
 IMMEDIATE:
 IMMEDIATE:
  - Clicking on a window to focus and immediately trying to drag/resize it, doesn't work. I first need to click, then click again to drag/resize.
  - Clicking on a window to focus and immediately trying to drag/resize it, doesn't work. I first need to click, then click again to drag/resize.
@@ -29,9 +30,6 @@ TextBox needed elements:
   - Add special text input commands, which will get repeatedly sent as long as their corresponding key is set in GUIManager
   - Add special text input commands, which will get repeatedly sent as long as their corresponding key is set in GUIManager
  - Get DebugCamera to ignore input if GUI has already processed it
  - Get DebugCamera to ignore input if GUI has already processed it
  - Cut/Copy/Paste
  - Cut/Copy/Paste
- - All classes dealing with text (Button, Toggle, Label, InputBox) determine text field size based on mBounds which is calculated from 
-    clipped mImageSprite coordinates. Which is wrong because text word wrap will change depending how clipped the sprite is.
-
 
 
  - LATER
  - LATER
   - TAB between input elements
   - TAB between input elements
@@ -50,10 +48,6 @@ Later add InputMap class in which you can bind certain actions (like move left,
 
 
 -----------
 -----------
 
 
-I need to be able to provide smaller bounds used for UI input 
- - Add padding - reduces the size of the element and that is used for input
- - Add margins - spacing that is added when laying out multiple controls after each other
-
  - My test model is rendering back faces. I need to flip them.
  - My test model is rendering back faces. I need to flip them.
   - Although more than likely I am loading the model incorrectly since it works in Unity?
   - Although more than likely I am loading the model incorrectly since it works in Unity?
   - I probably want to determine front faces based on normals
   - I probably want to determine front faces based on normals