Browse Source

TabbedTitleBar no longer uses layout

Marko Pintera 12 years ago
parent
commit
13f93f07b1

+ 2 - 1
BansheeEngine/Include/BsGUIButtonBase.h

@@ -29,6 +29,8 @@ namespace BansheeEngine
 		void _setOn(bool on);
 		bool _isOn() const;
 
+		virtual CM::Vector2I _getOptimalSize() const;
+
 		boost::signal<void()> onClick;
 		boost::signal<void()> onHover;
 		boost::signal<void()> onOut;
@@ -69,7 +71,6 @@ namespace BansheeEngine
 
 		virtual bool mouseEvent(const GUIMouseEvent& ev);
 
-		virtual CM::Vector2I _getOptimalSize() const;
 		virtual CM::UINT32 _getRenderElementDepth(CM::UINT32 renderElementIdx) const;
 
 		TEXT_SPRITE_DESC getTextDesc() const;

+ 2 - 2
BansheeEngine/Include/BsGUIInputBox.h

@@ -18,6 +18,8 @@ namespace BansheeEngine
 
 		const CM::WString& getText() const { return mText; }
 		void setText(const CM::WString& text);
+
+		virtual CM::Vector2I _getOptimalSize() const;
 	protected:
 		~GUIInputBox();
 
@@ -52,8 +54,6 @@ namespace BansheeEngine
 		 */
 		virtual void updateClippedBounds();
 
-		virtual CM::Vector2I _getOptimalSize() const;
-
 		virtual CM::Vector2I _getTextInputOffset() const;
 		virtual CM::RectI _getTextInputRect() const;
 

+ 1 - 2
BansheeEngine/Include/BsGUILabel.h

@@ -20,6 +20,7 @@ namespace BansheeEngine
 
 		void setContent(const GUIContent& content);
 
+		virtual CM::Vector2I _getOptimalSize() const;
 	protected:
 		~GUILabel();
 
@@ -53,8 +54,6 @@ namespace BansheeEngine
 		 * @copydoc GUIElement::updateBounds()
 		 */
 		virtual void updateClippedBounds();
-
-		virtual CM::Vector2I _getOptimalSize() const;
 	private:
 		TextSprite* mTextSprite;
 		GUIContent mContent;

+ 2 - 2
BansheeEngine/Include/BsGUIScrollArea.h

@@ -31,6 +31,8 @@ namespace BansheeEngine
 
 		GUILayout& getLayout() const { return *mContentLayout; }
 
+		virtual CM::Vector2I _getOptimalSize() const;
+
 	protected:
 		~GUIScrollArea();
 
@@ -64,8 +66,6 @@ namespace BansheeEngine
 		 * @copydoc GUIElement::updateBounds()
 		 */
 		virtual void updateClippedBounds();
-
-		virtual CM::Vector2I _getOptimalSize() const;
 	private:
 		GUIScrollArea(GUIWidget& parent, ScrollBarType vertBarType, ScrollBarType horzBarType, 
 			const GUIElementStyle* scrollBarStyle, const GUIElementStyle* scrollAreaStyle, const GUILayoutOptions& layoutOptions);

+ 2 - 2
BansheeEngine/Include/BsGUIScrollBar.h

@@ -23,6 +23,8 @@ namespace BansheeEngine
 
 		CM::UINT32 getMaxHandleSize() const;
 		CM::UINT32 getScrollableSize() const;
+
+		virtual CM::Vector2I _getOptimalSize() const;
 	protected:
 		GUIScrollBar(GUIWidget& parent, bool horizontal, const GUIElementStyle* style, const GUILayoutOptions& layoutOptions);
 		virtual ~GUIScrollBar();
@@ -58,8 +60,6 @@ namespace BansheeEngine
 		 */
 		virtual void updateClippedBounds();
 
-		virtual CM::Vector2I _getOptimalSize() const;
-
 		virtual CM::UINT32 _getRenderElementDepth(CM::UINT32 renderElementIdx) const;
 	private:
 		GUILayout* mLayout;

+ 2 - 2
BansheeEngine/Include/BsGUIScrollBarHandle.h

@@ -24,6 +24,8 @@ namespace BansheeEngine
 
 		CM::UINT32 getMaxSize() const;
 
