Răsfoiți Sursa

Refactored how editor windows and widgets work in preparation for docked windows (untested)

Marko Pintera 12 ani în urmă
părinte
comite
0ac9b2230d
30 a modificat fișierele cu 434 adăugiri și 240 ștergeri
  1. 31 11
      CamelotEditor/CamelotEditor.vcxproj
  2. 27 18
      CamelotEditor/CamelotEditor.vcxproj.filters
  3. 6 3
      CamelotEditor/Include/CmEditorPrefs.h
  4. 4 2
      CamelotEditor/Include/CmEditorPrerequisites.h
  5. 2 2
      CamelotEditor/Include/CmEditorWidgetFactory.h
  6. 21 7
      CamelotEditor/Include/CmEditorWindowManager.h
  7. 3 3
      CamelotEditor/Include/CmHierarchyWidgetFactory.h
  8. 31 0
      CamelotEditor/Include/CmQtEditorWidget.h
  9. 19 8
      CamelotEditor/Include/CmQtEditorWindow.h
  10. 15 0
      CamelotEditor/Include/CmQtHierarchyWidget.h
  11. 0 15
      CamelotEditor/Include/CmQtHierarchyWindow.h
  12. 15 0
      CamelotEditor/Include/CmQtSceneWidget.h
  13. 0 15
      CamelotEditor/Include/CmQtSceneWindow.h
  14. 3 3
      CamelotEditor/Include/CmSceneWidgetFactory.h
  15. 2 4
      CamelotEditor/Include/CmWindowDockManager.h
  16. 4 4
      CamelotEditor/Source/CmEditorApplication.cpp
  17. 20 5
      CamelotEditor/Source/CmEditorPrefs.cpp
  18. 56 32
      CamelotEditor/Source/CmEditorWindowManager.cpp
  19. 28 0
      CamelotEditor/Source/CmHierarchyWidgetFactory.cpp
  20. 0 28
      CamelotEditor/Source/CmHierarchyWindowFactory.cpp
  21. 10 0
      CamelotEditor/Source/CmQtEditorWidget.cpp
  22. 77 16
      CamelotEditor/Source/CmQtEditorWindow.cpp
  23. 12 0
      CamelotEditor/Source/CmQtHierarchyWidget.cpp
  24. 0 12
      CamelotEditor/Source/CmQtHierarchyWindow.cpp
  25. 13 0
      CamelotEditor/Source/CmQtSceneWidget.cpp
  26. 0 13
      CamelotEditor/Source/CmQtSceneWindow.cpp
  27. 28 0
      CamelotEditor/Source/CmSceneWidgetFactory.cpp
  28. 0 28
      CamelotEditor/Source/CmSceneWindowFactory.cpp
  29. 4 10
      CamelotEditor/Source/CmWindowDockManager.cpp
  30. 3 1
      TODOEditor.txt

+ 31 - 11
CamelotEditor/CamelotEditor.vcxproj

@@ -156,11 +156,12 @@
   <ItemGroup>
     <ClCompile Include="GeneratedFiles\moc_CmQtDockOverlayWidget.cpp" />
     <ClCompile Include="GeneratedFiles\moc_CmQtEditor.cpp" />
+    <ClCompile Include="GeneratedFiles\moc_CmQtEditorWidget.cpp" />
     <ClCompile Include="GeneratedFiles\moc_CmQtEditorWindow.cpp" />
-    <ClCompile Include="GeneratedFiles\moc_CmQtHierarchyWindow.cpp" />
+    <ClCompile Include="GeneratedFiles\moc_CmQtHierarchyWidget.cpp" />
     <ClCompile Include="GeneratedFiles\moc_CmQtNewProject.cpp" />
     <ClCompile Include="GeneratedFiles\moc_CmQtProjectSelection.cpp" />
-    <ClCompile Include="GeneratedFiles\moc_CmQtSceneWindow.cpp" />
+    <ClCompile Include="GeneratedFiles\moc_CmQtSceneWidget.cpp" />
     <ClCompile Include="GeneratedFiles\qrc_CmEditor.cpp">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
       </PrecompiledHeader>
@@ -175,19 +176,20 @@
     <ClCompile Include="Source\CmEditorApplication.cpp" />
     <ClCompile Include="Source\CmEditorPrefs.cpp" />
     <ClCompile Include="Source\CmEditorWindowManager.cpp" />
-    <ClCompile Include="Source\CmHierarchyWindowFactory.cpp" />
+    <ClCompile Include="Source\CmHierarchyWidgetFactory.cpp" />
     <ClCompile Include="Source\CmPreferences.cpp" />
     <ClCompile Include="Source\CmProjectPrefs.cpp" />
     <ClCompile Include="Source\CmQtDockOverlayWidget.cpp" />
     <ClCompile Include="Source\CmQtEditor.cpp" />
+    <ClCompile Include="Source\CmQtEditorWidget.cpp" />
     <ClCompile Include="Source\CmQtEditorWindow.cpp" />
-    <ClCompile Include="Source\CmQtHierarchyWindow.cpp" />
+    <ClCompile Include="Source\CmQtHierarchyWidget.cpp" />
     <ClCompile Include="Source\CmQtNewProject.cpp" />
     <ClCompile Include="Source\CmQtProjectSelection.cpp" />
-    <ClCompile Include="Source\CmSceneWindowFactory.cpp" />
+    <ClCompile Include="Source\CmSceneWidgetFactory.cpp" />
     <ClCompile Include="Source\CmWindowDockManager.cpp" />
     <ClCompile Include="Source\main.cpp" />
-    <ClCompile Include="Source\CmQtSceneWindow.cpp" />
+    <ClCompile Include="Source\CmQtSceneWidget.cpp" />
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="Include\CmQtEditor.h">
@@ -235,9 +237,9 @@
     <ClInclude Include="Include\CmEditorApplication.h" />
     <ClInclude Include="Include\CmEditorPrefs.h" />
     <ClInclude Include="Include\CmEditorPrerequisites.h" />
-    <ClInclude Include="Include\CmEditorWindowFactory.h" />
+    <ClInclude Include="Include\CmEditorWidgetFactory.h" />
     <ClInclude Include="Include\CmEditorWindowManager.h" />
-    <ClInclude Include="Include\CmHierarchyWindowFactory.h" />
+    <ClInclude Include="Include\CmHierarchyWidgetFactory.h" />
     <ClInclude Include="Include\CmPreferences.h" />
     <ClInclude Include="Include\CmProjectPrefs.h" />
     <CustomBuild Include="Include\CmQtDockOverlayWidget.h">
