BsEditorWidgetManager.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #include "BsEditorWidgetManager.h"
  2. #include "BsEditorWidget.h"
  3. #include "BsEditorWindow.h"
  4. #include "BsEditorWidgetContainer.h"
  5. #include "BsEditorWindowManager.h"
  6. #include "BsMainEditorWindow.h"
  7. #include "BsEditorWidgetLayout.h"
  8. #include "BsDockManager.h"
  9. #include "CmException.h"
  10. using namespace CamelotFramework;
  11. using namespace BansheeEngine;
  12. namespace BansheeEditor
  13. {
  14. Stack<std::pair<String, std::function<EditorWidgetBase*()>>>::type EditorWidgetManager::QueuedCreateCallbacks;
  15. EditorWidgetManager::EditorWidgetManager()
  16. {
  17. while(!QueuedCreateCallbacks.empty())
  18. {
  19. std::pair<String, std::function<EditorWidgetBase*()>> curElement = QueuedCreateCallbacks.top();
  20. QueuedCreateCallbacks.pop();
  21. registerWidget(curElement.first, curElement.second);
  22. }
  23. }
  24. void EditorWidgetManager::registerWidget(const String& name, std::function<EditorWidgetBase*()> createCallback)
  25. {
  26. auto iterFind = mCreateCallbacks.find(name);
  27. if(iterFind != mCreateCallbacks.end())
  28. CM_EXCEPT(InvalidParametersException, "Widget with the same name is already registered. Name: \"" + name + "\"");
  29. mCreateCallbacks[name] = createCallback;
  30. }
  31. EditorWidgetBase* EditorWidgetManager::open(const String& name)
  32. {
  33. auto iterFind = mActiveWidgets.find(name);
  34. if(iterFind != mActiveWidgets.end())
  35. return iterFind->second;
  36. EditorWidgetBase* newWidget = create(name);
  37. if(newWidget == nullptr)
  38. CM_EXCEPT(InvalidParametersException, "Trying to open a widget that is not registered with the widget manager. Name: \"" + name + "\"");
  39. EditorWindow* window = EditorWindow::create();
  40. window->widgets().add(*newWidget);
  41. newWidget->initialize();
  42. return newWidget;
  43. }
  44. void EditorWidgetManager::close(EditorWidgetBase* widget)
  45. {
  46. auto findIter = std::find_if(mActiveWidgets.begin(), mActiveWidgets.end(),
  47. [&] (const std::pair<String, EditorWidgetBase*>& entry) { return entry.second == widget; });
  48. if(findIter != mActiveWidgets.end())
  49. mActiveWidgets.erase(findIter);
  50. if(widget->mParent != nullptr)
  51. widget->mParent->_notifyWidgetDestroyed(widget);
  52. EditorWidgetBase::destroy(widget);
  53. }
  54. bool EditorWidgetManager::isOpen(const CM::String& name) const
  55. {
  56. auto iterFind = mActiveWidgets.find(name);
  57. return iterFind != mActiveWidgets.end();
  58. }
  59. EditorWidgetBase* EditorWidgetManager::create(const CM::String& name)
  60. {
  61. auto iterFind = mActiveWidgets.find(name);
  62. if(iterFind != mActiveWidgets.end())
  63. return iterFind->second;
  64. auto iterFindCreate = mCreateCallbacks.find(name);
  65. if(iterFindCreate == mCreateCallbacks.end())
  66. return nullptr;
  67. EditorWidgetBase* newWidget = mCreateCallbacks[name]();
  68. mActiveWidgets[name] = newWidget;
  69. return newWidget;
  70. }
  71. EditorWidgetLayoutPtr EditorWidgetManager::getLayout() const
  72. {
  73. auto GetWidgetNamesInContainer = [&] (const EditorWidgetContainer* container)
  74. {
  75. Vector<String>::type widgetNames;
  76. if(container != nullptr)
  77. {
  78. UINT32 numWidgets = container->getNumWidgets();
  79. for(UINT32 i = 0; i < numWidgets; i++)
  80. {
  81. EditorWidgetBase* widget = container->getWidget(i);
  82. widgetNames.push_back(widget->getName());
  83. }
  84. }
  85. return widgetNames;
  86. };
  87. MainEditorWindow* mainWindow = EditorWindowManager::instance().getMainWindow();
  88. DockManager& dockManager = mainWindow->getDockManager();
  89. EditorWidgetLayoutPtr layout = cm_shared_ptr<EditorWidgetLayout>(dockManager.getLayout());
  90. Vector<EditorWidgetLayout::Entry>::type& layoutEntries = layout->getEntries();
  91. UnorderedSet<EditorWidgetContainer*>::type widgetContainers;
  92. for(auto& widget : mActiveWidgets)
  93. {
  94. widgetContainers.insert(widget.second->_getParent());
  95. }
  96. for(auto& widgetContainer : widgetContainers)
  97. {
  98. if(widgetContainer == nullptr)
  99. continue;
  100. layoutEntries.push_back(EditorWidgetLayout::Entry());
  101. EditorWidgetLayout::Entry& entry = layoutEntries.back();
  102. entry.widgetNames = GetWidgetNamesInContainer(widgetContainer);
  103. EditorWindow* parentWindow = widgetContainer->getParentWindow();
  104. entry.isDocked = parentWindow == nullptr;
  105. if(!entry.isDocked)
  106. {
  107. entry.x = parentWindow->getLeft();
  108. entry.y = parentWindow->getTop();
  109. entry.width = parentWindow->getWidth();
  110. entry.height = parentWindow->getHeight();
  111. }
  112. }
  113. return layout;
  114. }
  115. void EditorWidgetManager::setLayout(const EditorWidgetLayoutPtr& layout)
  116. {
  117. Vector<EditorWidgetBase*>::type openWidgets;
  118. Vector<EditorWidgetBase*>::type widgetsNeedInitialization;
  119. // Create any necessary widgets
  120. for(auto& entry : layout->getEntries())
  121. {
  122. for(auto& widgetName : entry.widgetNames)
  123. {
  124. bool needsInitialization = !isOpen(widgetName);
  125. EditorWidgetBase* newWidget = create(widgetName);
  126. if(newWidget != nullptr)
  127. {
  128. openWidgets.push_back(newWidget);
  129. if(needsInitialization)
  130. widgetsNeedInitialization.push_back(newWidget);
  131. }
  132. }
  133. }
  134. // Unparent all widgets
  135. Vector<EditorWidgetBase*>::type unparentedWidgets;
  136. for(auto& widget : mActiveWidgets)
  137. {
  138. if(widget.second->_getParent() != nullptr)
  139. widget.second->_getParent()->remove(*(widget.second));
  140. unparentedWidgets.push_back(widget.second);
  141. }
  142. // Restore floating widgets
  143. for(auto& entry : layout->getEntries())
  144. {
  145. if(entry.isDocked)
  146. continue;
  147. EditorWindow* window = EditorWindow::create();
  148. for(auto& widgetName : entry.widgetNames)
  149. {
  150. EditorWidgetBase* widget = create(widgetName); // This will returned previously created widget
  151. window->widgets().add(*widget);
  152. }
  153. window->setPosition(entry.x, entry.y);
  154. window->setSize(entry.width, entry.height);
  155. }
  156. // Restore docked widgets
  157. MainEditorWindow* mainWindow = EditorWindowManager::instance().getMainWindow();
  158. DockManager& dockManager = mainWindow->getDockManager();
  159. dockManager.setLayout(layout->getDockLayout(), openWidgets);
  160. // Initialize any newly opened widgets
  161. for(auto& widget : widgetsNeedInitialization)
  162. {
  163. if(widget->_getParent() != nullptr)
  164. widget->initialize();
  165. }
  166. // Destroy any widgets that are no longer have parents
  167. for(auto& widget : unparentedWidgets)
  168. {
  169. if(widget->_getParent() == nullptr)
  170. widget->close();
  171. }
  172. }
  173. void EditorWidgetManager::preRegisterWidget(const String& name, std::function<EditorWidgetBase*()> createCallback)
  174. {
  175. QueuedCreateCallbacks.push(std::pair<String, std::function<EditorWidgetBase*()>>(name, createCallback));
  176. }
  177. }