+		virtual CM::Vector2I _getOptimalSize() const;
+
 		boost::signal<void(float newPosition)> onHandleMoved;
 	protected:
 		~GUIScrollBarHandle();
@@ -58,8 +60,6 @@ namespace BansheeEngine
 		 * @copydoc GUIElement::updateBounds()
 		 */
 		virtual void updateClippedBounds();
-
-		virtual CM::Vector2I _getOptimalSize() const;
 	private:
 		ImageSprite* mImageSprite;
 		CM::UINT32 mHandleSize;

+ 10 - 5
BansheeEngine/Include/BsGUITexture.h

@@ -19,18 +19,25 @@ namespace BansheeEngine
 	public:
 		static const CM::String& getGUITypeName();
 
-		static GUITexture* create(GUIWidget& parent, const HSpriteTexture& texture, GUIImageScaleMode scale = GUIImageScaleMode::StretchToFit, 
-			const GUIElementStyle* style = nullptr);
 		static GUITexture* create(GUIWidget& parent, const HSpriteTexture& texture, GUIImageScaleMode scale, 
 			const GUIOptions& layoutOptions, const GUIElementStyle* style = nullptr);
+		static GUITexture* create(GUIWidget& parent, const HSpriteTexture& texture, GUIImageScaleMode scale, 
+			const GUIElementStyle* style = nullptr);
+
 		static GUITexture* create(GUIWidget& parent, const HSpriteTexture& texture, 
 			const GUIOptions& layoutOptions, const GUIElementStyle* style = nullptr);
+		static GUITexture* create(GUIWidget& parent, const HSpriteTexture& texture, const GUIElementStyle* style = nullptr);
 
-		static GUITexture* create(GUIWidget& parent, GUIImageScaleMode scale = GUIImageScaleMode::StretchToFit, const GUIElementStyle* style = nullptr);
+		
 		static GUITexture* create(GUIWidget& parent, GUIImageScaleMode scale, const GUIOptions& layoutOptions, const GUIElementStyle* style = nullptr);
+		static GUITexture* create(GUIWidget& parent, GUIImageScaleMode scale, const GUIElementStyle* style = nullptr);
+
 		static GUITexture* create(GUIWidget& parent, const GUIOptions& layoutOptions, const GUIElementStyle* style = nullptr);
+		static GUITexture* create(GUIWidget& parent, const GUIElementStyle* style = nullptr);
 
 		void setTexture(const HSpriteTexture& texture);
+
+		virtual CM::Vector2I _getOptimalSize() const;
 	protected:
 		ImageSprite* mImageSprite;
 		HSpriteTexture mActiveTexture;
@@ -70,7 +77,5 @@ namespace BansheeEngine
 		 * @copydoc GUIElement::updateBounds()
 		 */
 		virtual void updateClippedBounds();
-
-		virtual CM::Vector2I _getOptimalSize() const;
 	};
 }

+ 3 - 2
BansheeEngine/Include/BsGUIViewport.h

@@ -24,6 +24,9 @@ namespace BansheeEngine
 		 */
 		static GUIViewport* create(GUIWidget& parent, const GUIOptions& layoutOptions, const HCamera& camera, 
 			float aspectRatio, CM::Degree fieldOfView, const GUIElementStyle* style = nullptr);
+
+		virtual CM::Vector2I _getOptimalSize() const;
+
 	protected:
 		~GUIViewport();
 
@@ -58,8 +61,6 @@ namespace BansheeEngine
 		 */
 		virtual void updateRenderElementsInternal();
 
-		virtual CM::Vector2I _getOptimalSize() const;
-
 	private:
 		HCamera mCamera;
 		float mAspectRatio;

+ 28 - 6
BansheeEngine/Source/BsGUITexture.cpp

