Browse Source

GUIArea now works using offsets so it can resized with window automatically, but still have some padding

Marko Pintera 12 năm trước cách đây
mục cha
commit
c275f0324a

+ 38 - 8
BansheeEngine/Include/BsGUIArea.h

@@ -12,11 +12,39 @@ namespace BansheeEngine
 		/**
 		 * @brief	Sets up a new GUI area. All the layouts used in the area will be placed
 		 * 			within the specified bounds.
-		 * 			
-		 *			If you want the area to expand vertically or horizontally, together with its parent
-		 *			widget, set height or width to 0, respectively.
 		 */
 		static GUIArea* create(GUIWidget& widget, CM::UINT32 x, CM::UINT32 y, CM::UINT32 width = 0, CM::UINT32 height = 0, CM::UINT16 depth = 0);
+
+		/**
+		 * @brief	Sets up a new GUI area. All the layouts used in the area will be placed
+		 * 			within the specified bounds.
+		 * 			
+		 *			This kind of GUI area will always stretch to completely fill the parent widget, while respecting the
+		 *			provided offsets. 
+		 */
+		static GUIArea* createStretchedXY(GUIWidget& widget, CM::UINT32 offsetLeft, 
+			CM::UINT32 offsetRight, CM::UINT32 offsetTop, CM::UINT32 offsetBottom, CM::UINT16 depth = 0);
+
+		/**
+		 * @brief	Sets up a new GUI area. All the layouts used in the area will be placed
+		 * 			within the specified bounds.
+		 * 			
+		 *			This kind of GUI area will always stretch in X dimension to completely fill the parent widget, while respecting the
+		 *			provided offsets. 
+		 */
+		static GUIArea* createStretchedX(GUIWidget& widget, CM::UINT32 offsetLeft, 
+			CM::UINT32 offsetRight, CM::UINT32 offsetTop, CM::UINT32 height, CM::UINT16 depth = 0);
+
+		/**
+		 * @brief	Sets up a new GUI area. All the layouts used in the area will be placed
+		 * 			within the specified bounds.
+		 * 			
+		 *			This kind of GUI area will always stretch in Y dimension to completely fill the parent widget, while respecting the
+		 *			provided offsets. 
+		 */
+		static GUIArea* createStretchedY(GUIWidget& widget, CM::UINT32 offsetTop, 
+			CM::UINT32 offsetBottom, CM::UINT32 offsetLeft, CM::UINT32 width, CM::UINT16 depth = 0);
+
 		static void destroy(GUIArea* area);
 
 		GUILayout& getLayout() const { return *mLayout; }
@@ -24,8 +52,8 @@ namespace BansheeEngine
 		CM::UINT16 getDepth() const { return mDepth; }
 		void setDepth(CM::UINT16 depth) { mDepth = depth; }
 
-		CM::UINT32 x() const { return mX; }
-		CM::UINT32 y() const { return mY; }
+		CM::UINT32 x() const { return mLeft; }
+		CM::UINT32 y() const { return mTop; }
 		CM::UINT32 width() const { return mWidth; }
 		CM::UINT32 height() const { return mHeight; }
 
@@ -34,14 +62,16 @@ namespace BansheeEngine
 		friend class GUIWidget;
 
 		GUIWidget& mWidget;
-		CM::UINT32 mX, mY, mWidth, mHeight;
+		CM::INT32 mLeft, mRight, mTop, mBottom;
+		CM::UINT32 mWidth, mHeight;
 		CM::UINT16 mDepth;
-		bool mResizeWidthWithWindow, mResizeHeightWithWindow;
+		bool mResizeXWithWidget;
+		bool mResizeYWithWidget;
 		bool mIsDirty;
 
 		GUILayout* mLayout;
 
-		GUIArea(GUIWidget& widget, CM::UINT32 x, CM::UINT32 y, CM::UINT32 width, CM::UINT32 height, CM::UINT16 depth);
+		GUIArea(GUIWidget& widget, CM::UINT32 x, CM::UINT32 y, CM::UINT16 depth);
 
 		bool isDirty() const;
 

+ 57 - 24
BansheeEngine/Source/BsGUIArea.cpp

