#include "EditorWindowManager.h" #include "State/EditorContext.h" #include "EditorWindow.h" #include namespace XCEngine::UI::Editor::App { std::wstring EditorWindowManager::BuildWindowTitle( const UIEditorWorkspaceController& workspaceController) const { const std::string& activePanelId = workspaceController.GetWorkspace().activePanelId; if (const UIEditorPanelDescriptor* descriptor = FindUIEditorPanelDescriptor( workspaceController.GetPanelRegistry(), activePanelId); descriptor != nullptr && !descriptor->defaultTitle.empty()) { const std::string titleText = descriptor->defaultTitle + " - XCEngine Editor"; return std::wstring(titleText.begin(), titleText.end()); } return std::wstring(L"XCEngine Editor"); } RECT EditorWindowManager::BuildDetachedWindowRect(const POINT& screenPoint) const { RECT rect = { screenPoint.x - 420, screenPoint.y - 24, screenPoint.x - 420 + 960, screenPoint.y - 24 + 720 }; const HMONITOR monitor = MonitorFromPoint(screenPoint, MONITOR_DEFAULTTONEAREST); MONITORINFO monitorInfo = {}; monitorInfo.cbSize = sizeof(monitorInfo); if (monitor != nullptr && GetMonitorInfoW(monitor, &monitorInfo)) { const RECT& workArea = monitorInfo.rcWork; const LONG width = rect.right - rect.left; const LONG height = rect.bottom - rect.top; rect.left = (std::max)(workArea.left, (std::min)(rect.left, workArea.right - width)); rect.top = (std::max)(workArea.top, (std::min)(rect.top, workArea.bottom - height)); rect.right = rect.left + width; rect.bottom = rect.top + height; } return rect; } bool EditorWindowManager::SynchronizeWindowsFromWindowSet( const UIEditorWindowWorkspaceSet& windowSet, std::string_view preferredNewWindowId, const POINT& preferredScreenPoint) { std::vector windowIdsInSet = {}; windowIdsInSet.reserve(windowSet.windows.size()); for (const UIEditorWindowWorkspaceState& entry : windowSet.windows) { windowIdsInSet.push_back(entry.windowId); if (EditorWindow* existingWindow = FindWindow(entry.windowId); existingWindow != nullptr) { existingWindow->ReplaceWorkspaceController(BuildWorkspaceControllerForWindow(entry)); existingWindow->ResetInteractionState(); if (!existingWindow->IsPrimary()) { existingWindow->SetTitle( BuildWindowTitle(existingWindow->GetWorkspaceController())); if (existingWindow->GetHwnd() != nullptr) { SetWindowTextW(existingWindow->GetHwnd(), existingWindow->GetTitle().c_str()); } } continue; } CreateParams createParams = {}; createParams.windowId = entry.windowId; createParams.primary = entry.windowId == windowSet.primaryWindowId; createParams.title = createParams.primary ? std::wstring( m_hostConfig.primaryWindowTitle != nullptr && m_hostConfig.primaryWindowTitle[0] != L'\0' ? m_hostConfig.primaryWindowTitle : L"XCEngine Editor") : BuildWindowTitle(BuildWorkspaceControllerForWindow(entry)); if (entry.windowId == preferredNewWindowId) { const RECT detachedRect = BuildDetachedWindowRect(preferredScreenPoint); createParams.initialX = detachedRect.left; createParams.initialY = detachedRect.top; createParams.initialWidth = detachedRect.right - detachedRect.left; createParams.initialHeight = detachedRect.bottom - detachedRect.top; } if (CreateEditorWindow(BuildWorkspaceControllerForWindow(entry), createParams) == nullptr) { return false; } } for (const std::unique_ptr& window : m_windows) { if (window == nullptr || window->GetHwnd() == nullptr || window->IsPrimary()) { continue; } const bool existsInWindowSet = std::find( windowIdsInSet.begin(), windowIdsInSet.end(), window->GetWindowId()) != windowIdsInSet.end(); if (!existsInWindowSet) { PostMessageW(window->GetHwnd(), WM_CLOSE, 0, 0); } } return true; } bool EditorWindowManager::SynchronizeWindowsFromController( const UIEditorWindowWorkspaceController& windowWorkspaceController, std::string_view preferredNewWindowId, const POINT& preferredScreenPoint) { return SynchronizeWindowsFromWindowSet( windowWorkspaceController.GetWindowSet(), preferredNewWindowId, preferredScreenPoint); } } // namespace XCEngine::UI::Editor::App