@@ -39,7 +39,7 @@ namespace BansheeEngine
 	}
 
 	GUITexture* GUITexture::create(GUIWidget& parent, const HSpriteTexture& texture, 
-		GUIImageScaleMode scale, const GUIElementStyle* style)
+		GUIImageScaleMode scale, const GUIOptions& layoutOptions, const GUIElementStyle* style)
 	{
 		if(style == nullptr)
 		{
@@ -47,11 +47,11 @@ namespace BansheeEngine
 			style = skin.getStyle(getGUITypeName());
 		}
 
-		return new (cm_alloc<GUITexture, PoolAlloc>()) GUITexture(parent, style, texture, scale, GUILayoutOptions::create(style));
+		return new (cm_alloc<GUITexture, PoolAlloc>()) GUITexture(parent, style, texture, scale, GUILayoutOptions::create(layoutOptions, style));
 	}
 
 	GUITexture* GUITexture::create(GUIWidget& parent, const HSpriteTexture& texture, 
-		GUIImageScaleMode scale, const GUIOptions& layoutOptions, const GUIElementStyle* style)
+		GUIImageScaleMode scale, const GUIElementStyle* style)
 	{
 		if(style == nullptr)
 		{
@@ -59,7 +59,7 @@ namespace BansheeEngine
 			style = skin.getStyle(getGUITypeName());
 		}
 
-		return new (cm_alloc<GUITexture, PoolAlloc>()) GUITexture(parent, style, texture, scale, GUILayoutOptions::create(layoutOptions, style));
+		return new (cm_alloc<GUITexture, PoolAlloc>()) GUITexture(parent, style, texture, scale, GUILayoutOptions::create(style));
 	}
 
 	GUITexture* GUITexture::create(GUIWidget& parent, const HSpriteTexture& texture, 
@@ -74,7 +74,7 @@ namespace BansheeEngine
 		return new (cm_alloc<GUITexture, PoolAlloc>()) GUITexture(parent, style, texture, GUIImageScaleMode::StretchToFit, GUILayoutOptions::create(layoutOptions, style));
 	}
 
-	GUITexture* GUITexture::create(GUIWidget& parent, GUIImageScaleMode scale, const GUIElementStyle* style)
+	GUITexture* GUITexture::create(GUIWidget& parent, const HSpriteTexture& texture, const GUIElementStyle* style)
 	{
 		if(style == nullptr)
 		{
@@ -82,7 +82,7 @@ namespace BansheeEngine
 			style = skin.getStyle(getGUITypeName());
 		}
 
-		return new (cm_alloc<GUITexture, PoolAlloc>()) GUITexture(parent, style, HSpriteTexture(), scale, GUILayoutOptions::create(style));
+		return new (cm_alloc<GUITexture, PoolAlloc>()) GUITexture(parent, style, texture, GUIImageScaleMode::StretchToFit, GUILayoutOptions::create(style));
 	}
 
 	GUITexture* GUITexture::create(GUIWidget& parent, GUIImageScaleMode scale, const GUIOptions& layoutOptions, const GUIElementStyle* style)
@@ -96,6 +96,17 @@ namespace BansheeEngine
 		return new (cm_alloc<GUITexture, PoolAlloc>()) GUITexture(parent, style, HTexture(), scale, GUILayoutOptions::create(layoutOptions, style));
 	}
 
+	GUITexture* GUITexture::create(GUIWidget& parent, GUIImageScaleMode scale, const GUIElementStyle* style)
+	{
+		if(style == nullptr)
+		{
+			const GUISkin& skin = parent.getSkin();
+			style = skin.getStyle(getGUITypeName());
+		}
+
+		return new (cm_alloc<GUITexture, PoolAlloc>()) GUITexture(parent, style, HSpriteTexture(), scale, GUILayoutOptions::create(style));
+	}
+
 	GUITexture* GUITexture::create(GUIWidget& parent, const GUIOptions& layoutOptions, const GUIElementStyle* style)
 	{
 		if(style == nullptr)
@@ -107,6 +118,17 @@ namespace BansheeEngine
 		return new (cm_alloc<GUITexture, PoolAlloc>()) GUITexture(parent, style, HTexture(), GUIImageScaleMode::StretchToFit, GUILayoutOptions::create(layoutOptions, style));
 	}
 
