Browse Source

EditorWidget keeps a reference to parent container, and notifies it on destroy more neatly

Marko Pintera 12 years ago
parent
commit
419403fcc8

+ 4 - 4
CamelotClient/Include/BsEditorWidget.h

@@ -14,19 +14,19 @@ namespace BansheeEditor
 
 
 		void _setSize(CM::UINT32 width, CM::UINT32 height);
 		void _setSize(CM::UINT32 width, CM::UINT32 height);
 		void _setPosition(CM::INT32 x, CM::INT32 y);
 		void _setPosition(CM::INT32 x, CM::INT32 y);
-		void _changeParent(BS::GUIWidget& widget);
+		void _changeParent(EditorWidgetContainer* parent);
 
 
 		void _disable();
 		void _disable();
 		void _enable();
 		void _enable();
 
 
 		static void destroy(EditorWidget* widget);
 		static void destroy(EditorWidget* widget);
-
-		boost::signal<void(EditorWidget*)> onClosed;
 	protected:
 	protected:
 		EditorWidget(const CM::WString& name);
 		EditorWidget(const CM::WString& name);
 
 
 		CM::WString mName;
 		CM::WString mName;
-		BS::GUIWidget* mParentWidget;
+		EditorWidgetContainer* mParent;
 		BS::GUIArea* mContent;
 		BS::GUIArea* mContent;
+
+		BS::GUIWidget& getParentWidget() const;
 	};
 	};
 }
 }

+ 4 - 12
CamelotClient/Include/BsEditorWidgetContainer.h

@@ -7,16 +7,6 @@ namespace BansheeEditor
 {
 {
 	class EditorWidgetContainer
 	class EditorWidgetContainer
 	{
 	{
-		struct WidgetInfo
-		{
-			WidgetInfo(EditorWidget* _widget, const boost::signals::connection& _conn)
-				:widget(_widget), conn(_conn)
-			{ }
-
-			EditorWidget* widget;
-			boost::signals::connection conn;
-		};
-
 	public:
 	public:
 		EditorWidgetContainer(BS::GUIWidget* parent);
 		EditorWidgetContainer(BS::GUIWidget* parent);
 		virtual ~EditorWidgetContainer();
 		virtual ~EditorWidgetContainer();
@@ -29,6 +19,9 @@ namespace BansheeEditor
 		void setPosition(CM::INT32 x, CM::INT32 y);
 		void setPosition(CM::INT32 x, CM::INT32 y);
 
 
 		CM::UINT32 getNumWidgets() const { return (CM::UINT32)mWidgets.size(); }
 		CM::UINT32 getNumWidgets() const { return (CM::UINT32)mWidgets.size(); }
+		BS::GUIWidget& getParentWidget() const { return *mParent; }
+
+		void _notifyWidgetDestroyed(EditorWidget* widget);
 
 
 		boost::signal<void()> onWidgetClosed;
 		boost::signal<void()> onWidgetClosed;
 	private:
 	private:
@@ -36,7 +29,7 @@ namespace BansheeEditor
 		BS::GUIWidget* mParent;
 		BS::GUIWidget* mParent;
 		CM::INT32 mX, mY;
 		CM::INT32 mX, mY;
 		CM::UINT32 mWidth, mHeight;
 		CM::UINT32 mWidth, mHeight;
-		CM::Vector<WidgetInfo>::type mWidgets;
+		CM::Vector<EditorWidget*>::type mWidgets;
 		CM::INT32 mActiveWidget;
 		CM::INT32 mActiveWidget;
 
 
 		static const CM::UINT32 TitleBarHeight;
 		static const CM::UINT32 TitleBarHeight;
@@ -44,6 +37,5 @@ namespace BansheeEditor
 		void setActiveWidget(CM::UINT32 idx);
 		void setActiveWidget(CM::UINT32 idx);
 		void tabActivated(CM::UINT32 idx);
 		void tabActivated(CM::UINT32 idx);
 		void tabClosed(CM::UINT32 idx);
 		void tabClosed(CM::UINT32 idx);
-		void widgetDestroyed(EditorWidget* widget);
 	};
 	};
 }
 }

+ 13 - 7
CamelotClient/Source/BsEditorWidget.cpp

@@ -6,6 +6,7 @@
 #include "BsGUILayout.h"
 #include "BsGUILayout.h"
 #include "BsEngineGUI.h"
 #include "BsEngineGUI.h"
 #include "BsGUIArea.h"
 #include "BsGUIArea.h"
+#include "BsEditorWidgetContainer.h"
 
 
 using namespace CamelotFramework;
 using namespace CamelotFramework;
 using namespace BansheeEngine;
 using namespace BansheeEngine;