@@ -276,7 +278,7 @@
       <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\moc_%(Filename).cpp</Outputs>
       <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
     </CustomBuild>
-    <CustomBuild Include="Include\CmQtHierarchyWindow.h">
+    <CustomBuild Include="Include\CmQtHierarchyWidget.h">
       <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe"  "%(FullPath)" -o ".\GeneratedFiles\moc_%(Filename).cpp"  -DQT_NO_KEYWORDS -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL  "-I.\GeneratedFiles" "-I.\Include" "-I.\Dependencies\Include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\CamelotCore\Include" "-I.\..\CamelotUtility\Include" "-I.\..\Dependencies\Include"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Filename)...</Message>
       <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\moc_%(Filename).cpp</Outputs>
@@ -294,7 +296,7 @@
       <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\moc_%(Filename).cpp</Outputs>
       <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
     </CustomBuild>
-    <CustomBuild Include="Include\CmQtSceneWindow.h">
+    <CustomBuild Include="Include\CmQtSceneWidget.h">
       <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe"  "%(FullPath)" -o ".\GeneratedFiles\moc_%(Filename).cpp"  -DQT_NO_KEYWORDS -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL  "-I.\GeneratedFiles" "-I.\Include" "-I.\Dependencies\Include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\CamelotCore\Include" "-I.\..\CamelotUtility\Include" "-I.\..\Dependencies\Include"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Filename)...</Message>
       <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\moc_%(Filename).cpp</Outputs>
@@ -312,7 +314,25 @@
       <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\moc_%(Filename).cpp</Outputs>
       <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
     </CustomBuild>
-    <ClInclude Include="Include\CmSceneWindowFactory.h" />
+    <CustomBuild Include="Include\CmQtEditorWidget.h">
+      <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Filename)...</Message>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\moc_%(Filename).cpp</Outputs>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe"  "%(FullPath)" -o ".\GeneratedFiles\moc_%(Filename).cpp"  -DQT_NO_KEYWORDS -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL  "-I.\GeneratedFiles" "-I.\Include" "-I.\Dependencies\Include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\CamelotCore\Include" "-I.\..\CamelotUtility\Include" "-I.\..\Dependencies\Include"</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe"  "%(FullPath)" -o ".\GeneratedFiles\moc_%(Filename).cpp"  -DQT_NO_KEYWORDS -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL  "-I.\GeneratedFiles" "-I.\Include" "-I.\Dependencies\Include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\CamelotCore\Include" "-I.\..\CamelotUtility\Include" "-I.\..\Dependencies\Include"</Command>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing %(Filename)...</Message>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\moc_%(Filename).cpp</Outputs>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe"  "%(FullPath)" -o ".\GeneratedFiles\moc_%(Filename).cpp"  -DQT_NO_KEYWORDS -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL  "-I.\GeneratedFiles" "-I.\Include" "-I.\Dependencies\Include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\CamelotCore\Include" "-I.\..\CamelotUtility\Include" "-I.\..\Dependencies\Include"</Command>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing %(Filename)...</Message>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\moc_%(Filename).cpp</Outputs>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe"  "%(FullPath)" -o ".\GeneratedFiles\moc_%(Filename).cpp"  -DQT_NO_KEYWORDS -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL  "-I.\GeneratedFiles" "-I.\Include" "-I.\Dependencies\Include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\CamelotCore\Include" "-I.\..\CamelotUtility\Include" "-I.\..\Dependencies\Include"</Command>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing %(Filename)...</Message>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\moc_%(Filename).cpp</Outputs>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+    </CustomBuild>
+    <ClInclude Include="Include\CmSceneWidgetFactory.h" />
     <ClInclude Include="Include\CmWindowDockManager.h" />
     <CustomBuild Include="Include\CmQtNewProject.h">
       <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe"  "%(FullPath)" -o ".\GeneratedFiles\moc_%(Filename).cpp"  -DQT_NO_KEYWORDS -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL  "-I.\GeneratedFiles" "-I.\Include" "-I.\Dependencies\Include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\CamelotCore\Include" "-I.\..\CamelotUtility\Include" "-I.\..\Dependencies\Include"</Command>

+ 27 - 18
CamelotEditor/CamelotEditor.vcxproj.filters

@@ -81,29 +81,35 @@
     <ClCompile Include="GeneratedFiles\moc_CmQtEditorWindow.cpp">
       <Filter>Generated Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\CmQtSceneWindow.cpp">
-      <Filter>Source Files\Qt</Filter>
+    <ClCompile Include="Source\CmWindowDockManager.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmEditorWindowManager.cpp">
+      <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\CmQtHierarchyWindow.cpp">
+    <ClCompile Include="Source\CmQtEditorWidget.cpp">
       <Filter>Source Files\Qt</Filter>
     </ClCompile>
-    <ClCompile Include="GeneratedFiles\moc_CmQtHierarchyWindow.cpp">
-      <Filter>Generated Files</Filter>
+    <ClCompile Include="Source\CmQtSceneWidget.cpp">
+      <Filter>Source Files\Qt</Filter>
     </ClCompile>
-    <ClCompile Include="GeneratedFiles\moc_CmQtSceneWindow.cpp">
-      <Filter>Generated Files</Filter>
+    <ClCompile Include="Source\CmQtHierarchyWidget.cpp">
+      <Filter>Source Files\Qt</Filter>
     </ClCompile>
-    <ClCompile Include="Source\CmWindowDockManager.cpp">
+    <ClCompile Include="Source\CmSceneWidgetFactory.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\CmSceneWindowFactory.cpp">
+    <ClCompile Include="Source\CmHierarchyWidgetFactory.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\CmHierarchyWindowFactory.cpp">
-      <Filter>Source Files</Filter>
+    <ClCompile Include="GeneratedFiles\moc_CmQtHierarchyWidget.cpp">
+      <Filter>Generated Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\CmEditorWindowManager.cpp">
-      <Filter>Source Files</Filter>
+    <ClCompile Include="GeneratedFiles\moc_CmQtSceneWidget.cpp">
+      <Filter>Generated Files</Filter>
+    </ClCompile>
+    <ClCompile Include="GeneratedFiles\moc_CmQtEditorWidget.cpp">
+      <Filter>Generated Files</Filter>
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
@@ -125,10 +131,13 @@
     <CustomBuild Include="Include\CmQtDockOverlayWidget.h">
       <Filter>Header Files\Qt</Filter>
     </CustomBuild>
