From 2e6643b4d1d983ced3ea3ccfe4d44c50e275e3d8 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Mon, 27 Apr 2026 15:37:39 +0800 Subject: [PATCH] Split utility window contracts from feature factories --- docs/plan/editor-core-refactor-plan.md | 49 ++++++++++--- editor/AGENTS.md | 33 ++++++--- editor/CMakeLists.txt | 7 +- editor/app/Bootstrap/Application.cpp | 4 +- editor/app/Composition/EditorContext.h | 2 +- .../EditorUtilityWindowRegistry.cpp | 19 +---- .../EditorUtilityWindowRegistry.h | 11 +++ .../EditorUtilityWindowRuntime.h | 65 +++++++++++++++++ editor/app/Core/Windowing/EditorWindowTypes.h | 71 +++++++++++++++++++ .../Features/ColorPicker/ColorPickerPanel.h | 2 +- .../Features/EditorUtilityWindowRegistry.cpp | 22 ++++++ .../Features/EditorUtilityWindowRegistry.h | 11 +++ .../Features/Inspector/AddComponentPanel.h | 2 +- .../State/EditorUtilityWindowRequestState.h | 2 +- .../UtilityWindows/EditorUtilityWindowKind.h | 13 ---- .../UtilityWindows/EditorUtilityWindowPanel.h | 34 --------- .../EditorUtilityWindowRegistry.h | 36 ---------- .../EditorUtilityWindowContentController.cpp | 8 +-- .../EditorUtilityWindowContentController.h | 3 +- .../Content/EditorWindowContentFactory.cpp | 21 ++++-- .../Content/EditorWindowContentFactory.h | 4 +- .../EditorUtilityWindowCoordinator.cpp | 2 +- editor/app/Windowing/EditorWindowManager.cpp | 6 +- editor/app/Windowing/EditorWindowManager.h | 4 +- .../Frame/EditorWindowTransferRequests.h | 2 +- editor/app/Windowing/Host/EditorWindowTypes.h | 69 +----------------- 26 files changed, 294 insertions(+), 208 deletions(-) rename editor/app/{ => Core}/UtilityWindows/EditorUtilityWindowRegistry.cpp (74%) create mode 100644 editor/app/Core/UtilityWindows/EditorUtilityWindowRegistry.h create mode 100644 editor/app/Core/UtilityWindows/EditorUtilityWindowRuntime.h create mode 100644 editor/app/Core/Windowing/EditorWindowTypes.h create mode 100644 editor/app/Features/EditorUtilityWindowRegistry.cpp create mode 100644 editor/app/Features/EditorUtilityWindowRegistry.h delete mode 100644 editor/app/UtilityWindows/EditorUtilityWindowKind.h delete mode 100644 editor/app/UtilityWindows/EditorUtilityWindowPanel.h delete mode 100644 editor/app/UtilityWindows/EditorUtilityWindowRegistry.h diff --git a/docs/plan/editor-core-refactor-plan.md b/docs/plan/editor-core-refactor-plan.md index 03315ef3..9ad8248e 100644 --- a/docs/plan/editor-core-refactor-plan.md +++ b/docs/plan/editor-core-refactor-plan.md @@ -33,12 +33,12 @@ The reusable layer is mostly healthy: - `editor/include/XCEditor/**` and `editor/src/**` form `XCUIEditor`. - `XCUIEditor` is testable and mostly free of app, Win32, and D3D12 concerns. -The app layer has a good directory vocabulary but weak enforcement: +The app layer has a good directory vocabulary but enforcement is still +incomplete: -- `editor/app/Composition` directly includes concrete feature-panel contracts - from `editor/app/Features`. -- `editor/app/Features` also includes `Composition/EditorContext.h` and - `Composition/EditorPanelIds.h`, creating a composition/feature cycle. +- `XCEditorCore` exists, but its include surface still exposes the whole + `editor/app` root to app code. +- Some feature panels still use `Composition/EditorContext.h` directly. - Win32 and D3D12 currently know about each other through concrete headers. - App-side tests exist but are not consistently wired into CMake; some are stale and reference removed headers. @@ -48,6 +48,14 @@ Completed boundary cuts: - Project service ownership has moved to `editor/app/Services/Project`. `EditorProjectRuntime` depends on the service-owned `ProjectBrowserModel`, and `Features/Project/ProjectPanel` owns the widget-tree projection. +- Panel IDs live under `editor/app/Core/Panels`, and workspace panel runtime + contracts live under `editor/app/Core/WorkspacePanels`. +- Shared window category, lifecycle, chrome-policy, and native-host-policy + contracts live under `editor/app/Core/Windowing`. +- Utility-window kinds, descriptors, and panel contracts live under + `editor/app/Core/UtilityWindows`; concrete Color Picker/Add Component panel + creation lives under `editor/app/Features/EditorUtilityWindowRegistry.*` and + is injected from `Application`. The root issue is not the existence of a single executable target by itself. The root issue is that shared app contracts are stored inside concrete layer @@ -65,6 +73,7 @@ editor/app/ Panels/ State/ UtilityWindows/ + Windowing/ WorkspacePanels/ Services/ @@ -213,7 +222,8 @@ Initial contents: - `app/Project/**` or `app/Services/Project/**` - `app/Scene/**` or `app/Services/Scene/**` - `app/State/**` -- `app/UtilityWindows/**` +- `app/Core/UtilityWindows/**` +- `app/Core/Windowing/**` - `app/Windowing/**` core files that do not require Win32 or D3D12 - host-facing abstract interfaces @@ -298,9 +308,30 @@ scene services, but scene services should not depend on concrete feature UI. ### Utility Windows -Move utility descriptors and kinds to `Core/UtilityWindows` if they are shared -by windowing and features. Concrete utility panel creation remains in -`Features`. +Completed: + +```text +UtilityWindows/EditorUtilityWindowKind.h +UtilityWindows/EditorUtilityWindowPanel.h +UtilityWindows/EditorUtilityWindowRegistry.* + -> Core/UtilityWindows/EditorUtilityWindowRuntime.h + -> Core/UtilityWindows/EditorUtilityWindowRegistry.* + -> Features/EditorUtilityWindowRegistry.* +``` + +Current shape: + +```text +Core/UtilityWindows/EditorUtilityWindowRuntime.h +Core/UtilityWindows/EditorUtilityWindowRegistry.* +Features/EditorUtilityWindowRegistry.* +``` + +Keep utility kinds, descriptors, host context, panel contract, and factory +type in `Core/UtilityWindows`. Keep concrete utility panel construction in +`Features/EditorUtilityWindowRegistry.*` and inject it from the application +composition root. Windowing may resolve descriptors from Core, but must not +include Color Picker, Add Component, or other concrete feature-panel headers. ## Phase 5: Host Boundary Cleanup diff --git a/editor/AGENTS.md b/editor/AGENTS.md index 5f44fb82..55f8b42a 100644 --- a/editor/AGENTS.md +++ b/editor/AGENTS.md @@ -43,7 +43,8 @@ change. `Application`. - `app/Core/` contains app-level contracts and shared app model definitions that are not owned by a concrete feature or composition implementation. - Current examples are panel IDs and the workspace-panel runtime interface. + Current examples are panel IDs, shared window type contracts, the + workspace-panel runtime interface, and utility-window runtime/descriptors. - `app/Composition/` builds the editor shell asset, coordinates shell update phases, and connects app state to hosted panel runtimes. - `app/Windowing/` owns window instances, content controllers, frame transfer @@ -60,6 +61,10 @@ change. workspace-panel runtime interfaces live under `app/Core/WorkspacePanels` so `app/Composition/**` can depend on the contract without depending on the feature registry. +- `app/Features/EditorUtilityWindowRegistry.*` is the concrete utility-window + panel factory. Shared utility-window contracts and descriptors live under + `app/Core/UtilityWindows` so windowing can resolve utility window shape + without constructing concrete feature panels. - `app/Services/Project/`, `app/Scene/`, and `app/State/` hold application services that panels should use instead of owning global state themselves. `ProjectBrowserModel` and `EditorProjectRuntime` live under @@ -181,9 +186,11 @@ inside pure shell/widget code. - Utility windows use `EditorUtilityWindowContentController`. They host an `EditorUtilityWindowPanel`, do not participate in workspace synchronization, and currently do not expose dock-host or viewport capabilities. -- Utility descriptors live in `EditorUtilityWindowRegistry.cpp`. Current - utility windows are Color Picker and Add Component; both are single-instance - topmost tool windows. +- Utility descriptors live in `app/Core/UtilityWindows/EditorUtilityWindowRegistry.cpp`. + Concrete utility panels are created by + `app/Features/EditorUtilityWindowRegistry.*` and injected through the window + content factory. Current utility windows are Color Picker and Add Component; + both are single-instance topmost tool windows. ## Shell, Panels, And Commands @@ -249,10 +256,11 @@ inside pure shell/widget code. - Add new workspace panels by updating the panel ID constants, panel registry, default workspace model, shell presentation, workspace panel runtime adapter, and command/menu entries together. -- Add new utility windows through `EditorUtilityWindowKind`, - `EditorUtilityWindowRegistry`, an `EditorUtilityWindowPanel`, and the - context/request path. Do not model utility windows as workspace panels unless - they really dock inside the workspace. +- Add new utility windows through `app/Core/UtilityWindows` for the kind, + shared descriptor, and `EditorUtilityWindowPanel` contract; add the concrete + panel factory case in `app/Features/EditorUtilityWindowRegistry.*`; then wire + the context/request path. Do not model utility windows as workspace panels + unless they really dock inside the workspace. - Add new commands in the command registry first, then menu/shortcut bindings, host command bridge routing, and focused route tests. - Keep workspace/window mutations transactional. Save the previous state, @@ -351,6 +359,15 @@ ownership rule. `EditorWindowSynchronizationPlanner`. - Utility windows are app content controllers backed by `EditorUtilityWindowPanel`; they are not workspace windows. +- Utility-window runtime contracts and descriptors now live under + `app/Core/UtilityWindows`. Concrete Color Picker/Add Component construction + is owned by `app/Features/EditorUtilityWindowRegistry.*` and injected from + `Application`, so `app/Windowing/**` no longer constructs concrete utility + feature panels. +- Shared window category, lifecycle, chrome-policy, and native-host-policy + contracts now live under `app/Core/Windowing`; the old + `app/Windowing/Host/EditorWindowTypes.h` path is only a compatibility + forwarding header. - Viewport rendering is routed through `ViewportHostService` and the per-window render runtime rather than directly from shell composition. - The old fine-grained app-split target residue was removed from CMake and diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 7bed3ad4..c4fdbf75 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -216,6 +216,10 @@ if(XCENGINE_BUILD_XCUI_EDITOR_APP) app/Bootstrap/Application.cpp ) + set(XCUI_EDITOR_APP_CORE_CONTRACT_SOURCES + app/Core/UtilityWindows/EditorUtilityWindowRegistry.cpp + ) + set(XCUI_EDITOR_APP_STATE_SOURCES app/State/EditorColorPickerToolState.cpp app/State/EditorUtilityWindowRequestState.cpp @@ -240,6 +244,7 @@ if(XCENGINE_BUILD_XCUI_EDITOR_APP) set(XCUI_EDITOR_APP_FEATURE_SOURCES app/Features/Console/ConsolePanel.cpp app/Features/ColorPicker/ColorPickerPanel.cpp + app/Features/EditorUtilityWindowRegistry.cpp app/Features/EditorWorkspacePanelRegistry.cpp app/Features/Hierarchy/HierarchyModel.cpp app/Features/Hierarchy/HierarchyPanel.cpp @@ -258,7 +263,6 @@ if(XCENGINE_BUILD_XCUI_EDITOR_APP) app/Features/Scene/SceneViewportFeature.cpp app/Features/Scene/SceneViewportToolOverlay.cpp app/Features/Scene/SceneViewportController.cpp - app/UtilityWindows/EditorUtilityWindowRegistry.cpp ) set(XCUI_EDITOR_APP_RENDERING_SOURCES @@ -294,6 +298,7 @@ if(XCENGINE_BUILD_XCUI_EDITOR_APP) ) set(XCUI_EDITOR_APP_CORE_SOURCES + ${XCUI_EDITOR_APP_CORE_CONTRACT_SOURCES} ${XCUI_EDITOR_APP_STATE_SOURCES} ${XCUI_EDITOR_APP_COMMAND_SOURCES} ${XCUI_EDITOR_APP_COMPOSITION_SOURCES} diff --git a/editor/app/Bootstrap/Application.cpp b/editor/app/Bootstrap/Application.cpp index 49cecdee..889f13b7 100644 --- a/editor/app/Bootstrap/Application.cpp +++ b/editor/app/Bootstrap/Application.cpp @@ -2,6 +2,7 @@ #include "Bootstrap/EditorResources.h" #include "System/SystemInteractionService.h" #include "Composition/EditorContext.h" +#include "Features/EditorUtilityWindowRegistry.h" #include "Features/EditorWorkspacePanelRegistry.h" #include "Windowing/EditorWindowManager.h" #include "Platform/Win32/Diagnostics/Win32CrashTrace.h" @@ -154,7 +155,8 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) { *m_windowSystem, *m_renderRuntimeFactory, *m_windowHostRuntime, - App::CreateEditorWorkspacePanelRuntimeSet); + App::CreateEditorWorkspacePanelRuntimeSet, + App::CreateEditorUtilityWindowPanel); m_editorContext->SetExitRequestHandler([this]() { if (m_windowManager == nullptr) { diff --git a/editor/app/Composition/EditorContext.h b/editor/app/Composition/EditorContext.h index a744da92..8adae4e9 100644 --- a/editor/app/Composition/EditorContext.h +++ b/editor/app/Composition/EditorContext.h @@ -3,7 +3,7 @@ #include "Composition/EditorShellVariant.h" #include "Scene/EditorSceneRuntime.h" #include "Services/Project/EditorProjectRuntime.h" -#include "UtilityWindows/EditorUtilityWindowKind.h" +#include "Core/UtilityWindows/EditorUtilityWindowRuntime.h" #include "Commands/EditorHostCommandBridge.h" #include "State/EditorColorPickerToolState.h" diff --git a/editor/app/UtilityWindows/EditorUtilityWindowRegistry.cpp b/editor/app/Core/UtilityWindows/EditorUtilityWindowRegistry.cpp similarity index 74% rename from editor/app/UtilityWindows/EditorUtilityWindowRegistry.cpp rename to editor/app/Core/UtilityWindows/EditorUtilityWindowRegistry.cpp index cb27ca9d..fc9e9b53 100644 --- a/editor/app/UtilityWindows/EditorUtilityWindowRegistry.cpp +++ b/editor/app/Core/UtilityWindows/EditorUtilityWindowRegistry.cpp @@ -1,7 +1,4 @@ -#include "UtilityWindows/EditorUtilityWindowRegistry.h" - -#include "Features/ColorPicker/ColorPickerPanel.h" -#include "Features/Inspector/AddComponentPanel.h" +#include "Core/UtilityWindows/EditorUtilityWindowRegistry.h" namespace XCEngine::UI::Editor::App { @@ -55,17 +52,5 @@ const EditorUtilityWindowDescriptor* ResolveEditorUtilityWindowDescriptor( } } -std::unique_ptr CreateEditorUtilityWindowPanel( - EditorUtilityWindowKind kind) { - switch (kind) { - case EditorUtilityWindowKind::ColorPicker: - return std::make_unique(); - case EditorUtilityWindowKind::AddComponent: - return std::make_unique(); - case EditorUtilityWindowKind::None: - default: - return nullptr; - } -} - } // namespace XCEngine::UI::Editor::App + diff --git a/editor/app/Core/UtilityWindows/EditorUtilityWindowRegistry.h b/editor/app/Core/UtilityWindows/EditorUtilityWindowRegistry.h new file mode 100644 index 00000000..e55a3d55 --- /dev/null +++ b/editor/app/Core/UtilityWindows/EditorUtilityWindowRegistry.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Core/UtilityWindows/EditorUtilityWindowRuntime.h" + +namespace XCEngine::UI::Editor::App { + +const EditorUtilityWindowDescriptor* ResolveEditorUtilityWindowDescriptor( + EditorUtilityWindowKind kind); + +} // namespace XCEngine::UI::Editor::App + diff --git a/editor/app/Core/UtilityWindows/EditorUtilityWindowRuntime.h b/editor/app/Core/UtilityWindows/EditorUtilityWindowRuntime.h new file mode 100644 index 00000000..4e734d60 --- /dev/null +++ b/editor/app/Core/UtilityWindows/EditorUtilityWindowRuntime.h @@ -0,0 +1,65 @@ +#pragma once + +#include "Core/Windowing/EditorWindowTypes.h" + +#include +#include + +#include +#include +#include +#include +#include + +namespace XCEngine::UI::Editor::App { + +class EditorContext; + +enum class EditorUtilityWindowKind : std::uint8_t { + None = 0, + ColorPicker, + AddComponent, +}; + +enum class EditorUtilityWindowReusePolicy { + SingleInstance = 0, +}; + +struct EditorUtilityWindowDescriptor { + EditorUtilityWindowKind kind = EditorUtilityWindowKind::None; + std::string_view windowId = {}; + const wchar_t* title = L""; + EditorUtilityWindowReusePolicy reusePolicy = + EditorUtilityWindowReusePolicy::SingleInstance; + EditorWindowChromePolicy chromePolicy = {}; + EditorWindowNativeHostPolicy nativeHostPolicy = {}; + ::XCEngine::UI::UISize preferredOuterSize = {}; + ::XCEngine::UI::UISize minimumOuterSize = {}; +}; + +struct EditorUtilityWindowHostContext { + bool mounted = false; + ::XCEngine::UI::UIRect bounds = {}; + bool allowInteraction = false; + bool focused = false; + bool focusGained = false; + bool focusLost = false; +}; + +class EditorUtilityWindowPanel { +public: + virtual ~EditorUtilityWindowPanel() = default; + + virtual std::string_view GetDrawListId() const = 0; + virtual void ResetInteractionState() = 0; + virtual void Update( + EditorContext& context, + const EditorUtilityWindowHostContext& hostContext, + const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) = 0; + virtual void Append(::XCEngine::UI::UIDrawList& drawList) const = 0; +}; + +using EditorUtilityWindowPanelFactory = + std::function(EditorUtilityWindowKind)>; + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Core/Windowing/EditorWindowTypes.h b/editor/app/Core/Windowing/EditorWindowTypes.h new file mode 100644 index 00000000..a164cdd7 --- /dev/null +++ b/editor/app/Core/Windowing/EditorWindowTypes.h @@ -0,0 +1,71 @@ +#pragma once + +#include +#include + +namespace XCEngine::UI::Editor::App { + +enum class EditorWindowLifecycleState : std::uint8_t { + PendingNativeCreate = 0, + NativeAttached, + Initializing, + Running, + Closing, + Destroyed, +}; + +enum class EditorWindowCategory : std::uint8_t { + Workspace = 0, + Utility, +}; + +enum class EditorWindowNativeShellRole : std::uint8_t { + AppWindow = 0, + ToolWindow, +}; + +inline std::string_view GetEditorWindowCategoryName( + EditorWindowCategory category) { + switch (category) { + case EditorWindowCategory::Workspace: + return "Workspace"; + case EditorWindowCategory::Utility: + return "Utility"; + } + + return "Unknown"; +} + +struct EditorWindowChromePolicy { + bool allowDetachedTitleBarTabStrip = true; + bool showFrameStats = true; + bool showTopmostButton = false; + bool topmostByDefault = false; +}; + +struct EditorWindowNativeHostPolicy { + EditorWindowNativeShellRole shellRole = EditorWindowNativeShellRole::AppWindow; +}; + +inline std::string_view GetEditorWindowLifecycleStateName( + EditorWindowLifecycleState state) { + switch (state) { + case EditorWindowLifecycleState::PendingNativeCreate: + return "PendingNativeCreate"; + case EditorWindowLifecycleState::NativeAttached: + return "NativeAttached"; + case EditorWindowLifecycleState::Initializing: + return "Initializing"; + case EditorWindowLifecycleState::Running: + return "Running"; + case EditorWindowLifecycleState::Closing: + return "Closing"; + case EditorWindowLifecycleState::Destroyed: + return "Destroyed"; + } + + return "Unknown"; +} + +} // namespace XCEngine::UI::Editor::App + diff --git a/editor/app/Features/ColorPicker/ColorPickerPanel.h b/editor/app/Features/ColorPicker/ColorPickerPanel.h index f9bb93fe..2303908a 100644 --- a/editor/app/Features/ColorPicker/ColorPickerPanel.h +++ b/editor/app/Features/ColorPicker/ColorPickerPanel.h @@ -1,6 +1,6 @@ #pragma once -#include "UtilityWindows/EditorUtilityWindowPanel.h" +#include "Core/UtilityWindows/EditorUtilityWindowRuntime.h" #include diff --git a/editor/app/Features/EditorUtilityWindowRegistry.cpp b/editor/app/Features/EditorUtilityWindowRegistry.cpp new file mode 100644 index 00000000..7398925e --- /dev/null +++ b/editor/app/Features/EditorUtilityWindowRegistry.cpp @@ -0,0 +1,22 @@ +#include "Features/EditorUtilityWindowRegistry.h" + +#include "Features/ColorPicker/ColorPickerPanel.h" +#include "Features/Inspector/AddComponentPanel.h" + +namespace XCEngine::UI::Editor::App { + +std::unique_ptr CreateEditorUtilityWindowPanel( + EditorUtilityWindowKind kind) { + switch (kind) { + case EditorUtilityWindowKind::ColorPicker: + return std::make_unique(); + case EditorUtilityWindowKind::AddComponent: + return std::make_unique(); + case EditorUtilityWindowKind::None: + default: + return nullptr; + } +} + +} // namespace XCEngine::UI::Editor::App + diff --git a/editor/app/Features/EditorUtilityWindowRegistry.h b/editor/app/Features/EditorUtilityWindowRegistry.h new file mode 100644 index 00000000..b55399d9 --- /dev/null +++ b/editor/app/Features/EditorUtilityWindowRegistry.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Core/UtilityWindows/EditorUtilityWindowRuntime.h" + +namespace XCEngine::UI::Editor::App { + +std::unique_ptr CreateEditorUtilityWindowPanel( + EditorUtilityWindowKind kind); + +} // namespace XCEngine::UI::Editor::App + diff --git a/editor/app/Features/Inspector/AddComponentPanel.h b/editor/app/Features/Inspector/AddComponentPanel.h index e21bcd27..ba002571 100644 --- a/editor/app/Features/Inspector/AddComponentPanel.h +++ b/editor/app/Features/Inspector/AddComponentPanel.h @@ -1,6 +1,6 @@ #pragma once -#include "UtilityWindows/EditorUtilityWindowPanel.h" +#include "Core/UtilityWindows/EditorUtilityWindowRuntime.h" #include #include diff --git a/editor/app/State/EditorUtilityWindowRequestState.h b/editor/app/State/EditorUtilityWindowRequestState.h index b2059dcf..9ec8a626 100644 --- a/editor/app/State/EditorUtilityWindowRequestState.h +++ b/editor/app/State/EditorUtilityWindowRequestState.h @@ -1,6 +1,6 @@ #pragma once -#include "UtilityWindows/EditorUtilityWindowKind.h" +#include "Core/UtilityWindows/EditorUtilityWindowRuntime.h" #include diff --git a/editor/app/UtilityWindows/EditorUtilityWindowKind.h b/editor/app/UtilityWindows/EditorUtilityWindowKind.h deleted file mode 100644 index cb8e3542..00000000 --- a/editor/app/UtilityWindows/EditorUtilityWindowKind.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -namespace XCEngine::UI::Editor::App { - -enum class EditorUtilityWindowKind : std::uint8_t { - None = 0, - ColorPicker, - AddComponent, -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/UtilityWindows/EditorUtilityWindowPanel.h b/editor/app/UtilityWindows/EditorUtilityWindowPanel.h deleted file mode 100644 index 5042f7d6..00000000 --- a/editor/app/UtilityWindows/EditorUtilityWindowPanel.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include - -#include -#include - -namespace XCEngine::UI::Editor::App { - -class EditorContext; - -struct EditorUtilityWindowHostContext { - bool mounted = false; - ::XCEngine::UI::UIRect bounds = {}; - bool allowInteraction = false; - bool focused = false; - bool focusGained = false; - bool focusLost = false; -}; - -class EditorUtilityWindowPanel { -public: - virtual ~EditorUtilityWindowPanel() = default; - - virtual std::string_view GetDrawListId() const = 0; - virtual void ResetInteractionState() = 0; - virtual void Update( - EditorContext& context, - const EditorUtilityWindowHostContext& hostContext, - const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) = 0; - virtual void Append(::XCEngine::UI::UIDrawList& drawList) const = 0; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/UtilityWindows/EditorUtilityWindowRegistry.h b/editor/app/UtilityWindows/EditorUtilityWindowRegistry.h deleted file mode 100644 index 89a747d5..00000000 --- a/editor/app/UtilityWindows/EditorUtilityWindowRegistry.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "UtilityWindows/EditorUtilityWindowKind.h" -#include "UtilityWindows/EditorUtilityWindowPanel.h" -#include "Windowing/Host/EditorWindowTypes.h" - -#include - -#include -#include - -namespace XCEngine::UI::Editor::App { - -enum class EditorUtilityWindowReusePolicy { - SingleInstance = 0, -}; - -struct EditorUtilityWindowDescriptor { - EditorUtilityWindowKind kind = EditorUtilityWindowKind::None; - std::string_view windowId = {}; - const wchar_t* title = L""; - EditorUtilityWindowReusePolicy reusePolicy = - EditorUtilityWindowReusePolicy::SingleInstance; - EditorWindowChromePolicy chromePolicy = {}; - EditorWindowNativeHostPolicy nativeHostPolicy = {}; - ::XCEngine::UI::UISize preferredOuterSize = {}; - ::XCEngine::UI::UISize minimumOuterSize = {}; -}; - -const EditorUtilityWindowDescriptor* ResolveEditorUtilityWindowDescriptor( - EditorUtilityWindowKind kind); - -std::unique_ptr CreateEditorUtilityWindowPanel( - EditorUtilityWindowKind kind); - -} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Windowing/Content/EditorUtilityWindowContentController.cpp b/editor/app/Windowing/Content/EditorUtilityWindowContentController.cpp index 563221f6..ddaf61c5 100644 --- a/editor/app/Windowing/Content/EditorUtilityWindowContentController.cpp +++ b/editor/app/Windowing/Content/EditorUtilityWindowContentController.cpp @@ -1,7 +1,6 @@ #include "Windowing/Content/EditorUtilityWindowContentController.h" -#include "UtilityWindows/EditorUtilityWindowPanel.h" -#include "UtilityWindows/EditorUtilityWindowRegistry.h" +#include "Core/UtilityWindows/EditorUtilityWindowRuntime.h" #include @@ -100,9 +99,8 @@ EditorUtilityWindowContentController::GetShellInteractionState() const { } std::unique_ptr CreateEditorUtilityWindowContentController( - const EditorUtilityWindowDescriptor& descriptor) { - std::unique_ptr panel = - CreateEditorUtilityWindowPanel(descriptor.kind); + const EditorUtilityWindowDescriptor& descriptor, + std::unique_ptr panel) { if (panel == nullptr) { return nullptr; } diff --git a/editor/app/Windowing/Content/EditorUtilityWindowContentController.h b/editor/app/Windowing/Content/EditorUtilityWindowContentController.h index 1b2d2d11..f8e6d31d 100644 --- a/editor/app/Windowing/Content/EditorUtilityWindowContentController.h +++ b/editor/app/Windowing/Content/EditorUtilityWindowContentController.h @@ -40,6 +40,7 @@ private: }; std::unique_ptr CreateEditorUtilityWindowContentController( - const EditorUtilityWindowDescriptor& descriptor); + const EditorUtilityWindowDescriptor& descriptor, + std::unique_ptr panel); } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Windowing/Content/EditorWindowContentFactory.cpp b/editor/app/Windowing/Content/EditorWindowContentFactory.cpp index cc3bf9e6..69598535 100644 --- a/editor/app/Windowing/Content/EditorWindowContentFactory.cpp +++ b/editor/app/Windowing/Content/EditorWindowContentFactory.cpp @@ -15,9 +15,11 @@ class DefaultEditorWindowContentFactory final : public EditorWindowContentFactor public: DefaultEditorWindowContentFactory( EditorWindowSystem& windowSystem, - EditorWorkspacePanelRuntimeSetFactory workspacePanelFactory) + EditorWorkspacePanelRuntimeSetFactory workspacePanelFactory, + EditorUtilityWindowPanelFactory utilityPanelFactory) : m_windowSystem(windowSystem) - , m_workspacePanelFactory(std::move(workspacePanelFactory)) {} + , m_workspacePanelFactory(std::move(workspacePanelFactory)) + , m_utilityPanelFactory(std::move(utilityPanelFactory)) {} std::unique_ptr CreateWorkspaceContentController( const UIEditorWindowWorkspaceState& windowState) const override { @@ -33,22 +35,31 @@ public: std::unique_ptr CreateUtilityContentController( const EditorUtilityWindowDescriptor& descriptor) const override { - return CreateEditorUtilityWindowContentController(descriptor); + std::unique_ptr panel = + m_utilityPanelFactory + ? m_utilityPanelFactory(descriptor.kind) + : nullptr; + return CreateEditorUtilityWindowContentController( + descriptor, + std::move(panel)); } private: EditorWindowSystem& m_windowSystem; EditorWorkspacePanelRuntimeSetFactory m_workspacePanelFactory = {}; + EditorUtilityWindowPanelFactory m_utilityPanelFactory = {}; }; } // namespace std::unique_ptr CreateDefaultEditorWindowContentFactory( EditorWindowSystem& windowSystem, - EditorWorkspacePanelRuntimeSetFactory workspacePanelFactory) { + EditorWorkspacePanelRuntimeSetFactory workspacePanelFactory, + EditorUtilityWindowPanelFactory utilityPanelFactory) { return std::make_unique( windowSystem, - std::move(workspacePanelFactory)); + std::move(workspacePanelFactory), + std::move(utilityPanelFactory)); } } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Windowing/Content/EditorWindowContentFactory.h b/editor/app/Windowing/Content/EditorWindowContentFactory.h index 14237f7b..83d686bd 100644 --- a/editor/app/Windowing/Content/EditorWindowContentFactory.h +++ b/editor/app/Windowing/Content/EditorWindowContentFactory.h @@ -1,5 +1,6 @@ #pragma once +#include "Core/UtilityWindows/EditorUtilityWindowRuntime.h" #include "Core/WorkspacePanels/EditorWorkspacePanelRuntime.h" #include @@ -29,6 +30,7 @@ public: std::unique_ptr CreateDefaultEditorWindowContentFactory( EditorWindowSystem& windowSystem, - EditorWorkspacePanelRuntimeSetFactory workspacePanelFactory); + EditorWorkspacePanelRuntimeSetFactory workspacePanelFactory, + EditorUtilityWindowPanelFactory utilityPanelFactory); } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Windowing/Coordinator/EditorUtilityWindowCoordinator.cpp b/editor/app/Windowing/Coordinator/EditorUtilityWindowCoordinator.cpp index b4eb0662..7c884bf9 100644 --- a/editor/app/Windowing/Coordinator/EditorUtilityWindowCoordinator.cpp +++ b/editor/app/Windowing/Coordinator/EditorUtilityWindowCoordinator.cpp @@ -1,6 +1,6 @@ #include "Windowing/Coordinator/EditorUtilityWindowCoordinator.h" -#include "UtilityWindows/EditorUtilityWindowRegistry.h" +#include "Core/UtilityWindows/EditorUtilityWindowRegistry.h" #include "Windowing/Content/EditorWindowContentController.h" #include "Windowing/Content/EditorWindowContentFactory.h" #include "Windowing/Coordinator/EditorWindowLifecycleCoordinator.h" diff --git a/editor/app/Windowing/EditorWindowManager.cpp b/editor/app/Windowing/EditorWindowManager.cpp index ea0dd9f1..a20e47e4 100644 --- a/editor/app/Windowing/EditorWindowManager.cpp +++ b/editor/app/Windowing/EditorWindowManager.cpp @@ -24,13 +24,15 @@ EditorWindowManager::EditorWindowManager( EditorWindowSystem& windowSystem, Rendering::Host::EditorWindowRenderRuntimeFactory& renderRuntimeFactory, EditorWindowHostRuntimeServices& hostRuntime, - EditorWorkspacePanelRuntimeSetFactory workspacePanelFactory) + EditorWorkspacePanelRuntimeSetFactory workspacePanelFactory, + EditorUtilityWindowPanelFactory utilityPanelFactory) : m_editorContext(editorContext) , m_renderRuntimeFactory(renderRuntimeFactory) , m_hostRuntime(hostRuntime) { m_contentFactory = CreateDefaultEditorWindowContentFactory( windowSystem, - std::move(workspacePanelFactory)); + std::move(workspacePanelFactory), + std::move(utilityPanelFactory)); m_workspaceCoordinator = std::make_unique( m_editorContext, diff --git a/editor/app/Windowing/EditorWindowManager.h b/editor/app/Windowing/EditorWindowManager.h index f7ebe62f..25670f06 100644 --- a/editor/app/Windowing/EditorWindowManager.h +++ b/editor/app/Windowing/EditorWindowManager.h @@ -4,6 +4,7 @@ #define NOMINMAX #endif +#include "Core/UtilityWindows/EditorUtilityWindowRuntime.h" #include "Windowing/Host/EditorWindowHostCoordinator.h" #include "Windowing/Host/EditorWindowHostInterfaces.h" #include "Windowing/Host/EditorWindowHostTypes.h" @@ -42,7 +43,8 @@ public: EditorWindowSystem& windowSystem, Rendering::Host::EditorWindowRenderRuntimeFactory& renderRuntimeFactory, EditorWindowHostRuntimeServices& hostRuntime, - EditorWorkspacePanelRuntimeSetFactory workspacePanelFactory); + EditorWorkspacePanelRuntimeSetFactory workspacePanelFactory, + EditorUtilityWindowPanelFactory utilityPanelFactory); ~EditorWindowManager(); EditorWindowManager(const EditorWindowManager&) = delete; diff --git a/editor/app/Windowing/Frame/EditorWindowTransferRequests.h b/editor/app/Windowing/Frame/EditorWindowTransferRequests.h index 8afa0cce..9e550603 100644 --- a/editor/app/Windowing/Frame/EditorWindowTransferRequests.h +++ b/editor/app/Windowing/Frame/EditorWindowTransferRequests.h @@ -5,7 +5,7 @@ #endif #include "Windowing/EditorWindowShared.h" -#include "UtilityWindows/EditorUtilityWindowKind.h" +#include "Core/UtilityWindows/EditorUtilityWindowRuntime.h" #include #include diff --git a/editor/app/Windowing/Host/EditorWindowTypes.h b/editor/app/Windowing/Host/EditorWindowTypes.h index 5e5d90be..e53ea3b6 100644 --- a/editor/app/Windowing/Host/EditorWindowTypes.h +++ b/editor/app/Windowing/Host/EditorWindowTypes.h @@ -1,70 +1,3 @@ #pragma once -#include -#include - -namespace XCEngine::UI::Editor::App { - -enum class EditorWindowLifecycleState : std::uint8_t { - PendingNativeCreate = 0, - NativeAttached, - Initializing, - Running, - Closing, - Destroyed, -}; - -enum class EditorWindowCategory : std::uint8_t { - Workspace = 0, - Utility, -}; - -enum class EditorWindowNativeShellRole : std::uint8_t { - AppWindow = 0, - ToolWindow, -}; - -inline std::string_view GetEditorWindowCategoryName( - EditorWindowCategory category) { - switch (category) { - case EditorWindowCategory::Workspace: - return "Workspace"; - case EditorWindowCategory::Utility: - return "Utility"; - } - - return "Unknown"; -} - -struct EditorWindowChromePolicy { - bool allowDetachedTitleBarTabStrip = true; - bool showFrameStats = true; - bool showTopmostButton = false; - bool topmostByDefault = false; -}; - -struct EditorWindowNativeHostPolicy { - EditorWindowNativeShellRole shellRole = EditorWindowNativeShellRole::AppWindow; -}; - -inline std::string_view GetEditorWindowLifecycleStateName( - EditorWindowLifecycleState state) { - switch (state) { - case EditorWindowLifecycleState::PendingNativeCreate: - return "PendingNativeCreate"; - case EditorWindowLifecycleState::NativeAttached: - return "NativeAttached"; - case EditorWindowLifecycleState::Initializing: - return "Initializing"; - case EditorWindowLifecycleState::Running: - return "Running"; - case EditorWindowLifecycleState::Closing: - return "Closing"; - case EditorWindowLifecycleState::Destroyed: - return "Destroyed"; - } - - return "Unknown"; -} - -} // namespace XCEngine::UI::Editor::App +#include "Core/Windowing/EditorWindowTypes.h"