Browse Source

Fixed multiple issues with new multi-widget windows and their docking
Window will no longer dock the moment you click its title bar

Marko Pintera 12 years ago
parent
commit
dc2db48914

+ 1 - 1
CamelotEditor/Include/CmEditorPrefs.h

@@ -29,7 +29,7 @@ namespace CamelotEditor
 
 
 		UINT32 activeWidget;
 		UINT32 activeWidget;
 		vector<QString>::type childWidgetNames;
 		vector<QString>::type childWidgetNames;
-		UINT32 id;
+		INT32 id;
 		UINT32 width;
 		UINT32 width;
 		UINT32 height;
 		UINT32 height;
 		UINT32 left;
 		UINT32 left;

+ 3 - 2
CamelotEditor/Include/CmEditorWindowManager.h

@@ -35,13 +35,14 @@ namespace CamelotEditor
 
 
 	private:
 	private:
 		map<QString, EditorWidgetFactory*>::type mFactories;
 		map<QString, EditorWidgetFactory*>::type mFactories;
-		map<UINT32, QtEditorWindow*>::type mOpenWindows;
+		map<INT32, QtEditorWindow*>::type mOpenWindows;
 		map<QString, QtEditorWidget*>::type mOpenWidgets;
 		map<QString, QtEditorWidget*>::type mOpenWidgets;
 		UINT32 mMaxOpenWindowId;
 		UINT32 mMaxOpenWindowId;
 
 
 		EditorWidgetFactory* getFactory(const QString& name) const;
 		EditorWidgetFactory* getFactory(const QString& name) const;
 
 
-		QtEditorWindow* openWindow(UINT32 forcedId = -1);
+		QtEditorWindow* openWindow(INT32 forcedId = -1);
+		void widgetClosed(QtEditorWidget* window);
 		void windowClosed(QtEditorWindow* window);
 		void windowClosed(QtEditorWindow* window);
 	};
 	};
 
 

+ 4 - 0
CamelotEditor/Include/CmQtEditorWidget.h

@@ -2,6 +2,7 @@
 
 
 #include "CmEditorPrerequisites.h"
 #include "CmEditorPrerequisites.h"
 #include <QtWidgets/QWidget>
 #include <QtWidgets/QWidget>
+#include <boost/signal.hpp>
 
 
 namespace CamelotEditor
 namespace CamelotEditor
 {
 {
@@ -18,6 +19,9 @@ namespace CamelotEditor
 
 
 		QtEditorWindow* getParentWindow() const { return mParentWindow; }
 		QtEditorWindow* getParentWindow() const { return mParentWindow; }
 
 
+		void closeWidget();
+
+		boost::signal<void(QtEditorWidget*)> onClosed;
 	private:
 	private:
 		friend class QtEditorWindow;
 		friend class QtEditorWindow;
 		
 		

+ 5 - 3
CamelotEditor/Include/CmQtEditorWindow.h

@@ -25,7 +25,7 @@ namespace CamelotEditor
 		};
 		};
 
 
 	public:
 	public:
-		QtEditorWindow(QWidget* parent, UINT32 id);
+		QtEditorWindow(QWidget* parent, INT32 id);
 		virtual ~QtEditorWindow() { }
 		virtual ~QtEditorWindow() { }
 
 
 		void undock();
 		void undock();
@@ -50,7 +50,7 @@ namespace CamelotEditor
 		QSizePolicy	sizePolicy() const;
 		QSizePolicy	sizePolicy() const;
 
 
 	private:
 	private:
-		UINT32 mId;
+		INT32 mId;
 		ResizeMode mResizeMode;
 		ResizeMode mResizeMode;
 		bool mMoveMode;
 		bool mMoveMode;
 		QPoint mDragOffset;
 		QPoint mDragOffset;
@@ -80,6 +80,8 @@ namespace CamelotEditor
 		ResizeMode getResizeMode(QPoint mousePos);
 		ResizeMode getResizeMode(QPoint mousePos);
 		bool isOverResizeArea(QPoint mousePos);
 		bool isOverResizeArea(QPoint mousePos);
 
 
