Browse Source

Fixed an issue where GUI layout update was delayed one frame after window was restored after drag and drop

Marko Pintera 12 years ago
parent
commit
b19effc118

+ 1 - 1
BansheeEngine/Include/BsGUIArea.h

@@ -84,7 +84,7 @@ namespace BansheeEngine
 
 		bool isDirty() const;
 
-		void notifyWindowResized(CM::UINT32 newWidth, CM::UINT32 newHeight);
+		void updateSizeBasedOnParent(CM::UINT32 parentWidth, CM::UINT32 parentHeight);
 
 		static void destroyInternal(GUIArea* area);
 	};

+ 14 - 3
BansheeEngine/Source/BsGUIArea.cpp

@@ -1,6 +1,8 @@
 #include "BsGUIArea.h"
 #include "BsGUIWidget.h"
 #include "BsGUILayoutX.h"
+#include "BsGUIWidget.h"
+#include "CmRenderWindow.h"
 #include "CmViewport.h"
 
 using namespace CamelotFramework;
@@ -114,6 +116,15 @@ namespace BansheeEngine
 		mWidget = widget;
 
 		mLayout->_changeParentWidget(widget);
+
+		if(mWidget != nullptr)
+		{
+			// TODO - It might be more appropriate to use Viewport size instead of window size
+			// Ensure the size is valid, otherwise next GUI layout update will calculate wrong element coordinates
+			updateSizeBasedOnParent(mWidget->getOwnerWindow()->getWidth(), mWidget->getOwnerWindow()->getHeight());
+		}
+
+		mIsDirty = true;
 	}
 
 	void GUIArea::_update()
@@ -150,13 +161,13 @@ namespace BansheeEngine
 		mIsDirty = true;
 	}
 
-	void GUIArea::notifyWindowResized(UINT32 newWidth, UINT32 newHeight)
+	void GUIArea::updateSizeBasedOnParent(CM::UINT32 parentWidth, CM::UINT32 parentHeight)
 	{
 		if(mResizeXWithWidget)
-			mWidth = (UINT32)std::max(0, (INT32)newWidth - (INT32)mLeft - (INT32)mRight);
+			mWidth = (UINT32)std::max(0, (INT32)parentWidth - (INT32)mLeft - (INT32)mRight);
 
 		if(mResizeYWithWidget)
-			mHeight = (UINT32)std::max(0, (INT32)newHeight - (INT32)mTop - (INT32)mBottom);
+			mHeight = (UINT32)std::max(0, (INT32)parentHeight - (INT32)mTop - (INT32)mBottom);
 
 		if(mResizeXWithWidget || mResizeYWithWidget)
 			mIsDirty = true;

+ 2 - 0
BansheeEngine/Source/BsGUIElementBase.cpp

@@ -188,5 +188,7 @@ namespace BansheeEngine
 		{
 			child->_changeParentWidget(widget);
 		}
+
+		markContentAsDirty();
 	}
 }

+ 2 - 1
BansheeEngine/Source/BsGUIWidget.cpp

@@ -312,7 +312,8 @@ namespace BansheeEngine
 	{
 		for(auto& area : mAreas)
 		{
-			area->notifyWindowResized(getOwnerWindow()->getWidth(), getOwnerWindow()->getHeight());
+			// TODO - It might be more appropriate to use Viewport size instead of window size
+			area->updateSizeBasedOnParent(getOwnerWindow()->getWidth(), getOwnerWindow()->getHeight());
 		}
 	}
 

+ 1 - 0
CamelotClient/Include/BsEditorWindow.h

@@ -22,6 +22,7 @@ namespace BansheeEditor
 	private:
 		EditorWidgetContainer* mWidgets;
 
+		void updateSize();
 		void widgetRemoved();
 	};
 }

+ 7 - 0
CamelotClient/Source/BsEditorWindow.cpp

@@ -10,6 +10,8 @@ namespace BansheeEditor
 	EditorWindow::EditorWindow()
 		:EditorWindowBase(), mWidgets(cm_new<EditorWidgetContainer>(mGUI.get()))
 	{
+		updateSize();
+
 		mWidgets->onWidgetClosed.connect(boost::bind(&EditorWindow::widgetRemoved, this));
 	}
 
@@ -22,6 +24,11 @@ namespace BansheeEditor
 	{
 		EditorWindowBase::movedOrResized();
 
+		updateSize();
+	}
+
+	void EditorWindow::updateSize()
+	{
 		mWidgets->setPosition(1, 1);
 
 		UINT32 widgetWidth = (UINT32)std::max(0, (INT32)getWidth() - 2);

+ 2 - 3
EditorWindowDock.txt

@@ -1,14 +1,13 @@
-Add icons to drag and drop
-Move WindowMover to BansheeEditor
+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?)
 
 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
 
+Reopening the window I can see the update takes a few frames. This shouldn't be the case.
 
 Drag and drop manager currently ignores the provided icon, but it should use it as a cursor