| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "EditorWindow/BsEditorWidgetManager.h"
- #include "EditorWindow/BsEditorWidget.h"
- #include "EditorWindow/BsEditorWindow.h"
- #include "EditorWindow/BsEditorWidgetContainer.h"
- #include "EditorWindow/BsEditorWindowManager.h"
- #include "EditorWindow/BsMainEditorWindow.h"
- #include "EditorWindow/BsEditorWidgetLayout.h"
- #include "EditorWindow/BsDockManager.h"
- #include "Error/BsException.h"
- #include "Input/BsInput.h"
- #include "RenderAPI/BsRenderWindow.h"
- #include "Managers/BsRenderWindowManager.h"
- #include "Math/BsVector2I.h"
- #include "CoreThread/BsCoreThread.h"
- using namespace std::placeholders;
- namespace bs
- {
- Stack<std::pair<String, std::function<EditorWidgetBase*(EditorWidgetContainer&)>>> EditorWidgetManager::QueuedCreateCallbacks;
- EditorWidgetManager::EditorWidgetManager()
- {
- while(!QueuedCreateCallbacks.empty())
- {
- std::pair<String, std::function<EditorWidgetBase*(EditorWidgetContainer&)>> curElement = QueuedCreateCallbacks.top();
- QueuedCreateCallbacks.pop();
- registerWidget(curElement.first, curElement.second);
- }
- mOnFocusLostConn = RenderWindowManager::instance().onFocusLost.connect(std::bind(&EditorWidgetManager::onFocusLost, this, _1));
- mOnFocusGainedConn = RenderWindowManager::instance().onFocusGained.connect(std::bind(&EditorWidgetManager::onFocusGained, this, _1));
- }
- EditorWidgetManager::~EditorWidgetManager()
- {
- mOnFocusLostConn.disconnect();
- mOnFocusGainedConn.disconnect();
- UnorderedMap<String, EditorWidgetBase*> widgetsCopy = mActiveWidgets;
- for (auto& widget : widgetsCopy)
- widget.second->close();
- }
- void EditorWidgetManager::update()
- {
- if (gInput().isPointerButtonDown(PointerEventButton::Left) || gInput().isPointerButtonDown(PointerEventButton::Right))
- {
- for (auto& widgetData : mActiveWidgets)
- {
- EditorWidgetBase* widget = widgetData.second;
- EditorWidgetContainer* parentContainer = widget->_getParent();
- if (parentContainer == nullptr)
- {
- widget->_setHasFocus(false);
- continue;
- }
- EditorWindowBase* parentWindow = parentContainer->getParentWindow();
- SPtr<RenderWindow> parentRenderWindow = parentWindow->getRenderWindow();
- const RenderWindowProperties& props = parentRenderWindow->getProperties();
- if (!props.hasFocus)
- {
- widget->_setHasFocus(false);
- continue;
- }
- if (parentContainer->getActiveWidget() != widget)
- {
- widget->_setHasFocus(false);
- continue;
- }
- Vector2I widgetPos = widget->screenToWidgetPos(gInput().getPointerPosition());
- if (widgetPos.x >= 0 && widgetPos.y >= 0
- && widgetPos.x < (INT32)widget->getWidth()
- && widgetPos.y < (INT32)widget->getHeight())
- {
- widget->_setHasFocus(true);
- }
- else
- widget->_setHasFocus(false);
- }
- }
- }
- void EditorWidgetManager::registerWidget(const String& name, std::function<EditorWidgetBase*(EditorWidgetContainer&)> createCallback)
- {
- auto iterFind = mCreateCallbacks.find(name);
- if(iterFind != mCreateCallbacks.end())
- BS_EXCEPT(InvalidParametersException, "Widget with the same name is already registered. Name: \"" + name + "\"");
- mCreateCallbacks[name] = createCallback;
- }
- void EditorWidgetManager::unregisterWidget(const String& name)
- {
- mCreateCallbacks.erase(name);
- }
- EditorWidgetBase* EditorWidgetManager::open(const String& name)
- {
- auto iterFind = mActiveWidgets.find(name);
- if(iterFind != mActiveWidgets.end())
- return iterFind->second;
- EditorWindow* window = EditorWindow::create();
- EditorWidgetBase* newWidget = create(name, window->widgets());
- if(newWidget == nullptr)
- {
- window->close();
- return nullptr;
- }
- Vector2I widgetSize(newWidget->getDefaultWidth(), newWidget->getDefaultHeight());
- Vector2I windowSize = EditorWidgetContainer::widgetToWindowSize(widgetSize);
- window->setSize((UINT32)windowSize.x, (UINT32)windowSize.y);
- return newWidget;
- }
- void EditorWidgetManager::close(EditorWidgetBase* widget)
- {
- auto findIter = std::find_if(mActiveWidgets.begin(), mActiveWidgets.end(),
- [&] (const std::pair<String, EditorWidgetBase*>& entry) { return entry.second == widget; });
- if(findIter != mActiveWidgets.end())
- mActiveWidgets.erase(findIter);
- for(auto iter = mSavedFocusedWidgets.begin(); iter != mSavedFocusedWidgets.end();)
- {
- if (iter->second == widget)
- iter = mSavedFocusedWidgets.erase(iter);
- else
- ++iter;
- }
- if(widget->mParent != nullptr)
- widget->mParent->_notifyWidgetDestroyed(widget);
- EditorWidgetBase::destroy(widget);
- }
- void EditorWidgetManager::closeAll()
- {
- Vector<EditorWidgetBase*> toClose(mActiveWidgets.size());
- UINT32 idx = 0;
- for (auto& widget : mActiveWidgets)
- toClose[idx++] = widget.second;
- for (auto& widget : toClose)
- widget->close();
- }
- EditorWidgetBase* EditorWidgetManager::create(const String& name, EditorWidgetContainer& parentContainer)
- {
- auto iterFind = mActiveWidgets.find(name);
- if(iterFind != mActiveWidgets.end())
- {
- EditorWidgetBase* existingWidget = iterFind->second;
- if(existingWidget->_getParent() != nullptr && existingWidget->_getParent() != &parentContainer)
- existingWidget->_getParent()->remove(*existingWidget);
- if(existingWidget->_getParent() != &parentContainer)
- parentContainer.add(*iterFind->second);
- return iterFind->second;
- }
- auto iterFindCreate = mCreateCallbacks.find(name);
- if(iterFindCreate == mCreateCallbacks.end())
- return nullptr;
- EditorWidgetBase* newWidget = mCreateCallbacks[name](parentContainer);
- parentContainer.add(*newWidget);
- if(newWidget != nullptr)
- mActiveWidgets[name] = newWidget;
- return newWidget;
- }
- bool EditorWidgetManager::isValidWidget(const String& name) const
- {
- auto iterFindCreate = mCreateCallbacks.find(name);
- return iterFindCreate != mCreateCallbacks.end();
- }
- SPtr<EditorWidgetLayout> EditorWidgetManager::getLayout() const
- {
- auto GetWidgetNamesInContainer = [&] (const EditorWidgetContainer* container)
- {
- Vector<String> widgetNames;
- if(container != nullptr)
- {
- UINT32 numWidgets = container->getNumWidgets();
- for(UINT32 i = 0; i < numWidgets; i++)
- {
- EditorWidgetBase* widget = container->getWidget(i);
- widgetNames.push_back(widget->getName());
- }
- }
- return widgetNames;
- };
- MainEditorWindow* mainWindow = EditorWindowManager::instance().getMainWindow();
- DockManager& dockManager = mainWindow->getDockManager();
- SPtr<EditorWidgetLayout> layout = bs_shared_ptr_new<EditorWidgetLayout>(dockManager.getLayout());
- Vector<EditorWidgetLayout::Entry>& layoutEntries = layout->getEntries();
- UnorderedSet<EditorWidgetContainer*> widgetContainers;
- for(auto& widget : mActiveWidgets)
- {
- widgetContainers.insert(widget.second->_getParent());
- }
- for(auto& widgetContainer : widgetContainers)
- {
- if(widgetContainer == nullptr)
- continue;
- layoutEntries.push_back(EditorWidgetLayout::Entry());
- EditorWidgetLayout::Entry& entry = layoutEntries.back();
- entry.widgetNames = GetWidgetNamesInContainer(widgetContainer);
- EditorWindowBase* parentWindow = widgetContainer->getParentWindow();
- entry.isDocked = parentWindow->isMain(); // Assumed widget is docked if part of main window
-
- if(!entry.isDocked)
- {
- entry.x = parentWindow->getLeft();
- entry.y = parentWindow->getTop();
- entry.width = parentWindow->getWidth();
- entry.height = parentWindow->getHeight();
- }
- }
- layout->setIsMainWindowMaximized(mainWindow->getRenderWindow()->getProperties().isMaximized);
- return layout;
- }
- void EditorWidgetManager::setLayout(const SPtr<EditorWidgetLayout>& layout)
- {
- // Unparent all widgets
- Vector<EditorWidgetBase*> unparentedWidgets;
- for(auto& widget : mActiveWidgets)
- {
- if(widget.second->_getParent() != nullptr)
- widget.second->_getParent()->remove(*(widget.second));
- unparentedWidgets.push_back(widget.second);
- }
- // Restore floating widgets
- for(auto& entry : layout->getEntries())
- {
- if(entry.isDocked)
- continue;
- EditorWindow* window = EditorWindow::create();
- for(auto& widgetName : entry.widgetNames)
- {
- create(widgetName, window->widgets());
- }
- window->setPosition(entry.x, entry.y);
- window->setSize(entry.width, entry.height);
- if(window->widgets().getNumWidgets() == 0)
- window->close();
- }
- // Restore docked widgets
- MainEditorWindow* mainWindow = EditorWindowManager::instance().getMainWindow();
- DockManager& dockManager = mainWindow->getDockManager();
- dockManager.setLayout(layout->getDockLayout());
- // Destroy any widgets that are no longer have parents
- for(auto& widget : unparentedWidgets)
- {
- if(widget->_getParent() == nullptr)
- widget->close();
- }
- if (layout->getIsMainWindowMaximized())
- mainWindow->getRenderWindow()->maximize();
- }
- void EditorWidgetManager::onFocusGained(const RenderWindow& window)
- {
- auto iterFind = mSavedFocusedWidgets.find(&window);
- if(iterFind != mSavedFocusedWidgets.end())
- {
- EditorWidgetBase* widget = iterFind->second;
- EditorWidgetContainer* parentContainer = widget->_getParent();
- if (parentContainer != nullptr)
- {
- EditorWindowBase* parentWindow = parentContainer->getParentWindow();
- SPtr<RenderWindow> parentRenderWindow = parentWindow->getRenderWindow();
- if (parentRenderWindow.get() == &window)
- widget->_setHasFocus(true);
- }
-
- mSavedFocusedWidgets.erase(iterFind);;
- }
- }
- void EditorWidgetManager::onFocusLost(const RenderWindow& window)
- {
- for (auto& widgetData : mActiveWidgets)
- {
- EditorWidgetBase* widget = widgetData.second;
- EditorWidgetContainer* parentContainer = widget->_getParent();
- if (parentContainer == nullptr)
- continue;
- EditorWindowBase* parentWindow = parentContainer->getParentWindow();
- SPtr<RenderWindow> parentRenderWindow = parentWindow->getRenderWindow();
- if (parentRenderWindow.get() != &window)
- continue;
- if (widget->hasFocus())
- mSavedFocusedWidgets[&window] = widget;
- widget->_setHasFocus(false);
- }
- }
- void EditorWidgetManager::preRegisterWidget(const String& name, std::function<EditorWidgetBase*(EditorWidgetContainer&)> createCallback)
- {
- QueuedCreateCallbacks.push(std::pair<String, std::function<EditorWidgetBase*(EditorWidgetContainer&)>>(name, createCallback));
- }
- }
|