-    <CustomBuild Include="Include\CmQtHierarchyWindow.h">
+    <CustomBuild Include="Include\CmQtEditorWidget.h">
+      <Filter>Header Files\Qt</Filter>
+    </CustomBuild>
+    <CustomBuild Include="Include\CmQtSceneWidget.h">
       <Filter>Header Files\Qt</Filter>
     </CustomBuild>
-    <CustomBuild Include="Include\CmQtSceneWindow.h">
+    <CustomBuild Include="Include\CmQtHierarchyWidget.h">
       <Filter>Header Files\Qt</Filter>
     </CustomBuild>
   </ItemGroup>
@@ -160,13 +169,13 @@
     <ClInclude Include="Include\CmEditorWindowManager.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\CmEditorWindowFactory.h">
+    <ClInclude Include="Include\CmSceneWidgetFactory.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\CmSceneWindowFactory.h">
+    <ClInclude Include="Include\CmHierarchyWidgetFactory.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\CmHierarchyWindowFactory.h">
+    <ClInclude Include="Include\CmEditorWidgetFactory.h">
       <Filter>Header Files</Filter>
     </ClInclude>
   </ItemGroup>

+ 6 - 3
CamelotEditor/Include/CmEditorPrefs.h

@@ -21,12 +21,15 @@ namespace CamelotEditor
 	{
 		WindowLayoutDesc()
 			:width(0), height(0), left(0), top(0), 
-			screenIdx(-1), maximized(true), dockState(WDS_FLOATING)
+			screenIdx(-1), maximized(true), dockState(WDS_FLOATING), 
+			dockParentId(-1), activeWidget(0), id(0)
 		{
 
 		}
 
-		QString name;
+		UINT32 activeWidget;
+		vector<QString>::type childWidgetNames;
+		UINT32 id;
 		UINT32 width;
 		UINT32 height;
 		UINT32 left;
@@ -34,7 +37,7 @@ namespace CamelotEditor
 		UINT32 screenIdx;
 		bool maximized;
 		WindowDockState dockState;
-		QString dockParentName;
+		INT32 dockParentId;
 	};
 
 	class EditorPrefs : public CamelotEngine::Module<EditorPrefs>

+ 4 - 2
CamelotEditor/Include/CmEditorPrerequisites.h

@@ -12,12 +12,14 @@ namespace CamelotEditor
 	class ProjectPrefs;
 	class QtEditor;
 	class QtDockOverlayWidget;
-	class EditorWindowFactory;
+	class EditorWidgetFactory;
 	class QtEditorWindow;
+	class QtEditorWidget;
 }
 
 // Qt
 class QWidget;
 class QLabel;
 class QPushButton;
-class QSplitter;
+class QSplitter;
+class QStackedWidget;

+ 2 - 2
CamelotEditor/Include/CmEditorWindowFactory.h → CamelotEditor/Include/CmEditorWidgetFactory.h