+	GUITexture* GUITexture::create(GUIWidget& parent, const GUIElementStyle* style)
+	{
+		if(style == nullptr)
+		{
+			const GUISkin& skin = parent.getSkin();
+			style = skin.getStyle(getGUITypeName());
+		}
+
+		return new (cm_alloc<GUITexture, PoolAlloc>()) GUITexture(parent, style, HTexture(), GUIImageScaleMode::StretchToFit, GUILayoutOptions::create(style));
+	}
+
 	void GUITexture::setTexture(const HSpriteTexture& texture)
 	{
 		mActiveTexture = texture;

+ 0 - 5
CSharpWrap.txt

@@ -34,7 +34,6 @@ Systems:
  -----------------
 
  Implementation steps:
-  - Finish up minor scroll area issues
   - Implement flexible TreeView GUI component
   - Finish up Window Docking
   - EditorApplication
@@ -49,10 +48,6 @@ Systems:
 
 ----------------------------
 
-ScrollBar update:
-  Ensure that scroll bar type is actually used somewhere in GUIScrollBar.cpp
-  Test it properly
-
  - GUISkin
    - List of properties with all common styles, like .button, .label
    - Get/SetStyle methods for custom styles

+ 11 - 6
CamelotClient/Include/BsGUITabbedTitleBar.h

@@ -23,19 +23,26 @@ namespace BansheeEditor
 		boost::signal<void(CM::UINT32)> onTabDraggedOff;
 		boost::signal<void(CM::UINT32)> onTabDraggedOn;
 	protected:
-		CM::Vector<GUIWindowDropArea*>::type mDragDropElements;
+		static const CM::UINT32 TAB_SPACING;
+		static const CM::UINT32 OPTION_BTN_SPACING;
+
 		CM::Vector<GUITabButton*>::type mTabButtons;
 
 		CM::UINT32 mUniqueTabIdx;
 		CM::UINT32 mActiveTabIdx;
 		BS::GUIWidget* mParentWidget;
-		BS::GUIArea* mMainArea;
 		BS::GUIArea* mBackgroundArea;
-		BS::GUILayout* mMainLayout;
 		BS::GUIButton* mMinBtn;
 		BS::GUIButton* mCloseBtn;
-		GUIWindowDropArea* mLastDropElement;
 		CM::RenderWindow* mParentWindow;
+		CM::INT32 mX, mY;
+		CM::UINT32 mWidth, mHeight;
+
+		const BS::GUIElementStyle* mCloseBtnStyle;
+		const BS::GUIElementStyle* mMinimizeBtnStyle;
+
+		void updateLayout(CM::INT32 x, CM::INT32 y, CM::UINT32 width, CM::UINT32 height,
+			CM::RectI clipRect, CM::UINT8 widgetDepth);
 
 		void tabToggled(CM::UINT32 tabIdx);
 		void tabClosed();
@@ -43,7 +50,5 @@ namespace BansheeEditor
 		void tabDraggedOn(CM::UINT32 tabIdx);
 
 		CM::INT32 uniqueIdxToSeqIdx(CM::UINT32 uniqueIdx) const;
-
-		void refreshNonClientAreas();
 	};
 }

+ 2 - 2
CamelotClient/Source/BsEditorApplication.cpp

@@ -217,8 +217,8 @@ namespace BansheeEditor
 
 		gApplication().mainLoopCallback.connect(boost::bind(&EditorApplication::update, this));
 
-		//DbgEditorWidget1::open(); // DEBUG ONLY
-		//DbgEditorWidget2::open(); // DEBUG ONLY
+		DbgEditorWidget1::open(); // DEBUG ONLY
+		DbgEditorWidget2::open(); // DEBUG ONLY
 
 		gBansheeApp().runMainLoop();
 

+ 88 - 59
CamelotClient/Source/BsGUITabbedTitleBar.cpp

@@ -16,43 +16,33 @@ using namespace BansheeEngine;
 
 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), mLastDropElement(nullptr), mMinBtn(nullptr), mCloseBtn(nullptr), 