+		void closeWindow();
+
 		/**
 		/**
 		 * @brief	Query if 'mousePos' is over the area that can be used for dragging the window around.
 		 * @brief	Query if 'mousePos' is over the area that can be used for dragging the window around.
 		 *
 		 *
@@ -95,6 +97,6 @@ namespace CamelotEditor
 		/************************************************************************/
 		/************************************************************************/
 	private Q_SLOTS:
 	private Q_SLOTS:
 		void timerUpdate();
 		void timerUpdate();
-		void closeWindow();
+		void closeWidget();
 	};
 	};
 }
 }

+ 1 - 1
CamelotEditor/Source/CmEditorPrefs.cpp

@@ -126,7 +126,7 @@ namespace CamelotEditor
 	{
 	{
 		WindowLayoutDesc desc;
 		WindowLayoutDesc desc;
 
 
-		desc.id = node.attribute("id").as_uint();
+		desc.id = node.attribute("id").as_int();
 
 
 		desc.left = node.child("Geometry").attribute("left").as_uint();
 		desc.left = node.child("Geometry").attribute("left").as_uint();
 		desc.top = node.child("Geometry").attribute("top").as_uint();
 		desc.top = node.child("Geometry").attribute("top").as_uint();

+ 17 - 3
CamelotEditor/Source/CmEditorWindowManager.cpp

@@ -36,6 +36,7 @@ namespace CamelotEditor
 		parent->addWidget(widget);
 		parent->addWidget(widget);
 
 
 		mOpenWidgets[name] = widget;
 		mOpenWidgets[name] = widget;
+		widget->onClosed.connect(boost::bind(&EditorWindowManager::widgetClosed, this, _1));
 	}
 	}
 
 
 	boost::function<void()> EditorWindowManager::getOpenCallback(const QString& name)
 	boost::function<void()> EditorWindowManager::getOpenCallback(const QString& name)
@@ -43,7 +44,7 @@ namespace CamelotEditor
 		return boost::bind(&EditorWindowManager::openWidget, this, name, nullptr);
 		return boost::bind(&EditorWindowManager::openWidget, this, name, nullptr);
 	}
 	}
 
 
-	QtEditorWindow* EditorWindowManager::openWindow(UINT32 forcedId)
+	QtEditorWindow* EditorWindowManager::openWindow(INT32 forcedId)
 	{
 	{
 		if(forcedId != -1)
 		if(forcedId != -1)
 		{
 		{
@@ -52,9 +53,9 @@ namespace CamelotEditor
 				CM_EXCEPT(InvalidParametersException, "Window with the specified id already exists: " + toString(forcedId));
 				CM_EXCEPT(InvalidParametersException, "Window with the specified id already exists: " + toString(forcedId));
 		}
 		}
 
 
-		UINT32 windowId = 0;
+		INT32 windowId = 0;
 		if(forcedId != -1)
 		if(forcedId != -1)
-			windowId = -1;
+			windowId = forcedId;
 		else
 		else
 			windowId = mMaxOpenWindowId;
 			windowId = mMaxOpenWindowId;
 
 
@@ -146,6 +147,19 @@ namespace CamelotEditor
 		return iterFind->second;
 		return iterFind->second;
 	}
 	}
 
 
+	void EditorWindowManager::widgetClosed(QtEditorWidget* widget)
+	{
+		assert(widget != nullptr);
+
+		auto iterFind = mOpenWidgets.find(widget->getName());
+		if(iterFind == mOpenWidgets.end())
+			CM_EXCEPT(InternalErrorException, "Trying to close a widget " + widget->getName().toStdString() + " that is not in the open widget list.");
+
+		assert(iterFind->second == widget);
+
+		mOpenWidgets.erase(iterFind);
+	}
+
 	void EditorWindowManager::windowClosed(QtEditorWindow* window)
 	void EditorWindowManager::windowClosed(QtEditorWindow* window)
 	{
 	{
 		assert(window != nullptr);
 		assert(window != nullptr);

+ 6 - 0
CamelotEditor/Source/CmQtEditorWidget.cpp

@@ -7,4 +7,10 @@ namespace CamelotEditor
 	{
 	{
 
 
 	}
 	}
+
+	void QtEditorWidget::closeWidget()
+	{
+		onClosed(this);
+		destroy();
+	}
 }
 }