@@ -5,10 +5,10 @@
 
 namespace CamelotEditor
 {
-	class EditorWindowFactory
+	class EditorWidgetFactory
 	{
 	public:
-		virtual QtEditorWindow* create(QWidget* parent) = 0;
+		virtual QtEditorWidget* create(QWidget* parent) = 0;
 
 		virtual const QString& getWindowName() const = 0;
 		virtual const QString& getMenuCategory() const = 0;

+ 21 - 7
CamelotEditor/Include/CmEditorWindowManager.h

@@ -10,12 +10,23 @@ namespace CamelotEditor
 	class EditorWindowManager : public Module<EditorWindowManager>
 	{		
 	public:
-		void registerWindowFactory(EditorWindowFactory* factory);
-
-		QtEditorWindow* openWindow(const QString& name);
+		EditorWindowManager();
+
+		void registerWidgetFactory(EditorWidgetFactory* factory);
+
+		/**
+		 * @brief	Opens a widget with the specified name and adds it to a window. Only one widget of a
+		 * 			certain type may be open at one time.
+		 *
+		 * @param	name  	The name of the widget type. This will be used to find the widget factory.
+		 * @param	parent	(optional) Parent to which to attach the widget to. If null, a new window will be created.
+		 *
+		 * @return	Returns the window the widget was added to.
+		 */
+		void openWidget(const QString& name, QtEditorWindow* parent = nullptr);
 		boost::function<void()> getOpenCallback(const QString& name);
 
-		QtEditorWindow* getOpenWindow(const QString& name) const;
+		QtEditorWindow* getOpenWindow(INT32 id) const;
 
 		void restoreWindowsFromPrefs();
 		void saveWindowsToPrefs();
@@ -23,11 +34,14 @@ namespace CamelotEditor
 		vector<QString>::type getAvailableWindowTypes() const;
 
 	private:
-		map<QString, EditorWindowFactory*>::type mFactories;
-		map<QString, QtEditorWindow*>::type mOpenWindows;
+		map<QString, EditorWidgetFactory*>::type mFactories;
+		map<UINT32, QtEditorWindow*>::type mOpenWindows;
+		map<QString, QtEditorWidget*>::type mOpenWidgets;
+		UINT32 mMaxOpenWindowId;
 
-		EditorWindowFactory* getFactory(const QString& name) const;
+		EditorWidgetFactory* getFactory(const QString& name) const;
 
+		QtEditorWindow* openWindow(UINT32 forcedId = -1);
 		void windowClosed(QtEditorWindow* window);
 	};
 

+ 3 - 3
CamelotEditor/Include/CmHierarchyWindowFactory.h → CamelotEditor/Include/CmHierarchyWidgetFactory.h

@@ -1,15 +1,15 @@
 #pragma once
 
 #include "CmEditorPrerequisites.h"
-#include "CmEditorWindowFactory.h"
+#include "CmEditorWidgetFactory.h"
 #include <QtCore/QString>
 
 namespace CamelotEditor
 {
-	class HierarchyWindowFactory : public EditorWindowFactory
+	class HierarchyWidgetFactory : public EditorWidgetFactory
 	{
 	public:
-		QtEditorWindow* create(QWidget* parent);
+		QtEditorWidget* create(QWidget* parent);
 
 		const QString& getWindowName() const;
 		const QString& getMenuCategory() const;

+ 31 - 0
CamelotEditor/Include/CmQtEditorWidget.h

@@ -0,0 +1,31 @@
+#pragma once
+
+#include "CmEditorPrerequisites.h"
+#include <QtWidgets/QWidget>
+
+namespace CamelotEditor
+{
+	class QtEditorWidget : public QWidget
+	{
+		Q_OBJECT
+
+	public:
+		QtEditorWidget(QWidget* parent, const QString& name, const QString& title);
+		virtual ~QtEditorWidget() { }
+
+		const QString& getName() const { return mName; }
+		const QString& getTitle() const { return mTitle; }
+
+		QtEditorWindow* getParentWindow() const { return mParentWindow; }
+
+	private:
+		friend class QtEditorWindow;
+		
+		QString mName;
+		QString mTitle;
+
+		QtEditorWindow* mParentWindow;
+
+		void setParentWindow(QtEditorWindow* parentWindow) { mParentWindow = parentWindow; }
+	};
+}

+ 19 - 8
CamelotEditor/Include/CmQtEditorWindow.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include "CmEditorPrerequisites.h"
+#include "CmQtEditorWidget.h"
 #include "CmEditorPrefs.h"
 #include <QtWidgets/QWidget>
 #include <QtCore/QPoint>
@@ -24,25 +25,32 @@ namespace CamelotEditor
 		};
 
 	public:
-		QtEditorWindow(QWidget* parent, const QString& name, const QString& title);
+		QtEditorWindow(QWidget* parent, UINT32 id);
 		virtual ~QtEditorWindow() { }
 
-		const QString& getName() const { return mName; }
-
 		void undock();
 		void dock();
 
 		bool isDocked() const { return mIsDocked; }
+		UINT32 getId() const { return mId; }
+
 		WindowLayoutDesc getLayoutDesc() const;
 		void restoreFromLayoutDesc(const WindowLayoutDesc& desc);
 
+		void addWidget(QtEditorWidget* widget);
+		void insertWidget(UINT32 idx, QtEditorWidget* widget);
+		void removeWidget(UINT32 idx);
+		UINT32 getNumWidgets() const { return (UINT32)mEditorWidgets.size(); }
+		QtEditorWidget* getWidget(UINT32 idx) const;
+
+		void setActiveWidget(UINT32 idx);
+
 		boost::signal<void(QtEditorWindow*)> onClosed;
 	protected:
-		QWidget* mContentWidget;
-
 		QSizePolicy	sizePolicy() const;
 
 	private:
+		UINT32 mId;
 		ResizeMode mResizeMode;
 		bool mMoveMode;
 		QPoint mDragOffset;
@@ -50,13 +58,16 @@ namespace CamelotEditor
 		QLabel* mLblTitle;
 		QPushButton* mBtnClose;
 		QWidget* mCentralWidget;
+		QStackedWidget* mStackedWidget;
 		QTimer* mTimer;
 		bool mIsDocked;
-		QString mName;
 
-		void setupUi(QString title);
+		vector<QtEditorWidget*>::type mEditorWidgets;
+		UINT32 mActiveWidgetIdx;
+
+		void setupUi();
 		void setupSignals();
-		void retranslateUi(QString title);
+		void retranslateUi();
 		void setObjectNames();
 
 		void enterEvent(QEvent *e);

+ 15 - 0
CamelotEditor/Include/CmQtHierarchyWidget.h

@@ -0,0 +1,15 @@
+#pragma once
+
+#include "CmEditorPrefs.h"
+#include "CmQtEditorWidget.h"
+
+namespace CamelotEditor
+{
+	class QtHierarchyWidget: public QtEditorWidget
+	{
+		Q_OBJECT
+	public:
+		QtHierarchyWidget(QWidget* parent);
+		virtual ~QtHierarchyWidget();
+	};
+}

+ 0 - 15
CamelotEditor/Include/CmQtHierarchyWindow.h

@@ -1,15 +0,0 @@
-#pragma once
-
-#include "CmEditorPrefs.h"
-#include "CmQtEditorWindow.h"
-
-namespace CamelotEditor
-{
-	class QtHierarchyWindow: public QtEditorWindow
-	{
-		Q_OBJECT
-	public:
-		QtHierarchyWindow(QWidget* parent);
-		virtual ~QtHierarchyWindow();
-	};
-}

+ 15 - 0
CamelotEditor/Include/CmQtSceneWidget.h

@@ -0,0 +1,15 @@
+#pragma once
+
+#include "CmEditorPrefs.h"
+#include "CmQtEditorWidget.h"
+
+namespace CamelotEditor
+{
+	class QtSceneWidget: public QtEditorWidget
+	{
+		Q_OBJECT
+	public:
+		QtSceneWidget(QWidget* parent);
+		virtual ~QtSceneWidget();
+	};
+}

+ 0 - 15
CamelotEditor/Include/CmQtSceneWindow.h

@@ -1,15 +0,0 @@
-#pragma once
-
-#include "CmEditorPrefs.h"
-#include "CmQtEditorWindow.h"
-
-namespace CamelotEditor
-{
-	class QtSceneWindow: public QtEditorWindow
-	{
-		Q_OBJECT
-	public:
-		QtSceneWindow(QWidget* parent);
-		virtual ~QtSceneWindow();
-	};
-}

+ 3 - 3
CamelotEditor/Include/CmSceneWindowFactory.h → CamelotEditor/Include/CmSceneWidgetFactory.h

@@ -1,15 +1,15 @@
 #pragma once
 
 #include "CmEditorPrerequisites.h"
-#include "CmEditorWindowFactory.h"
+#include "CmEditorWidgetFactory.h"
 #include <QtCore/QString>
 
 namespace CamelotEditor
 {
-	class SceneWindowFactory : public EditorWindowFactory
+	class SceneWidgetFactory : public EditorWidgetFactory
 	{
 	public:
-		QtEditorWindow* create(QWidget* parent);
+		QtEditorWidget* create(QWidget* parent);
 
 		const QString& getWindowName() const;
 		const QString& getMenuCategory() const;

+ 2 - 4
CamelotEditor/Include/CmWindowDockManager.h

@@ -10,7 +10,7 @@ namespace CamelotEditor
 	{
 		struct DockedWindowInfo
 		{
-			QString parentName;
+			INT32 parentId;
 			WindowDragDropLocation dockLocation;
 		};
 
@@ -26,9 +26,7 @@ namespace CamelotEditor
 
 		bool isDocked(const QtEditorWindow* window) const;
 		WindowDragDropLocation getDockLocation(const QtEditorWindow* window) const;
-		QString getDockParentName(const QtEditorWindow* window) const;
-
-		const QString& getRootDockNodeName() const;
+		INT32 getDockParentId(const QtEditorWindow* window) const;
 	private:
 		QtDockOverlayWidget* mDockOverlayWidget;
 		QWidget* mCentralWidget;

+ 4 - 4
CamelotEditor/Source/CmEditorApplication.cpp

@@ -5,8 +5,8 @@
 #include "CmQtProjectSelection.h"
 #include "CmEditorWindowManager.h"
 #include "CmWindowDockManager.h"
-#include "CmSceneWindowFactory.h"
-#include "CmHierarchyWindowFactory.h"
+#include "CmSceneWidgetFactory.h"
+#include "CmHierarchyWidgetFactory.h"
 #include "CmFileSystem.h"
 #include "CmException.h"
 #include "CmDataStream.h"
@@ -51,8 +51,8 @@ namespace CamelotEditor
 		EditorWindowManager::startUp(new EditorWindowManager());
 		WindowDockManager::startUp(new WindowDockManager(p->mEditor->getCentralWidget(), p->mEditor->getDockOverlayWidget()));
 
-		gEditorWindowManager().registerWindowFactory(new SceneWindowFactory());
-		gEditorWindowManager().registerWindowFactory(new HierarchyWindowFactory());
+		gEditorWindowManager().registerWidgetFactory(new SceneWidgetFactory());
+		gEditorWindowManager().registerWidgetFactory(new HierarchyWidgetFactory());
 
 		vector<QString>::type windowTypes = gEditorWindowManager().getAvailableWindowTypes();
 		for(auto iter = windowTypes.begin(); iter != windowTypes.end(); ++iter)

+ 20 - 5
CamelotEditor/Source/CmEditorPrefs.cpp

@@ -47,7 +47,6 @@ namespace CamelotEditor
 	void EditorPrefs::setMainWindowLayout(const WindowLayoutDesc& desc)
 	{
 		mMainWindowLayout = desc;
-		mMainWindowLayout.name = "MainWindow";
 	}
 
 	const WindowLayoutDesc& EditorPrefs::getMainWindowLayout() const
@@ -98,7 +97,7 @@ namespace CamelotEditor
 	void EditorPrefs::saveWindowLayout(xml_node parentNode, const WindowLayoutDesc& desc) const
 	{
 		xml_node windowLayout = parentNode.append_child("WindowLayout");
-		windowLayout.append_attribute("name").set_value(desc.name.toStdString().c_str());
+		parentNode.append_attribute("id").set_value(desc.id);
 
 		xml_node windowGeometry = windowLayout.append_child("Geometry");
 		windowGeometry.append_attribute("left").set_value(desc.left);
@@ -112,14 +111,22 @@ namespace CamelotEditor
 
 		xml_node dockInfo = windowLayout.append_child("DockInfo");
 		dockInfo.append_attribute("state").set_value((UINT32)desc.dockState);
-		dockInfo.append_attribute("parentName").set_value(desc.dockParentName.toStdString().c_str());
+		dockInfo.append_attribute("parentId").set_value(desc.dockParentId);
+
+		xml_node childWidgets = windowLayout.append_child("ChildWidgets");
+		childWidgets.append_attribute("activeWidgetIdx").set_value(desc.activeWidget);
+
+		for(auto iter = desc.childWidgetNames.begin(); iter != desc.childWidgetNames.end(); ++iter)
+		{
+			childWidgets.append_child("ChildWidget").append_attribute("name").set_value(iter->toStdString().c_str());
+		}
 	}
 
 	WindowLayoutDesc EditorPrefs::loadWindowLayout(xml_node node) const
 	{
 		WindowLayoutDesc desc;
 
-		desc.name = node.attribute("name").value();
+		desc.id = node.attribute("id").as_uint();
 
 		desc.left = node.child("Geometry").attribute("left").as_uint();
 		desc.top = node.child("Geometry").attribute("top").as_uint();
@@ -130,7 +137,15 @@ namespace CamelotEditor
 		desc.screenIdx = node.child("Screen").attribute("screenIdx").as_uint();
 
 		desc.dockState = (WindowDockState)node.child("DockInfo").attribute("state").as_uint();
-		desc.dockParentName = node.child("DockInfo").attribute("parentName").as_string();
+		desc.dockParentId = node.child("DockInfo").attribute("parentId").as_int();
+
+		desc.activeWidget = node.child("ChildWidgets").attribute("activeWidgetIdx").as_uint();
+
+		xml_node childWidgets = node.child("ChildWidgets");
+		for (xml_node childWidget = childWidgets.child("ChildWidget"); childWidget; childWidget = childWidgets.next_sibling("ChildWidget"))
+		{
+			desc.childWidgetNames.push_back(childWidget.attribute("name").as_string());
+		}
 
 		return desc;
 	}

+ 56 - 32
CamelotEditor/Source/CmEditorWindowManager.cpp

@@ -1,7 +1,7 @@
 #include "CmEditorWindowManager.h"
 #include "CmEditorApplication.h"
 #include "CmQtEditorWindow.h"
-#include "CmEditorWindowFactory.h"
+#include "CmEditorWidgetFactory.h"
 #include "CmWindowDockManager.h"
 #include "CmEditorPrefs.h"
 #include "CmException.h"
@@ -10,47 +10,71 @@
 
 namespace CamelotEditor
 {
-	struct WindowLayoutNode
-	{
-		QtEditorWindow* window;
-		WindowLayoutNode* child;
-	};
+	EditorWindowManager::EditorWindowManager()
+		:mMaxOpenWindowId(0)
+	{ }
 
-	void EditorWindowManager::registerWindowFactory(EditorWindowFactory* factory)
+	void EditorWindowManager::registerWidgetFactory(EditorWidgetFactory* factory)
 	{
 		assert(factory != nullptr);
 
 		mFactories[factory->getWindowName()] = factory;
 	}
 
-	QtEditorWindow* EditorWindowManager::openWindow(const QString& name)
+	void EditorWindowManager::openWidget(const QString& name, QtEditorWindow* parent)
 	{
-		auto iterFind = mOpenWindows.find(name);
-		if(iterFind != mOpenWindows.end())
-			return nullptr; // Window already open
+		auto iterFind = mOpenWidgets.find(name);
+		if(iterFind != mOpenWidgets.end())
+			return; // Widget already open
+
+		EditorWidgetFactory* factory = getFactory(name);
+		
+		if(parent == nullptr)
+			parent = openWindow();
+		
+		QtEditorWidget* widget = factory->create(parent);
+		parent->addWidget(widget);
 
-		EditorWindowFactory* factory = getFactory(name);
-		QtEditorWindow* window = factory->create(gEditorApp().getMainWindow());
+		mOpenWidgets[name] = widget;
+	}
+
+	boost::function<void()> EditorWindowManager::getOpenCallback(const QString& name)
+	{
+		return boost::bind(&EditorWindowManager::openWidget, this, name, nullptr);
+	}
+
+	QtEditorWindow* EditorWindowManager::openWindow(UINT32 forcedId)
+	{
+		if(forcedId != -1)
+		{
+			auto iterFindId = mOpenWindows.find(forcedId);
+			if(iterFindId != mOpenWindows.end())
+				CM_EXCEPT(InvalidParametersException, "Window with the specified id already exists: " + toString(forcedId));
+		}
+
+		UINT32 windowId = 0;
+		if(forcedId != -1)
+			windowId = -1;
+		else
+			windowId = mMaxOpenWindowId;
+
+		mMaxOpenWindowId = windowId + 1;
+
+		QtEditorWindow* window = new QtEditorWindow(gEditorApp().getMainWindow(), windowId);
+		mOpenWindows[windowId] = window;
 
 		window->onClosed.connect(boost::bind(&EditorWindowManager::windowClosed, this, _1));
 		window->setAttribute(Qt::WA_DeleteOnClose, true);
 		window->show();
 
-		mOpenWindows[name] = window;
-
 		return window;
 	}
 
-	boost::function<void()> EditorWindowManager::getOpenCallback(const QString& name)
-	{
-		return boost::bind(&EditorWindowManager::openWindow, this, name);
-	}
-
-	QtEditorWindow* EditorWindowManager::getOpenWindow(const QString& name) const
+	QtEditorWindow* EditorWindowManager::getOpenWindow(INT32 id) const
 	{
-		auto iterFind = mOpenWindows.find(name);
+		auto iterFind = mOpenWindows.find(id);
 		if(iterFind == mOpenWindows.end())
-			CM_EXCEPT(InvalidParametersException, "There is no open window with name " + name.toStdString() + ".");
+			CM_EXCEPT(InvalidParametersException, "There is no open window with id " + toString(id) + ".");
 
 		return iterFind->second;
 	}
@@ -59,19 +83,19 @@ namespace CamelotEditor
 	{
 		vector<WindowLayoutDesc>::type windowLayouts = gEditorPrefs().getWindowLayouts();
 		
-		WindowLayoutNode* rootDockNode = nullptr;
-		QString parentName = gWindowDockManager().getRootDockNodeName();
+		UINT32 parentId = -1;
 		bool foundDockedWindow = true;
 		while(foundDockedWindow)
 		{
 			foundDockedWindow = false;
 			for(auto iter = windowLayouts.begin(); iter != windowLayouts.end(); ++iter)
 			{
-				if(iter->dockState != WDS_FLOATING && iter->dockParentName == parentName)
+				if(iter->dockState != WDS_FLOATING && iter->dockParentId == parentId)
 				{
-					QtEditorWindow* window = openWindow(iter->name);
+					QtEditorWindow* window = openWindow(iter->id);
+					
 					window->restoreFromLayoutDesc(*iter);
-					parentName = window->getName();
+					parentId = window->getId();
 
 					foundDockedWindow = true;
 					break;
@@ -84,7 +108,7 @@ namespace CamelotEditor
 		{
 			if(iter->dockState == WDS_FLOATING)
 			{
-				QtEditorWindow* window = openWindow(iter->name);
+				QtEditorWindow* window = openWindow(iter->id);
 				window->restoreFromLayoutDesc(*iter);
 			}
 		}
@@ -112,7 +136,7 @@ namespace CamelotEditor
 		return types;
 	}
 
-	EditorWindowFactory* EditorWindowManager::getFactory(const QString& name) const
+	EditorWidgetFactory* EditorWindowManager::getFactory(const QString& name) const
 	{
 		auto iterFind = mFactories.find(name);
 
@@ -126,9 +150,9 @@ namespace CamelotEditor
 	{
 		assert(window != nullptr);
 
-		auto iterFind = mOpenWindows.find(window->getName());
+		auto iterFind = mOpenWindows.find(window->getId());
 		if(iterFind == mOpenWindows.end())
-			CM_EXCEPT(InternalErrorException, "Trying to close a window " + window->getName().toStdString() + " that is not in the open window list.");
+			CM_EXCEPT(InternalErrorException, "Trying to close a window " + toString(window->getId()) + " that is not in the open window list.");
 
 		assert(iterFind->second == window);
 

+ 28 - 0
CamelotEditor/Source/CmHierarchyWidgetFactory.cpp

@@ -0,0 +1,28 @@
+#include "CmHierarchyWidgetFactory.h"
+#include "CmQtHierarchyWidget.h"
+
+namespace CamelotEditor
+{
+	QtEditorWidget* HierarchyWidgetFactory::create(QWidget* parent)
+	{
+		return new QtHierarchyWidget(parent);
+	}
+
+	const QString& HierarchyWidgetFactory::getWindowName() const
+	{
+		static QString name = "Hierarchy";
+		return name;
+	}
+
+	const QString& HierarchyWidgetFactory::getMenuCategory() const
+	{
+		static QString name = "Windows";
+		return name;
+	}
+
+	const QString& HierarchyWidgetFactory::getMenuItemName() const
+	{
+		static QString name = "Hierarchy";
+		return name;
+	}
+}

+ 0 - 28
CamelotEditor/Source/CmHierarchyWindowFactory.cpp

@@ -1,28 +0,0 @@
-#include "CmHierarchyWindowFactory.h"
-#include "CmQtHierarchyWindow.h"
-
-namespace CamelotEditor
-{
-	QtEditorWindow* HierarchyWindowFactory::create(QWidget* parent)
-	{
-		return new QtHierarchyWindow(parent);
-	}
-
-	const QString& HierarchyWindowFactory::getWindowName() const
-	{
-		static QString name = "Hierarchy";
-		return name;
-	}
-
-	const QString& HierarchyWindowFactory::getMenuCategory() const
-	{
-		static QString name = "Windows";
-		return name;
-	}
-
-	const QString& HierarchyWindowFactory::getMenuItemName() const
-	{
-		static QString name = "Hierarchy";
-		return name;
-	}
-}

+ 10 - 0
CamelotEditor/Source/CmQtEditorWidget.cpp

@@ -0,0 +1,10 @@
+#include "CmQtEditorWidget.h"
+
+namespace CamelotEditor
+{
+	QtEditorWidget::QtEditorWidget(QWidget* parent, const QString& name, const QString& title)
+		:QWidget(parent), mName(name), mTitle(title)
+	{
+
+	}
+}

+ 77 - 16
CamelotEditor/Source/CmQtEditorWindow.cpp

@@ -5,23 +5,25 @@
 #include <QtWidgets/QLayout>
 #include <QtWidgets/QLabel>
 #include <QtWidgets/QApplication>
+#include <QtWidgets/QStackedWidget>
 #include <QtGui/QMouseEvent>
 #include <QtGui/QPainter>
 #include <QtCore/QTimer>
 
 #include "CmDebug.h"
+#include "CmQtEditorWidget.h"
 #include "CmWindowDockManager.h"
 #include "CmEditorWindowManager.h"
 
 namespace CamelotEditor
 {
-	QtEditorWindow::QtEditorWindow(QWidget* parent, const QString& name, const QString& title)
-		:QWidget(parent), mResizeMode(RM_NONE), mMoveMode(false), mIsDocked(false), mName(name)
+	QtEditorWindow::QtEditorWindow(QWidget* parent, UINT32 id)
+		:QWidget(parent), mResizeMode(RM_NONE), mMoveMode(false), mIsDocked(false), mId(id), mActiveWidgetIdx(0)
 	{
-		setupUi(title);
+		setupUi();
 	}
 
-	void QtEditorWindow::setupUi(QString title)
+	void QtEditorWindow::setupUi()
 	{
 		setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
 		
@@ -52,8 +54,7 @@ namespace CamelotEditor
 		/************************************************************************/
 
 		mCentralWidget = new QWidget(this);
-
-		mContentWidget = new QWidget(this);
+		mStackedWidget = new QStackedWidget(this);
 
 		QVBoxLayout* centralLayout = new QVBoxLayout(this);
 		centralLayout->setMargin(0);
@@ -65,11 +66,11 @@ namespace CamelotEditor
 		mainLayout->setContentsMargins(2, 0, 2, 2);
 		mainLayout->setSpacing(0);
 		mainLayout->addWidget(mTitleBar);
-		mainLayout->addWidget(mContentWidget, 1);
+		mainLayout->addWidget(mStackedWidget, 1);
 		mCentralWidget->setLayout(mainLayout);
 		
 		setObjectNames();
-		retranslateUi(title);
+		retranslateUi();
 		setupSignals();
 	}
 
@@ -79,9 +80,9 @@ namespace CamelotEditor
 		connect(mTimer, SIGNAL(timeout()), this, SLOT(timerUpdate()));
 	}
 
-	void QtEditorWindow::retranslateUi(QString title)
+	void QtEditorWindow::retranslateUi()
 	{
-		mLblTitle->setText(title);
+		mLblTitle->setText("No title");
 		mBtnClose->setText(tr("Close"));
 	}
 
@@ -92,7 +93,7 @@ namespace CamelotEditor
 		mBtnClose->setObjectName(QStringLiteral("BtnClose"));
 
 		mCentralWidget->setObjectName(QStringLiteral("CentralWidget"));
-		mContentWidget->setObjectName(QStringLiteral("ContentWidget"));
+		mStackedWidget->setObjectName(QStringLiteral("StackedWidget"));
 	}
 
 	QSizePolicy	QtEditorWindow::sizePolicy() const
@@ -126,7 +127,7 @@ namespace CamelotEditor
 		desc.left = geometry().x();
 		desc.top = geometry().y();
 		desc.screenIdx = -1;
-		desc.name = getName();
+		desc.id = getId();
 		desc.maximized = false;
 		desc.dockState = WDS_FLOATING;
 
@@ -155,14 +156,19 @@ namespace CamelotEditor
 				assert(false);
 			}
 
-			desc.dockParentName = gWindowDockManager().getDockParentName(this);
+			desc.dockParentId = gWindowDockManager().getDockParentId(this);
 		}
 		else 
 		{
 			desc.dockState = WDS_FLOATING;
-			desc.dockParentName = "";
+			desc.dockParentId = -1;
 		}
 
+		desc.activeWidget = mActiveWidgetIdx;
+
+		for(auto iter = mEditorWidgets.begin(); iter != mEditorWidgets.end(); ++iter)
+			desc.childWidgetNames.push_back((*iter)->getName());
+
 		return desc;
 	}
 
@@ -170,6 +176,9 @@ namespace CamelotEditor
 	{
 		setGeometry(desc.left, desc.top, desc.width, desc.height);
 
+		for(auto iter2 = desc.childWidgetNames.begin(); iter2 != desc.childWidgetNames.end(); ++iter2)
+			gEditorWindowManager().openWidget(*iter2, this);
+
 		if(desc.dockState != WDS_FLOATING)
 		{
 			WindowDragDropLocation dockLocation = CM_WINDROP_NONE;
@@ -194,11 +203,63 @@ namespace CamelotEditor
 
 			QtEditorWindow* dockParent = nullptr;
 
-			if(gWindowDockManager().getRootDockNodeName() != desc.dockParentName)
-				dockParent = gEditorWindowManager().getOpenWindow(desc.dockParentName);
+			if(desc.dockParentId != -1)
+				dockParent = gEditorWindowManager().getOpenWindow(desc.dockParentId);
 				
 			gWindowDockManager().dockWindow(this, dockParent, dockLocation);
 		}
+
+		setActiveWidget(desc.activeWidget);
+	}
+
+	void QtEditorWindow::addWidget(QtEditorWidget* widget)
+	{
+		assert(widget != nullptr);
+
+		auto iterFind = std::find(mEditorWidgets.begin(), mEditorWidgets.end(), widget);
+		if(iterFind != mEditorWidgets.end())
+			CM_EXCEPT(InvalidParametersException, "Specified widget already exists in this window.");
+
+		widget->setParentWindow(this);
+		mEditorWidgets.push_back(widget);
+	}
+
+	void QtEditorWindow::insertWidget(UINT32 idx, QtEditorWidget* widget)
+	{
+		assert(widget != nullptr);
+
+		auto iterFind = std::find(mEditorWidgets.begin(), mEditorWidgets.end(), widget);
+		if(iterFind != mEditorWidgets.end())
+			CM_EXCEPT(InvalidParametersException, "Specified widget already exists in this window.");
+
+		if(idx > (UINT32)mEditorWidgets.size())
+			idx = (UINT32)mEditorWidgets.size();
+
+		widget->setParentWindow(this);
+		mEditorWidgets.insert(mEditorWidgets.begin() + idx, widget);
+	}
+
+	void QtEditorWindow::removeWidget(UINT32 idx)
+	{
+		if(idx >= (UINT32)mEditorWidgets.size())
+			CM_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx) +". Valid range: 0 .. " + toString((UINT32)mEditorWidgets.size()));
+
+		mEditorWidgets.erase(mEditorWidgets.begin() + idx);
+	}
+
+	QtEditorWidget* QtEditorWindow::getWidget(UINT32 idx) const
+	{
+		return mEditorWidgets.at(idx);
+	}
+
+	void QtEditorWindow::setActiveWidget(UINT32 idx)
+	{
+		if(idx >= (UINT32)mEditorWidgets.size())
+			CM_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx) +". Valid range: 0 .. " + toString((UINT32)mEditorWidgets.size()));
+
+		mActiveWidgetIdx = idx;
+
+		// TODO
 	}
 
 	void QtEditorWindow::enterEvent(QEvent *e)

+ 12 - 0
CamelotEditor/Source/CmQtHierarchyWidget.cpp

@@ -0,0 +1,12 @@
+#include "CmQtHierarchyWidget.h"
+
+namespace CamelotEditor
+{
+	QtHierarchyWidget::QtHierarchyWidget(QWidget* parent)
+		:QtEditorWidget(parent, "Hierarchy", tr("Hierarchy"))
+	{
+
+	}
+
+	QtHierarchyWidget::~QtHierarchyWidget() { }
+}

+ 0 - 12
CamelotEditor/Source/CmQtHierarchyWindow.cpp

@@ -1,12 +0,0 @@
-#include "CmQtHierarchyWindow.h"
-
-namespace CamelotEditor
-{
-	QtHierarchyWindow::QtHierarchyWindow(QWidget* parent)
-		:QtEditorWindow(parent, "Hierarchy", tr("Hierarchy"))
-	{
-
-	}
-
-	QtHierarchyWindow::~QtHierarchyWindow() { }
-}

+ 13 - 0
CamelotEditor/Source/CmQtSceneWidget.cpp

@@ -0,0 +1,13 @@
+#include "CmQtSceneWidget.h"
+#include "QtWidgets/QFrame"
+
+namespace CamelotEditor
+{
+	QtSceneWidget::QtSceneWidget(QWidget* parent)
+		:QtEditorWidget(parent, "Scene", tr("Scene"))
+	{
+
+	}
+
+	QtSceneWidget::~QtSceneWidget() { }
+}

+ 0 - 13
CamelotEditor/Source/CmQtSceneWindow.cpp

@@ -1,13 +0,0 @@
-#include "CmQtSceneWindow.h"
-#include "QtWidgets/QFrame"
-
-namespace CamelotEditor
-{
-	QtSceneWindow::QtSceneWindow(QWidget* parent)
-		:QtEditorWindow(parent, "Scene", tr("Scene"))
-	{
-		QFrame* frame = new QFrame(this);
-	}
-
-	QtSceneWindow::~QtSceneWindow() { }
-}

+ 28 - 0
CamelotEditor/Source/CmSceneWidgetFactory.cpp

@@ -0,0 +1,28 @@
+#include "CmSceneWidgetFactory.h"
+#include "CmQtSceneWidget.h"
+
+namespace CamelotEditor
+{
+	QtEditorWidget* SceneWidgetFactory::create(QWidget* parent)
+	{
+		return new QtSceneWidget(parent);
+	}
+
+	const QString& SceneWidgetFactory::getWindowName() const
+	{
+		static QString name = "Scene";
+		return name;
+	}
+
+	const QString& SceneWidgetFactory::getMenuCategory() const
+	{
+		static QString name = "Windows";
+		return name;
+	}
+
+	const QString& SceneWidgetFactory::getMenuItemName() const
+	{
+		static QString name = "Scene";
+		return name;
+	}
+}

+ 0 - 28
CamelotEditor/Source/CmSceneWindowFactory.cpp

@@ -1,28 +0,0 @@
-#include "CmSceneWindowFactory.h"
-#include "CmQtSceneWindow.h"
-
-namespace CamelotEditor
-{
-	QtEditorWindow* SceneWindowFactory::create(QWidget* parent)
-	{
-		return new QtSceneWindow(parent);
-	}
-
-	const QString& SceneWindowFactory::getWindowName() const
-	{
-		static QString name = "Scene";
-		return name;
-	}
-
-	const QString& SceneWindowFactory::getMenuCategory() const
-	{
-		static QString name = "Windows";
-		return name;
-	}
-
-	const QString& SceneWindowFactory::getMenuItemName() const
-	{
-		static QString name = "Scene";
-		return name;
-	}
-}

+ 4 - 10
CamelotEditor/Source/CmWindowDockManager.cpp

@@ -108,12 +108,12 @@ namespace CamelotEditor
 		return findIter->second.dockLocation;
 	}
 
-	QString WindowDockManager::getDockParentName(const QtEditorWindow* window) const
+	INT32 WindowDockManager::getDockParentId(const QtEditorWindow* window) const
 	{
 		auto findIter = mDockedWindows.find(const_cast<QtEditorWindow*>(window));
 		assert(findIter != mDockedWindows.end());
 
-		return findIter->second.parentName;
+		return findIter->second.parentId;
 	}
 
 	QtEditorWindow* WindowDockManager::getDockedWindowAtPosition(const QPoint& globalPos)
@@ -256,9 +256,9 @@ namespace CamelotEditor
 		DockedWindowInfo dockedInfo;
 		dockedInfo.dockLocation = dockAtPosition;
 		if(dockAtWidget == nullptr)
-			dockedInfo.parentName = getRootDockNodeName();
+			dockedInfo.parentId = -1;
 		else
-			dockedInfo.parentName = dockAtWidget->getName();
+			dockedInfo.parentId = dockAtWidget->getId();
 
 		mDockedWindows[windowToDock] = dockedInfo;
 	}
@@ -351,12 +351,6 @@ namespace CamelotEditor
 		return dragLocations;
 	}
 
-	const QString& WindowDockManager::getRootDockNodeName() const
-	{
-		static QString rootWidgetName = "DockManagerRoot";
-		return rootWidgetName;
-	}
-
 	WindowDockManager& gWindowDockManager()
 	{
 		return WindowDockManager::instance();

+ 3 - 1
TODOEditor.txt

@@ -30,5 +30,7 @@ TODO for next few days:
 
 Dock overlay widget colors need to be customizable
 
+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.
 
-I need to save EditorWindow layout. Especially dock information. Figure out how to save that.
+When restoring windows what happens why I try to restore an unloaded plugin?
+ - A NullWindow?