diff --git a/editor/app/Bootstrap/Application.cpp b/editor/app/Bootstrap/Application.cpp index ed758413..1754a8b6 100644 --- a/editor/app/Bootstrap/Application.cpp +++ b/editor/app/Bootstrap/Application.cpp @@ -2,13 +2,19 @@ #include "Bootstrap/EditorResources.h" #include "System/SystemInteractionService.h" #include "Composition/EditorContext.h" +#include "Windowing/Content/EditorWindowContentFactory.h" #include "Windowing/EditorWindowManager.h" #include "Platform/Win32/System/Win32SystemInteractionHost.h" +#include "Platform/Win32/Windowing/EditorWindow.h" +#include "Platform/Win32/Windowing/EditorWindowHostConfig.h" +#include "Platform/Win32/Windowing/EditorWindowHostRuntime.h" +#include "Platform/Win32/Windowing/EditorWindowMessageDispatcher.h" #include "Support/EnvironmentFlags.h" #include "Support/ExecutablePath.h" #include #include +#include #include #include @@ -72,6 +78,16 @@ void EnableDpiAwareness() { } } +UIEditorWindowWorkspaceState BuildPrimaryWindowState( + std::string_view windowId, + const UIEditorWorkspaceController& workspaceController) { + UIEditorWindowWorkspaceState windowState = {}; + windowState.windowId = std::string(windowId); + windowState.workspace = workspaceController.GetWorkspace(); + windowState.session = workspaceController.GetSession(); + return windowState; +} + } // namespace Application::Application() @@ -125,11 +141,17 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) { hostConfig.windowStyle = kBorderlessWindowStyle; hostConfig.primaryWindowTitle = kWindowTitle; hostConfig.windowUserData = this; - m_windowManager = std::make_unique( + m_windowContentFactory = + App::CreateDefaultEditorWindowContentFactory(*m_windowSystem); + m_windowHostRuntime = std::make_unique( hostConfig, m_repoRoot, *m_editorContext, - *m_windowSystem); + *m_windowContentFactory); + m_windowManager = std::make_unique( + *m_editorContext, + *m_windowSystem, + *m_windowHostRuntime); m_editorContext->SetExitRequestHandler([this]() { if (m_windowManager == nullptr) { @@ -168,10 +190,12 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) { m_smokeTestStartTime = {}; UIEditorWorkspaceController primaryWorkspaceController = m_editorContext->BuildWorkspaceController(); + const UIEditorWindowWorkspaceState primaryWindowState = + BuildPrimaryWindowState(createParams.windowId, primaryWorkspaceController); std::string windowSystemError = {}; if (!m_windowSystem->BootstrapPrimaryWindow( createParams.windowId, - primaryWorkspaceController, + primaryWindowState, windowSystemError)) { AppendUIEditorRuntimeTrace( "app", @@ -179,7 +203,7 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) { return false; } if (m_windowManager->CreateWorkspaceWindow( - std::move(primaryWorkspaceController), + primaryWindowState, createParams) == nullptr) { AppendUIEditorRuntimeTrace("app", "primary window creation failed"); return false; @@ -203,6 +227,8 @@ void Application::Shutdown() { m_windowManager->Shutdown(); m_windowManager.reset(); } + m_windowHostRuntime.reset(); + m_windowContentFactory.reset(); m_windowSystem.reset(); if (m_editorContext != nullptr) { @@ -390,8 +416,8 @@ LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT message, WPARAM wParam, LP ? reinterpret_cast(createStruct->lpCreateParams) : nullptr; SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast(application)); - if (application != nullptr && application->m_windowManager != nullptr) { - application->m_windowManager->HandlePendingNativeWindowCreated(hwnd); + if (application != nullptr && application->m_windowHostRuntime != nullptr) { + application->m_windowHostRuntime->HandlePendingNativeWindowCreated(hwnd); } return TRUE; } @@ -399,14 +425,20 @@ LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT message, WPARAM wParam, LP Application* application = GetApplicationFromWindowUserData(hwnd); LRESULT dispatcherResult = 0; if (application != nullptr && - application->m_windowManager != nullptr && - application->m_windowManager->TryDispatchWindowMessage( + application->m_windowHostRuntime != nullptr && + application->m_windowManager != nullptr) { + if (App::EditorWindow* const window = application->m_windowHostRuntime->FindWindow(hwnd); + window != nullptr && + App::EditorWindowMessageDispatcher::TryDispatch( hwnd, + *application->m_windowManager, + *window, message, wParam, lParam, dispatcherResult)) { - return dispatcherResult; + return dispatcherResult; + } } return DefWindowProcW(hwnd, message, wParam, lParam); diff --git a/editor/app/Bootstrap/Application.h b/editor/app/Bootstrap/Application.h index ebb61e81..6443c379 100644 --- a/editor/app/Bootstrap/Application.h +++ b/editor/app/Bootstrap/Application.h @@ -15,7 +15,9 @@ class EditorWindowSystem; namespace App { class EditorContext; +class EditorWindowContentFactory; class EditorWindowManager; +class EditorWindowHostRuntime; } namespace System { @@ -53,6 +55,8 @@ private: std::chrono::milliseconds m_smokeTestDuration = std::chrono::milliseconds::zero(); std::unique_ptr m_editorContext = {}; std::unique_ptr m_windowSystem = {}; + std::unique_ptr m_windowContentFactory = {}; + std::unique_ptr m_windowHostRuntime = {}; std::unique_ptr m_windowManager = {}; std::unique_ptr m_systemInteractionHost = {}; int m_smokeTestFrameLimit = 0; diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.cpp b/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.cpp index 51dabe83..96eb9124 100644 --- a/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.cpp +++ b/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.cpp @@ -7,14 +7,10 @@ #include "Platform/Win32/Windowing/EditorWindow.h" #include "Windowing/Content/EditorWindowContentFactory.h" #include "Windowing/Content/EditorWindowContentController.h" +#include "Windowing/Host/EditorWindowHostCoordinator.h" #include "Platform/Win32/Runtime/EditorWindowFrameDriver.h" -#include "Windowing/Coordinator/EditorUtilityWindowCoordinator.h" -#include "Windowing/Coordinator/EditorWindowLifecycleCoordinator.h" -#include "Windowing/Coordinator/EditorWindowWorkspaceCoordinator.h" -#include #include -#include #include #include @@ -62,12 +58,10 @@ EditorWindowHostRuntime::EditorWindowHostRuntime( EditorWindowHostConfig hostConfig, std::filesystem::path repoRoot, EditorContext& editorContext, - EditorWindowSystem& windowSystem, EditorWindowContentFactory& contentFactory) : m_hostConfig(hostConfig), m_repoRoot(std::move(repoRoot)), m_editorContext(editorContext), - m_windowSystem(windowSystem), m_contentFactory(contentFactory) {} EditorWindowHostRuntime::~EditorWindowHostRuntime() = default; @@ -152,7 +146,11 @@ EditorWindow* EditorWindowHostRuntime::CreateEditorWindow( auto failWindowInitialization = [&](std::string_view message) { LogRuntimeTrace("window", std::string(message)); - m_lifecycleCoordinator->AbortUnregisteredWindow(*rawWindow); + if (m_hostCoordinator != nullptr) { + m_hostCoordinator->AbortUnregisteredWindow(*rawWindow); + } else { + eraseRawWindow(); + } return static_cast(nullptr); }; @@ -193,13 +191,23 @@ EditorWindow* EditorWindowHostRuntime::CreateEditorWindow( } EditorWindow* EditorWindowHostRuntime::CreateWorkspaceWindow( - UIEditorWorkspaceController workspaceController, + const UIEditorWindowWorkspaceState& windowState, const EditorWindowCreateParams& params) { + if (windowState.windowId.empty()) { + LogRuntimeTrace("window", "workspace window creation rejected: state missing window id"); + return nullptr; + } + if (!params.windowId.empty() && windowState.windowId != params.windowId) { + LogRuntimeTrace( + "window", + "workspace window creation rejected: state window id '" + + windowState.windowId + "' does not match create params '" + + params.windowId + "'"); + return nullptr; + } + return CreateEditorWindow( - m_contentFactory.CreateWorkspaceContentController( - params.windowId, - std::move(workspaceController), - m_windowSystem), + m_contentFactory.CreateWorkspaceContentController(windowState), params); } @@ -211,9 +219,9 @@ EditorWindow* EditorWindowHostRuntime::CreateUtilityWindow( params); } -void EditorWindowHostRuntime::BindLifecycleCoordinator( - EditorWindowLifecycleCoordinator& lifecycleCoordinator) { - m_lifecycleCoordinator = &lifecycleCoordinator; +void EditorWindowHostRuntime::BindHostCoordinator( + EditorWindowHostCoordinator& hostCoordinator) { + m_hostCoordinator = &hostCoordinator; } void EditorWindowHostRuntime::HandlePendingNativeWindowCreated(HWND hwnd) { @@ -334,10 +342,11 @@ std::string EditorWindowHostRuntime::DescribeWindows() const { return DescribeHostWindows(m_windows); } -void EditorWindowHostRuntime::RenderAllWindows( - bool globalTabDragActive, - EditorWindowWorkspaceCoordinator& workspaceCoordinator, - EditorUtilityWindowCoordinator& utilityCoordinator) { +void EditorWindowHostRuntime::RenderAllWindows() { + if (m_hostCoordinator == nullptr) { + return; + } + struct WindowFrameTransferBatch { EditorWindow* sourceWindow = nullptr; EditorWindowFrameTransferRequests requests = {}; @@ -354,7 +363,7 @@ void EditorWindowHostRuntime::RenderAllWindows( } if (window->ConsumeSkipNextSteadyStateFrame()) { - workspaceCoordinator.RefreshWindowPresentation(*window); + m_hostCoordinator->RefreshWindowPresentation(*window); continue; } @@ -362,8 +371,8 @@ void EditorWindowHostRuntime::RenderAllWindows( EditorWindowFrameDriver::DriveFrame( *window, m_editorContext, - globalTabDragActive); - workspaceCoordinator.RefreshWindowPresentation(*window); + m_hostCoordinator->IsGlobalTabDragActive()); + m_hostCoordinator->RefreshWindowPresentation(*window); if (!transferRequests.HasPendingRequests()) { continue; } @@ -381,10 +390,7 @@ void EditorWindowHostRuntime::RenderAllWindows( continue; } - workspaceCoordinator.HandleWindowFrameTransferRequests( - *batch.sourceWindow, - batch.requests); - utilityCoordinator.HandleWindowFrameTransferRequests( + m_hostCoordinator->DispatchWindowFrameTransferRequests( *batch.sourceWindow, batch.requests); } diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.h b/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.h index 63e63d6c..03875d48 100644 --- a/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.h +++ b/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.h @@ -2,37 +2,28 @@ #include "Platform/Win32/Windowing/EditorWindow.h" #include "Platform/Win32/Windowing/EditorWindowHostConfig.h" +#include "Windowing/Host/EditorWindowHostCoordinator.h" #include "Windowing/Host/EditorWindowHostInterfaces.h" -#include - #include #include #include #include -namespace XCEngine::UI::Editor { -class EditorWindowSystem; -} - namespace XCEngine::UI::Editor::App { class EditorContext; class EditorWindow; class EditorWindowContentController; class EditorWindowContentFactory; -class EditorWindowLifecycleCoordinator; -class EditorUtilityWindowCoordinator; -class EditorWindowWorkspaceCoordinator; struct EditorUtilityWindowDescriptor; -class EditorWindowHostRuntime final : public EditorWindowHost { +class EditorWindowHostRuntime final : public EditorWindowHostRuntimeServices { public: EditorWindowHostRuntime( EditorWindowHostConfig hostConfig, std::filesystem::path repoRoot, EditorContext& editorContext, - EditorWindowSystem& windowSystem, EditorWindowContentFactory& contentFactory); ~EditorWindowHostRuntime(); @@ -40,12 +31,12 @@ public: std::unique_ptr contentController, const EditorWindowCreateParams& params); EditorWindow* CreateWorkspaceWindow( - UIEditorWorkspaceController workspaceController, + const UIEditorWindowWorkspaceState& windowState, const EditorWindowCreateParams& params) override; EditorWindow* CreateUtilityWindow( const EditorUtilityWindowDescriptor& descriptor, const EditorWindowCreateParams& params) override; - void BindLifecycleCoordinator(EditorWindowLifecycleCoordinator& lifecycleCoordinator); + void BindHostCoordinator(EditorWindowHostCoordinator& hostCoordinator) override; void HandlePendingNativeWindowCreated(HWND hwnd); EditorWindow* FindWindow(HWND hwnd); @@ -70,18 +61,7 @@ public: const EditorWindowScreenPoint& screenPoint) const override; void ReapDestroyedWindows() override; std::string DescribeWindows() const override; - void RenderAllWindows( - bool globalTabDragActive, - EditorWindowWorkspaceCoordinator& workspaceCoordinator, - EditorUtilityWindowCoordinator& utilityCoordinator); - - EditorContext& GetEditorContext() { - return m_editorContext; - } - - const EditorContext& GetEditorContext() const { - return m_editorContext; - } + void RenderAllWindows() override; const EditorWindowHostConfig& GetHostConfig() const { return m_hostConfig; @@ -108,11 +88,10 @@ private: EditorWindowHostConfig m_hostConfig = {}; std::filesystem::path m_repoRoot = {}; EditorContext& m_editorContext; - EditorWindowSystem& m_windowSystem; EditorWindowContentFactory& m_contentFactory; std::vector> m_windows = {}; EditorWindow* m_pendingCreateWindow = nullptr; - EditorWindowLifecycleCoordinator* m_lifecycleCoordinator = nullptr; + EditorWindowHostCoordinator* m_hostCoordinator = nullptr; }; } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.cpp b/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.cpp index 9c749467..35dc3e87 100644 --- a/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.cpp +++ b/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.cpp @@ -7,10 +7,7 @@ #include "Platform/Win32/Runtime/EditorWindowFrameDriver.h" #include "Platform/Win32/Runtime/EditorWindowRuntimeController.h" #include "Platform/Win32/Windowing/EditorWindowPointerCapture.h" -#include "Platform/Win32/Windowing/EditorWindowHostRuntime.h" -#include "Windowing/Coordinator/EditorWindowLifecycleCoordinator.h" -#include "Windowing/Coordinator/EditorUtilityWindowCoordinator.h" -#include "Windowing/Coordinator/EditorWindowWorkspaceCoordinator.h" +#include "Windowing/Host/EditorWindowHostCoordinator.h" #include #include @@ -27,20 +24,14 @@ constexpr UINT kMessageNcUaDrawFrame = 0x00AFu; struct EditorWindowMessageDispatcher::DispatchContext { HWND hwnd = nullptr; - EditorWindowHostRuntime& hostRuntime; - EditorWindowLifecycleCoordinator& lifecycleCoordinator; - EditorUtilityWindowCoordinator& utilityCoordinator; - EditorWindowWorkspaceCoordinator& workspaceCoordinator; + EditorWindowHostCoordinator& hostCoordinator; EditorWindow& window; }; void EditorWindowMessageDispatcher::DispatchWindowFrameTransferRequests( const DispatchContext& context, const EditorWindowFrameTransferRequests& transferRequests) { - context.workspaceCoordinator.HandleWindowFrameTransferRequests( - context.window, - transferRequests); - context.utilityCoordinator.HandleWindowFrameTransferRequests( + context.hostCoordinator.DispatchWindowFrameTransferRequests( context.window, transferRequests); } @@ -48,7 +39,7 @@ void EditorWindowMessageDispatcher::DispatchWindowFrameTransferRequests( void EditorWindowMessageDispatcher::FinalizeImmediateFrame( const DispatchContext& context, const EditorWindowFrameTransferRequests& transferRequests) { - context.workspaceCoordinator.RefreshWindowPresentation(context.window); + context.hostCoordinator.RefreshWindowPresentation(context.window); if (!transferRequests.HasPendingRequests()) { return; } @@ -72,8 +63,8 @@ void EditorWindowMessageDispatcher::RenderAndHandleWindowFrame(const DispatchCon context, EditorWindowFrameDriver::DriveImmediateFrame( context.window, - context.hostRuntime.GetEditorContext(), - context.workspaceCoordinator.IsGlobalTabDragActive())); + context.hostCoordinator.GetEditorContext(), + context.hostCoordinator.IsGlobalTabDragActive())); } bool EditorWindowMessageDispatcher::EnsureTrackingMouseLeave(const DispatchContext& context) { @@ -152,8 +143,8 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowPointerMessage( case WM_MOUSEMOVE: if (CanRouteEditorWindowGlobalTabDragPointerMessages( inputController.GetPointerCaptureOwner(), - context.workspaceCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId())) && - context.workspaceCoordinator.HandleGlobalTabDragPointerMove(context.window)) { + context.hostCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId())) && + context.hostCoordinator.HandleGlobalTabDragPointerMove(context.window)) { outResult = 0; return true; } @@ -161,8 +152,8 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowPointerMessage( inputController.GetPointerCaptureOwner()) && chromeController.HandleResizePointerMove( context.window, - context.hostRuntime.GetEditorContext(), - context.workspaceCoordinator.IsGlobalTabDragActive())) { + context.hostCoordinator.GetEditorContext(), + context.hostCoordinator.IsGlobalTabDragActive())) { outResult = 0; return true; } @@ -170,8 +161,8 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowPointerMessage( inputController.GetPointerCaptureOwner()) && chromeController.HandleChromeDragRestorePointerMove( context.window, - context.hostRuntime.GetEditorContext(), - context.workspaceCoordinator.IsGlobalTabDragActive())) { + context.hostCoordinator.GetEditorContext(), + context.hostCoordinator.IsGlobalTabDragActive())) { outResult = 0; return true; } @@ -195,8 +186,8 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowPointerMessage( outResult = 0; return true; case WM_LBUTTONDOWN: - if (context.workspaceCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId())) { - context.workspaceCoordinator.EndGlobalTabDragSession(); + if (context.hostCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId())) { + context.hostCoordinator.EndGlobalTabDragSession(); } if (chromeController.HandleResizeButtonDown(context.window, lParam)) { outResult = 0; @@ -241,8 +232,8 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowPointerMessage( case WM_LBUTTONUP: if (CanRouteEditorWindowGlobalTabDragPointerMessages( inputController.GetPointerCaptureOwner(), - context.workspaceCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId())) && - context.workspaceCoordinator.HandleGlobalTabDragPointerButtonUp(context.window)) { + context.hostCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId())) && + context.hostCoordinator.HandleGlobalTabDragPointerButtonUp(context.window)) { outResult = 0; return true; } @@ -256,8 +247,8 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowPointerMessage( inputController.GetPointerCaptureOwner()) && chromeController.HandleChromeButtonUp( context.window, - context.hostRuntime.GetEditorContext(), - context.workspaceCoordinator.IsGlobalTabDragActive(), + context.hostCoordinator.GetEditorContext(), + context.hostCoordinator.IsGlobalTabDragActive(), lParam)) { outResult = 0; return true; @@ -288,8 +279,8 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowPointerMessage( case WM_LBUTTONDBLCLK: if (chromeController.HandleChromeDoubleClick( context.window, - context.hostRuntime.GetEditorContext(), - context.workspaceCoordinator.IsGlobalTabDragActive(), + context.hostCoordinator.GetEditorContext(), + context.hostCoordinator.IsGlobalTabDragActive(), lParam)) { outResult = 0; return true; @@ -360,9 +351,9 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowInputMessage( if (reinterpret_cast(lParam) != context.hwnd) { inputController.ClearPointerCaptureOwner(); } - if (context.workspaceCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId()) && + if (context.hostCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId()) && reinterpret_cast(lParam) != context.hwnd) { - context.workspaceCoordinator.EndGlobalTabDragSession(); + context.hostCoordinator.EndGlobalTabDragSession(); outResult = 0; return true; } @@ -442,22 +433,22 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowLifecycleMessage( outResult = 0; return true; case WM_CLOSE: - context.lifecycleCoordinator.ExecuteCloseRequest(context.window); + context.hostCoordinator.ExecuteCloseRequest(context.window); outResult = 0; return true; case WM_PAINT: FinalizeImmediateFrame( context, context.window.OnPaintMessage( - context.hostRuntime.GetEditorContext(), - context.workspaceCoordinator.IsGlobalTabDragActive())); + context.hostCoordinator.GetEditorContext(), + context.hostCoordinator.IsGlobalTabDragActive())); outResult = 0; return true; case WM_ERASEBKGND: outResult = 1; return true; case WM_DESTROY: - context.lifecycleCoordinator.HandleNativeWindowDestroyed(context.window); + context.hostCoordinator.HandleNativeWindowDestroyed(context.window); outResult = 0; return true; default: @@ -497,8 +488,8 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowChromeMessage( case WM_SYSCOMMAND: if (chromeController.HandleSystemCommand( context.window, - context.hostRuntime.GetEditorContext(), - context.workspaceCoordinator.IsGlobalTabDragActive(), + context.hostCoordinator.GetEditorContext(), + context.hostCoordinator.IsGlobalTabDragActive(), wParam)) { outResult = 0; return true; @@ -517,10 +508,7 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowChromeMessage( bool EditorWindowMessageDispatcher::TryDispatch( HWND hwnd, - EditorWindowHostRuntime& hostRuntime, - EditorWindowLifecycleCoordinator& lifecycleCoordinator, - EditorUtilityWindowCoordinator& utilityCoordinator, - EditorWindowWorkspaceCoordinator& workspaceCoordinator, + EditorWindowHostCoordinator& hostCoordinator, EditorWindow& window, UINT message, WPARAM wParam, @@ -528,10 +516,7 @@ bool EditorWindowMessageDispatcher::TryDispatch( LRESULT& outResult) { const DispatchContext context = { .hwnd = hwnd, - .hostRuntime = hostRuntime, - .lifecycleCoordinator = lifecycleCoordinator, - .utilityCoordinator = utilityCoordinator, - .workspaceCoordinator = workspaceCoordinator, + .hostCoordinator = hostCoordinator, .window = window, }; diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.h b/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.h index 03a3436d..49a90e6b 100644 --- a/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.h +++ b/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.h @@ -10,23 +10,13 @@ namespace XCEngine::UI::Editor::App { class EditorWindow; -} - -namespace XCEngine::UI::Editor::App { - -class EditorWindowHostRuntime; -class EditorWindowLifecycleCoordinator; -class EditorUtilityWindowCoordinator; -class EditorWindowWorkspaceCoordinator; +class EditorWindowHostCoordinator; class EditorWindowMessageDispatcher final { public: static bool TryDispatch( HWND hwnd, - EditorWindowHostRuntime& hostRuntime, - EditorWindowLifecycleCoordinator& lifecycleCoordinator, - EditorUtilityWindowCoordinator& utilityCoordinator, - EditorWindowWorkspaceCoordinator& workspaceCoordinator, + EditorWindowHostCoordinator& hostCoordinator, EditorWindow& window, UINT message, WPARAM wParam, diff --git a/editor/app/Windowing/Content/EditorWindowContentFactory.cpp b/editor/app/Windowing/Content/EditorWindowContentFactory.cpp index efdbbd88..fe257536 100644 --- a/editor/app/Windowing/Content/EditorWindowContentFactory.cpp +++ b/editor/app/Windowing/Content/EditorWindowContentFactory.cpp @@ -13,26 +13,28 @@ namespace { class DefaultEditorWindowContentFactory final : public EditorWindowContentFactory { public: + explicit DefaultEditorWindowContentFactory(EditorWindowSystem& windowSystem) + : m_windowSystem(windowSystem) {} + std::unique_ptr CreateWorkspaceContentController( - std::string_view windowId, - UIEditorWorkspaceController workspaceController, - EditorWindowSystem& windowSystem) const override { - return CreateEditorWorkspaceWindowContentController( - windowId, - std::move(workspaceController), - windowSystem); + const UIEditorWindowWorkspaceState& windowState) const override { + return CreateEditorWorkspaceWindowContentController(windowState, m_windowSystem); } std::unique_ptr CreateUtilityContentController( const EditorUtilityWindowDescriptor& descriptor) const override { return CreateEditorUtilityWindowContentController(descriptor); } + +private: + EditorWindowSystem& m_windowSystem; }; } // namespace -std::unique_ptr CreateDefaultEditorWindowContentFactory() { - return std::make_unique(); +std::unique_ptr CreateDefaultEditorWindowContentFactory( + EditorWindowSystem& windowSystem) { + return std::make_unique(windowSystem); } } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Windowing/Content/EditorWindowContentFactory.h b/editor/app/Windowing/Content/EditorWindowContentFactory.h index 2f9ce9ce..f96f23db 100644 --- a/editor/app/Windowing/Content/EditorWindowContentFactory.h +++ b/editor/app/Windowing/Content/EditorWindowContentFactory.h @@ -6,7 +6,7 @@ namespace XCEngine::UI::Editor { class EditorWindowSystem; -class UIEditorWorkspaceController; +struct UIEditorWindowWorkspaceState; } // namespace XCEngine::UI::Editor @@ -20,13 +20,12 @@ public: virtual ~EditorWindowContentFactory() = default; virtual std::unique_ptr CreateWorkspaceContentController( - std::string_view windowId, - UIEditorWorkspaceController workspaceController, - EditorWindowSystem& windowSystem) const = 0; + const UIEditorWindowWorkspaceState& windowState) const = 0; virtual std::unique_ptr CreateUtilityContentController( const EditorUtilityWindowDescriptor& descriptor) const = 0; }; -std::unique_ptr CreateDefaultEditorWindowContentFactory(); +std::unique_ptr CreateDefaultEditorWindowContentFactory( + EditorWindowSystem& windowSystem); } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Windowing/Content/EditorWorkspaceWindowContentController.cpp b/editor/app/Windowing/Content/EditorWorkspaceWindowContentController.cpp index c045023b..3386a55a 100644 --- a/editor/app/Windowing/Content/EditorWorkspaceWindowContentController.cpp +++ b/editor/app/Windowing/Content/EditorWorkspaceWindowContentController.cpp @@ -10,6 +10,15 @@ namespace XCEngine::UI::Editor::App { namespace { +UIEditorWorkspaceController BuildWorkspaceControllerForWindowState( + const UIEditorPanelRegistry& panelRegistry, + const UIEditorWindowWorkspaceState& windowState) { + return UIEditorWorkspaceController( + panelRegistry, + windowState.workspace, + windowState.session); +} + UIEditorWindowWorkspaceState BuildWindowStateFromController( std::string_view windowId, const UIEditorWorkspaceController& workspaceController) { @@ -43,27 +52,18 @@ EditorWindowContentCursorKind ToContentCursorKind( } } -EditorWorkspaceWindowProjection BuildWorkspaceProjectionFromController( - const UIEditorWorkspaceController& workspaceController) { - EditorWorkspaceWindowProjection projection = {}; - projection.minimumOuterSize = ResolveUIEditorDetachedWorkspaceMinimumOuterSize( - workspaceController); - projection.useDetachedTitleBarTabStrip = HasUIEditorSingleVisibleRootTab(workspaceController); - projection.tabStripTitleText = ResolveUIEditorDetachedWorkspaceTitle(workspaceController); - projection.detachedWindowTitleText = ResolveUIEditorDetachedWorkspaceTitle(workspaceController); - return projection; -} - } // namespace EditorWorkspaceWindowContentController::EditorWorkspaceWindowContentController( - std::string windowId, - UIEditorWorkspaceController workspaceController, + const UIEditorWindowWorkspaceState& windowState, EditorWindowSystem& windowSystem) - : m_windowId(std::move(windowId)), - m_windowSystem(windowSystem) { - RefreshProjectionFromWorkspaceController(workspaceController); -} + : m_windowId(windowState.windowId) + , m_windowSystem(windowSystem) + , m_projection(BuildEditorWorkspaceWindowProjection( + std::wstring_view{}, + windowSystem.GetPanelRegistry(), + windowState, + false)) {} EditorWorkspaceWindowContentController::~EditorWorkspaceWindowContentController() = default; @@ -131,22 +131,6 @@ bool EditorWorkspaceWindowContentController::TryBuildAuthoritativeWorkspaceContr return true; } -void EditorWorkspaceWindowContentController::RefreshProjectionFromWorkspaceController( - const UIEditorWorkspaceController& workspaceController, - bool primary) { - const std::wstring preservedWindowTitle = m_projection.windowTitle; - m_projection = BuildWorkspaceProjectionFromController(workspaceController); - if (!primary) { - m_projection.windowTitle = ResolveEditorWindowPresentationTitle( - std::wstring_view{}, - workspaceController.GetPanelRegistry(), - BuildWindowStateFromController(m_windowId, workspaceController), - false); - } else if (!preservedWindowTitle.empty()) { - m_projection.windowTitle = preservedWindowTitle; - } -} - void EditorWorkspaceWindowContentController::Initialize( const EditorWindowContentInitializationContext& context) { m_shellRuntime.Initialize(context.repoRoot, context.textureHost, context.textMeasurer); @@ -196,18 +180,9 @@ EditorWindowFrameTransferRequests EditorWorkspaceWindowContentController::Update workspaceController.GetWorkspace(), workspaceController.GetSession()); if (!AreUIEditorWorkspaceLayoutSnapshotsEquivalent(beforeSnapshot, afterSnapshot)) { - std::string error = {}; - if (!m_windowSystem.CommitLiveWindowMutation( - m_windowId, - workspaceController, - error)) { - AppendUIEditorRuntimeTrace( - "window", - "workspace direct commit rejected for window '" + - m_windowId + "': " + error); - } else { - RefreshProjectionFromWorkspaceController(workspaceController, context.primary); - } + transferRequests.workspace.workspaceMutation = EditorWindowWorkspaceMutationRequest{ + .windowState = BuildWindowStateFromController(m_windowId, workspaceController), + }; } return transferRequests; } @@ -297,12 +272,10 @@ std::string EditorWorkspaceWindowContentController::ResolveDetachedWindowTitleTe } std::unique_ptr CreateEditorWorkspaceWindowContentController( - std::string_view windowId, - UIEditorWorkspaceController workspaceController, + const UIEditorWindowWorkspaceState& windowState, EditorWindowSystem& windowSystem) { return std::make_unique( - std::string(windowId), - std::move(workspaceController), + windowState, windowSystem); } diff --git a/editor/app/Windowing/Content/EditorWorkspaceWindowContentController.h b/editor/app/Windowing/Content/EditorWorkspaceWindowContentController.h index d90b13b1..79be8a79 100644 --- a/editor/app/Windowing/Content/EditorWorkspaceWindowContentController.h +++ b/editor/app/Windowing/Content/EditorWorkspaceWindowContentController.h @@ -10,6 +10,7 @@ namespace XCEngine::UI::Editor { class EditorWindowSystem; +struct UIEditorWindowWorkspaceState; } namespace XCEngine::UI::Editor::App { @@ -22,8 +23,7 @@ class EditorWorkspaceWindowContentController final , public EditorWindowTitleBarBinding { public: EditorWorkspaceWindowContentController( - std::string windowId, - UIEditorWorkspaceController workspaceController, + const UIEditorWindowWorkspaceState& windowState, EditorWindowSystem& windowSystem); ~EditorWorkspaceWindowContentController() override; @@ -77,9 +77,6 @@ public: private: bool TryBuildAuthoritativeWorkspaceController(UIEditorWorkspaceController& outController) const; - void RefreshProjectionFromWorkspaceController( - const UIEditorWorkspaceController& workspaceController, - bool primary = false); std::string m_windowId = {}; EditorWindowSystem& m_windowSystem; @@ -89,8 +86,7 @@ private: }; std::unique_ptr CreateEditorWorkspaceWindowContentController( - std::string_view windowId, - UIEditorWorkspaceController workspaceController, + const UIEditorWindowWorkspaceState& windowState, EditorWindowSystem& windowSystem); } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Windowing/Coordinator/EditorWindowWorkspaceCoordinator.cpp b/editor/app/Windowing/Coordinator/EditorWindowWorkspaceCoordinator.cpp index 1c6855e1..843e57fa 100644 --- a/editor/app/Windowing/Coordinator/EditorWindowWorkspaceCoordinator.cpp +++ b/editor/app/Windowing/Coordinator/EditorWindowWorkspaceCoordinator.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include @@ -50,12 +49,8 @@ bool CanStartGlobalTabDragFromWindow( return false; } - const UIEditorWorkspaceController workspaceController = - BuildWorkspaceControllerForWindowState( - windowSystem.GetPanelRegistry(), - *windowState); - UIEditorWorkspaceModel workspace = workspaceController.GetWorkspace(); - UIEditorWorkspaceSession session = workspaceController.GetSession(); + UIEditorWorkspaceModel workspace = windowState->workspace; + UIEditorWorkspaceSession session = windowState->session; UIEditorWorkspaceExtractedPanel extractedPanel = {}; return TryExtractUIEditorWorkspaceVisiblePanel( workspace, @@ -384,9 +379,7 @@ bool EditorWindowWorkspaceCoordinator::ApplySynchronizationPlan( } EditorHostWindow* const createdWindow = m_hostRuntime.CreateWorkspaceWindow( - BuildWorkspaceControllerForWindowState( - m_windowSystem.GetPanelRegistry(), - action.create.windowState), + action.create.windowState, createParams); if (createdWindow == nullptr) { for (const ExistingWindowSnapshot& snapshot : existingWindowSnapshots) { diff --git a/editor/app/Windowing/Coordinator/EditorWindowWorkspaceCoordinator.h b/editor/app/Windowing/Coordinator/EditorWindowWorkspaceCoordinator.h index 58143130..8903e8bd 100644 --- a/editor/app/Windowing/Coordinator/EditorWindowWorkspaceCoordinator.h +++ b/editor/app/Windowing/Coordinator/EditorWindowWorkspaceCoordinator.h @@ -9,7 +9,6 @@ #include #include -#include #include #include diff --git a/editor/app/Windowing/EditorWindowManager.cpp b/editor/app/Windowing/EditorWindowManager.cpp index 35b1da59..aca4ad52 100644 --- a/editor/app/Windowing/EditorWindowManager.cpp +++ b/editor/app/Windowing/EditorWindowManager.cpp @@ -1,62 +1,40 @@ #include "Windowing/EditorWindowManager.h" -#include "Platform/Win32/Windowing/EditorWindow.h" -#include "Windowing/Content/EditorWindowContentFactory.h" -#include "Windowing/Content/EditorWindowContentController.h" -#include "Platform/Win32/Windowing/EditorWindowHostRuntime.h" #include "Windowing/Coordinator/EditorWindowLifecycleCoordinator.h" #include "Windowing/Coordinator/EditorUtilityWindowCoordinator.h" -#include "Platform/Win32/Windowing/EditorWindowMessageDispatcher.h" #include "Windowing/Coordinator/EditorWindowWorkspaceCoordinator.h" -#include +#include #include namespace XCEngine::UI::Editor::App { EditorWindowManager::EditorWindowManager( - EditorWindowHostConfig hostConfig, - std::filesystem::path repoRoot, EditorContext& editorContext, - EditorWindowSystem& windowSystem) - : m_contentFactory(CreateDefaultEditorWindowContentFactory()) - , m_hostRuntime(std::make_unique( - hostConfig, - std::move(repoRoot), - editorContext, - windowSystem, - *m_contentFactory)) { + EditorWindowSystem& windowSystem, + EditorWindowHostRuntimeServices& hostRuntime) + : m_editorContext(editorContext) + , m_hostRuntime(hostRuntime) { m_workspaceCoordinator = - std::make_unique(*m_hostRuntime, windowSystem); + std::make_unique(m_hostRuntime, windowSystem); m_utilityCoordinator = - std::make_unique(*m_hostRuntime); + std::make_unique(m_hostRuntime); m_lifecycleCoordinator = std::make_unique( - *m_hostRuntime, + m_hostRuntime, *m_workspaceCoordinator); - m_hostRuntime->BindLifecycleCoordinator(*m_lifecycleCoordinator); + m_hostRuntime.BindHostCoordinator(*this); m_workspaceCoordinator->BindLifecycleCoordinator(*m_lifecycleCoordinator); m_utilityCoordinator->BindLifecycleCoordinator(*m_lifecycleCoordinator); } EditorWindowManager::~EditorWindowManager() = default; -EditorHostWindow* EditorWindowManager::CreateEditorWindow( - std::unique_ptr contentController, - const EditorWindowCreateParams& params) { - EditorHostWindow* const window = - m_hostRuntime->CreateEditorWindow(std::move(contentController), params); - if (window != nullptr) { - m_workspaceCoordinator->RegisterExistingWindow(*window); - } - return window; -} - EditorHostWindow* EditorWindowManager::CreateWorkspaceWindow( - UIEditorWorkspaceController workspaceController, + const UIEditorWindowWorkspaceState& windowState, const EditorWindowCreateParams& params) { EditorHostWindow* const window = - m_hostRuntime->CreateWorkspaceWindow(std::move(workspaceController), params); + m_hostRuntime.CreateWorkspaceWindow(windowState, params); if (window != nullptr) { m_workspaceCoordinator->RegisterExistingWindow(*window); } @@ -66,90 +44,37 @@ EditorHostWindow* EditorWindowManager::CreateWorkspaceWindow( EditorHostWindow* EditorWindowManager::CreateUtilityWindow( const EditorUtilityWindowDescriptor& descriptor, const EditorWindowCreateParams& params) { - EditorHostWindow* const window = m_hostRuntime->CreateUtilityWindow(descriptor, params); + EditorHostWindow* const window = m_hostRuntime.CreateUtilityWindow(descriptor, params); if (window != nullptr) { m_workspaceCoordinator->RegisterExistingWindow(*window); } return window; } -void EditorWindowManager::HandlePendingNativeWindowCreated(HWND hwnd) { - m_hostRuntime->HandlePendingNativeWindowCreated(hwnd); -} - void EditorWindowManager::Shutdown() { m_workspaceCoordinator->EndGlobalTabDragSession(); m_lifecycleCoordinator->ShutdownAllWindows(); } bool EditorWindowManager::RequestPrimaryWindowClose() { - if (m_hostRuntime == nullptr || m_lifecycleCoordinator == nullptr) { + if (m_lifecycleCoordinator == nullptr) { return false; } - EditorHostWindow* const primaryWindow = m_hostRuntime->FindPrimaryWindow(); - if (primaryWindow == nullptr) { - return false; + for (EditorHostWindow* window : m_hostRuntime.GetWindows()) { + if (window == nullptr || !window->IsPrimary()) { + continue; + } + + m_lifecycleCoordinator->PostCloseRequest(*window); + return true; } - m_lifecycleCoordinator->PostCloseRequest(*primaryWindow); - return true; -} - -bool EditorWindowManager::TryDispatchWindowMessage( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam, - LRESULT& outResult) { - if (m_hostRuntime == nullptr || m_workspaceCoordinator == nullptr) { - return false; - } - - EditorWindow* const window = m_hostRuntime->FindWindow(hwnd); - if (window == nullptr) { - return false; - } - - return EditorWindowMessageDispatcher::TryDispatch( - hwnd, - *m_hostRuntime, - *m_lifecycleCoordinator, - *m_utilityCoordinator, - *m_workspaceCoordinator, - *window, - message, - wParam, - lParam, - outResult); -} - -EditorHostWindow* EditorWindowManager::FindWindow(HWND hwnd) { - return m_hostRuntime->FindWindow(hwnd); -} - -const EditorHostWindow* EditorWindowManager::FindWindow(HWND hwnd) const { - return m_hostRuntime->FindWindow(hwnd); -} - -EditorHostWindow* EditorWindowManager::FindWindow(std::string_view windowId) { - return m_hostRuntime->FindWindowById(windowId); -} - -const EditorHostWindow* EditorWindowManager::FindWindow(std::string_view windowId) const { - return m_hostRuntime->FindWindowById(windowId); -} - -EditorHostWindow* EditorWindowManager::FindPrimaryWindow() { - return m_hostRuntime->FindPrimaryWindow(); -} - -const EditorHostWindow* EditorWindowManager::FindPrimaryWindow() const { - return m_hostRuntime->FindPrimaryWindow(); + return false; } bool EditorWindowManager::HasWindows() const { - return m_hostRuntime->HasWindows(); + return !m_hostRuntime.GetWindows().empty(); } void EditorWindowManager::DestroyClosedWindows() { @@ -157,10 +82,86 @@ void EditorWindowManager::DestroyClosedWindows() { } void EditorWindowManager::RenderAllWindows() { - m_hostRuntime->RenderAllWindows( - m_workspaceCoordinator->IsGlobalTabDragActive(), - *m_workspaceCoordinator, - *m_utilityCoordinator); + m_hostRuntime.RenderAllWindows(); +} + +EditorContext& EditorWindowManager::GetEditorContext() { + return m_editorContext; +} + +const EditorContext& EditorWindowManager::GetEditorContext() const { + return m_editorContext; +} + +bool EditorWindowManager::IsGlobalTabDragActive() const { + return m_workspaceCoordinator != nullptr && + m_workspaceCoordinator->IsGlobalTabDragActive(); +} + +bool EditorWindowManager::OwnsActiveGlobalTabDrag(std::string_view windowId) const { + return m_workspaceCoordinator != nullptr && + m_workspaceCoordinator->OwnsActiveGlobalTabDrag(windowId); +} + +bool EditorWindowManager::HandleGlobalTabDragPointerMove(EditorHostWindow& window) { + return m_workspaceCoordinator != nullptr && + m_workspaceCoordinator->HandleGlobalTabDragPointerMove(window); +} + +bool EditorWindowManager::HandleGlobalTabDragPointerButtonUp(EditorHostWindow& window) { + return m_workspaceCoordinator != nullptr && + m_workspaceCoordinator->HandleGlobalTabDragPointerButtonUp(window); +} + +void EditorWindowManager::EndGlobalTabDragSession() { + if (m_workspaceCoordinator != nullptr) { + m_workspaceCoordinator->EndGlobalTabDragSession(); + } +} + +void EditorWindowManager::RefreshWindowPresentation(EditorHostWindow& window) { + if (m_workspaceCoordinator != nullptr) { + m_workspaceCoordinator->RefreshWindowPresentation(window); + } +} + +void EditorWindowManager::DispatchWindowFrameTransferRequests( + EditorHostWindow& sourceWindow, + const EditorWindowFrameTransferRequests& transferRequests) { + if (m_workspaceCoordinator != nullptr) { + m_workspaceCoordinator->HandleWindowFrameTransferRequests( + sourceWindow, + transferRequests); + } + if (m_utilityCoordinator != nullptr) { + m_utilityCoordinator->HandleWindowFrameTransferRequests( + sourceWindow, + transferRequests); + } +} + +void EditorWindowManager::ExecuteCloseRequest(EditorHostWindow& window) { + if (m_lifecycleCoordinator != nullptr) { + m_lifecycleCoordinator->ExecuteCloseRequest(window); + } +} + +void EditorWindowManager::HandleNativeWindowDestroyed(EditorHostWindow& window) { + if (m_lifecycleCoordinator != nullptr) { + m_lifecycleCoordinator->HandleNativeWindowDestroyed(window); + } +} + +void EditorWindowManager::AbortUnregisteredWindow(EditorHostWindow& window) { + if (m_lifecycleCoordinator != nullptr) { + m_lifecycleCoordinator->AbortUnregisteredWindow(window); + } +} + +void EditorWindowManager::ReapDestroyedWindows() { + if (m_lifecycleCoordinator != nullptr) { + m_lifecycleCoordinator->ReapDestroyedWindows(); + } } } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Windowing/EditorWindowManager.h b/editor/app/Windowing/EditorWindowManager.h index 77b8ac9d..9bc3e245 100644 --- a/editor/app/Windowing/EditorWindowManager.h +++ b/editor/app/Windowing/EditorWindowManager.h @@ -4,25 +4,15 @@ #define NOMINMAX #endif -#include "Platform/Win32/Windowing/EditorWindowHostConfig.h" +#include "Windowing/Host/EditorWindowHostCoordinator.h" #include "Windowing/Host/EditorWindowHostInterfaces.h" #include "Windowing/Host/EditorWindowHostTypes.h" - -#include - -#include #include -#include #include -#include namespace XCEngine::UI::Editor { -class UIEditorWorkspaceController; -class UIEditorWindowWorkspaceController; class EditorWindowSystem; - -struct UIEditorWindowWorkspaceSet; struct UIEditorWindowWorkspaceState; } // namespace XCEngine::UI::Editor @@ -30,23 +20,19 @@ struct UIEditorWindowWorkspaceState; namespace XCEngine::UI::Editor::App { class EditorContext; -class EditorWindowContentController; -class EditorWindowContentFactory; -class EditorWindowHostRuntime; +class EditorWindowHostRuntimeServices; class EditorWindowLifecycleCoordinator; class EditorUtilityWindowCoordinator; class EditorWindowWorkspaceCoordinator; struct EditorUtilityWindowDescriptor; -struct EditorWindowPanelTransferRequest; struct EditorWindowFrameTransferRequests; -class EditorWindowManager final { +class EditorWindowManager final : public EditorWindowHostCoordinator { public: EditorWindowManager( - EditorWindowHostConfig hostConfig, - std::filesystem::path repoRoot, EditorContext& editorContext, - EditorWindowSystem& windowSystem); + EditorWindowSystem& windowSystem, + EditorWindowHostRuntimeServices& hostRuntime); ~EditorWindowManager(); EditorWindowManager(const EditorWindowManager&) = delete; @@ -54,39 +40,38 @@ public: EditorWindowManager(EditorWindowManager&&) = delete; EditorWindowManager& operator=(EditorWindowManager&&) = delete; - EditorHostWindow* CreateEditorWindow( - std::unique_ptr contentController, - const EditorWindowCreateParams& params); EditorHostWindow* CreateWorkspaceWindow( - UIEditorWorkspaceController workspaceController, + const UIEditorWindowWorkspaceState& windowState, const EditorWindowCreateParams& params); EditorHostWindow* CreateUtilityWindow( const EditorUtilityWindowDescriptor& descriptor, const EditorWindowCreateParams& params); - void HandlePendingNativeWindowCreated(HWND hwnd); void Shutdown(); bool RequestPrimaryWindowClose(); - bool TryDispatchWindowMessage( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam, - LRESULT& outResult); - - EditorHostWindow* FindWindow(HWND hwnd); - const EditorHostWindow* FindWindow(HWND hwnd) const; - EditorHostWindow* FindWindow(std::string_view windowId); - const EditorHostWindow* FindWindow(std::string_view windowId) const; - EditorHostWindow* FindPrimaryWindow(); - const EditorHostWindow* FindPrimaryWindow() const; bool HasWindows() const; void DestroyClosedWindows(); void RenderAllWindows(); private: - std::unique_ptr m_contentFactory = {}; - std::unique_ptr m_hostRuntime = {}; + EditorContext& GetEditorContext() override; + const EditorContext& GetEditorContext() const override; + bool IsGlobalTabDragActive() const override; + bool OwnsActiveGlobalTabDrag(std::string_view windowId) const override; + bool HandleGlobalTabDragPointerMove(EditorHostWindow& window) override; + bool HandleGlobalTabDragPointerButtonUp(EditorHostWindow& window) override; + void EndGlobalTabDragSession() override; + void RefreshWindowPresentation(EditorHostWindow& window) override; + void DispatchWindowFrameTransferRequests( + EditorHostWindow& sourceWindow, + const EditorWindowFrameTransferRequests& transferRequests) override; + void ExecuteCloseRequest(EditorHostWindow& window) override; + void HandleNativeWindowDestroyed(EditorHostWindow& window) override; + void AbortUnregisteredWindow(EditorHostWindow& window) override; + void ReapDestroyedWindows() override; + + EditorContext& m_editorContext; + EditorWindowHostRuntimeServices& m_hostRuntime; std::unique_ptr m_lifecycleCoordinator = {}; std::unique_ptr m_utilityCoordinator = {}; std::unique_ptr m_workspaceCoordinator = {}; diff --git a/editor/app/Windowing/Host/EditorWindowHostCoordinator.h b/editor/app/Windowing/Host/EditorWindowHostCoordinator.h new file mode 100644 index 00000000..f04ebf7f --- /dev/null +++ b/editor/app/Windowing/Host/EditorWindowHostCoordinator.h @@ -0,0 +1,36 @@ +#pragma once + +#include "Windowing/Frame/EditorWindowTransferRequests.h" +#include "Windowing/Host/EditorWindowHostInterfaces.h" + +#include + +namespace XCEngine::UI::Editor::App { + +class EditorContext; + +class EditorWindowHostCoordinator { +public: + virtual ~EditorWindowHostCoordinator() = default; + + virtual EditorContext& GetEditorContext() = 0; + virtual const EditorContext& GetEditorContext() const = 0; + + virtual bool IsGlobalTabDragActive() const = 0; + virtual bool OwnsActiveGlobalTabDrag(std::string_view windowId) const = 0; + virtual bool HandleGlobalTabDragPointerMove(EditorHostWindow& window) = 0; + virtual bool HandleGlobalTabDragPointerButtonUp(EditorHostWindow& window) = 0; + virtual void EndGlobalTabDragSession() = 0; + + virtual void RefreshWindowPresentation(EditorHostWindow& window) = 0; + virtual void DispatchWindowFrameTransferRequests( + EditorHostWindow& sourceWindow, + const EditorWindowFrameTransferRequests& transferRequests) = 0; + + virtual void ExecuteCloseRequest(EditorHostWindow& window) = 0; + virtual void HandleNativeWindowDestroyed(EditorHostWindow& window) = 0; + virtual void AbortUnregisteredWindow(EditorHostWindow& window) = 0; + virtual void ReapDestroyedWindows() = 0; +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Windowing/Host/EditorWindowHostInterfaces.h b/editor/app/Windowing/Host/EditorWindowHostInterfaces.h index 5121c006..2db954ee 100644 --- a/editor/app/Windowing/Host/EditorWindowHostInterfaces.h +++ b/editor/app/Windowing/Host/EditorWindowHostInterfaces.h @@ -6,7 +6,7 @@ #include "Windowing/Host/EditorWindowTypes.h" #include -#include +#include #include #include @@ -26,6 +26,7 @@ struct UIEditorDockHostTabDropTarget; namespace XCEngine::UI::Editor::App { +class EditorWindowHostCoordinator; class EditorWindowDockHostBinding; struct EditorUtilityWindowDescriptor; @@ -79,7 +80,7 @@ public: virtual ~EditorWindowHost() = default; virtual EditorHostWindow* CreateWorkspaceWindow( - UIEditorWorkspaceController workspaceController, + const UIEditorWindowWorkspaceState& windowState, const EditorWindowCreateParams& params) = 0; virtual EditorHostWindow* CreateUtilityWindow( const EditorUtilityWindowDescriptor& descriptor, @@ -103,4 +104,12 @@ public: virtual void LogRuntimeTrace(std::string_view channel, std::string_view message) const = 0; }; +class EditorWindowHostRuntimeServices : public EditorWindowHost { +public: + virtual ~EditorWindowHostRuntimeServices() = default; + + virtual void BindHostCoordinator(EditorWindowHostCoordinator& hostCoordinator) = 0; + virtual void RenderAllWindows() = 0; +}; + } // namespace XCEngine::UI::Editor::App diff --git a/editor/include/XCEditor/Windowing/EditorWindowPresentationPolicy.h b/editor/include/XCEditor/Windowing/EditorWindowPresentationPolicy.h index 415ad4c7..e65a0e00 100644 --- a/editor/include/XCEditor/Windowing/EditorWindowPresentationPolicy.h +++ b/editor/include/XCEditor/Windowing/EditorWindowPresentationPolicy.h @@ -2,17 +2,12 @@ #include #include -#include #include #include namespace XCEngine::UI::Editor { -UIEditorWorkspaceController BuildWorkspaceControllerForWindowState( - const UIEditorPanelRegistry& panelRegistry, - const UIEditorWindowWorkspaceState& windowState); - EditorWorkspaceWindowProjection BuildEditorWorkspaceWindowProjection( std::wstring_view primaryWindowTitle, const UIEditorPanelRegistry& panelRegistry, diff --git a/editor/include/XCEditor/Windowing/EditorWindowSystem.h b/editor/include/XCEditor/Windowing/EditorWindowSystem.h index 09f1d8a7..1af794bb 100644 --- a/editor/include/XCEditor/Windowing/EditorWindowSystem.h +++ b/editor/include/XCEditor/Windowing/EditorWindowSystem.h @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -26,7 +25,7 @@ public: bool BootstrapPrimaryWindow( std::string_view primaryWindowId, - const UIEditorWorkspaceController& workspaceController, + const UIEditorWindowWorkspaceState& primaryWindowState, std::string& outError); bool ValidateWindowSet( @@ -37,10 +36,6 @@ public: const UIEditorWindowWorkspaceSet& GetWindowSet() const; const UIEditorWindowWorkspaceState* FindWindowState(std::string_view windowId) const; UIEditorWindowWorkspaceController BuildWorkspaceMutationController() const; - bool CommitLiveWindowMutation( - std::string_view windowId, - const UIEditorWorkspaceController& workspaceController, - std::string& outError); EditorWindowSynchronizationPlan BuildPlanForWindowSet( const UIEditorWindowWorkspaceSet& targetWindowSet, const std::vector& hostWindows, @@ -48,12 +43,6 @@ public: std::string_view preferredNewWindowId, const EditorWindowSynchronizationPlacement& preferredPlacement, std::string& outError) const; - EditorWindowSynchronizationPlan BuildPlanForLiveWindowMutation( - std::string_view windowId, - const UIEditorWorkspaceController& workspaceController, - const std::vector& hostWindows, - std::wstring_view primaryWindowTitle, - std::string& outError) const; EditorWindowSynchronizationPlan BuildPlanForWorkspaceMutationRequest( const EditorWindowWorkspaceMutationRequest& request, const std::vector& hostWindows, diff --git a/editor/src/Windowing/EditorWindowPresentationPolicy.cpp b/editor/src/Windowing/EditorWindowPresentationPolicy.cpp index 43201ef8..9e735bb6 100644 --- a/editor/src/Windowing/EditorWindowPresentationPolicy.cpp +++ b/editor/src/Windowing/EditorWindowPresentationPolicy.cpp @@ -1,6 +1,7 @@ #include #include +#include namespace XCEngine::UI::Editor { @@ -12,8 +13,6 @@ std::wstring ResolvePrimaryTitle(std::wstring_view primaryWindowTitle) { : std::wstring(primaryWindowTitle); } -} // namespace - UIEditorWorkspaceController BuildWorkspaceControllerForWindowState( const UIEditorPanelRegistry& panelRegistry, const UIEditorWindowWorkspaceState& windowState) { @@ -23,6 +22,8 @@ UIEditorWorkspaceController BuildWorkspaceControllerForWindowState( windowState.session); } +} // namespace + EditorWorkspaceWindowProjection BuildEditorWorkspaceWindowProjection( std::wstring_view primaryWindowTitle, const UIEditorPanelRegistry& panelRegistry, diff --git a/editor/src/Windowing/EditorWindowSystem.cpp b/editor/src/Windowing/EditorWindowSystem.cpp index 6ce13ea6..67514d56 100644 --- a/editor/src/Windowing/EditorWindowSystem.cpp +++ b/editor/src/Windowing/EditorWindowSystem.cpp @@ -21,7 +21,7 @@ const UIEditorPanelRegistry& EditorWindowSystem::GetPanelRegistry() const { bool EditorWindowSystem::BootstrapPrimaryWindow( std::string_view primaryWindowId, - const UIEditorWorkspaceController& workspaceController, + const UIEditorWindowWorkspaceState& primaryWindowState, std::string& outError) { const std::string resolvedPrimaryWindowId = primaryWindowId.empty() ? std::string("main-window") : std::string(primaryWindowId); @@ -30,11 +30,9 @@ bool EditorWindowSystem::BootstrapPrimaryWindow( windowSet.primaryWindowId = resolvedPrimaryWindowId; windowSet.activeWindowId = resolvedPrimaryWindowId; - UIEditorWindowWorkspaceState primaryWindowState = {}; - primaryWindowState.windowId = resolvedPrimaryWindowId; - primaryWindowState.workspace = workspaceController.GetWorkspace(); - primaryWindowState.session = workspaceController.GetSession(); - windowSet.windows.push_back(std::move(primaryWindowState)); + UIEditorWindowWorkspaceState resolvedPrimaryWindowState = primaryWindowState; + resolvedPrimaryWindowState.windowId = resolvedPrimaryWindowId; + windowSet.windows.push_back(std::move(resolvedPrimaryWindowState)); return m_workspaceStore->TrySetWindowSet(std::move(windowSet), outError); } @@ -62,30 +60,6 @@ UIEditorWindowWorkspaceController EditorWindowSystem::BuildWorkspaceMutationCont return UIEditorWindowWorkspaceController(GetPanelRegistry(), GetWindowSet()); } -bool EditorWindowSystem::CommitLiveWindowMutation( - std::string_view windowId, - const UIEditorWorkspaceController& workspaceController, - std::string& outError) { - if (windowId.empty()) { - outError = "live window mutation missing window id"; - return false; - } - - UIEditorWindowWorkspaceSet nextWindowSet = GetWindowSet(); - UIEditorWindowWorkspaceState* existingState = - FindMutableUIEditorWindowWorkspaceState(nextWindowSet, windowId); - if (existingState == nullptr) { - outError = - "live window mutation references unknown window '" + - std::string(windowId) + "'"; - return false; - } - - existingState->workspace = workspaceController.GetWorkspace(); - existingState->session = workspaceController.GetSession(); - return m_workspaceStore->TrySetWindowSet(std::move(nextWindowSet), outError); -} - EditorWindowSynchronizationPlan EditorWindowSystem::BuildPlanForWindowSet( const UIEditorWindowWorkspaceSet& targetWindowSet, const std::vector& hostWindows, @@ -104,23 +78,6 @@ EditorWindowSynchronizationPlan EditorWindowSystem::BuildPlanForWindowSet( outError); } -EditorWindowSynchronizationPlan EditorWindowSystem::BuildPlanForLiveWindowMutation( - std::string_view windowId, - const UIEditorWorkspaceController& workspaceController, - const std::vector& hostWindows, - std::wstring_view primaryWindowTitle, - std::string& outError) const { - EditorWindowWorkspaceMutationRequest request = {}; - request.windowState.windowId = std::string(windowId); - request.windowState.workspace = workspaceController.GetWorkspace(); - request.windowState.session = workspaceController.GetSession(); - return BuildPlanForWorkspaceMutationRequest( - request, - hostWindows, - primaryWindowTitle, - outError); -} - EditorWindowSynchronizationPlan EditorWindowSystem::BuildPlanForWorkspaceMutationRequest( const EditorWindowWorkspaceMutationRequest& request, const std::vector& hostWindows,