-		mMainArea(nullptr), mMainLayout(nullptr), mParentWidget(parent), mBackgroundArea(nullptr), mUniqueTabIdx(0), mActiveTabIdx(0)
+		:mParentWindow(parentWindow), mMinBtn(nullptr), mCloseBtn(nullptr), mCloseBtnStyle(nullptr),
+		mMinimizeBtnStyle(nullptr), mParentWidget(parent), mBackgroundArea(nullptr), mUniqueTabIdx(0), mActiveTabIdx(0),
+		mX(0), mY(0), mWidth(0), mHeight(0)
 	{
 		mBackgroundArea = GUIArea::create(*parent, 0, 0, 1, 13, 9900);
-		GUIWindowDropArea* titleBarBg = GUIWindowDropArea::create(*parent, parent->getSkin().getStyle("TitleBarBackground"));
+		GUITexture* titleBarBg = GUITexture::create(*parent, parent->getSkin().getStyle("TitleBarBackground"));
 		mBackgroundArea->getLayout().addSpace(1);
 		mBackgroundArea->getLayout().addElement(titleBarBg);
 		mBackgroundArea->getLayout().addSpace(1);
 
-		mMainArea = GUIArea::create(*parent, 0, 0, 1, 13, 9899);
-
-		GUIWindowDropArea* dragDropElement = GUIWindowDropArea::create(*parent, GUIOptions(GUIOption::flexibleWidth(20)), parent->getSkin().getStyle("TabbedBarDropArea"));
-		mLastDropElement = dragDropElement;
+		mMinimizeBtnStyle = parent->getSkin().getStyle("WinMinimizeBtn");
+		mCloseBtnStyle = parent->getSkin().getStyle("WinCloseBtn");
 
-		mMinBtn = GUIButton::create(*parent, HString(L""), parent->getSkin().getStyle("WinMinimizeBtn"));
-		mCloseBtn = GUIButton::create(*parent, HString(L""), parent->getSkin().getStyle("WinCloseBtn"));
+		mMinBtn = GUIButton::create(*parent, HString(L""), mMinimizeBtnStyle);
+		mCloseBtn = GUIButton::create(*parent, HString(L""), mCloseBtnStyle);
 
 		mCloseBtn->onClick.connect(boost::bind(&GUITabbedTitleBar::tabClosed, this));
-
-		mMainArea->getLayout().addSpace(1);
-		mMainLayout = &mMainArea->getLayout().addLayoutX();
-		mMainLayout->addElement(dragDropElement);
-		mMainLayout->addElement(mMinBtn);
-		mMainLayout->addSpace(3);
-		mMainLayout->addElement(mCloseBtn);
-		mMainArea->getLayout().addSpace(3);
-
-		refreshNonClientAreas();
 	}
 
 	GUITabbedTitleBar::~GUITabbedTitleBar()
 	{
-		GUIArea::destroy(mMainArea);
 		GUIArea::destroy(mBackgroundArea);
 
-		GUIElement::destroy(mLastDropElement);
 		GUIElement::destroy(mMinBtn);
 		GUIElement::destroy(mCloseBtn);
 
@@ -60,11 +50,6 @@ namespace BansheeEditor
 		{
 			GUIElement::destroy(tabButton);
 		}
-
-		for(auto& dragDropButton : mDragDropElements)
-		{
-			GUIElement::destroy(dragDropButton);
-		}
 	}
 
 	void GUITabbedTitleBar::addTab(const CM::HString& name)
@@ -75,24 +60,15 @@ namespace BansheeEditor
 	void GUITabbedTitleBar::insertTab(UINT32 idx, const CM::HString& name)
 	{
 		GUITabButton* newTabToggle = GUITabButton::create(*mParentWidget, this, mUniqueTabIdx, name, EngineGUI::instance().getSkin().getStyle("TabbedBarBtn"));
-		GUIWindowDropArea* newDragDropElement = GUIWindowDropArea::create(*mParentWidget, EngineGUI::instance().getSkin().getStyle("TabbedBarDropArea"));
 
 		idx = Math::clamp(idx, 0U, (UINT32)mTabButtons.size());
 
 		newTabToggle->onToggled.connect(boost::bind(&GUITabbedTitleBar::tabToggled, this, mUniqueTabIdx));
 		newTabToggle->onDragged.connect(boost::bind(&GUITabbedTitleBar::tabDraggedOff, this, _1));
 
-		newDragDropElement->onDraggedItemDropped.connect(boost::bind(&GUITabbedTitleBar::tabDraggedOn, this, mUniqueTabIdx));
-
 		mTabButtons.insert(mTabButtons.begin() + idx, newTabToggle);
-		mDragDropElements.insert(mDragDropElements.begin() + idx, newDragDropElement);
-
-		mMainLayout->insertElement(idx * 2, newTabToggle);
-		mMainLayout->insertElement(idx * 2, newDragDropElement);
 
 		mUniqueTabIdx++;
-
-		refreshNonClientAreas();
 	}
 
 	void GUITabbedTitleBar::removeTab(UINT32 idx)