@@ -13,7 +14,7 @@ using namespace BansheeEngine;
 namespace BansheeEditor
 namespace BansheeEditor
 {
 {
 	EditorWidget::EditorWidget(const WString& name)
 	EditorWidget::EditorWidget(const WString& name)
-		:mName(name), mParentWidget(nullptr), mContent(nullptr)
+		:mName(name), mParent(nullptr), mContent(nullptr)
 	{
 	{
 		
 		
 	}
 	}
@@ -44,16 +45,16 @@ namespace BansheeEditor
 		mContent->setSize(width, height);
 		mContent->setSize(width, height);
 	}
 	}
 
 
-	void EditorWidget::_changeParent(BS::GUIWidget& widget)
+	void EditorWidget::_changeParent(EditorWidgetContainer* parent)
 	{
 	{
-		if(mParentWidget != &widget) 
+		if(mParent != parent) 
 		{
 		{
-			if(mParentWidget == nullptr)
-				mContent = GUIArea::create(widget, 0, 0, 0, 0, 10000);
+			if(mParent == nullptr)
+				mContent = GUIArea::create(parent->getParentWidget(), 0, 0, 0, 0, 10000);
 			else
 			else
-				mContent->changeParentWidget(widget);
+				mContent->changeParentWidget(parent->getParentWidget());
 
 
-			mParentWidget = &widget;
+			mParent = parent;
 		}
 		}
 	}
 	}
 
 
@@ -66,4 +67,9 @@ namespace BansheeEditor
 	{
 	{
 		mContent->enable();
 		mContent->enable();
 	}
 	}
+
+	GUIWidget& EditorWidget::getParentWidget() const
+	{
+		return mParent->getParentWidget();
+	}
 }
 }

+ 12 - 15
CamelotClient/Source/BsEditorWidgetContainer.cpp

@@ -23,7 +23,7 @@ namespace BansheeEditor
 
 
 		for(auto& widget : mWidgets)
 		for(auto& widget : mWidgets)
 		{
 		{
-			EditorWidget::destroy(widget.widget);
+			EditorWidget::destroy(widget);
 		}
 		}
 	}
 	}
 
 
