Ver código fonte

Refactored GUITabbedTitleBar so it is a GUIElement

Marko Pintera 12 anos atrás
pai
commit
7bfb833d68

+ 0 - 5
BansheeEngine/Include/BsGUIScrollArea.h

@@ -57,11 +57,6 @@ namespace BansheeEngine
 		virtual void fillBuffer(CM::UINT8* vertices, CM::UINT8* uv, CM::UINT32* indices, CM::UINT32 startingQuad, 
 			CM::UINT32 maxNumQuads, CM::UINT32 vertexStride, CM::UINT32 indexStride, CM::UINT32 renderElementIdx) const;
 
-		/**
-		 * @copydoc GUIElement::updateRenderElementsInternal()
-		 */
-		virtual void updateRenderElementsInternal();
-
 		/**
 		 * @copydoc GUIElement::updateBounds()
 		 */

+ 2 - 2
BansheeEngine/Include/BsGUISkin.h

@@ -8,14 +8,14 @@ namespace BansheeEngine
 	class BS_EXPORT GUISkin
 	{
 	public:
+		static GUIElementStyle DefaultStyle;
+		
 		GUISkin() {}
 
 		const GUIElementStyle* getStyle(const CM::String& guiElemType) const;
 		void setStyle(const CM::String& guiElemType, const GUIElementStyle& style);
 
 	private:
-		static GUIElementStyle DefaultStyle;
-
 		CM::UnorderedMap<CM::String, GUIElementStyle>::type mStyles;
 
 		GUISkin(const GUISkin& skin) {} // Disable copying

+ 3 - 0
BansheeEngine/Source/BsGUIElement.cpp

@@ -191,6 +191,9 @@ namespace BansheeEngine
 
 	void GUIElement::destroy(GUIElement* element)
 	{
+		if(element->mIsDestroyed)
+			return;
+
 		if(element->mParent != nullptr)
 			element->mParent->unregisterElement(element);
 

+ 1 - 6
BansheeEngine/Source/BsGUIScrollArea.cpp

@@ -39,7 +39,7 @@ namespace BansheeEngine
 
 	const GUIMaterialInfo& GUIScrollArea::getMaterial(UINT32 renderElementIdx) const
 	{
-		CM_EXCEPT(InternalErrorException, "Trying to retrieve a material from an element with no render elements.");
+		CM_EXCEPT(InvalidStateException, "Trying to retrieve a material from an element with no render elements.");
 	}
 
 	UINT32 GUIScrollArea::getNumQuads(UINT32 renderElementIdx) const
@@ -47,11 +47,6 @@ namespace BansheeEngine
 		return 0;
 	}
 
-	void GUIScrollArea::updateRenderElementsInternal()
-	{
-		GUIElement::updateRenderElementsInternal();
-	}
-
 	void GUIScrollArea::updateClippedBounds()
 	{
 		mClippedBounds = RectI(0, 0, 0, 0); // We don't want any mouse input for this element. This is just a container.

+ 52 - 9
CamelotClient/Include/BsGUITabbedTitleBar.h

@@ -1,28 +1,66 @@
 #pragma once
 
 #include "BsEditorPrerequisites.h"
+#include "BsGUIElement.h"
 #include "CmRectI.h"
 #include <boost/signal.hpp>
 
 namespace BansheeEditor
 {
-	class GUITabbedTitleBar
+	class GUITabbedTitleBar : public BS::GUIElement
 	{
 	public:
-		GUITabbedTitleBar(BS::GUIWidget* parent, CM::RenderWindow* parentWindow);
-		virtual ~GUITabbedTitleBar();
+		static const CM::String& getGUITypeName();
+
+		static GUITabbedTitleBar* create(BS::GUIWidget& parent, CM::RenderWindow* parentWindow,
+			BS::GUIElementStyle* backgroundStyle = nullptr, BS::GUIElementStyle* tabBtnStyle = nullptr, 
+			BS::GUIElementStyle* minBtnStyle = nullptr, BS::GUIElementStyle* closeBtnStyle = nullptr);
 
-		void setSize(CM::UINT32 width, CM::UINT32 height);
-		void setPosition(CM::INT32 x, CM::INT32 y);
+		static GUITabbedTitleBar* create(BS::GUIWidget& parent, CM::RenderWindow* parentWindow, const BS::GUILayoutOptions& layoutOptions);
+		static GUITabbedTitleBar* create(BS::GUIWidget& parent, CM::RenderWindow* parentWindow, const BS::GUILayoutOptions& layoutOptions, 
+			BS::GUIElementStyle* backgroundStyle = nullptr, BS::GUIElementStyle* tabBtnStyle = nullptr, 
+			BS::GUIElementStyle* minBtnStyle = nullptr, BS::GUIElementStyle* closeBtnStyle = nullptr);
 
 		void addTab(const CM::HString& name);
 		void insertTab(CM::UINT32 idx, const CM::HString& name);
 		void removeTab(CM::UINT32 idx);
 
+		void _updateLayoutInternal(CM::INT32 x, CM::INT32 y, CM::UINT32 width, CM::UINT32 height,
+			CM::RectI clipRect, CM::UINT8 widgetDepth, CM::UINT16 areaDepth);
+
 		boost::signal<void(CM::UINT32)> onTabActivated;
 		boost::signal<void(CM::UINT32)> onTabClosed;
 		boost::signal<void(CM::UINT32)> onTabDraggedOff;
 		boost::signal<void(CM::UINT32)> onTabDraggedOn;
+
+	protected:
+		virtual ~GUITabbedTitleBar();
+
+		/**
+		 * @copydoc GUIElement::getNumRenderElements()
+		 */
+		virtual CM::UINT32 getNumRenderElements() const;
+
+		/**
+		 * @copydoc GUIElement::getMaterial()
+		 */
+		virtual const BS::GUIMaterialInfo& getMaterial(CM::UINT32 renderElementIdx) const;
+
+		/**
+		 * @copydoc GUIElement::getNumQuads()
+		 */
+		virtual CM::UINT32 getNumQuads(CM::UINT32 renderElementIdx) const;
+
+		/**
+		 * @copydoc GUIElement::fillBuffer()
+		 */
+		virtual void fillBuffer(CM::UINT8* vertices, CM::UINT8* uv, CM::UINT32* indices, CM::UINT32 startingQuad, 
+			CM::UINT32 maxNumQuads, CM::UINT32 vertexStride, CM::UINT32 indexStride, CM::UINT32 renderElementIdx) const;
+
+		/**
+		 * @copydoc GUIElement::updateBounds()
+		 */
+		virtual void updateClippedBounds();
 	protected:
 		static const CM::UINT32 TAB_SPACING;
 		static const CM::UINT32 OPTION_BTN_SPACING;
@@ -32,23 +70,28 @@ namespace BansheeEditor
 		CM::UINT32 mUniqueTabIdx;
 		CM::UINT32 mActiveTabIdx;
 		BS::GUIWidget* mParentWidget;
-		BS::GUIArea* mBackgroundArea;
+		BS::GUITexture* mBackgroundImage;
 		BS::GUIButton* mMinBtn;
 		BS::GUIButton* mCloseBtn;
 		BS::GUIToggleGroupPtr mTabToggleGroup;
 		CM::RenderWindow* mParentWindow;
-		CM::RectI mArea;
 
 		bool mDragInProgress;
 		GUITabButton* mDraggedBtn;
 		CM::INT32 mDragBtnOffset;
 		CM::INT32 mInitialDragOffset;
 
+		const BS::GUIElementStyle* mBackgroundStyle;
 		const BS::GUIElementStyle* mCloseBtnStyle;
 		const BS::GUIElementStyle* mMinimizeBtnStyle;
+		const BS::GUIElementStyle* mTabBtnStyle;
+
+		GUITabbedTitleBar(BS::GUIWidget& parent, CM::RenderWindow* parentWindow, BS::GUIElementStyle* backgroundStyle, BS::GUIElementStyle* tabBtnStyle, 
+			BS::GUIElementStyle* minBtnStyle, BS::GUIElementStyle* closeBtnStyle, const BS::GUILayoutOptions& layoutOptions);
 
-		void updateLayout(CM::INT32 x, CM::INT32 y, CM::UINT32 width, CM::UINT32 height,
-			CM::RectI clipRect, CM::UINT8 widgetDepth);
+		virtual bool mouseEvent(const BS::GUIMouseEvent& ev);
+		virtual CM::Vector2I _getOptimalSize() const;
+		void _changeParentWidget(BS::GUIWidget* widget);
 
 		void tabToggled(CM::UINT32 tabIdx);
 		void tabClosed();

+ 34 - 4
CamelotClient/Source/BsEditorWidgetContainer.cpp

@@ -5,6 +5,7 @@
 #include "BsEditorWindow.h"
 #include "CmMath.h"
 #include "CmInput.h"
+#include "BsGUIWidget.h"
 
 using namespace CamelotFramework;
 using namespace BansheeEngine;
@@ -17,7 +18,7 @@ namespace BansheeEditor
 		:mParent(parent), mX(0), mY(0), mWidth(0), mHeight(0), mTitleBar(nullptr), mActiveWidget(-1),
 		mIsHandlingWidgetDragAndDrop(false)
 	{
-		mTitleBar = cm_new<GUITabbedTitleBar>(parent, renderWindow);
+		mTitleBar = GUITabbedTitleBar::create(*parent, renderWindow);
 		mTitleBar->onTabActivated.connect(boost::bind(&EditorWidgetContainer::tabActivated, this, _1));
 		mTitleBar->onTabClosed.connect(boost::bind(&EditorWidgetContainer::tabClosed, this, _1));
 		mTitleBar->onTabDraggedOff.connect(boost::bind(&EditorWidgetContainer::tabDraggedOff, this, _1));
@@ -26,7 +27,7 @@ namespace BansheeEditor
 
 	EditorWidgetContainer::~EditorWidgetContainer()
 	{
-		cm_delete(mTitleBar);
+		GUIElement::destroy(mTitleBar);
 
 		for(auto& widget : mWidgets)
 		{
@@ -93,7 +94,20 @@ namespace BansheeEditor
 	void EditorWidgetContainer::setSize(UINT32 width, UINT32 height)
 	{
 		// TODO - Title bar is always TitleBarHeight size, so what happens when the container area is smaller than that?
-		mTitleBar->setSize(width, TitleBarHeight);
+		RectI clipRect(mX, mY, width, TitleBarHeight);
+
+		// TODO - Consider making EditorWidgetContainer a GUIElement so this gets called automatically
+		Vector2I offset(mX, mY);
+		mTitleBar->_setOffset(offset);
+		mTitleBar->_setWidth(width);
+		mTitleBar->_setHeight(TitleBarHeight);
+		mTitleBar->_setAreaDepth(9900);
+		mTitleBar->_setWidgetDepth(mParent->getDepth());
+
+		RectI elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
+		mTitleBar->_setClipRect(elemClipRect);
+
+		mTitleBar->_updateLayoutInternal(mX, mY, width, TitleBarHeight, clipRect, mParent->getDepth(), 9900);
 
 		if(mActiveWidget >= 0)
 		{
@@ -109,7 +123,20 @@ namespace BansheeEditor
 
 	void EditorWidgetContainer::setPosition(INT32 x, INT32 y)
 	{
-		mTitleBar->setPosition(x, y);
+		RectI clipRect(x, y, mWidth, mHeight);
+
+		// TODO - Consider making EditorWidgetContainer a GUIElement so this gets called automatically
+		Vector2I offset(x, y);
+		mTitleBar->_setOffset(offset);
+		mTitleBar->_setWidth(mWidth);
+		mTitleBar->_setHeight(mHeight);
+		mTitleBar->_setAreaDepth(9900);
+		mTitleBar->_setWidgetDepth(mParent->getDepth());
+
+		RectI elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
+		mTitleBar->_setClipRect(elemClipRect);
+
+		mTitleBar->_updateLayoutInternal(x, y, mWidth, mHeight, clipRect, mParent->getDepth(), 9900);
 
 		if(mActiveWidget >= 0)
 		{
@@ -207,7 +234,10 @@ namespace BansheeEditor
 		mIsHandlingWidgetDragAndDrop = false;
 
 		if(mWidgetDroppedCallback != nullptr)
+		{
 			mWidgetDroppedCallback();
+			mWidgetDroppedCallback = nullptr;
+		}
 	}
 
 	void EditorWidgetContainer::_notifyWidgetDestroyed(EditorWidget* widget)

+ 125 - 44
CamelotClient/Source/BsGUITabbedTitleBar.cpp

@@ -19,22 +19,28 @@ namespace BansheeEditor
 	const UINT32 GUITabbedTitleBar::TAB_SPACING = 20;
 	const UINT32 GUITabbedTitleBar::OPTION_BTN_SPACING = 3;
 
-	GUITabbedTitleBar::GUITabbedTitleBar(BS::GUIWidget* parent, CM::RenderWindow* parentWindow)
-		:mParentWindow(parentWindow), mMinBtn(nullptr), mCloseBtn(nullptr), mCloseBtnStyle(nullptr),
-		mMinimizeBtnStyle(nullptr), mParentWidget(parent), mBackgroundArea(nullptr), mUniqueTabIdx(0), mActiveTabIdx(0),
-		mDragInProgress(false), mDraggedBtn(nullptr), mDragBtnOffset(0), mInitialDragOffset(0)
+	GUITabbedTitleBar::GUITabbedTitleBar(GUIWidget& parent, RenderWindow* parentWindow, GUIElementStyle* backgroundStyle, GUIElementStyle* tabBtnStyle, 
+		GUIElementStyle* minBtnStyle, GUIElementStyle* closeBtnStyle, const GUILayoutOptions& layoutOptions)
+		:GUIElement(parent, &GUISkin::DefaultStyle, layoutOptions, false), mParentWindow(parentWindow), mMinBtn(nullptr), 
+		mCloseBtn(nullptr), mParentWidget(&parent), mBackgroundImage(nullptr), mUniqueTabIdx(0), mActiveTabIdx(0),
+		mDragInProgress(false), mDraggedBtn(nullptr), mDragBtnOffset(0), mInitialDragOffset(0), mBackgroundStyle(backgroundStyle),
+		mTabBtnStyle(tabBtnStyle), mMinimizeBtnStyle(minBtnStyle), mCloseBtnStyle(closeBtnStyle)
 	{
-		mBackgroundArea = GUIArea::create(*parent, 0, 0, 1, 13, 9900);
-		GUITexture* titleBarBg = GUITexture::create(*parent, parent->getSkin().getStyle("TitleBarBackground"));
-		mBackgroundArea->getLayout().addSpace(1);
-		mBackgroundArea->getLayout().addElement(titleBarBg);
-		mBackgroundArea->getLayout().addSpace(1);
+		if(mBackgroundStyle == nullptr)
+			mBackgroundStyle = parent.getSkin().getStyle("TitleBarBackground");
 
-		mMinimizeBtnStyle = parent->getSkin().getStyle("WinMinimizeBtn");
-		mCloseBtnStyle = parent->getSkin().getStyle("WinCloseBtn");
+		if(mMinimizeBtnStyle == nullptr)
+			mMinimizeBtnStyle = parent.getSkin().getStyle("WinMinimizeBtn");
 
-		mMinBtn = GUIButton::create(*parent, HString(L""), mMinimizeBtnStyle);
-		mCloseBtn = GUIButton::create(*parent, HString(L""), mCloseBtnStyle);
+		if(mCloseBtnStyle == nullptr)
+			mCloseBtnStyle = parent.getSkin().getStyle("WinCloseBtn");
+
+		if(mTabBtnStyle == nullptr)
+			mTabBtnStyle = parent.getSkin().getStyle("TabbedBarBtn");
+
+		mBackgroundImage = GUITexture::create(parent, mBackgroundStyle);
+		mMinBtn = GUIButton::create(parent, HString(L""), mMinimizeBtnStyle);
+		mCloseBtn = GUIButton::create(parent, HString(L""), mCloseBtnStyle);
 
 		mCloseBtn->onClick.connect(boost::bind(&GUITabbedTitleBar::tabClosed, this));
 
@@ -43,7 +49,7 @@ namespace BansheeEditor
 
 	GUITabbedTitleBar::~GUITabbedTitleBar()
 	{
-		GUIArea::destroy(mBackgroundArea);
+		GUIElement::destroy(mBackgroundImage);
 
 		GUIElement::destroy(mMinBtn);
 		GUIElement::destroy(mCloseBtn);
@@ -54,6 +60,26 @@ namespace BansheeEditor
 		}
 	}
 
+	GUITabbedTitleBar* GUITabbedTitleBar::create(GUIWidget& parent, RenderWindow* parentWindow, GUIElementStyle* backgroundStyle, 
+		GUIElementStyle* tabBtnStyle, GUIElementStyle* minBtnStyle, GUIElementStyle* closeBtnStyle)
+	{
+		return new (cm_alloc<GUITabbedTitleBar, PoolAlloc>()) GUITabbedTitleBar(parent, parentWindow, backgroundStyle, tabBtnStyle, 
+			minBtnStyle, closeBtnStyle, GUILayoutOptions::create(&GUISkin::DefaultStyle));
+	}
+
+	GUITabbedTitleBar* GUITabbedTitleBar::create(GUIWidget& parent, RenderWindow* parentWindow, const GUILayoutOptions& layoutOptions)
+	{
+		return new (cm_alloc<GUITabbedTitleBar, PoolAlloc>()) GUITabbedTitleBar(parent, parentWindow, nullptr, nullptr, 
+			nullptr, nullptr, layoutOptions);
+	}
+
+	GUITabbedTitleBar* GUITabbedTitleBar::create(GUIWidget& parent, RenderWindow* parentWindow, const GUILayoutOptions& layoutOptions, 
+		GUIElementStyle* backgroundStyle, GUIElementStyle* tabBtnStyle, GUIElementStyle* minBtnStyle, GUIElementStyle* closeBtnStyle)
+	{
+		return new (cm_alloc<GUITabbedTitleBar, PoolAlloc>()) GUITabbedTitleBar(parent, parentWindow, backgroundStyle, tabBtnStyle, 
+			minBtnStyle, closeBtnStyle, layoutOptions);
+	}
+
 	void GUITabbedTitleBar::addTab(const CM::HString& name)
 	{
 		insertTab((UINT32)mTabButtons.size(), name);
@@ -61,7 +87,7 @@ namespace BansheeEditor
 
 	void GUITabbedTitleBar::insertTab(UINT32 idx, const CM::HString& name)
 	{
-		GUITabButton* newTabToggle = GUITabButton::create(*mParentWidget, mTabToggleGroup, mUniqueTabIdx, name, EngineGUI::instance().getSkin().getStyle("TabbedBarBtn"));
+		GUITabButton* newTabToggle = GUITabButton::create(*mParentWidget, mTabToggleGroup, mUniqueTabIdx, name, mTabBtnStyle);
 
 		idx = Math::clamp(idx, 0U, (UINT32)mTabButtons.size());
 
@@ -86,11 +112,74 @@ namespace BansheeEditor
 		mTabButtons.erase(mTabButtons.begin() + idx);
 	}
 
-	void GUITabbedTitleBar::updateLayout(INT32 x, INT32 y, UINT32 width, UINT32 height,
-		RectI clipRect, UINT8 widgetDepth)
+	UINT32 GUITabbedTitleBar::getNumRenderElements() const
+	{
+		return 0;
+	}
+
+	const GUIMaterialInfo& GUITabbedTitleBar::getMaterial(UINT32 renderElementIdx) const
+	{
+		CM_EXCEPT(InvalidStateException, "Trying to retrieve a material from an element with no render elements.");
+	}
+
+	UINT32 GUITabbedTitleBar::getNumQuads(UINT32 renderElementIdx) const
+	{
+		return 0;
+	}
+
+	void GUITabbedTitleBar::updateClippedBounds()
+	{
+		mClippedBounds = RectI(0, 0, 0, 0); // We don't want any mouse input for this element. This is just a container.
+	}
+
+	void GUITabbedTitleBar::fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, UINT32 maxNumQuads, 
+		UINT32 vertexStride, UINT32 indexStride, UINT32 renderElementIdx) const
+	{ }
+
+	bool GUITabbedTitleBar::mouseEvent(const GUIMouseEvent& ev)
+	{
+		// TODO
+
+		return false;
+	}
+
+	Vector2I GUITabbedTitleBar::_getOptimalSize() const
+	{
+		return Vector2I();
+	}
+
+	void GUITabbedTitleBar::_changeParentWidget(GUIWidget* widget)
+	{
+		GUIElement::_changeParentWidget(widget);
+
+		mBackgroundImage->_changeParentWidget(widget);
+		mMinBtn->_changeParentWidget(widget);
+		mCloseBtn->_changeParentWidget(widget);
+
+		for(auto& tabButton : mTabButtons)
+		{
+			tabButton->_changeParentWidget(widget);
+		}
+	}
+
+	void GUITabbedTitleBar::_updateLayoutInternal(INT32 x, INT32 y, UINT32 width, UINT32 height,
+		RectI clipRect, UINT8 widgetDepth, UINT16 areaDepth)
 	{
 		CM::Vector<CM::RectI>::type nonClientAreas;
 
+		{
+			Vector2I optimalSize = mBackgroundImage->_getOptimalSize();
+			Vector2I offset(x + 1, y + 1);
+			mBackgroundImage->_setOffset(offset);
+			mBackgroundImage->_setWidth(width - 2);
+			mBackgroundImage->_setHeight(optimalSize.y);
+			mBackgroundImage->_setAreaDepth(areaDepth + 1);
+			mBackgroundImage->_setWidgetDepth(widgetDepth);
+
+			RectI elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
+			mBackgroundImage->_setClipRect(elemClipRect);
+		}
+
 		UINT32 curX = x + 1;
 		UINT32 curY = y;
 		UINT32 tabBtnHeight = 0;
@@ -110,7 +199,7 @@ namespace BansheeEditor
 			btn->_setOffset(offset);
 			btn->_setWidth(optimalSize.x);
 			btn->_setHeight(optimalSize.y);
-			btn->_setAreaDepth(9899);
+			btn->_setAreaDepth(areaDepth);
 			btn->_setWidgetDepth(widgetDepth);
 
 			RectI elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
@@ -134,7 +223,7 @@ namespace BansheeEditor
 			mMinBtn->_setOffset(offset);
 			mMinBtn->_setWidth(minBtnOptimalSize.x);
 			mMinBtn->_setHeight(minBtnOptimalSize.y);
-			mMinBtn->_setAreaDepth(9899);
+			mMinBtn->_setAreaDepth(areaDepth);
 			mMinBtn->_setWidgetDepth(widgetDepth);
 
 			RectI elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
@@ -149,7 +238,7 @@ namespace BansheeEditor
 			mCloseBtn->_setOffset(offset);
 			mCloseBtn->_setWidth(closeBtnOptimalSize.x);
 			mCloseBtn->_setHeight(closeBtnOptimalSize.y);
-			mCloseBtn->_setAreaDepth(9899);
+			mCloseBtn->_setAreaDepth(areaDepth);
 			mCloseBtn->_setWidgetDepth(widgetDepth);
 
 			RectI elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
@@ -159,26 +248,6 @@ namespace BansheeEditor
 		Platform::setCaptionNonClientAreas(*mParentWindow, nonClientAreas);
 	}
 
-	void GUITabbedTitleBar::setPosition(INT32 x, INT32 y)
-	{
-		mArea.x = x;
-		mArea.y = y;
-
-		mBackgroundArea->setPosition(x, y);
-
-		updateLayout(mArea.x, mArea.y, mArea.width, mArea.height, RectI(mArea.x, mArea.y, mArea.width, mArea.height), mParentWidget->getDepth());
-	}
-
-	void GUITabbedTitleBar::setSize(UINT32 width, UINT32 height)
-	{
-		mArea.width = width;
-		mArea.height = height;
-
-		mBackgroundArea->setSize(width, height);
-
-		updateLayout(mArea.x, mArea.y, mArea.width, mArea.height, RectI(mArea.x, mArea.y, mArea.width, mArea.height), mParentWidget->getDepth());
-	}
-
 	void GUITabbedTitleBar::tabToggled(CM::UINT32 tabIdx)
 	{
 		INT32 idx = uniqueIdxToSeqIdx(tabIdx);
@@ -211,7 +280,8 @@ namespace BansheeEditor
 		INT32 idx = uniqueIdxToSeqIdx(tabIdx);
 		if(idx != -1)
 		{
-			if(mArea.contains(dragPos))
+			RectI bounds = getBounds();
+			if(bounds.contains(dragPos))
 			{
 				mDraggedBtn = mTabButtons[idx];
 
@@ -223,7 +293,7 @@ namespace BansheeEditor
 					mDragInProgress = true;
 				}
 
-				mDragBtnOffset = dragPos.x - mArea.x - mInitialDragOffset;
+				mDragBtnOffset = dragPos.x - bounds.x - mInitialDragOffset;
 				
 				Vector2I offset = mDraggedBtn->_getOffset();
 				INT32 diff = mDragBtnOffset - offset.x;
@@ -236,7 +306,7 @@ namespace BansheeEditor
 
 				mDragInProgress = true;
 
-				for(UINT32 i = 0; i < idx; i++)
+				for(INT32 i = 0; i < idx; i++)
 				{
 					UINT32 width = mTabButtons[i]->_getWidth();
 					INT32 centerX = mTabButtons[i]->_getOffset().x + width / 2;
@@ -282,7 +352,12 @@ namespace BansheeEditor
 		mDragInProgress = false;
 		mDraggedBtn = nullptr;
 
-		updateLayout(mArea.x, mArea.y, mArea.width, mArea.height, RectI(mArea.x, mArea.y, mArea.width, mArea.height), mParentWidget->getDepth());
+		markContentAsDirty();
+
+		// HACK - Remove once EditorWidgetContainer is a proper GUI object
+		RectI bounds = getBounds();
+		_updateLayoutInternal(bounds.x, bounds.y, bounds.width, bounds.height,
+			_getClipRect(), mParent->getDepth(), 9900);
 	}
 
 	void GUITabbedTitleBar::tabDraggedOn(CM::UINT32 tabIdx)
@@ -308,4 +383,10 @@ namespace BansheeEditor
 
 		return -1;
 	}
+
+	const String& GUITabbedTitleBar::getGUITypeName()
+	{
+		static String typeName = "TabbedTitleBar";
+		return typeName;
+	}
 }

+ 2 - 0
EditorWindowDock.txt

@@ -13,6 +13,8 @@ TitleBar dock/undock
 
 CONSIDER getting rid of mouse event filters for DockManager
  - I can probably convert DockManager into a GUIElement?
+   - EditorWidgetContainer as well!
+      - Make sure to update GUITabbedTitleBar::tabDragEnd when I do convert it to GUIElement
 
 Polish TOOD:
  - Change cursor icon when window is dragged