+ 14 - 2
CamelotEditor/Source/CmQtEditorWindow.cpp

@@ -17,7 +17,7 @@
 
 
 namespace CamelotEditor
 namespace CamelotEditor
 {
 {
-	QtEditorWindow::QtEditorWindow(QWidget* parent, UINT32 id)
+	QtEditorWindow::QtEditorWindow(QWidget* parent, INT32 id)
 		:QWidget(parent), mResizeMode(RM_NONE), mMoveMode(false), mIsDocked(false), mId(id), mActiveWidgetIdx(0)
 		:QWidget(parent), mResizeMode(RM_NONE), mMoveMode(false), mIsDocked(false), mId(id), mActiveWidgetIdx(0)
 	{
 	{
 		setupUi();
 		setupUi();
@@ -76,7 +76,7 @@ namespace CamelotEditor
 
 
 	void QtEditorWindow::setupSignals()
 	void QtEditorWindow::setupSignals()
 	{
 	{
-		connect(mBtnClose, SIGNAL(clicked()), this, SLOT(closeWindow()));
+		connect(mBtnClose, SIGNAL(clicked()), this, SLOT(closeWidget()));
 		connect(mTimer, SIGNAL(timeout()), this, SLOT(timerUpdate()));
 		connect(mTimer, SIGNAL(timeout()), this, SLOT(timerUpdate()));
 	}
 	}
 
 
@@ -175,6 +175,7 @@ namespace CamelotEditor
 	void QtEditorWindow::restoreFromLayoutDesc(const WindowLayoutDesc& desc)
 	void QtEditorWindow::restoreFromLayoutDesc(const WindowLayoutDesc& desc)
 	{
 	{
 		setGeometry(desc.left, desc.top, desc.width, desc.height);
 		setGeometry(desc.left, desc.top, desc.width, desc.height);
+		mId = desc.id;
 
 
 		for(auto iter2 = desc.childWidgetNames.begin(); iter2 != desc.childWidgetNames.end(); ++iter2)
 		for(auto iter2 = desc.childWidgetNames.begin(); iter2 != desc.childWidgetNames.end(); ++iter2)
 			gEditorWindowManager().openWidget(*iter2, this);
 			gEditorWindowManager().openWidget(*iter2, this);
@@ -432,6 +433,17 @@ namespace CamelotEditor
 		close();
 		close();
 	}
 	}
 
 
+	void QtEditorWindow::closeWidget()
+	{
+		QtEditorWidget* activeWidget = getWidget(mActiveWidgetIdx);
+		removeWidget(mActiveWidgetIdx);
+
+		activeWidget->closeWidget();
+
+		if(getNumWidgets() == 0)
+			closeWindow();		
+	}
+
 	QtEditorWindow::ResizeMode QtEditorWindow::getResizeMode(QPoint mousePos)
 	QtEditorWindow::ResizeMode QtEditorWindow::getResizeMode(QPoint mousePos)
 	{
 	{
 		QPoint localMousePos = mapFromGlobal(mousePos);
 		QPoint localMousePos = mapFromGlobal(mousePos);

+ 58 - 52
CamelotEditor/Source/CmWindowDockManager.cpp

@@ -45,7 +45,11 @@ namespace CamelotEditor
 				QPoint drawOffset = mCentralWidget->mapToGlobal(QPoint(0, 0)) - mDockOverlayWidget->mapToGlobal(QPoint(0, 0));
 				QPoint drawOffset = mCentralWidget->mapToGlobal(QPoint(0, 0)) - mDockOverlayWidget->mapToGlobal(QPoint(0, 0));
 
 
 				mDockOverlayWidget->enableDropOverlay(dropLocations, drawOffset);
 				mDockOverlayWidget->enableDropOverlay(dropLocations, drawOffset);
-				mDockOverlayWidget->highlightDropLocation(dragLocation);
+
+				if(dragLocation != CM_WINDROP_CENTER)
+					mDockOverlayWidget->highlightDropLocation(dragLocation);
+				else
+					mDockOverlayWidget->highlightDropLocation(CM_WINDROP_NONE);
 			}
 			}
 			else
 			else
 			{
 			{
@@ -69,7 +73,16 @@ namespace CamelotEditor
 		mDockOverlayWidget->highlightDropLocation(CM_WINDROP_NONE);
 		mDockOverlayWidget->highlightDropLocation(CM_WINDROP_NONE);
 		mDockOverlayWidget->disableDropOverlay();
 		mDockOverlayWidget->disableDropOverlay();
 
 
-		if(!window->isDocked())
+		if(mLastDraggedWindow != window)
+		{
+			mLastDragPosition = mousePos;
+			mLastDraggedWindow = window;
+		}
+
+		QPoint diff = mLastDragPosition - mousePos;
+		bool wasDragged = diff.manhattanLength() > 4; // Ensure user actually moved the window
+
+		if(wasDragged && !window->isDocked())
 		{
 		{
 			QtEditorWindow* windowUnderCursor = getDockedWindowAtPosition(mousePos);
 			QtEditorWindow* windowUnderCursor = getDockedWindowAtPosition(mousePos);
 			if(windowUnderCursor != nullptr)
 			if(windowUnderCursor != nullptr)
@@ -170,7 +183,7 @@ namespace CamelotEditor
 		auto findIter = mDockedWindows.find(windowToDock);
 		auto findIter = mDockedWindows.find(windowToDock);
 		assert(findIter == mDockedWindows.end());
 		assert(findIter == mDockedWindows.end());
 
 
-		if(dockAtPosition == CM_WINDROP_NONE)
+		if(dockAtPosition == CM_WINDROP_NONE || dockAtPosition == CM_WINDROP_CENTER)
 			return;
 			return;
 
 
 		if(dockAtWidget == nullptr)
 		if(dockAtWidget == nullptr)
@@ -188,65 +201,58 @@ namespace CamelotEditor
 				return;
 				return;
 			}
 			}
 
 
-			if(dockAtPosition == CM_WINDROP_CENTER)
+			if(parentSplitter->orientation() == Qt::Horizontal)
 			{
 			{
-				CM_ASSERT(false); // TODO - Not implemented
+				int idxDockAt = parentSplitter->indexOf(dockAtWidget);
+				if(dockAtPosition == CM_WINDROP_LEFT)
+					parentSplitter->insertWidget(idxDockAt, windowToDock);
+				else if(dockAtPosition == CM_WINDROP_RIGHT)
+					parentSplitter->insertWidget(idxDockAt + 1, windowToDock);
+				else // Top or bottom
+				{
+					QSplitter* newSplitter = new QSplitter();
+					newSplitter->setOrientation(Qt::Vertical);
+					newSplitter->setChildrenCollapsible(false);
+						
+					if(dockAtPosition == CM_WINDROP_TOP)
+					{
+						newSplitter->addWidget(windowToDock);
+						newSplitter->addWidget(dockAtWidget);
+					}
+					else
+					{
+						newSplitter->addWidget(dockAtWidget);
+						newSplitter->addWidget(windowToDock);
+					}
+
+					parentSplitter->insertWidget(idxDockAt, newSplitter);
+				}
 			}
 			}
 			else
 			else
 			{
 			{
-				if(parentSplitter->orientation() == Qt::Horizontal)
+				int idxDockAt = parentSplitter->indexOf(dockAtWidget);
+				if(dockAtPosition == CM_WINDROP_TOP)
+					parentSplitter->insertWidget(idxDockAt, windowToDock);
+				else if(dockAtPosition == CM_WINDROP_BOTTOM)
+					parentSplitter->insertWidget(idxDockAt + 1, windowToDock);
+				else // Left or right
 				{
 				{
-					int idxDockAt = parentSplitter->indexOf(dockAtWidget);
+					QSplitter* newSplitter = new QSplitter();
+					newSplitter->setOrientation(Qt::Horizontal);
+					newSplitter->setChildrenCollapsible(false);
+
 					if(dockAtPosition == CM_WINDROP_LEFT)
 					if(dockAtPosition == CM_WINDROP_LEFT)
-						parentSplitter->insertWidget(idxDockAt, windowToDock);
-					else if(dockAtPosition == CM_WINDROP_RIGHT)
-						parentSplitter->insertWidget(idxDockAt + 1, windowToDock);
-					else // Top or bottom
 					{
 					{
-						QSplitter* newSplitter = new QSplitter();
-						newSplitter->setOrientation(Qt::Vertical);
-						newSplitter->setChildrenCollapsible(false);
-						
-						if(dockAtPosition == CM_WINDROP_TOP)
-						{
-							newSplitter->addWidget(windowToDock);
-							newSplitter->addWidget(dockAtWidget);
-						}
-						else
-						{
-							newSplitter->addWidget(dockAtWidget);
-							newSplitter->addWidget(windowToDock);
-						}
-
-						parentSplitter->insertWidget(idxDockAt, newSplitter);
+						newSplitter->addWidget(windowToDock);
+						newSplitter->addWidget(dockAtWidget);
 					}
 					}
-				}
-				else
-				{
-					int idxDockAt = parentSplitter->indexOf(dockAtWidget);
-					if(dockAtPosition == CM_WINDROP_TOP)
-						parentSplitter->insertWidget(idxDockAt, windowToDock);
-					else if(dockAtPosition == CM_WINDROP_BOTTOM)
-						parentSplitter->insertWidget(idxDockAt + 1, windowToDock);
-					else // Left or right
+					else
 					{
 					{
-						QSplitter* newSplitter = new QSplitter();
-						newSplitter->setOrientation(Qt::Horizontal);
-						newSplitter->setChildrenCollapsible(false);
-
-						if(dockAtPosition == CM_WINDROP_LEFT)
-						{
-							newSplitter->addWidget(windowToDock);
-							newSplitter->addWidget(dockAtWidget);
-						}
-						else
-						{
-							newSplitter->addWidget(dockAtWidget);
-							newSplitter->addWidget(windowToDock);
-						}
-
-						parentSplitter->insertWidget(idxDockAt, newSplitter);
+						newSplitter->addWidget(dockAtWidget);
+						newSplitter->addWidget(windowToDock);
 					}
 					}
+
+					parentSplitter->insertWidget(idxDockAt, newSplitter);
 				}
 				}
 			}
 			}
 
 

+ 9 - 0
TODO.txt

@@ -78,6 +78,15 @@ So final solution:
  - Resource creation on DX11 should be direct though, without a queue (especially if we manage to populate a resource in the same step)
  - Resource creation on DX11 should be direct though, without a queue (especially if we manage to populate a resource in the same step)
  - Remove & replace internal data copying in GpuParamBlock (or just use a allocator instead of new())
  - Remove & replace internal data copying in GpuParamBlock (or just use a allocator instead of new())
 
 
+A POSSIBLY BETTER SOLUTION THAN COPYING ALL THE DATA?
+Classes derive from ISharedMemoryBuffer
+ - For example PixelData, used when setting texture pixels
+ - They have lock, unlock & clone methods
+  - Users can choose whether they want to lock themselves out from modifying the class, or clone it, before passing it to a threaded method
+ - Downside is that I need to do this for every class that will be used in threaded methods
+ - Upside is that I think that is how DX handles its buffers at the moment
+
+
 <<<<RenderSystem needed modifications>>>>
 <<<<RenderSystem needed modifications>>>>
   - Texture resource views (Specifying just a subresource of a texture as a shader parameter)
   - Texture resource views (Specifying just a subresource of a texture as a shader parameter)
   - UAV for textures
   - UAV for textures

+ 1 - 0
TODOEditor.txt

@@ -30,6 +30,7 @@ TODO for next few days:
 
 
 Dock overlay widget colors need to be customizable
 Dock overlay widget colors need to be customizable
 
 
+Test if new docked widgets work
 Unique IDs for windows. Currently I don't guarantee IDs will be the same if user adds a window before I restore them from file.
 Unique IDs for windows. Currently I don't guarantee IDs will be the same if user adds a window before I restore them from file.
 
 
 When restoring windows what happens why I try to restore an unloaded plugin?
 When restoring windows what happens why I try to restore an unloaded plugin?