@@ -31,15 +31,13 @@ namespace BansheeEditor
 	{
 	{
 		for(auto& curWidget : mWidgets)
 		for(auto& curWidget : mWidgets)
 		{
 		{
-			if(curWidget.widget == &widget)
+			if(curWidget == &widget)
 				return;
 				return;
 		}
 		}
 
 
-		auto conn = widget.onClosed.connect(boost::bind(&EditorWidgetContainer::widgetDestroyed, this, _1));
-
 		mTitleBar->addTab(widget.getName());
 		mTitleBar->addTab(widget.getName());
-		mWidgets.push_back(WidgetInfo(&widget, conn));
-		widget._changeParent(*mParent);
+		mWidgets.push_back(&widget);
+		widget._changeParent(this);
 
 
 		if(mActiveWidget == -1)
 		if(mActiveWidget == -1)
 		{
 		{
@@ -55,7 +53,7 @@ namespace BansheeEditor
 		UINT32 curIdx = 0;
 		UINT32 curIdx = 0;
 		for(auto& curWidget : mWidgets)
 		for(auto& curWidget : mWidgets)
 		{
 		{
-			if(curWidget.widget == &widget)
+			if(curWidget == &widget)
 			{
 			{
 				widgetIdx = curIdx;
 				widgetIdx = curIdx;
 				break;
 				break;
@@ -67,7 +65,6 @@ namespace BansheeEditor
 		if(widgetIdx == -1)
 		if(widgetIdx == -1)
 			return;
 			return;
 
 
-		mWidgets[widgetIdx].conn.disconnect();
 		mWidgets.erase(mWidgets.begin() + widgetIdx);
 		mWidgets.erase(mWidgets.begin() + widgetIdx);
 		mTitleBar->removeTab((UINT32)widgetIdx);
 		mTitleBar->removeTab((UINT32)widgetIdx);
 
 
@@ -92,7 +89,7 @@ namespace BansheeEditor
 
 
 		if(mActiveWidget >= 0)
 		if(mActiveWidget >= 0)
 		{
 		{
-			EditorWidget* activeWidgetPtr = mWidgets[mActiveWidget].widget;
+			EditorWidget* activeWidgetPtr = mWidgets[mActiveWidget];
 			UINT32 contentHeight = (UINT32)std::max(0, (INT32)height - (INT32)TitleBarHeight);
 			UINT32 contentHeight = (UINT32)std::max(0, (INT32)height - (INT32)TitleBarHeight);
 
 
 			activeWidgetPtr->_setSize(width, contentHeight);
 			activeWidgetPtr->_setSize(width, contentHeight);
@@ -108,7 +105,7 @@ namespace BansheeEditor
 
 
 		if(mActiveWidget >= 0)
 		if(mActiveWidget >= 0)
 		{
 		{
-			EditorWidget* activeWidgetPtr = mWidgets[mActiveWidget].widget;
+			EditorWidget* activeWidgetPtr = mWidgets[mActiveWidget];
 
 
 			activeWidgetPtr->_setPosition(x, y + TitleBarHeight);
 			activeWidgetPtr->_setPosition(x, y + TitleBarHeight);
 		}
 		}
@@ -128,9 +125,9 @@ namespace BansheeEditor
 		for(auto& curWidget : mWidgets)
 		for(auto& curWidget : mWidgets)
 		{
 		{
 			if(curIdx != (UINT32)mActiveWidget)
 			if(curIdx != (UINT32)mActiveWidget)
-				curWidget.widget->_disable();
+				curWidget->_disable();
 			else
 			else
-				curWidget.widget->_enable();
+				curWidget->_enable();
 
 
 			curIdx++;
 			curIdx++;
 		}
 		}
@@ -146,7 +143,7 @@ namespace BansheeEditor
 
 
 	void EditorWidgetContainer::tabClosed(UINT32 idx)
 	void EditorWidgetContainer::tabClosed(UINT32 idx)
 	{
 	{
-		EditorWidget* widget = mWidgets[idx].widget;
+		EditorWidget* widget = mWidgets[idx];
 		remove(*widget);
 		remove(*widget);
 		EditorWidget::destroy(widget);
 		EditorWidget::destroy(widget);
 
 
@@ -154,11 +151,11 @@ namespace BansheeEditor
 			onWidgetClosed();
 			onWidgetClosed();
 	}
 	}
 
 
-	void EditorWidgetContainer::widgetDestroyed(EditorWidget* widget)
+	void EditorWidgetContainer::_notifyWidgetDestroyed(EditorWidget* widget)
 	{
 	{
 		for(auto& curWidget : mWidgets)
 		for(auto& curWidget : mWidgets)
 		{
 		{
-			if(curWidget.widget == widget)
+			if(curWidget == widget)
 			{
 			{
 				remove(*widget);
 				remove(*widget);
 
 

+ 5 - 6
CamelotClient/Source/DbgEditorWidget1.cpp

@@ -37,7 +37,7 @@ namespace BansheeEditor
 		//layout.addElement(GUIInputBox::create(*mGUI));
 		//layout.addElement(GUIInputBox::create(*mGUI));
 		//layout.addElement(GUIInputBox::create(*mGUI, GUILayoutOptions::fixed(100, 100), true));
 		//layout.addElement(GUIInputBox::create(*mGUI, GUILayoutOptions::fixed(100, 100), true));
 
 
-		GUIScrollArea* scrollArea = GUIScrollArea::create(*mParentWidget);
+		GUIScrollArea* scrollArea = GUIScrollArea::create(getParentWidget());
 		layout.addElement(scrollArea);
 		layout.addElement(scrollArea);
 
 
 		GUILayout& scrollLayout = scrollArea->getLayout().addLayoutX();
 		GUILayout& scrollLayout = scrollArea->getLayout().addLayoutX();
@@ -55,9 +55,9 @@ namespace BansheeEditor
 		//scrollLayout.addElement(GUIButton::create(*mGUI, L"Test K"));
 		//scrollLayout.addElement(GUIButton::create(*mGUI, L"Test K"));
 		//scrollLayout.addElement(GUIButton::create(*mGUI, L"Test L"));
 		//scrollLayout.addElement(GUIButton::create(*mGUI, L"Test L"));
 
 
-		scrollLayout.addElement(GUIInputBox::create(*mParentWidget, GUILayoutOptions::fixed(100, 100), true));
-		scrollLayout.addElement(GUIInputBox::create(*mParentWidget, GUILayoutOptions::fixed(100, 100), true));
-		scrollLayout.addElement(GUIInputBox::create(*mParentWidget, GUILayoutOptions::fixed(100, 100), true));
+		scrollLayout.addElement(GUIInputBox::create(getParentWidget(), GUILayoutOptions::fixed(100, 100), true));
+		scrollLayout.addElement(GUIInputBox::create(getParentWidget(), GUILayoutOptions::fixed(100, 100), true));
+		scrollLayout.addElement(GUIInputBox::create(getParentWidget(), GUILayoutOptions::fixed(100, 100), true));
 
 
 		//GUIFlexibleSpace& space4 = otherLayout.addFlexibleSpace();
 		//GUIFlexibleSpace& space4 = otherLayout.addFlexibleSpace();
 		//otherLayout.addElement(mDbgLabel);
 		//otherLayout.addElement(mDbgLabel);
@@ -108,8 +108,7 @@ namespace BansheeEditor
 	{
 	{
 		if(Instance != nullptr)
 		if(Instance != nullptr)
 		{
 		{
-			if(!Instance->onClosed.empty()) // TODO - This is very hackish
-				Instance->onClosed(Instance);
+			Instance->mParent->_notifyWidgetDestroyed(Instance);
 
 
 			EditorWidget::destroy(Instance);
 			EditorWidget::destroy(Instance);
 		}
 		}

+ 7 - 8
CamelotClient/Source/DbgEditorWidget2.cpp

@@ -30,18 +30,18 @@ namespace BansheeEditor
 	{
 	{
 		GUILayout& layout = mContent->getLayout();
 		GUILayout& layout = mContent->getLayout();
 
 
-		GUIScrollArea* scrollArea = GUIScrollArea::create(*mParentWidget);
+		GUIScrollArea* scrollArea = GUIScrollArea::create(getParentWidget());
 		layout.addElement(scrollArea);
 		layout.addElement(scrollArea);
 
 
 		GUILayout& scrollLayout = scrollArea->getLayout().addLayoutY();
 		GUILayout& scrollLayout = scrollArea->getLayout().addLayoutY();
 
 
 		std::shared_ptr<GUIToggleGroup> toggleGroup = GUIToggle::createToggleGroup();
 		std::shared_ptr<GUIToggleGroup> toggleGroup = GUIToggle::createToggleGroup();
 
 
-		scrollLayout.addElement(GUIToggle::create(*mParentWidget, L"Test A", toggleGroup, EngineGUI::instance().getSkin().getStyle("Button")));
-		scrollLayout.addElement(GUIToggle::create(*mParentWidget, L"Test B", toggleGroup, EngineGUI::instance().getSkin().getStyle("Button")));
-		scrollLayout.addElement(GUIToggle::create(*mParentWidget, L"Test C", toggleGroup, EngineGUI::instance().getSkin().getStyle("Button")));
-		scrollLayout.addElement(GUIToggle::create(*mParentWidget, L"Test D", toggleGroup, EngineGUI::instance().getSkin().getStyle("Button")));
-		scrollLayout.addElement(GUIToggle::create(*mParentWidget, L"Test E", toggleGroup, EngineGUI::instance().getSkin().getStyle("Button")));
+		scrollLayout.addElement(GUIToggle::create(getParentWidget(), L"Test A", toggleGroup, EngineGUI::instance().getSkin().getStyle("Button")));
+		scrollLayout.addElement(GUIToggle::create(getParentWidget(), L"Test B", toggleGroup, EngineGUI::instance().getSkin().getStyle("Button")));
+		scrollLayout.addElement(GUIToggle::create(getParentWidget(), L"Test C", toggleGroup, EngineGUI::instance().getSkin().getStyle("Button")));
+		scrollLayout.addElement(GUIToggle::create(getParentWidget(), L"Test D", toggleGroup, EngineGUI::instance().getSkin().getStyle("Button")));
+		scrollLayout.addElement(GUIToggle::create(getParentWidget(), L"Test E", toggleGroup, EngineGUI::instance().getSkin().getStyle("Button")));
 	}
 	}
 
 
 	DbgEditorWidget2* DbgEditorWidget2::instance()
 	DbgEditorWidget2* DbgEditorWidget2::instance()
@@ -68,8 +68,7 @@ namespace BansheeEditor
 	{
 	{
 		if(Instance != nullptr)
 		if(Instance != nullptr)
 		{
 		{
-			if(!Instance->onClosed.empty()) // TODO - This is very hackish
-				Instance->onClosed(Instance);
+			Instance->mParent->_notifyWidgetDestroyed(Instance);
 
 
 			EditorWidget::destroy(Instance);
 			EditorWidget::destroy(Instance);
 		}
 		}

+ 0 - 4
EditorWindowDock.txt

@@ -56,10 +56,6 @@ Implementation plan:
    - Will require implementing most of the DragAndDropManager and improve GUIManager
    - Will require implementing most of the DragAndDropManager and improve GUIManager
  - Continue with DockManager (flesh it out later)
  - Continue with DockManager (flesh it out later)
 
 
- GUIManager holds a ptr to GUIElements, and when elements are destroyed, GUIManager holds an invalid ptr
-Hook up DbgEditorWidget1::close()
- - In EditorWidget instead of having a onClose callback, instead keep EditorWidgetContainer parent and then notify it before it is closed. And if the widget is closed by parent container, 
-   then the container can remove parent and then close it so it doesn't receive the callback.
 Test tab switch/tab close/window close
 Test tab switch/tab close/window close
 
 
 ------------------------
 ------------------------