@@ -7,24 +7,12 @@ using namespace CamelotFramework;
 
 namespace BansheeEngine
 {
-	GUIArea::GUIArea(GUIWidget& widget, UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT16 depth)
-		:mWidget(widget), mX(x), mY(y), mWidth(width), mHeight(height), mDepth(depth), mIsDirty(true), 
-		mResizeHeightWithWindow(false), mResizeWidthWithWindow(false)
+	GUIArea::GUIArea(GUIWidget& widget, UINT32 x, UINT32 y, UINT16 depth)
+		:mWidget(widget), mLeft(x), mTop(y), mDepth(depth), mIsDirty(true), 
+		mResizeXWithWidget(false), mResizeYWithWidget(false), mWidth(0), mHeight(0), mRight(0), mBottom(0)
 	{
 		mLayout = cm_new<GUILayoutX, PoolAlloc>();
 
-		if(width <= 0)
-		{
-			mWidth = mWidget.getTarget()->getWidth() - mX;
-			mResizeWidthWithWindow = true;
-		}
-
-		if(height <= 0)
-		{
-			mHeight = mWidget.getTarget()->getHeight() - mY;
-			mResizeHeightWithWindow = true;
-		}
-
 		mWidget.registerArea(this);
 	}
 
@@ -35,7 +23,54 @@ namespace BansheeEngine
 
 	GUIArea* GUIArea::create(GUIWidget& widget, UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT16 depth)
 	{
-		return new (cm_alloc<GUIArea, PoolAlloc>()) GUIArea(widget, x, y, width, height, depth);
+		GUIArea* area = new (cm_alloc<GUIArea, PoolAlloc>()) GUIArea(widget, x, y, depth);
+		area->mWidth = width;
+		area->mHeight = height;
+
+		return area;
+	}
+
+	GUIArea* GUIArea::createStretchedXY(GUIWidget& widget, UINT32 offsetLeft, 
+		UINT32 offsetRight, UINT32 offsetTop, UINT32 offsetBottom, UINT16 depth)
+	{
+		GUIArea* area = new (cm_alloc<GUIArea, PoolAlloc>()) GUIArea(widget, offsetLeft, offsetTop, depth);
+
+		area->mWidth = std::max(0, (INT32)widget.getTarget()->getWidth() - (INT32)offsetLeft - (INT32)offsetRight);
+		area->mHeight = std::max(0, (INT32)widget.getTarget()->getHeight() - (INT32)offsetTop - (INT32)offsetBottom);
+		area->mRight = offsetRight;
+		area->mBottom = offsetBottom;
+		area->mResizeXWithWidget = true;
+		area->mResizeYWithWidget = true;
+
+		return area;
+	}
+
+	GUIArea* GUIArea::createStretchedX(GUIWidget& widget, CM::UINT32 offsetLeft, 
+		CM::UINT32 offsetRight, CM::UINT32 offsetTop, CM::UINT32 height, CM::UINT16 depth)
+	{
+		GUIArea* area = new (cm_alloc<GUIArea, PoolAlloc>()) GUIArea(widget, offsetLeft, offsetTop, depth);
+
+		area->mWidth = std::max(0, (INT32)widget.getTarget()->getWidth() - (INT32)offsetLeft - (INT32)offsetRight);
+		area->mHeight = height;
+		area->mRight = offsetRight;
+		area->mResizeXWithWidget = true;
+		area->mResizeYWithWidget = false;
+
+		return area;
+	}
+
+	GUIArea* GUIArea::createStretchedY(GUIWidget& widget, CM::UINT32 offsetTop, 
+		CM::UINT32 offsetBottom, CM::UINT32 offsetLeft, CM::UINT32 width, CM::UINT16 depth)
+	{
+		GUIArea* area = new (cm_alloc<GUIArea, PoolAlloc>()) GUIArea(widget, offsetLeft, offsetTop, depth);
+
+		area->mWidth = width;
+		area->mHeight = std::max(0, (INT32)widget.getTarget()->getHeight() - (INT32)offsetTop - (INT32)offsetBottom);
+		area->mBottom = offsetBottom;
+		area->mResizeXWithWidget = false;
+		area->mResizeYWithWidget = true;
+
+		return area;
 	}
 
 	void GUIArea::destroy(GUIArea* area)
@@ -54,7 +89,7 @@ namespace BansheeEngine
 	{
 		if(isDirty())
 		{
-			mLayout->_updateLayout(mX, mY, mWidth, mHeight, mWidget.getDepth(), mDepth);
+			mLayout->_updateLayout(mLeft, mTop, mWidth, mHeight, mWidget.getDepth(), mDepth);
 			mIsDirty = false;
 		}
 	}
@@ -69,15 +104,13 @@ namespace BansheeEngine
 
 	void GUIArea::notifyWindowResized(UINT32 newWidth, UINT32 newHeight)
 	{
-		if(mResizeWidthWithWindow)
-			mWidth = newWidth - mX;
+		if(mResizeXWithWidget)
+			mWidth = (UINT32)std::max(0, (INT32)newWidth - (INT32)mLeft - (INT32)mRight);
 
-		if(mResizeHeightWithWindow)
-			mHeight = newHeight - mY;
+		if(mResizeYWithWidget)
+			mHeight = (UINT32)std::max(0, (INT32)newHeight - (INT32)mTop - (INT32)mBottom);
 
-		if(mResizeWidthWithWindow || mResizeHeightWithWindow)
-		{
+		if(mResizeXWithWidget || mResizeYWithWidget)
 			mIsDirty = true;
-		}
 	}
 }