@@ -103,28 +79,98 @@ namespace BansheeEditor
 		idx = Math::clamp(idx, 0U, (UINT32)mTabButtons.size() - 1);
 
 		GUIElement::destroy(mTabButtons[idx]);
-		GUIElement::destroy(mDragDropElements[idx]);
 
 		mTabButtons.erase(mTabButtons.begin() + idx);
-		mDragDropElements.erase(mDragDropElements.begin() + idx);
+	}
+
+	void GUITabbedTitleBar::updateLayout(INT32 x, INT32 y, UINT32 width, UINT32 height,
+		RectI clipRect, UINT8 widgetDepth)
+	{
+		CM::Vector<CM::RectI>::type nonClientAreas;
+
+		UINT32 curX = x + 1;
+		UINT32 curY = y;
+		UINT32 tabBtnHeight = 0;
+		for(UINT32 i = 0; i < (UINT32)mTabButtons.size(); i++)
+		{
+			GUITabButton* btn = mTabButtons[i];
+			Vector2I optimalSize = btn->_getOptimalSize();
+
+			tabBtnHeight = optimalSize.y;
+			nonClientAreas.push_back(RectI(curX, curY, TAB_SPACING, tabBtnHeight));
+			curX += TAB_SPACING;
+
+			Vector2I offset(curX, curY);
+			btn->_setOffset(offset);
+			btn->_setWidth(optimalSize.x);
+			btn->_setHeight(optimalSize.y);
+			btn->_setAreaDepth(9899);
+			btn->_setWidgetDepth(widgetDepth);
+
+			RectI elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
+			btn->_setClipRect(elemClipRect);
+
+			curX += optimalSize.x;
+		}
+
+		Vector2I minBtnOptimalSize = mMinBtn->_getOptimalSize();
+		Vector2I closeBtnOptimalSize = mCloseBtn->_getOptimalSize();
+
+		UINT32 endButtonWidth = minBtnOptimalSize.x + closeBtnOptimalSize.x + OPTION_BTN_SPACING;
+		UINT32 remainingWidth = (UINT32)std::max(0, (INT32)(width - curX - endButtonWidth - 1));
+		nonClientAreas.push_back(RectI(curX, curY, remainingWidth, tabBtnHeight));
 
-		refreshNonClientAreas();
+		INT32 optionBtnXPos = x + width - endButtonWidth - 1;
+		{
+			INT32 optionBtnYPos = curY + Math::floorToInt((tabBtnHeight - minBtnOptimalSize.y) * 0.5f);
+
+			Vector2I offset(optionBtnXPos, optionBtnYPos);
+			mMinBtn->_setOffset(offset);
+			mMinBtn->_setWidth(minBtnOptimalSize.x);
+			mMinBtn->_setHeight(minBtnOptimalSize.y);
+			mMinBtn->_setAreaDepth(9899);
+			mMinBtn->_setWidgetDepth(widgetDepth);
+
+			RectI elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
+			mMinBtn->_setClipRect(elemClipRect);
+		}
+
+		optionBtnXPos += minBtnOptimalSize.x + OPTION_BTN_SPACING;
+		{
+			INT32 optionBtnYPos = curY + Math::floorToInt((tabBtnHeight - closeBtnOptimalSize.y) * 0.5f);
+
+			Vector2I offset(optionBtnXPos, optionBtnYPos);
+			mCloseBtn->_setOffset(offset);
+			mCloseBtn->_setWidth(closeBtnOptimalSize.x);
+			mCloseBtn->_setHeight(closeBtnOptimalSize.y);
+			mCloseBtn->_setAreaDepth(9899);
+			mCloseBtn->_setWidgetDepth(widgetDepth);
+
+			RectI elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
+			mCloseBtn->_setClipRect(elemClipRect);
+		}
+
+		Platform::setCaptionNonClientAreas(*mParentWindow, nonClientAreas);
 	}
 
 	void GUITabbedTitleBar::setPosition(INT32 x, INT32 y)
 	{
-		mMainArea->setPosition(x, y);
+		mX = x;
+		mY = y;
+
 		mBackgroundArea->setPosition(x, y);
 
-		refreshNonClientAreas();
+		updateLayout(mX, mY, mWidth, mHeight, RectI(mX, mY, mWidth, mHeight), mParentWidget->getDepth());
 	}
 
 	void GUITabbedTitleBar::setSize(UINT32 width, UINT32 height)
 	{
-		mMainArea->setSize(width, height);
+		mWidth = width;
+		mHeight = height;
+
 		mBackgroundArea->setSize(width, height);
 
-		refreshNonClientAreas();
+		updateLayout(mX, mY, mWidth, mHeight, RectI(mX, mY, mWidth, mHeight), mParentWidget->getDepth());
 	}
 
 	void GUITabbedTitleBar::tabToggled(CM::UINT32 tabIdx)
