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 ScriptEditorWindow::internal_isPointerHovering(ScriptEditorWindow* thisPtr) { if (!thisPtr->isDestroyed()) { EditorWidgetBase* widget = thisPtr->getEditorWidget(); EditorWindowBase* window = widget->getParentWindow(); if (window == nullptr) return false; SPtr<RenderWindow> renderWindow = window->getRenderWindow(); Vector2I pointerPos = gInput().getPointerPosition(); if(Platform::isPointOverWindow(*renderWindow, pointerPos)) { Rect2I bounds = thisPtr->getEditorWidget()->getBounds(); Vector2I widgetPos(bounds.x, bounds.y); Vector2I screenPos = widget->widgetToScreenPos(widgetPos); bounds.x = screenPos.x; bounds.y = screenPos.y; return bounds.contains(pointerPos); } } return false; }
MonoObject* ScriptDropDownWindow::internal_CreateInstance(MonoString* ns, MonoString* typeName, ScriptEditorWindow* parentWindow, Vector2I* position) { String strTypeName = MonoUtil::monoToString(typeName); String strNamespace = MonoUtil::monoToString(ns); String fullName = strNamespace + "." + strTypeName; MonoClass* windowClass = MonoManager::instance().findClass(strNamespace, strTypeName); if (windowClass == nullptr) return nullptr; MonoAssembly* assembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY); MonoClass* defaultSizeAttrib = assembly->getClass("BansheeEditor", "DefaultSize"); if (defaultSizeAttrib == nullptr) BS_EXCEPT(InternalErrorException, "Cannot find DefaultSize managed class."); MonoField* defaultWidthField = defaultSizeAttrib->getField("width"); MonoField* defaultHeightField = defaultSizeAttrib->getField("height"); int width = 200; int height = 200; MonoObject* defaultSizeObj = windowClass->getAttribute(defaultSizeAttrib); if (defaultSizeObj != nullptr) { defaultWidthField->get(defaultSizeObj, &width); defaultHeightField->get(defaultSizeObj, &height); } MonoObject* instance = windowClass->createInstance(false); ManagedDropDownWindow* dropDownWindow = nullptr; if (parentWindow != nullptr && !parentWindow->isDestroyed()) { EditorWidgetBase* editorWidget = parentWindow->getEditorWidget(); EditorWidgetContainer* parentContainer = editorWidget->_getParent(); if (parentContainer != nullptr) { SPtr<RenderWindow> parentRenderWindow = parentContainer->getParentWindow()->getRenderWindow(); SPtr<Camera> parentCamera = parentContainer->getParentWidget().getCamera(); position->x += editorWidget->getX(); position->y += editorWidget->getY(); dropDownWindow = DropDownWindowManager::instance().open<ManagedDropDownWindow>( parentRenderWindow, parentCamera, *position, instance, width, height); } } ScriptDropDownWindow* nativeInstance = new (bs_alloc<ScriptDropDownWindow>()) ScriptDropDownWindow(dropDownWindow); if (dropDownWindow != nullptr) dropDownWindow->initialize(nativeInstance); windowClass->construct(instance); return instance; }
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 ScriptEditorWindow::internal_getBounds(ScriptEditorWindow* thisPtr, Rect2I* bounds) { if (!thisPtr->isDestroyed()) { EditorWidgetBase* widget = thisPtr->getEditorWidget(); *bounds = thisPtr->getEditorWidget()->getBounds(); Vector2I widgetPos(0, 0); Vector2I screenPos = widget->widgetToScreenPos(widgetPos); bounds->x = screenPos.x; bounds->y = screenPos.y; } else *bounds = Rect2I(); }
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; widget->_setHasFocus(false); } }
ScriptOSDropTarget::ScriptOSDropTarget(MonoObject* instance, ScriptEditorWindow* parent) :ScriptObject(instance), mParent(parent), mDropTarget(nullptr), mIsDestroyed(false) { EditorWidgetBase* parentWidget = getParentWidget(); if (parentWidget != nullptr) { mWidgetParentChangedConn = parentWidget->onParentChanged.connect(std::bind(&ScriptOSDropTarget::widgetParentChanged, this, _1)); mWidgetResizedConn = parentWidget->onResized.connect(std::bind(&ScriptOSDropTarget::widgetResized, this, _1, _2)); mWidgetMovedConn = parentWidget->onMoved.connect(std::bind(&ScriptOSDropTarget::widgetMoved, this, _1, _2)); EditorWindowBase* parentWindow = parentWidget->getParentWindow(); if (parentWindow != nullptr) setDropTarget(parentWindow->getRenderWindow(), 0, 0, 0, 0); mParentArea = parentWidget->getBounds(); } }
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); } } }
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; }
bool GUITabbedTitleBar::_mouseEvent(const GUIMouseEvent& event) { if(event.getType() == GUIMouseEventType::MouseDragAndDropDragged) { if(DragAndDropManager::instance().getDragTypeId() != (UINT32)DragAndDropType::EditorWidget) return false; EditorWidgetBase* draggedWidget = reinterpret_cast<EditorWidgetBase*>(DragAndDropManager::instance().getDragData()); const Vector2I& widgetRelPos = event.getPosition(); if(mTempDraggedWidget == nullptr) { UINT32 numTabButtons = (UINT32)mTabButtons.size(); for(UINT32 i = 0; i < numTabButtons; i++) { UINT32 width = mTabButtons[i]->_getLayoutData().area.width; INT32 centerX = mTabButtons[i]->_getLayoutData().area.x + width / 2; if((i + 1) == numTabButtons) { if(i == 0 && widgetRelPos.x <= centerX) { insertTab(0, draggedWidget->getDisplayName()); mTempDraggedTabIdx = mTabButtons[0]->getIndex(); break; } else if(widgetRelPos.x > centerX) { addTab(draggedWidget->getDisplayName()); mTempDraggedTabIdx = mTabButtons[i + 1]->getIndex(); break; } } else { if(i == 0 && widgetRelPos.x <= centerX) { insertTab(0, draggedWidget->getDisplayName()); mTempDraggedTabIdx = mTabButtons[0]->getIndex(); break; } else { UINT32 nextWidth = mTabButtons[i + 1]->_getLayoutData().area.width; INT32 nextCenterX = mTabButtons[i + 1]->_getLayoutData().area.x + nextWidth / 2; if(widgetRelPos.x > centerX && widgetRelPos.x < nextCenterX) { insertTab(i + 1, draggedWidget->getDisplayName()); mTempDraggedTabIdx = mTabButtons[i + 1]->getIndex(); break; } } } } mTempDraggedWidget = draggedWidget; startDrag(uniqueIdxToSeqIdx(mTempDraggedTabIdx), Vector2I()); mInitialDragOffset = Math::roundToInt(mDraggedBtn->_getOptimalSize().x * 0.5f); } if(mTempDraggedWidget != nullptr) tabDragged(mTempDraggedTabIdx, widgetRelPos); return true; } else if(event.getType() == GUIMouseEventType::MouseDragAndDropDropped) { if(DragAndDropManager::instance().getDragTypeId() != (UINT32)DragAndDropType::EditorWidget) return false; if(mTempDraggedWidget != nullptr) { UINT32 seqIdx = uniqueIdxToSeqIdx(mTempDraggedTabIdx); removeTab(mTempDraggedTabIdx); endDrag(); if(!onTabDraggedOn.empty()) onTabDraggedOn(seqIdx); } return true; } else if(event.getType() == GUIMouseEventType::MouseDragAndDropLeft) { if(mTempDraggedWidget != nullptr) { removeTab(mTempDraggedTabIdx); endDrag(); } } return false; }