+ 2 - 2
CamelotClient/BsGUITabbedTitleBar.cpp

@@ -62,13 +62,13 @@ namespace BansheeEditor
 	{
 		GUIWidget::initialize(target, ownerWindow);
 
-		GUIArea* backgroundArea = GUIArea::create(*this, 0, 1, 0, 13, 500);
+		GUIArea* backgroundArea = GUIArea::createStretchedX(*this, 0, 0, 1, 13, 500);
 		GUIWindowMover* titleBarBg = GUIWindowMover::create(*this, getSkin()->getStyle("TitleBarBackground"));
 		backgroundArea->getLayout().addSpace(1);
 		backgroundArea->getLayout().addElement(titleBarBg);
 		backgroundArea->getLayout().addSpace(1);
 
-		mMainArea = GUIArea::create(*this, 0, 1, 0, 13, 499);
+		mMainArea = GUIArea::createStretchedX(*this, 0, 0, 1, 13, 499);
 
 		GUIWindowMover* dragDropElement = GUIWindowMover::create(*this, GUILayoutOptions::expandableX(13, 20), getSkin()->getStyle("TabbedBarDropArea"));
 		mLastDropElement = dragDropElement;

+ 2 - 2
CamelotClient/BsGUIWindowFrameWidget.cpp

@@ -28,10 +28,10 @@ namespace BansheeEditor
 	{
 		GUIWidget::initialize(target, ownerWindow);
 
-		GUIArea* backgroundArea = GUIArea::create(*this, 0, 0, 0, 0, 500);
+		GUIArea* backgroundArea = GUIArea::createStretchedXY(*this, 0, 0, 0, 0, 500);
 		backgroundArea->getLayout().addElement(GUITexture::create(*this, GUILayoutOptions::expandableXY(), GUIImageScaleMode::RepeatToFit, getSkin()->getStyle("WindowBackground")));
 
-		mWindowFrameArea = GUIArea::create(*this, 0, 0, 0, 0, 499);
+		mWindowFrameArea = GUIArea::createStretchedXY(*this, 0, 0, 0, 0, 499);
 
 		mWindowFrame = GUIWindowFrame::create(*this, getSkin()->getStyle("WindowFrame"));
 		mWindowFrameArea->getLayout().addElement(mWindowFrame);

+ 1 - 1
CamelotClient/CmEditorWindow.cpp

@@ -66,7 +66,7 @@ namespace BansheeEditor
 
 		//// DEBUG
 		
-		GUIArea* dbgArea = GUIArea::create(*mGUI, 5, 14, 190, 0, 475);
+		GUIArea* dbgArea = GUIArea::createStretchedXY(*mGUI, 5, 5, 14, 2, 475);
 		GUILayout& layout = dbgArea->getLayout();
 		//
 		//mDbgLabel = GUILabel::create(*mGUI, "Testing test");

+ 7 - 0
TODO.txt

@@ -25,6 +25,13 @@ IMMEDIATE:
     - Make sure GUI system uses a dummy texture if one isn't available
 	- SpriteTexture keeps a static reference to DUmmyTexture which I need to release before shutdown
 
+- Hover colors of the scroll bar are wrong
+- GUIArea needs a margin, so it can still be resized with window but always with an offset
+- Scroll bar background
+- Add horizontal scrollbar
+- Resizable scroll handle (Special element)
+  - Maybe a slider element I can re-use?
+
 TextBox needed elements:
  - Key-repeat? Pressing left/right/up/down arrows doesn't repeat the keys (also delete/backspace)
   - Add special text input commands, which will get repeatedly sent as long as their corresponding key is set in GUIManager