Browse Source

GUIPanelContainer works with clipping
Fixed a cleanup issue with a managed GUILayout created by ScrollArea

Marko Pintera 11 years ago
parent
commit
5501d158b7

+ 15 - 0
BansheeEngine/Include/BsGUIArea.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include "BsPrerequisites.h"
+#include "BsRectI.h"
 
 namespace BansheeEngine
 {
@@ -130,6 +131,19 @@ namespace BansheeEngine
 		 */
 		void setSize(UINT32 width, UINT32 height);
 
+		/**
+		 * @brief	Sets a rectangle that will be used for clipping of the area contents.
+		 *
+		 * @param	clipRect	Rectangle in coordinates relative to the area. If width or height
+		 *						is zero, no clipping will be done.
+		 */
+		void setClipRect(const RectI& clipRect);
+
+		/**
+		 * @brief	Gets a rectangle that is used for clipping of the area contents.
+		 */
+		RectI getClipRect() const { return mClipRect; }
+
 		/**
 		 * @brief	Hides the area and any child elements.
 		 */
@@ -204,6 +218,7 @@ namespace BansheeEngine
 		INT32 mLeft, mRight, mTop, mBottom;
 		UINT32 mWidth, mHeight;
 		UINT16 mDepth;
+		RectI mClipRect;
 		bool mResizeXWithWidget;
 		bool mResizeYWithWidget;
 		bool mIsDirty;

+ 14 - 0
BansheeEngine/Source/BsGUIArea.cpp

@@ -130,6 +130,13 @@ namespace BansheeEngine
 		if(!mIsDisabled && isDirty() && (mWidget != nullptr))
 		{
 			RectI clipRect(mLeft, mTop, mWidth, mHeight);
+			if (mClipRect.width > 0 && mClipRect.height > 0)
+			{
+				RectI newClipRect = RectI(mLeft + mClipRect.x, mTop + mClipRect.y, mClipRect.width, mClipRect.height);
+				newClipRect.clip(clipRect);
+				clipRect = newClipRect;
+			}
+
 			mLayout->_updateLayout(mLeft, mTop, mWidth, mHeight, clipRect, mWidget->getDepth(), mDepth);
 			mIsDirty = false;
 		}
@@ -159,6 +166,13 @@ namespace BansheeEngine
 		mIsDirty = true;
 	}
 
+	void GUIArea::setClipRect(const RectI& clipRect)
+	{
+		mClipRect = clipRect;
+
+		mIsDirty = true;
+	}
+
 	void GUIArea::updateSizeBasedOnParent(UINT32 parentWidth, UINT32 parentHeight)
 	{
 		if(mResizeXWithWidget)

+ 1 - 1
BansheeEngine/Source/BsGUIScrollArea.cpp

@@ -105,7 +105,7 @@ namespace BansheeEngine
 			if (mHorzBarType == ScrollBarType::NeverShow)
 				maxedContentLayoutWidth = mClippedContentWidth;
 			else
-				maxedContentLayoutWidth = std::max(contentLayoutWidth, maxedContentLayoutWidth); // Never go below optimal size
+				maxedContentLayoutWidth = std::max(contentLayoutWidth, mClippedContentWidth); // Never go below optimal size
 
 			if(hasHorzScrollbar)
 			{

+ 4 - 0
SBansheeEditor/Source/BsGUIPanelContainer.cpp

@@ -43,6 +43,10 @@ namespace BansheeEngine
 			if (area->width() != width || area->height() != height)
 				area->setSize(width, height);
 
+			RectI areaClipRect(clipRect.x - x, clipRect.y - y, clipRect.width, clipRect.height);
+			if (area->getClipRect() != areaClipRect)
+				area->setClipRect(areaClipRect);
+
 			// We want to force the layout update right away otherwise it might get delayed until next frame.
 			// (Since we are currently in a middle of a layout update its possible this area was already processed)
 			area->_update();

+ 1 - 1
SBansheeEngine/Source/BsScriptGUILayout.cpp

@@ -100,7 +100,7 @@ namespace BansheeEngine
 		GUILayout* nativeLayout = &scrollArea->getLayout();
 
 		ScriptGUILayout* nativeInstance = new (bs_alloc<ScriptGUILayout>()) 
-			ScriptGUILayout(instance, nativeLayout, nativeLayout);
+			ScriptGUILayout(instance, nativeLayout, nullptr);
 	}
 
 	void ScriptGUILayout::internal_addElement(ScriptGUILayout* instance, ScriptGUIElementTBase* element)