BsEditorWidgetManager.cpp 6.3 KB

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