Selaa lähdekoodia

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

Marko Pintera 12 vuotta sitten
vanhempi
sitoutus
b19effc118

+ 1 - 1
BansheeEngine/Include/BsGUIArea.h

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

+ 14 - 3
BansheeEngine/Source/BsGUIArea.cpp

@@ -1,6 +1,8 @@
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
 #include "BsGUIWidget.h"
 #include "BsGUIWidget.h"
 #include "BsGUILayoutX.h"
 #include "BsGUILayoutX.h"
+#include "BsGUIWidget.h"
+#include "CmRenderWindow.h"
 #include "CmViewport.h"
 #include "CmViewport.h"
 
 
 using namespace CamelotFramework;
 using namespace CamelotFramework;
@@ -114,6 +116,15 @@ namespace BansheeEngine
 		mWidget = widget;
 		mWidget = widget;
 
 
 		mLayout->_changeParentWidget(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()
 	void GUIArea::_update()
@@ -150,13 +161,13 @@ namespace BansheeEngine
 		mIsDirty = true;
 		mIsDirty = true;
 	}
 	}
 
 
-	void GUIArea::notifyWindowResized(UINT32 newWidth, UINT32 newHeight)
+	void GUIArea::updateSizeBasedOnParent(CM::UINT32 parentWidth, CM::UINT32 parentHeight)
 	{
 	{
 		if(mResizeXWithWidget)
 		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)
 		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)
 		if(mResizeXWithWidget || mResizeYWithWidget)
 			mIsDirty = true;
 			mIsDirty = true;

+ 2 - 0
BansheeEngine/Source/BsGUIElementBase.cpp

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

+ 2 - 1
BansheeEngine/Source/BsGUIWidget.cpp

@@ -312,7 +312,8 @@ namespace BansheeEngine
 	{
 	{
 		for(auto& area : mAreas)
 		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:
 	private:
 		EditorWidgetContainer* mWidgets;
 		EditorWidgetContainer* mWidgets;
 
 
+		void updateSize();
 		void widgetRemoved();
 		void widgetRemoved();
 	};
 	};
 }
 }

+ 7 - 0
CamelotClient/Source/BsEditorWindow.cpp

@@ -10,6 +10,8 @@ namespace BansheeEditor
 	EditorWindow::EditorWindow()
 	EditorWindow::EditorWindow()
 		:EditorWindowBase(), mWidgets(cm_new<EditorWidgetContainer>(mGUI.get()))
 		:EditorWindowBase(), mWidgets(cm_new<EditorWidgetContainer>(mGUI.get()))
 	{
 	{
+		updateSize();
+
 		mWidgets->onWidgetClosed.connect(boost::bind(&EditorWindow::widgetRemoved, this));
 		mWidgets->onWidgetClosed.connect(boost::bind(&EditorWindow::widgetRemoved, this));
 	}
 	}
 
 
@@ -22,6 +24,11 @@ namespace BansheeEditor
 	{
 	{
 		EditorWindowBase::movedOrResized();
 		EditorWindowBase::movedOrResized();
 
 
+		updateSize();
+	}
+
+	void EditorWindow::updateSize()
+	{
 		mWidgets->setPosition(1, 1);
 		mWidgets->setPosition(1, 1);
 
 
 		UINT32 widgetWidth = (UINT32)std::max(0, (INT32)getWidth() - 2);
 		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
 end drag doesn't get called unless mouse is released over a window
  - Capture mouse on start drag (SetCapture, and release with ReleaseCapture)
  - 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
  - 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
    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
 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
 Drag and drop manager currently ignores the provided icon, but it should use it as a cursor