Quellcode durchsuchen

Fixed a few issues with window drag and drop and reparenting

Marko Pintera vor 12 Jahren
Ursprung
Commit
6df63da9fe

+ 3 - 3
BansheeEngine/Include/BsGUIArea.h

@@ -58,7 +58,7 @@ namespace BansheeEngine
 		void disable();
 		void enable();
 
-		void changeParentWidget(GUIWidget& widget);
+		void changeParentWidget(GUIWidget* widget);
 
 		CM::UINT32 x() const { return mLeft; }
 		CM::UINT32 y() const { return mTop; }
@@ -69,7 +69,7 @@ namespace BansheeEngine
 	private:
 		friend class GUIWidget;
 
-		GUIWidget& mWidget;
+		GUIWidget* mWidget;
 		CM::INT32 mLeft, mRight, mTop, mBottom;
 		CM::UINT32 mWidth, mHeight;
 		CM::UINT16 mDepth;
@@ -80,7 +80,7 @@ namespace BansheeEngine
 
 		GUILayout* mLayout;
 
-		GUIArea(GUIWidget& widget, CM::UINT32 x, CM::UINT32 y, CM::UINT16 depth);
+		GUIArea(GUIWidget* widget, CM::UINT32 x, CM::UINT32 y, CM::UINT16 depth);
 
 		bool isDirty() const;
 

+ 3 - 3
BansheeEngine/Include/BsGUIElement.h

@@ -92,7 +92,7 @@ namespace BansheeEngine
 		void _setClipRect(const CM::Rect& clipRect);
 		void _setAcceptsKeyboardFocus(bool acceptsKeyboardFocus) { mAcceptsKeyboardFocus = acceptsKeyboardFocus; }
 		virtual void _setFocus(bool focus) {}
-		virtual void _changeParentWidget(GUIWidget& widget);
+		virtual void _changeParentWidget(GUIWidget* widget);
 
 		CM::UINT32 _getWidth() const { return mWidth; }
 		CM::UINT32 _getHeight() const { return mHeight; }
@@ -102,7 +102,7 @@ namespace BansheeEngine
 
 		const CM::Rect& _getBounds() const { return mBounds; }
 		CM::UINT32 _getDepth() const { return mDepth; }
-		GUIWidget& _getParentWidget() const { return mParent; }
+		GUIWidget& _getParentWidget() const { return *mParent; }
 		virtual bool _isInBounds(const CM::Int2 position) const;
 		bool _acceptsKeyboardFocus() const { return mAcceptsKeyboardFocus; }
 
@@ -131,7 +131,7 @@ namespace BansheeEngine
 
 		static GUILayoutOptions getDefaultLayoutOptions(const GUIElementStyle* style);
 
-		GUIWidget& mParent;
+		GUIWidget* mParent;
 		GUILayoutOptions mLayoutOptions;
 		CM::Rect mBounds;
 

+ 1 - 1
BansheeEngine/Include/BsGUIElementBase.h

@@ -59,7 +59,7 @@ namespace BansheeEngine
 		bool _isMeshDirty() const; 
 		bool _isDisabled() const { return mIsDisabled; }
 