@@ -187,21 +233,4 @@ namespace BansheeEditor
 
 		return -1;
 	}
-
-	void GUITabbedTitleBar::refreshNonClientAreas()
-	{
-		// If the size or contents of the area changed this frame the layout won't be updated yet,
-		// so force the update right away so we get correct element bounds
-		mMainArea->_update();
-
-		CM::Vector<CM::RectI>::type nonClientAreas;
-		for(auto& elem : mDragDropElements)
-		{
-			nonClientAreas.push_back(elem->getBounds());
-		}
-
-		nonClientAreas.push_back(mLastDropElement->getBounds());
-
-		Platform::setCaptionNonClientAreas(*mParentWindow, nonClientAreas);
-	}
 }

+ 27 - 15
EditorWindowDock.txt

@@ -1,24 +1,36 @@
-Add icons to drag and drop - There's a built-in windows icon for this. I think. Although solution that accepts custom cursors is probably better longterm. (Special class BuiltinCursors?)
- - Drag and drop manager currently ignores the provided icon, but it should use it as a cursor
+DockManager implementation steps:
+Initial:
+ - Open up two editor windows on app start
+ - Initially DockManager has empty background
+ - Dragging one editor window anywhere on the empty background docks the window
+ - Dragging another editor window over the window shows the drop overlay and you can dock that window onto any side
+   - Currently the overlay is always shown and will trigger on mouse move and not only mouse drag
 
-Add highlight to WindowMover so I can know when I'm mousing over it with a dragged window in hand
-Ensure that dropping a window onto a mover will actually docks it properly
+Undock:
+ - Dragging on a title of a docked window undocks it
 
-Prevent docking if available size is less than 20 pixels, otherwise there might be some weirdness
+Resize sliders
+ - Add a button between docked windows
+ - Allow the button to be dragged, and it will automatically resize separating widgets
 
-When using the scroll bar and then mousing over non-client area the scroll bar will get reset!
+TitleBar dock/undock move
+ - Dragging a title bar will move the title bar button while the cursor is within the widget area
+   - If there are other title bars this will allow you to reposition the title bar
+   - If cursor leaves the title bar (or widget area?) close the window and start actual drag and drop operation
+
+TitleBar dock/undock 
+ - Releasing the dragged window anywhere not on editor will re-open the window at that location
+ - Releasing the dragged window over the drop overlay will dock the window
+ - Moving the dragged window over a title bar will temporarily dock the title bar and allow you to move it (as in first step)
+   - If you release the mouse the window will then be permanently docked at that location
+
+Polish TOOD:
+ - Change cursor icon when window is dragged
+ - Prevent docking if available size is less than 20 pixels, otherwise there might be some weirdness
 
 ------------------------
 
 Other things to remember:
  - Possibly add a way to have hidden widgets in the EditorWidgetContainer (like side-bars that pop on mouse over in Visual Studio)
  - A way to persist window states
- - Also a way to reset all widgets to original locations
-
-Will destroying a GUIWidget properly schedule destruction? (i.e. so it won't be destroyed mid-frame)
- - I will probably need to add deferred destroy to Components and SceneObjects as well
-
-GUIViewport:
- - TODO - GUIViewport updateRenderElementsInternal only gets called when contents change, but viewport should update even if 
-    only its offset changes (normally that just marks the mesh as modified, which doesn't result in a call to updateRenderElementsInternal)
-	- UPDATE: I don't use GUIViewport anymore
+ - Also a way to reset all widgets to original locations