-		virtual void _changeParentWidget(GUIWidget& widget);
+		virtual void _changeParentWidget(GUIWidget* widget);
 
 	protected:
 		/**

+ 17 - 13
BansheeEngine/Source/BsGUIArea.cpp

@@ -7,13 +7,13 @@ using namespace CamelotFramework;
 
 namespace BansheeEngine
 {
-	GUIArea::GUIArea(GUIWidget& widget, UINT32 x, UINT32 y, UINT16 depth)
+	GUIArea::GUIArea(GUIWidget* widget, UINT32 x, UINT32 y, UINT16 depth)
 		:mWidget(widget), mLeft(x), mTop(y), mDepth(depth), mIsDirty(true), mIsDisabled(false),
 		mResizeXWithWidget(false), mResizeYWithWidget(false), mWidth(0), mHeight(0), mRight(0), mBottom(0)
 	{
 		mLayout = cm_new<GUILayoutX, PoolAlloc>();
 
-		mWidget.registerArea(this);
+		mWidget->registerArea(this);
 	}
 
 	GUIArea::~GUIArea() 
@@ -23,7 +23,7 @@ namespace BansheeEngine
 
 	GUIArea* GUIArea::create(GUIWidget& widget, UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT16 depth)
 	{
-		GUIArea* area = new (cm_alloc<GUIArea, PoolAlloc>()) GUIArea(widget, x, y, depth);
+		GUIArea* area = new (cm_alloc<GUIArea, PoolAlloc>()) GUIArea(&widget, x, y, depth);
 		area->mWidth = width;
 		area->mHeight = height;
 
@@ -33,7 +33,7 @@ namespace BansheeEngine
 	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);
+		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);
@@ -48,7 +48,7 @@ namespace BansheeEngine
 	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);
+		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;
@@ -62,7 +62,7 @@ namespace BansheeEngine
 	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);
+		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);
@@ -75,7 +75,8 @@ namespace BansheeEngine
 
 	void GUIArea::destroy(GUIArea* area)
 	{
-		area->mWidget.unregisterArea(area);
+		if(area->mWidget != nullptr)
+			area->mWidget->unregisterArea(area);
 
 		cm_delete<PoolAlloc>(area);
 	}
@@ -99,13 +100,16 @@ namespace BansheeEngine
 		mLayout->enableRecursively();
 	}
 
-	void GUIArea::changeParentWidget(GUIWidget& widget)
+	void GUIArea::changeParentWidget(GUIWidget* widget)
 	{
-		if(&mWidget == &widget)
+		if(mWidget == widget)
 			return;
 
-		mWidget.unregisterArea(this);
-		widget.registerArea(this);
+		if(mWidget != nullptr)
+			mWidget->unregisterArea(this);
+
+		if(widget != nullptr)
+			widget->registerArea(this);
 
 		mWidget = widget;
 
@@ -114,10 +118,10 @@ namespace BansheeEngine
 
 	void GUIArea::_update()
 	{
-		if(!mIsDisabled && isDirty())
+		if(!mIsDisabled && isDirty() && (mWidget != nullptr))
 		{
 			Rect clipRect(mLeft, mTop, mWidth, mHeight);
-			mLayout->_updateLayout(mLeft, mTop, mWidth, mHeight, clipRect, mWidget.getDepth(), mDepth);
+			mLayout->_updateLayout(mLeft, mTop, mWidth, mHeight, clipRect, mWidget->getDepth(), mDepth);
 			mIsDirty = false;
 		}
 	}

+ 11 - 7
BansheeEngine/Source/BsGUIElement.cpp

@@ -9,10 +9,10 @@ using namespace CamelotFramework;
 namespace BansheeEngine
 {
 	GUIElement::GUIElement(GUIWidget& parent, const GUIElementStyle* style, const GUILayoutOptions& layoutOptions, bool acceptsKeyboardFocus)
-		:mParent(parent), mLayoutOptions(layoutOptions), mWidth(0), mHeight(0), mDepth(0), mStyle(style),
+		:mParent(&parent), mLayoutOptions(layoutOptions), mWidth(0), mHeight(0), mDepth(0), mStyle(style),
 		mAcceptsKeyboardFocus(acceptsKeyboardFocus)
 	{
-		mParent.registerElement(this);
+		mParent->registerElement(this);
 	}
 
 	GUIElement::~GUIElement()
@@ -118,12 +118,15 @@ namespace BansheeEngine
 		}
 	}
 
-	void GUIElement::_changeParentWidget(GUIWidget& widget)
+	void GUIElement::_changeParentWidget(GUIWidget* widget)
 	{
-		if(&mParent != &widget)
+		if(mParent != widget)
 		{
-			mParent.unregisterElement(this);
-			widget.registerElement(this);
+			if(mParent != nullptr)
+				mParent->unregisterElement(this);
+
+			if(widget != nullptr)
+				widget->registerElement(this);
 
 			mParent = widget;
 		}
@@ -198,7 +201,8 @@ namespace BansheeEngine
 
 	void GUIElement::destroy(GUIElement* element)
 	{
-		element->mParent.unregisterElement(element);
+		if(element->mParent != nullptr)
+			element->mParent->unregisterElement(element);
 
 		// Destroy at beginning of next frame, because we can't be sure that something isn't currently referencing
 		// this element (e..g GUIManager)

+ 1 - 1
BansheeEngine/Source/BsGUIElementBase.cpp

@@ -182,7 +182,7 @@ namespace BansheeEngine
 		return *entry;
 	}
 
-	void GUIElementBase::_changeParentWidget(GUIWidget& widget)
+	void GUIElementBase::_changeParentWidget(GUIWidget* widget)
 	{
 		for(auto& child : mChildren)
 		{

+ 6 - 3
CamelotClient/Source/BsEditorWidget.cpp

@@ -51,13 +51,16 @@ namespace BansheeEditor
 		{
 			if(parent != nullptr)
 			{
-				if(mParent == nullptr)
+				if(mContent == nullptr)
 					mContent = GUIArea::create(parent->getParentWidget(), 0, 0, 0, 0, 10000);
 				else
-					mContent->changeParentWidget(parent->getParentWidget());
+					mContent->changeParentWidget(&parent->getParentWidget());
 			}
 			else
-				mContent = nullptr;
+			{
+				if(mContent != nullptr)
+					mContent->changeParentWidget(nullptr);
+			}
 
 			mParent = parent;
 		}

+ 1 - 1
CamelotClient/Source/BsEditorWindow.cpp

@@ -8,7 +8,7 @@ using namespace BansheeEngine;
 namespace BansheeEditor
 {
 	EditorWindow::EditorWindow()
-		:mWidgets(cm_new<EditorWidgetContainer>(mGUI.get()))
+		:EditorWindowBase(), mWidgets(cm_new<EditorWidgetContainer>(mGUI.get()))
 	{
 		mWidgets->onWidgetClosed.connect(boost::bind(&EditorWindow::widgetRemoved, this));
 	}

+ 3 - 0
EditorWindowDock.txt

@@ -2,6 +2,9 @@ Add icons to drag and drop
 Move WindowMover to BansheeEditor
 
 end drag doesn't get called unless mouse is released over a window
+ - Capture mouse on start drag (SetCapture, and release with ReleaseCapture)
+ - End drag should be handled by GUIManager, but if it doesn't process it DragAndDrop manager should check if mouse was released, and
+   release capture and activate end drag callback
 When I do drop it over a window an exception with layout happens
 
 Add highlight to WindowMover so I can know when I'm mousing over it with a dragged window in hand