diff --git a/docs/plan/editor-core-refactor-plan.md b/docs/plan/editor-core-refactor-plan.md index af9ccbeb..339a6390 100644 --- a/docs/plan/editor-core-refactor-plan.md +++ b/docs/plan/editor-core-refactor-plan.md @@ -48,9 +48,13 @@ incomplete: code to load built-in PNGs, title-bar branding, or executable-relative capture output paths. - Scene viewport shader paths now flow through runtime initialization. The - scene viewport feature builds the paths from the runtime repo root and + viewport runtime service builds the paths from the runtime repo root and injects them into the render service/pass bundle instead of letting render passes infer source-tree paths from a compile-time repo-root macro. +- Editor icon and viewport runtime contracts now live under + `editor/app/Core/Assets` and `editor/app/Core/Viewport`. Concrete icon + loading, viewport host services, scene viewport rendering, render targets, + and object-id picking stay under `editor/app/Rendering`. - Feature panels no longer use `Composition/EditorContext.h` directly. The app-core and app feature/viewport test targets now exercise `XCEditorCore` outside the executable host. @@ -105,9 +109,13 @@ Completed boundary cuts: - The private `editor/app` compatibility include root is gone from `XCEditorCore` and `XCEditor`. App implementation files now include through explicit module roots such as `app/Composition`, `app/Features`, - `app/Windowing`, `app/Rendering`, `app/Scene`, `app/Services`, - `app/Support`, `app/Host/Interfaces`, `app/Host/Win32`, and - `app/Host/D3D12`; only executable-host code consumes `app/Bootstrap`. + `app/Windowing`, `app/Scene`, `app/Services`, `app/Support`, + `app/Host/Interfaces`, `app/Host/Win32`, and `app/Host/D3D12`; only + executable-host code consumes `app/Bootstrap`. +- Concrete `app/Rendering/**` files now build through the + `XCEditorCoreRendering` object library. `XCEditorCore` consumes the object + files but does not expose `app/Rendering` to Composition, Features, or Core + sources. - `editor_app_core_tests` now links `XCEditorCore` directly and uses explicit app module include roots. Its initial suite covers host command routing, project runtime, shell asset validation, project browser model, hierarchy @@ -143,11 +151,13 @@ The refactor should converge on this shape: ```text editor/app/ Core/ + Assets/ Commands/ Panels/ Scene/ State/ UtilityWindows/ + Viewport/ Windowing/ WorkspacePanels/ @@ -175,6 +185,10 @@ editor/app/ Win32/ D3D12/ + Rendering/ + Assets/ + Viewport/ + Bootstrap/ Support/ ``` @@ -183,6 +197,12 @@ This is a convergence target, not a requirement to move every file at once. The first cut should only move contracts that are already acting as global app interfaces. +Same domain names under different layers are acceptable only when the layer +meaning is explicit and build-checked: `Core/Viewport` is the shared contract +surface, while `Rendering/Viewport` is the concrete implementation. If a +Composition or Feature file needs a viewport concept, it should include the +Core contract, not the concrete Rendering path. + ## Dependency Rules The final direction should be: @@ -197,6 +217,12 @@ Within `XCEditorCore`: `XCUIEditor`. - `Composition` must not include concrete feature panel headers. - `Features` may depend on `Core`, `Services`, and `XCUIEditor`. +- `Composition` and `Features` must not include concrete `app/Rendering/**` + headers. They should use `Core/Assets/EditorIconService.h` and + `Core/Viewport/**` contracts. +- `app/Rendering/**` may depend on `Core`, `Host/Interfaces`, `XCUIEditor`, + and engine renderer/editor support. It implements Core contracts and is wired + from `Application`. - `Services` must not depend on `Features`. - `State` must not depend on `Composition`. - `Windowing` may depend on `Core`, `Composition` interfaces, and @@ -458,7 +484,7 @@ not a rendering implementation detail. Keep future scene-to-viewport request values under `Core/Scene` so scene services can build requests without taking an `app/Rendering/**` include dependency. - Scene viewport shader paths are runtime configuration now. Build them from - the runtime repo root in `SceneViewportFeature`, inject them into + the runtime repo root in the viewport runtime service, inject them into `SceneViewportRenderService`, and keep grid/selection render passes from inferring source-tree paths with compile-time macros or `__FILE__`. @@ -554,8 +580,25 @@ Completed cuts: scene viewport request contract without depending on `app/Rendering/**`, and `editor_app_core_tests` no longer needs the app rendering include root to validate scene runtime behavior. -- Scene viewport shader/resource paths are now injected from - `SceneViewportFeature` into `SceneViewportRenderService` and +- Editor icon contracts now live under + `editor/app/Core/Assets/EditorIconService.h`. `BuiltInIcons` remains the + concrete `editor/app/Rendering` implementation, and panels/tool overlays + resolve icons through the contract instead of loading resource files or + naming concrete icon storage. +- Viewport runtime contracts now live under `editor/app/Core/Viewport/**`. + `SceneViewportFeature` consumes `EditorSceneViewportRuntime`, while + `ViewportHostService` and `SceneViewportRenderService` stay concrete + rendering implementations behind `CreateEditorViewportRuntimeServices()`. +- `Application` injects `CreateEditorIconService()` and + `CreateEditorViewportRuntimeServices()` into `EditorShellRuntime`, making + the executable startup path the only place that names those concrete + rendering factories. +- `app/Rendering/**` now builds as `XCEditorCoreRendering`, a dedicated object + library consumed by `XCEditorCore`. This keeps rendering behavior in the + product core while preventing Composition/Features/Core from regaining an + `app/Rendering` include root. +- Scene viewport shader/resource paths are now injected from the viewport + runtime service into `SceneViewportRenderService` and `SceneViewportRenderPassBundle`. The concrete grid and selection-outline passes no longer depend on `XCUIEDITOR_REPO_ROOT` or `__FILE__` source-tree fallback logic to find editor shaders. @@ -615,6 +658,8 @@ The refactor is complete when: - `XCEditor` executable source is limited to host startup and concrete platform/render backend wiring. - `Composition` no longer includes concrete feature panel headers. +- `Composition` and `Features` no longer include concrete `app/Rendering/**` + headers; icon and viewport use flows through Core contracts. - `Windowing` no longer includes concrete composition runtime/state headers; it depends on `Core/Windowing` composition interfaces instead. - `Services` no longer include `Features/**`. diff --git a/editor/AGENTS.md b/editor/AGENTS.md index 51346a92..cc58927a 100644 --- a/editor/AGENTS.md +++ b/editor/AGENTS.md @@ -35,8 +35,12 @@ change. contracts under `app/Core` and `app/Host/Interfaces`. - `XCEditorCore` also does not consume the whole `editor/app` root privately. Its implementation include paths enumerate concrete app module roots such as - `app/Composition`, `app/Features`, `app/Windowing`, `app/Rendering`, - `app/Scene`, `app/Services`, and `app/Support`. + `app/Composition`, `app/Features`, `app/Windowing`, `app/Scene`, + `app/Services`, and `app/Support`. +- Concrete `app/Rendering/**` implementation builds as the + `XCEditorCoreRendering` object library. `XCEditorCore` consumes those object + files, but it does not publish or privately widen its include surface back to + `app/Rendering`. - `XCEditorCore` and `XCEditor` require `XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT=ON`; the root build defaults that support on when either the core library or app executable is enabled. @@ -71,8 +75,9 @@ change. state contracts, panel IDs, shared window type contracts, host window geometry/metrics, frame transfer requests, the panel-facing service view, the windowing-facing frame-services/shell-runtime contracts, - scene-viewport request contracts, workspace-panel runtime interface, and - utility-window runtime/descriptors. + scene-viewport request contracts, icon-service and viewport-runtime + contracts, workspace-panel runtime interface, and utility-window + runtime/descriptors. - `app/Host/Interfaces/` contains neutral host-facing contracts used across editor core and executable host code: editor window host interfaces, render-runtime factories, UI texture hosts, viewport render hosts, host @@ -86,7 +91,9 @@ change. - `app/Windowing/` owns window instances, content controllers, lifecycle, workspace synchronization, and utility-window creation. - `app/Rendering/` owns built-in icons, viewport render targets, object - picking, scene viewport passes, and viewport render services. + picking, scene viewport passes, and viewport render services. It is the + concrete implementation side of Core-owned editor icon and viewport runtime + contracts. - `app/Features/` contains user-facing panels and editor tools: Hierarchy, Scene viewport, Inspector, Project, Console, Color Picker, and component UI. - `app/Features/EditorWorkspacePanelRegistry.*` is the concrete workspace @@ -115,6 +122,11 @@ change. shared value contracts in `app/Core`. Do not add new public app contracts under concrete `app/Windowing`, `app/Rendering`, `app/Host/Win32`, `app/Host/D3D12`, or legacy `app/Platform` paths. +- `app/Composition/**` and `app/Features/**` may depend on + `app/Core/Assets/EditorIconService.h` and `app/Core/Viewport/**`, but they + must not include concrete `app/Rendering/**` headers such as + `Assets/BuiltInIcons.h`, `Viewport/ViewportHostService.h`, or + `Viewport/SceneViewportRenderService.h`. - `app/Windowing/**` may depend on `app/Core/Windowing` contracts such as `EditorFrameServices` and `EditorWorkspaceShellRuntime`, but it must not include concrete `app/Composition/EditorContext.h` or @@ -166,17 +178,20 @@ change. `UIEditorWorkspaceController` every frame. A live controller writes mutations through to the authoritative window workspace state; a copied controller is only a preview. -- `EditorShellRuntime` owns per-window interactive runtime state: viewport host - service, built-in icons, the workspace panel runtime set, shell interaction - state/frame, splitter correction state, trace entries, draw composer, - interaction engine, hosted panel coordinator, and session coordinator. +- `EditorShellRuntime` owns per-window interactive runtime state: injected + editor icon and viewport-runtime services, the workspace panel runtime set, + shell interaction state/frame, splitter correction state, trace entries, + draw composer, interaction engine, hosted panel coordinator, and session + coordinator. - `EditorWorkspaceShellRuntime` is the windowing-facing shell runtime contract. `EditorShellRuntime` is the current concrete implementation, and `Application` injects it through the content factory instead of letting `app/Windowing/**` construct or name the concrete type directly. - The workspace shell runtime factory passed into windowing is intentionally zero-argument. `Application` composes the concrete workspace-panel runtime - set with `EditorShellRuntime`; `app/Windowing/**` must not accept or call + set, `CreateEditorIconService()`, and + `CreateEditorViewportRuntimeServices()` with `EditorShellRuntime`; + `app/Windowing/**` must not accept or call `EditorWorkspacePanelRuntimeSetFactory`. - `EditorWindowRuntimeController` owns the content controller, render runtime, screenshot controller, title-bar logo texture, text measurer access, DPI @@ -288,18 +303,27 @@ inside pure shell/widget code. - Scene and Game are `ViewportShell` presentations. The Scene panel is the active editor viewport implementation; Game is registered as a viewport panel but is not equivalent to the runtime game view yet. -- `SceneViewportFeature` owns `SceneViewportController` and - `SceneViewportRenderService`. -- `ViewportHostService` is the per-window manager for viewport requests, - render-target allocation, retirement, fallback clearing, and dispatch to the - attached `ViewportRenderHost`. -- `SceneViewportRenderService` renders scene content through the engine - renderer and owns object-id picking state. Keep editor picking/render support - behind `XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT`. +- Core viewport contracts now live under `app/Core/Viewport/**`: shared + viewport frame/resource types, object-picking contracts, and the editor + scene/runtime service abstractions. +- `SceneViewportFeature` owns `SceneViewportController` and consumes the + injected `EditorSceneViewportRuntime` contract instead of constructing or + naming concrete rendering services. +- `ViewportHostService` is the concrete per-window implementation of + `EditorViewportRuntimeServices`. It manages viewport requests, render-target + allocation, retirement, fallback clearing, and dispatch to the attached + `ViewportRenderHost`. +- `SceneViewportRenderService` is the concrete `EditorSceneViewportRuntime` + implementation. It renders scene content through the engine renderer and + owns object-id picking state. Keep editor picking/render support behind + `XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT`. +- Core icon contracts now live under `app/Core/Assets/EditorIconService.h`. + `BuiltInIcons` is the concrete implementation, and scene/tool overlays must + resolve editor icons through that contract rather than probing + `editor/resources/Icons` directly. - Scene viewport shader/resource paths are runtime data. Build them from the - startup/runtime repo root in `SceneViewportFeature`, pass them into - `SceneViewportRenderService`, and keep render passes free of compile-time - source-tree path discovery. + startup/runtime repo root inside the rendering runtime service and keep + render passes free of compile-time source-tree path discovery. - D3D12 window rendering is behind the abstract `Rendering::Host::EditorWindowRenderRuntime`; native startup surface data is passed through the neutral @@ -317,6 +341,10 @@ inside pure shell/widget code. `EditorWorkspacePanel` adapter interface; do not include concrete feature panel headers from `EditorShellRuntime`, `EditorShellHostedPanelCoordinator`, `EditorShellDrawComposer`, or `EditorShellSessionCoordinator`. +- Add new icon/viewport cross-layer contracts under `app/Core/Assets` or + `app/Core/Viewport`. Keep concrete texture loading, render-target ownership, + viewport host wiring, and scene viewport rendering in `app/Rendering/**`, + then inject those implementations from `Application`. - 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. @@ -352,6 +380,10 @@ inside pure shell/widget code. `app/Host/Interfaces`, `include`, and engine headers; implementation files use explicit module roots instead of the app-wide compatibility root. +- Concrete rendering stays behind the `XCEditorCoreRendering` object library. + `XCEditorCore` consumes the object files, while Composition/Features/Core + continue to see only `app/Core` contracts and never gain an `app/Rendering` + include root. - App-facing unit tests follow the same rule. `editor_app_core_tests` uses explicit module include roots and must not regain the whole `editor/app` root to make stale tests compile. @@ -362,6 +394,11 @@ inside pure shell/widget code. - `XCEditor` is the thin executable host that wires `XCEditorCore` to concrete Win32 and D3D12 implementations. Do not move concrete platform/render host code into `XCEditorCore` without first introducing neutral host contracts. +- `Application` is also the composition root for concrete editor icon and + viewport runtime services. It wires `CreateEditorIconService()` and + `CreateEditorViewportRuntimeServices()` into + `CreateEditorWorkspaceShellRuntime(...)` so `app/Composition/**` and + `app/Features/**` do not take concrete `app/Rendering/**` dependencies. - `app/Core/Windowing/EditorFrameServices.h` and `app/Core/Windowing/EditorWorkspaceShellRuntime.h` are the current composition-to-windowing contract boundary. `EditorContext` and @@ -436,7 +473,11 @@ inside pure shell/widget code. - `editor/app/Host/Win32/Windowing/EditorWindowMessageDispatcher.cpp` - `editor/app/Host/Interfaces/EditorWindowRenderRuntime.h` - `editor/app/Host/Interfaces/EditorWindowHostInterfaces.h` +- `editor/app/Core/Assets/EditorIconService.h` +- `editor/app/Core/Viewport/EditorViewportRuntimeServices.h` - `editor/app/Core/Windowing/EditorWindowTransferRequests.h` +- `editor/app/Rendering/Assets/EditorIconServiceFactory.h` +- `editor/app/Rendering/Viewport/EditorViewportRuntimeServicesFactory.h` - `editor/app/Rendering/Viewport/ViewportHostService.h` - `tests/UI/Editor/unit/CMakeLists.txt` - `tests/UI/Editor/smoke/CMakeLists.txt` @@ -529,8 +570,18 @@ ownership rule. `app/Host/Win32/Resources`, so `XCEditorCore` no longer consumes `app/Bootstrap` or Win32 resource helpers to initialize built-in icons, title-bar branding, or screenshot output roots. -- Scene viewport shader paths are now injected at runtime from - `SceneViewportFeature` into `SceneViewportRenderService` and its pass bundle. +- Concrete editor icons and scene viewport runtime services are now hidden + behind `Core/Assets/EditorIconService.h` and `Core/Viewport/**` contracts. + `Application` injects `CreateEditorIconService()` and + `CreateEditorViewportRuntimeServices()` into `EditorShellRuntime`, so + `app/Composition/**` and `app/Features/**` no longer include concrete + `app/Rendering/**` headers. +- `XCEditorCoreRendering` now builds `app/Rendering/**` as a dedicated object + library. That keeps concrete rendering implementation in the core product + build without reopening `app/Rendering` as an include root for + Composition/Features/Core. +- Scene viewport shader paths are now injected at runtime by the viewport + runtime service into `SceneViewportRenderService` and its pass bundle. Grid/selection passes no longer infer source-tree shader paths through `XCUIEDITOR_REPO_ROOT` or `__FILE__`. - `Application` no longer resolves the editor repo root from a compile-time diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 029b9216..8c933dba 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -265,7 +265,9 @@ if(XCENGINE_BUILD_XCUI_EDITOR_CORE) ) set(XCUI_EDITOR_APP_RENDERING_SOURCES + app/Rendering/Assets/EditorIconServiceFactory.cpp app/Rendering/Assets/BuiltInIcons.cpp + app/Rendering/Viewport/EditorViewportRuntimeServicesFactory.cpp app/Rendering/Viewport/Passes/SceneViewportGridPass.cpp app/Rendering/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp app/Rendering/Viewport/Passes/SceneViewportSelectedHelpersPass.cpp @@ -289,13 +291,35 @@ if(XCENGINE_BUILD_XCUI_EDITOR_CORE) ${XCUI_EDITOR_APP_COMMAND_SOURCES} ${XCUI_EDITOR_APP_COMPOSITION_SOURCES} ${XCUI_EDITOR_APP_FEATURE_SOURCES} - ${XCUI_EDITOR_APP_RENDERING_SOURCES} ${XCUI_EDITOR_APP_SUPPORT_SOURCES} ) + add_library(XCEditorCoreRendering OBJECT + ${XCUI_EDITOR_APP_RENDERING_SOURCES} + ) + + target_include_directories(XCEditorCoreRendering + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/app/Core + ${CMAKE_CURRENT_SOURCE_DIR}/app/Host/Interfaces + ${CMAKE_CURRENT_SOURCE_DIR}/app/Rendering + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/engine/include + ${CMAKE_SOURCE_DIR}/engine/third_party/stb + ) + + xcui_editor_apply_common_target_settings(XCEditorCoreRendering PRIVATE) + + target_link_libraries(XCEditorCoreRendering PRIVATE + XCEngine + XCUIEditor + XCEngineRenderingEditorSupport + ) + set(XCUI_EDITOR_CORE_SOURCES ${XCUI_EDITOR_APP_WINDOWING_SOURCES} ${XCUI_EDITOR_APP_CORE_SOURCES} + $ ) add_library(XCEditorCore STATIC @@ -312,7 +336,6 @@ if(XCENGINE_BUILD_XCUI_EDITOR_CORE) PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/app/Composition ${CMAKE_CURRENT_SOURCE_DIR}/app/Features - ${CMAKE_CURRENT_SOURCE_DIR}/app/Rendering ${CMAKE_CURRENT_SOURCE_DIR}/app/Scene ${CMAKE_CURRENT_SOURCE_DIR}/app/Services ${CMAKE_CURRENT_SOURCE_DIR}/app/Support diff --git a/editor/app/Bootstrap/Application.cpp b/editor/app/Bootstrap/Application.cpp index a2395b52..455d121e 100644 --- a/editor/app/Bootstrap/Application.cpp +++ b/editor/app/Bootstrap/Application.cpp @@ -6,7 +6,9 @@ #include "EditorUtilityWindowRegistry.h" #include "EditorWorkspacePanelRegistry.h" #include "EditorWindowManager.h" +#include "Assets/EditorIconServiceFactory.h" #include "Diagnostics/Win32CrashTrace.h" +#include "Viewport/EditorViewportRuntimeServicesFactory.h" #include "System/Win32SystemInteractionHost.h" #include "Resources/Win32EditorResourceService.h" #include "Windowing/EditorWindow.h" @@ -153,7 +155,9 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) { std::make_unique(); App::EditorWorkspaceShellRuntimeFactory workspaceShellRuntimeFactory = []() { return App::CreateEditorWorkspaceShellRuntime( - App::CreateEditorWorkspacePanelRuntimeSet()); + App::CreateEditorWorkspacePanelRuntimeSet(), + App::CreateEditorIconService(), + App::CreateEditorViewportRuntimeServices()); }; m_windowManager = std::make_unique( *m_editorContext, diff --git a/editor/app/Bootstrap/EditorApp.rc b/editor/app/Bootstrap/EditorApp.rc index d733b253..a831421c 100644 --- a/editor/app/Bootstrap/EditorApp.rc +++ b/editor/app/Bootstrap/EditorApp.rc @@ -14,3 +14,13 @@ IDR_PNG_LOGO_ICON PNG "../resources/Icons/logo_icon.png" IDR_PNG_PLAY_BUTTON_ICON PNG "../resources/Icons/play_button.png" IDR_PNG_PAUSE_BUTTON_ICON PNG "../resources/Icons/pause_button.png" IDR_PNG_STEP_BUTTON_ICON PNG "../resources/Icons/step_button.png" +IDR_PNG_VIEW_MOVE_TOOL_ICON PNG "../resources/Icons/view_move_tool.png" +IDR_PNG_VIEW_MOVE_TOOL_ACTIVE_ICON PNG "../resources/Icons/view_move_tool_on.png" +IDR_PNG_MOVE_TOOL_ICON PNG "../resources/Icons/move_tool.png" +IDR_PNG_MOVE_TOOL_ACTIVE_ICON PNG "../resources/Icons/move_tool_on.png" +IDR_PNG_ROTATE_TOOL_ICON PNG "../resources/Icons/rotate_tool.png" +IDR_PNG_ROTATE_TOOL_ACTIVE_ICON PNG "../resources/Icons/rotate_tool_on.png" +IDR_PNG_SCALE_TOOL_ICON PNG "../resources/Icons/scale_tool.png" +IDR_PNG_SCALE_TOOL_ACTIVE_ICON PNG "../resources/Icons/scale_tool_on.png" +IDR_PNG_TRANSFORM_TOOL_ICON PNG "../resources/Icons/transform_tool.png" +IDR_PNG_TRANSFORM_TOOL_ACTIVE_ICON PNG "../resources/Icons/transform_tool_on.png" diff --git a/editor/app/Bootstrap/EditorResources.h b/editor/app/Bootstrap/EditorResources.h index 83adce4b..28af4870 100644 --- a/editor/app/Bootstrap/EditorResources.h +++ b/editor/app/Bootstrap/EditorResources.h @@ -14,3 +14,13 @@ #define IDR_PNG_PLAY_BUTTON_ICON 210 #define IDR_PNG_PAUSE_BUTTON_ICON 211 #define IDR_PNG_STEP_BUTTON_ICON 212 +#define IDR_PNG_VIEW_MOVE_TOOL_ICON 213 +#define IDR_PNG_VIEW_MOVE_TOOL_ACTIVE_ICON 214 +#define IDR_PNG_MOVE_TOOL_ICON 215 +#define IDR_PNG_MOVE_TOOL_ACTIVE_ICON 216 +#define IDR_PNG_ROTATE_TOOL_ICON 217 +#define IDR_PNG_ROTATE_TOOL_ACTIVE_ICON 218 +#define IDR_PNG_SCALE_TOOL_ICON 219 +#define IDR_PNG_SCALE_TOOL_ACTIVE_ICON 220 +#define IDR_PNG_TRANSFORM_TOOL_ICON 221 +#define IDR_PNG_TRANSFORM_TOOL_ACTIVE_ICON 222 diff --git a/editor/app/Composition/EditorShellAssetBuilder.cpp b/editor/app/Composition/EditorShellAssetBuilder.cpp index 72b53976..93e4ddab 100644 --- a/editor/app/Composition/EditorShellAssetBuilder.cpp +++ b/editor/app/Composition/EditorShellAssetBuilder.cpp @@ -6,7 +6,7 @@ #include #include "Panels/EditorPanelIds.h" #include -#include "Assets/BuiltInIcons.h" +#include "Assets/EditorIconService.h" namespace XCEngine::UI::Editor::App { diff --git a/editor/app/Composition/EditorShellDrawComposer.cpp b/editor/app/Composition/EditorShellDrawComposer.cpp index 517704e4..d797cd26 100644 --- a/editor/app/Composition/EditorShellDrawComposer.cpp +++ b/editor/app/Composition/EditorShellDrawComposer.cpp @@ -1,7 +1,7 @@ #include "EditorShellDrawComposer.h" #include "WorkspacePanels/EditorWorkspacePanelRuntime.h" -#include "Assets/BuiltInIcons.h" +#include "Assets/EditorIconService.h" #include #include @@ -18,16 +18,16 @@ using ::XCEngine::UI::UIDrawList; class BuiltInIconResolver final : public UIEditorShellIconResolver { public: - explicit BuiltInIconResolver(const BuiltInIcons& icons) - : m_icons(icons) {} + explicit BuiltInIconResolver(const EditorIconService& iconService) + : m_iconService(iconService) {} const ::XCEngine::UI::UITextureHandle* TryResolveIcon( std::uint8_t iconKind) const override { - return &m_icons.Resolve(static_cast(iconKind)); + return &m_iconService.Resolve(static_cast(iconKind)); } private: - const BuiltInIcons& m_icons; + const EditorIconService& m_iconService; }; UIEditorShellComposeModel BuildShellComposeModelFromFrame( @@ -90,7 +90,7 @@ void EditorShellDrawComposer::Append( const auto& palette = ResolveUIEditorShellInteractionPalette(); const UIEditorShellComposeModel shellComposeModel = BuildShellComposeModelFromFrame(context.shellFrame); - const BuiltInIconResolver iconResolver(context.builtInIcons); + const BuiltInIconResolver iconResolver(context.iconService); AppendDrawPacket( drawData, diff --git a/editor/app/Composition/EditorShellDrawComposer.h b/editor/app/Composition/EditorShellDrawComposer.h index 25313aeb..0999afef 100644 --- a/editor/app/Composition/EditorShellDrawComposer.h +++ b/editor/app/Composition/EditorShellDrawComposer.h @@ -11,13 +11,13 @@ struct UIEditorShellInteractionState; namespace XCEngine::UI::Editor::App { -class BuiltInIcons; +class EditorIconService; class EditorWorkspacePanelRuntimeSet; struct EditorShellDrawComposerContext { const UIEditorShellInteractionFrame& shellFrame; const UIEditorShellInteractionState& shellInteractionState; - const BuiltInIcons& builtInIcons; + const EditorIconService& iconService; const EditorWorkspacePanelRuntimeSet& workspacePanels; }; diff --git a/editor/app/Composition/EditorShellInteractionEngine.cpp b/editor/app/Composition/EditorShellInteractionEngine.cpp index e1c13fb4..46d2a65b 100644 --- a/editor/app/Composition/EditorShellInteractionEngine.cpp +++ b/editor/app/Composition/EditorShellInteractionEngine.cpp @@ -18,7 +18,7 @@ bool IsViewportPanel(std::string_view panelId) { } void ApplyViewportFrameToPresentation( - const ViewportFrame& viewportFrame, + const EditorViewportFrame& viewportFrame, UIEditorWorkspacePanelPresentationModel& presentation) { presentation.viewportShellModel.frame.texture = viewportFrame.texture; presentation.viewportShellModel.frame.requestedSize = viewportFrame.requestedSize; @@ -28,7 +28,7 @@ void ApplyViewportFrameToPresentation( } void ApplyViewportFrameToShellModel( - const ViewportFrame& viewportFrame, + const EditorViewportFrame& viewportFrame, UIEditorViewportShellModel& shellModel) { shellModel.frame.texture = viewportFrame.texture; shellModel.frame.requestedSize = viewportFrame.requestedSize; @@ -51,7 +51,7 @@ UIEditorWorkspacePanelPresentationModel* FindMutableWorkspacePresentation( void ApplyViewportFramesToShellFrame( UIEditorShellInteractionFrame& shellFrame, - ViewportHostService& viewportHostService) { + EditorViewportRuntimeServices& viewportRuntimeServices) { auto applyToViewportFrames = [&](std::vector& viewportFrames) { for (UIEditorWorkspaceViewportComposeFrame& viewportComposeFrame : viewportFrames) { @@ -59,8 +59,8 @@ void ApplyViewportFramesToShellFrame( continue; } - const ViewportFrame viewportFrame = - viewportHostService.RequestViewport( + const EditorViewportFrame viewportFrame = + viewportRuntimeServices.RequestViewport( viewportComposeFrame.panelId, viewportComposeFrame.viewportShellFrame.requestedViewportSize); ApplyViewportFrameToShellModel( @@ -128,7 +128,7 @@ void EditorShellInteractionEngine::Update( const Widgets::UIEditorDockHostLayout preUpdateDockLayout = context.shellFrame.workspaceInteractionFrame.dockHostFrame.layout; - context.viewportHostService.BeginFrame(); + context.viewportRuntimeServices.BeginFrame(); const std::vector shellEvents = context.hostedContentCaptureActive ? FilterShellInputEventsForHostedContentCapture(context.inputEvents) @@ -160,7 +160,7 @@ void EditorShellInteractionEngine::Update( metrics); } - ApplyViewportFramesToShellFrame(context.shellFrame, context.viewportHostService); + ApplyViewportFramesToShellFrame(context.shellFrame, context.viewportRuntimeServices); } } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Composition/EditorShellInteractionEngine.h b/editor/app/Composition/EditorShellInteractionEngine.h index 50cb0114..f627f7a9 100644 --- a/editor/app/Composition/EditorShellInteractionEngine.h +++ b/editor/app/Composition/EditorShellInteractionEngine.h @@ -1,6 +1,6 @@ #pragma once -#include "Viewport/ViewportHostService.h" +#include "Viewport/EditorViewportRuntimeServices.h" #include #include @@ -33,7 +33,7 @@ struct EditorShellInteractionEngineContext { bool useDetachedTitleBarTabStrip = false; float detachedTitleBarTabHeight = 0.0f; float detachedWindowChromeHeight = 0.0f; - ViewportHostService& viewportHostService; + EditorViewportRuntimeServices& viewportRuntimeServices; }; class EditorShellInteractionEngine final { diff --git a/editor/app/Composition/EditorShellRuntime.cpp b/editor/app/Composition/EditorShellRuntime.cpp index 0857c2e1..e6e9c597 100644 --- a/editor/app/Composition/EditorShellRuntime.cpp +++ b/editor/app/Composition/EditorShellRuntime.cpp @@ -4,40 +4,57 @@ #include #include +#include #include namespace XCEngine::UI::Editor::App { -EditorShellRuntime::EditorShellRuntime(EditorWorkspacePanelRuntimeSet workspacePanels) - : m_workspacePanels(std::move(workspacePanels)) {} +EditorShellRuntime::EditorShellRuntime( + EditorWorkspacePanelRuntimeSet workspacePanels, + std::unique_ptr iconService, + std::unique_ptr viewportRuntimeServices) + : m_iconService(std::move(iconService)) + , m_viewportRuntimeServices(std::move(viewportRuntimeServices)) + , m_workspacePanels(std::move(workspacePanels)) {} void EditorShellRuntime::Initialize( const std::filesystem::path& repoRoot, Rendering::Host::UiTextureHost& textureHost, Host::EditorHostResourceService& resourceService, UIEditorTextMeasurer& textMeasurer) { - m_textureHost = &textureHost; - m_builtInIcons.Initialize(textureHost, resourceService); + assert(m_iconService != nullptr); + assert(m_viewportRuntimeServices != nullptr); + if (m_iconService == nullptr || m_viewportRuntimeServices == nullptr) { + return; + } + + m_iconService->Initialize(textureHost, resourceService); + m_viewportRuntimeServices->Initialize(repoRoot); m_workspacePanels.Initialize( EditorWorkspacePanelInitializationContext{ .repoRoot = repoRoot, - .textureHost = textureHost, .textMeasurer = textMeasurer, - .builtInIcons = m_builtInIcons, - .viewportHostService = m_viewportHostService, + .iconService = *m_iconService, + .sceneViewportRuntime = &m_viewportRuntimeServices->GetSceneViewportRuntime(), }); } void EditorShellRuntime::AttachViewportWindowRenderer(Rendering::Host::ViewportRenderHost& renderer) { - m_viewportHostService.AttachWindowRenderer(renderer); + if (m_viewportRuntimeServices != nullptr) { + m_viewportRuntimeServices->AttachWindowRenderer(renderer); + } } void EditorShellRuntime::DetachViewportWindowRenderer() { - m_viewportHostService.DetachWindowRenderer(); + if (m_viewportRuntimeServices != nullptr) { + m_viewportRuntimeServices->DetachWindowRenderer(); + } } void EditorShellRuntime::SetViewportSurfacePresentationEnabled(bool enabled) { - m_viewportHostService.SetSurfacePresentationEnabled(enabled); + if (m_viewportRuntimeServices != nullptr) { + m_viewportRuntimeServices->SetSurfacePresentationEnabled(enabled); + } } void EditorShellRuntime::Shutdown() { @@ -45,20 +62,14 @@ void EditorShellRuntime::Shutdown() { m_shellInteractionState = {}; m_splitterDragCorrectionState = {}; m_traceEntries.clear(); - if (m_textureHost != nullptr) { - m_workspacePanels.Shutdown( - EditorWorkspacePanelShutdownContext{ - .textureHost = *m_textureHost, - .viewportHostService = m_viewportHostService, - }); - m_workspacePanels = {}; - m_builtInIcons.Shutdown(); - m_textureHost = nullptr; - } else { - m_workspacePanels = {}; - m_builtInIcons.Shutdown(); + m_workspacePanels.Shutdown(EditorWorkspacePanelShutdownContext{}); + m_workspacePanels = {}; + if (m_iconService != nullptr) { + m_iconService->Shutdown(); + } + if (m_viewportRuntimeServices != nullptr) { + m_viewportRuntimeServices->Shutdown(); } - m_viewportHostService.Shutdown(); } void EditorShellRuntime::ResetInteractionState() { @@ -82,7 +93,8 @@ const std::vector& EditorShellRuntime::GetTraceEntries() co } const std::string& EditorShellRuntime::GetBuiltInIconError() const { - return m_builtInIcons.GetLastError(); + static const std::string kEmptyError = {}; + return m_iconService != nullptr ? m_iconService->GetLastError() : kEmptyError; } void EditorShellRuntime::SetExternalDockHostDropPreview( @@ -144,8 +156,13 @@ bool EditorShellRuntime::HasInteractiveCapture() const { } std::unique_ptr CreateEditorWorkspaceShellRuntime( - EditorWorkspacePanelRuntimeSet workspacePanels) { - return std::make_unique(std::move(workspacePanels)); + EditorWorkspacePanelRuntimeSet workspacePanels, + std::unique_ptr iconService, + std::unique_ptr viewportRuntimeServices) { + return std::make_unique( + std::move(workspacePanels), + std::move(iconService), + std::move(viewportRuntimeServices)); } } // namespace XCEngine::UI::Editor::App @@ -154,15 +171,21 @@ namespace XCEngine::UI::Editor::App { void EditorShellRuntime::RenderRequestedViewports( const ::XCEngine::Rendering::RenderContext& renderContext) { - m_viewportHostService.RenderRequestedViewports(renderContext); + if (m_viewportRuntimeServices != nullptr) { + m_viewportRuntimeServices->RenderRequestedViewports(renderContext); + } } void EditorShellRuntime::Append(::XCEngine::UI::UIDrawData& drawData) const { + if (m_iconService == nullptr) { + return; + } + m_drawComposer.Append( EditorShellDrawComposerContext{ .shellFrame = m_shellFrame, .shellInteractionState = m_shellInteractionState, - .builtInIcons = m_builtInIcons, + .iconService = *m_iconService, .workspacePanels = m_workspacePanels, }, drawData); @@ -182,6 +205,10 @@ void EditorShellRuntime::Update( bool useDetachedTitleBarTabStrip, float detachedTitleBarTabHeight, float detachedWindowChromeHeight) { + if (m_viewportRuntimeServices == nullptr) { + return; + } + const auto buildDefinition = [&]() { return m_sessionCoordinator.PrepareShellDefinition( EditorShellSessionCoordinatorContext{ @@ -206,7 +233,7 @@ void EditorShellRuntime::Update( .useDetachedTitleBarTabStrip = useDetachedTitleBarTabStrip, .detachedTitleBarTabHeight = detachedTitleBarTabHeight, .detachedWindowChromeHeight = detachedWindowChromeHeight, - .viewportHostService = m_viewportHostService, + .viewportRuntimeServices = *m_viewportRuntimeServices, }); m_sessionCoordinator.FinalizeFrame(frameServices, workspaceController, m_shellFrame.result); diff --git a/editor/app/Composition/EditorShellRuntime.h b/editor/app/Composition/EditorShellRuntime.h index 3a177fb3..48d8c67a 100644 --- a/editor/app/Composition/EditorShellRuntime.h +++ b/editor/app/Composition/EditorShellRuntime.h @@ -4,10 +4,10 @@ #include "EditorShellHostedPanelCoordinator.h" #include "EditorShellInteractionEngine.h" #include "EditorShellSessionCoordinator.h" +#include "Assets/EditorIconService.h" +#include "Viewport/EditorViewportRuntimeServices.h" #include "Windowing/EditorWorkspaceShellRuntime.h" #include "WorkspacePanels/EditorWorkspacePanelRuntime.h" -#include "Assets/BuiltInIcons.h" -#include "Viewport/ViewportHostService.h" #include #include @@ -45,8 +45,10 @@ namespace XCEngine::UI::Editor::App { class EditorShellRuntime final : public EditorWorkspaceShellRuntime { public: - EditorShellRuntime() = default; - explicit EditorShellRuntime(EditorWorkspacePanelRuntimeSet workspacePanels); + EditorShellRuntime( + EditorWorkspacePanelRuntimeSet workspacePanels, + std::unique_ptr iconService, + std::unique_ptr viewportRuntimeServices); void Initialize( const std::filesystem::path& repoRoot, @@ -95,9 +97,8 @@ public: bool HasInteractiveCapture() const override; private: - ViewportHostService m_viewportHostService = {}; - BuiltInIcons m_builtInIcons = {}; - Rendering::Host::UiTextureHost* m_textureHost = nullptr; + std::unique_ptr m_iconService = {}; + std::unique_ptr m_viewportRuntimeServices = {}; EditorWorkspacePanelRuntimeSet m_workspacePanels = {}; UIEditorShellInteractionState m_shellInteractionState = {}; UIEditorShellInteractionFrame m_shellFrame = {}; @@ -110,7 +111,9 @@ private: }; std::unique_ptr CreateEditorWorkspaceShellRuntime( - EditorWorkspacePanelRuntimeSet workspacePanels); + EditorWorkspacePanelRuntimeSet workspacePanels, + std::unique_ptr iconService, + std::unique_ptr viewportRuntimeServices); } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Core/Assets/EditorIconService.h b/editor/app/Core/Assets/EditorIconService.h new file mode 100644 index 00000000..fbc807d7 --- /dev/null +++ b/editor/app/Core/Assets/EditorIconService.h @@ -0,0 +1,60 @@ +#pragma once + +#include "HostFwd.h" + +#include + +#include +#include +#include + +namespace XCEngine::UI::Editor::Rendering::Host { + +class UiTextureHost; + +} // namespace XCEngine::UI::Editor::Rendering::Host + +namespace XCEngine::UI::Editor::App { + +enum class BuiltInIconKind : std::uint8_t { + Folder = 0, + GameObject, + Scene, + CameraGizmo, + DirectionalLightGizmo, + PointLightGizmo, + SpotLightGizmo, + PlayButton, + PauseButton, + StepButton, + ViewMoveTool, + ViewMoveToolActive, + MoveTool, + MoveToolActive, + RotateTool, + RotateToolActive, + ScaleTool, + ScaleToolActive, + TransformTool, + TransformToolActive +}; + +class EditorIconService { +public: + virtual ~EditorIconService() = default; + + virtual void Initialize( + Rendering::Host::UiTextureHost& renderer, + Host::EditorHostResourceService& resourceService) = 0; + virtual void Shutdown() = 0; + virtual void BeginFrame() = 0; + + [[nodiscard]] virtual const ::XCEngine::UI::UITextureHandle& Resolve( + BuiltInIconKind kind) const = 0; + [[nodiscard]] virtual const ::XCEngine::UI::UITextureHandle* ResolveAssetPreview( + const std::filesystem::path& assetPath, + const std::filesystem::path& projectRoot) = 0; + [[nodiscard]] virtual const std::string& GetLastError() const = 0; +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Core/Viewport/EditorViewportPicking.h b/editor/app/Core/Viewport/EditorViewportPicking.h new file mode 100644 index 00000000..573bd854 --- /dev/null +++ b/editor/app/Core/Viewport/EditorViewportPicking.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +#include + +namespace XCEngine::UI::Editor::App { + +enum class ViewportObjectIdPickStatus : std::uint8_t { + Unavailable = 0, + Success, + ReadbackFailed +}; + +struct ViewportObjectIdPickResult { + ViewportObjectIdPickStatus status = ViewportObjectIdPickStatus::Unavailable; + std::uint64_t frameSerial = 0u; + ::XCEngine::Rendering::RenderObjectId renderObjectId = + ::XCEngine::Rendering::kInvalidRenderObjectId; + std::uint64_t resolvedEntityId = 0u; + + bool HasResolvedSample() const { + return status == ViewportObjectIdPickStatus::Success; + } + + bool HasResolvedEntity() const { + return HasResolvedSample() && resolvedEntityId != 0u; + } +}; + +class IViewportObjectPickerService { +public: + virtual ~IViewportObjectPickerService() = default; + + virtual ViewportObjectIdPickResult PickObject( + const ::XCEngine::UI::UISize& viewportSize, + const ::XCEngine::UI::UIPoint& viewportMousePosition) const = 0; +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Core/Viewport/EditorViewportRuntimeServices.h b/editor/app/Core/Viewport/EditorViewportRuntimeServices.h new file mode 100644 index 00000000..b1f1e579 --- /dev/null +++ b/editor/app/Core/Viewport/EditorViewportRuntimeServices.h @@ -0,0 +1,50 @@ +#pragma once + +#include "Scene/SceneViewportRenderRequest.h" +#include "Viewport/EditorViewportPicking.h" +#include "Viewport/EditorViewportTypes.h" + +#include +#include + +namespace XCEngine::Rendering { + +class RenderContext; + +} // namespace XCEngine::Rendering + +namespace XCEngine::UI::Editor::Rendering::Host { + +class ViewportRenderHost; + +} // namespace XCEngine::UI::Editor::Rendering::Host + +namespace XCEngine::UI::Editor::App { + +class EditorSceneViewportRuntime { +public: + virtual ~EditorSceneViewportRuntime() = default; + + virtual void SetRenderRequest(SceneViewportRenderRequest request) = 0; + [[nodiscard]] virtual const IViewportObjectPickerService& GetObjectPicker() const = 0; +}; + +class EditorViewportRuntimeServices { +public: + virtual ~EditorViewportRuntimeServices() = default; + + virtual void Initialize(const std::filesystem::path& repoRoot) = 0; + virtual void Shutdown() = 0; + virtual void AttachWindowRenderer(Rendering::Host::ViewportRenderHost& windowRenderer) = 0; + virtual void DetachWindowRenderer() = 0; + virtual void SetSurfacePresentationEnabled(bool enabled) = 0; + virtual void BeginFrame() = 0; + [[nodiscard]] virtual EditorViewportFrame RequestViewport( + std::string_view viewportId, + const ::XCEngine::UI::UISize& requestedSize) = 0; + virtual void RenderRequestedViewports( + const ::XCEngine::Rendering::RenderContext& renderContext) = 0; + [[nodiscard]] virtual EditorSceneViewportRuntime& GetSceneViewportRuntime() = 0; +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Core/Viewport/EditorViewportTypes.h b/editor/app/Core/Viewport/EditorViewportTypes.h new file mode 100644 index 00000000..89672776 --- /dev/null +++ b/editor/app/Core/Viewport/EditorViewportTypes.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include + +namespace XCEngine::UI::Editor::App { + +struct EditorViewportResourceRequirements { + bool requiresDepthSampling = false; + bool requiresObjectIdSurface = false; + bool requiresSelectionMaskSurface = false; +}; + +struct EditorViewportFrame { + ::XCEngine::UI::UITextureHandle texture = {}; + ::XCEngine::UI::UISize requestedSize = {}; + ::XCEngine::UI::UISize renderSize = {}; + bool hasTexture = false; + bool wasRequested = false; + std::string statusText = {}; +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Core/WorkspacePanels/EditorWorkspacePanelRuntime.h b/editor/app/Core/WorkspacePanels/EditorWorkspacePanelRuntime.h index 144da34a..0c8c4acc 100644 --- a/editor/app/Core/WorkspacePanels/EditorWorkspacePanelRuntime.h +++ b/editor/app/Core/WorkspacePanels/EditorWorkspacePanelRuntime.h @@ -1,8 +1,10 @@ #pragma once +#include "Assets/EditorIconService.h" #include "Commands/EditorEditCommandRoute.h" #include "State/EditorSession.h" #include "Panels/EditorPanelServices.h" +#include "Viewport/EditorViewportRuntimeServices.h" #include #include @@ -25,17 +27,8 @@ struct UIInputEvent; } // namespace XCEngine::UI -namespace XCEngine::UI::Editor::Rendering::Host { - -class UiTextureHost; - -} // namespace XCEngine::UI::Editor::Rendering::Host - namespace XCEngine::UI::Editor::App { -class BuiltInIcons; -class ViewportHostService; - enum class EditorWorkspacePanelCursorKind : std::uint8_t { Arrow = 0, ResizeEW @@ -54,16 +47,12 @@ struct EditorWorkspacePanelFrameEvent { struct EditorWorkspacePanelInitializationContext { const std::filesystem::path& repoRoot; - Rendering::Host::UiTextureHost& textureHost; UIEditorTextMeasurer& textMeasurer; - BuiltInIcons& builtInIcons; - ViewportHostService& viewportHostService; + EditorIconService& iconService; + EditorSceneViewportRuntime* sceneViewportRuntime = nullptr; }; -struct EditorWorkspacePanelShutdownContext { - Rendering::Host::UiTextureHost& textureHost; - ViewportHostService& viewportHostService; -}; +struct EditorWorkspacePanelShutdownContext {}; struct EditorWorkspacePanelUpdateContext { EditorPanelServices& services; diff --git a/editor/app/Features/EditorWorkspacePanelRegistry.cpp b/editor/app/Features/EditorWorkspacePanelRegistry.cpp index af95e2dc..3137cdcb 100644 --- a/editor/app/Features/EditorWorkspacePanelRegistry.cpp +++ b/editor/app/Features/EditorWorkspacePanelRegistry.cpp @@ -7,8 +7,6 @@ #include "Project/ProjectPanel.h" #include "Scene/SceneEditCommandRoute.h" #include "Scene/SceneViewportFeature.h" -#include "Assets/BuiltInIcons.h" -#include "Viewport/ViewportHostService.h" #include @@ -219,7 +217,7 @@ public: } void Initialize(const EditorWorkspacePanelInitializationContext& context) override { - m_panel.SetBuiltInIcons(&context.builtInIcons); + m_panel.SetIconService(&context.iconService); m_panel.SetTextMeasurer(&context.textMeasurer); m_panel.Initialize(); } @@ -330,7 +328,7 @@ public: } void Initialize(const EditorWorkspacePanelInitializationContext& context) override { - m_panel.SetBuiltInIcons(&context.builtInIcons); + m_panel.SetIconService(&context.iconService); m_panel.SetTextMeasurer(&context.textMeasurer); } @@ -406,15 +404,16 @@ public: } void Initialize(const EditorWorkspacePanelInitializationContext& context) override { - m_feature.Initialize( - context.repoRoot, - context.textureHost, - &context.builtInIcons, - context.viewportHostService); + if (context.sceneViewportRuntime != nullptr) { + m_feature.Initialize( + &context.iconService, + *context.sceneViewportRuntime); + } } void Shutdown(const EditorWorkspacePanelShutdownContext& context) override { - m_feature.Shutdown(context.textureHost, context.viewportHostService); + (void)context; + m_feature.Shutdown(); m_commandRoute.BindSceneRuntime(nullptr); } diff --git a/editor/app/Features/Hierarchy/HierarchyPanel.cpp b/editor/app/Features/Hierarchy/HierarchyPanel.cpp index eb2cd4d7..92d4843b 100644 --- a/editor/app/Features/Hierarchy/HierarchyPanel.cpp +++ b/editor/app/Features/Hierarchy/HierarchyPanel.cpp @@ -1,5 +1,5 @@ #include "HierarchyPanel.h" -#include "Assets/BuiltInIcons.h" +#include "Assets/EditorIconService.h" #include #include #include "EditorSceneRuntime.h" @@ -15,13 +15,13 @@ using ::XCEngine::UI::UIColor; inline constexpr float kDragThreshold = 4.0f; inline constexpr UIColor kDragPreviewColor(0.92f, 0.92f, 0.92f, 0.42f); -::XCEngine::UI::UITextureHandle ResolveGameObjectIcon(const BuiltInIcons* icons); +::XCEngine::UI::UITextureHandle ResolveGameObjectIcon(const EditorIconService* icons); } // namespace XCEngine::UI::Editor::App namespace XCEngine::UI::Editor::App { -::XCEngine::UI::UITextureHandle ResolveGameObjectIcon(const BuiltInIcons* icons) { +::XCEngine::UI::UITextureHandle ResolveGameObjectIcon(const EditorIconService* icons) { return icons != nullptr ? icons->Resolve(BuiltInIconKind::GameObject) : ::XCEngine::UI::UITextureHandle {}; @@ -80,7 +80,7 @@ void HierarchyPanel::SetCommandFocusService( m_commandFocusService = commandFocusService; } -void HierarchyPanel::SetBuiltInIcons(const BuiltInIcons* icons) { +void HierarchyPanel::SetIconService(const EditorIconService* icons) { m_icons = icons; RebuildItems(); } diff --git a/editor/app/Features/Hierarchy/HierarchyPanel.h b/editor/app/Features/Hierarchy/HierarchyPanel.h index d58d9ccb..11ccb12b 100644 --- a/editor/app/Features/Hierarchy/HierarchyPanel.h +++ b/editor/app/Features/Hierarchy/HierarchyPanel.h @@ -20,8 +20,8 @@ namespace XCEngine::UI::Editor::App { -class BuiltInIcons; class EditorCommandFocusService; +class EditorIconService; class EditorSceneRuntime; class HierarchyPanel final : public EditorEditCommandRoute { @@ -44,7 +44,7 @@ public: void Initialize(); void SetSceneRuntime(EditorSceneRuntime* sceneRuntime); void SetCommandFocusService(EditorCommandFocusService* commandFocusService); - void SetBuiltInIcons(const BuiltInIcons* icons); + void SetIconService(const EditorIconService* icons); void SetTextMeasurer(const ::XCEngine::UI::Editor::UIEditorTextMeasurer* textMeasurer); void ResetInteractionState(); void Update( @@ -90,7 +90,7 @@ private: const std::vector& GetPresentedTreeItems() const; const ::XCEngine::UI::Widgets::UIExpansionModel& GetPresentedExpansionModel() const; - const BuiltInIcons* m_icons = nullptr; + const EditorIconService* m_icons = nullptr; EditorCommandFocusService* m_commandFocusService = nullptr; EditorSceneRuntime* m_sceneRuntime = nullptr; HierarchyModel m_model = {}; diff --git a/editor/app/Features/Project/ProjectPanel.cpp b/editor/app/Features/Project/ProjectPanel.cpp index aecd1867..0c621b1d 100644 --- a/editor/app/Features/Project/ProjectPanel.cpp +++ b/editor/app/Features/Project/ProjectPanel.cpp @@ -1,5 +1,5 @@ #include "ProjectPanel.h" -#include "Assets/BuiltInIcons.h" +#include "Assets/EditorIconService.h" #include #include #include @@ -71,7 +71,7 @@ float MeasureTextWidth( const UIEditorTextMeasurer* textMeasurer, std::string_view text, float fontSize); -::XCEngine::UI::UITextureHandle ResolveFolderIcon(const BuiltInIcons* icons); +::XCEngine::UI::UITextureHandle ResolveFolderIcon(const EditorIconService* icons); float ClampNavigationWidth(float value, float totalWidth); UIRect ComputeFittedTextureRect( const UIRect& bounds, @@ -129,7 +129,7 @@ float MeasureTextWidth( return static_cast(text.size()) * fontSize * 0.56f; } -::XCEngine::UI::UITextureHandle ResolveFolderIcon(const BuiltInIcons* icons) { +::XCEngine::UI::UITextureHandle ResolveFolderIcon(const EditorIconService* icons) { return icons != nullptr ? icons->Resolve(BuiltInIconKind::Folder) : ::XCEngine::UI::UITextureHandle {}; @@ -425,7 +425,7 @@ void ProjectPanel::SetSystemInteractionHost( m_systemInteractionHost = systemInteractionHost; } -void ProjectPanel::SetBuiltInIcons(BuiltInIcons* icons) { +void ProjectPanel::SetIconService(EditorIconService* icons) { m_icons = icons; RebuildWindowTreeItems(); } diff --git a/editor/app/Features/Project/ProjectPanel.h b/editor/app/Features/Project/ProjectPanel.h index 6cdc6693..3014b6a5 100644 --- a/editor/app/Features/Project/ProjectPanel.h +++ b/editor/app/Features/Project/ProjectPanel.h @@ -29,8 +29,8 @@ namespace XCEngine::UI::Editor::App { -class BuiltInIcons; class EditorCommandFocusService; +class EditorIconService; } // namespace XCEngine::UI::Editor::App @@ -86,7 +86,7 @@ public: void SetProjectRuntime(EditorProjectRuntime* projectRuntime); void SetCommandFocusService(EditorCommandFocusService* commandFocusService); void SetSystemInteractionHost(System::SystemInteractionService* systemInteractionHost); - void SetBuiltInIcons(BuiltInIcons* icons); + void SetIconService(EditorIconService* icons); void SetTextMeasurer(const ::XCEngine::UI::Editor::UIEditorTextMeasurer* textMeasurer); void ResetInteractionState(); void Update( @@ -254,7 +254,7 @@ private: EditorProjectRuntime* m_projectRuntime = nullptr; EditorCommandFocusService* m_commandFocusService = nullptr; System::SystemInteractionService* m_systemInteractionHost = nullptr; - BuiltInIcons* m_icons = nullptr; + EditorIconService* m_icons = nullptr; const ::XCEngine::UI::Editor::UIEditorTextMeasurer* m_textMeasurer = nullptr; std::vector m_windowTreeItems = {}; ::XCEngine::UI::Widgets::UISelectionModel m_folderSelection = {}; diff --git a/editor/app/Features/Scene/SceneViewportController.cpp b/editor/app/Features/Scene/SceneViewportController.cpp index 17aaff7e..8012c1fc 100644 --- a/editor/app/Features/Scene/SceneViewportController.cpp +++ b/editor/app/Features/Scene/SceneViewportController.cpp @@ -1,6 +1,6 @@ #include "Scene/SceneViewportController.h" -#include "Viewport/ViewportObjectPickerService.h" +#include "Viewport/EditorViewportPicking.h" #include "EditorSceneRuntime.h" #include "State/EditorCommandFocusService.h" @@ -136,17 +136,15 @@ void ApplySceneViewportToggleButton( } // namespace -void SceneViewportController::Initialize( - const std::filesystem::path& repoRoot, - Rendering::Host::UiTextureHost& renderer, - const BuiltInIcons* builtInIcons) { - m_toolOverlay.Initialize(repoRoot, renderer); - m_sceneOverlay.SetBuiltInIcons(builtInIcons); +void SceneViewportController::Initialize(const EditorIconService* iconService) { + m_toolOverlay.SetIconService(iconService); + m_sceneOverlay.SetIconService(iconService); ResetInteractionState(); } -void SceneViewportController::Shutdown(Rendering::Host::UiTextureHost& renderer) { - m_toolOverlay.Shutdown(renderer); +void SceneViewportController::Shutdown() { + m_toolOverlay.SetIconService(nullptr); + m_sceneOverlay.SetIconService(nullptr); ResetInteractionState(); } diff --git a/editor/app/Features/Scene/SceneViewportController.h b/editor/app/Features/Scene/SceneViewportController.h index ff676212..bcf5ea1e 100644 --- a/editor/app/Features/Scene/SceneViewportController.h +++ b/editor/app/Features/Scene/SceneViewportController.h @@ -10,32 +10,18 @@ #include #include -#include namespace XCEngine::UI::Editor::App { class EditorCommandFocusService; -class BuiltInIcons; +class EditorIconService; class EditorSceneRuntime; class IViewportObjectPickerService; -} // namespace XCEngine::UI::Editor::App - -namespace XCEngine::UI::Editor::Rendering::Host { - -class UiTextureHost; - -} // namespace XCEngine::UI::Editor::Rendering::Host - -namespace XCEngine::UI::Editor::App { - class SceneViewportController { public: - void Initialize( - const std::filesystem::path& repoRoot, - Rendering::Host::UiTextureHost& renderer, - const BuiltInIcons* builtInIcons); - void Shutdown(Rendering::Host::UiTextureHost& renderer); + void Initialize(const EditorIconService* iconService); + void Shutdown(); void ResetInteractionState(); void SetCommandFocusService(EditorCommandFocusService* commandFocusService); diff --git a/editor/app/Features/Scene/SceneViewportFeature.cpp b/editor/app/Features/Scene/SceneViewportFeature.cpp index bd48cf03..152e4edb 100644 --- a/editor/app/Features/Scene/SceneViewportFeature.cpp +++ b/editor/app/Features/Scene/SceneViewportFeature.cpp @@ -1,33 +1,20 @@ #include "Scene/SceneViewportFeature.h" -#include "Panels/EditorPanelIds.h" -#include "UiTextureHost.h" -#include "Viewport/SceneViewportResourcePaths.h" -#include "Viewport/ViewportHostService.h" #include "EditorSceneRuntime.h" #include "State/EditorCommandFocusService.h" namespace XCEngine::UI::Editor::App { void SceneViewportFeature::Initialize( - const std::filesystem::path& repoRoot, - Rendering::Host::UiTextureHost& textureHost, - const BuiltInIcons* builtInIcons, - ViewportHostService& viewportHostService) { - m_renderService.Initialize(BuildSceneViewportShaderPaths(repoRoot)); - viewportHostService.SetContentRenderer( - kScenePanelId, - &m_renderService, - SceneViewportRenderService::GetViewportResourceRequirements()); - m_controller.Initialize(repoRoot, textureHost, builtInIcons); + const EditorIconService* iconService, + EditorSceneViewportRuntime& sceneViewportRuntime) { + m_sceneViewportRuntime = &sceneViewportRuntime; + m_controller.Initialize(iconService); } -void SceneViewportFeature::Shutdown( - Rendering::Host::UiTextureHost& textureHost, - ViewportHostService& viewportHostService) { - viewportHostService.SetContentRenderer(kScenePanelId, nullptr, {}); - m_controller.Shutdown(textureHost); - m_renderService.Shutdown(); +void SceneViewportFeature::Shutdown() { + m_controller.Shutdown(); + m_sceneViewportRuntime = nullptr; } void SceneViewportFeature::ResetInteractionState() { @@ -40,17 +27,23 @@ void SceneViewportFeature::SetCommandFocusService( } void SceneViewportFeature::SyncRenderRequest(EditorSceneRuntime& sceneRuntime) { - m_renderService.SetRenderRequest( - sceneRuntime.BuildSceneViewportRenderRequest()); + if (m_sceneViewportRuntime != nullptr) { + m_sceneViewportRuntime->SetRenderRequest( + sceneRuntime.BuildSceneViewportRenderRequest()); + } } void SceneViewportFeature::Update( EditorSceneRuntime& sceneRuntime, const UIEditorWorkspaceComposeState& composeState, const UIEditorWorkspaceComposeFrame& composeFrame) { + if (m_sceneViewportRuntime == nullptr) { + return; + } + m_controller.Update( sceneRuntime, - m_renderService, + m_sceneViewportRuntime->GetObjectPicker(), composeState, composeFrame); SyncRenderRequest(sceneRuntime); diff --git a/editor/app/Features/Scene/SceneViewportFeature.h b/editor/app/Features/Scene/SceneViewportFeature.h index 3e9b1baa..42e47789 100644 --- a/editor/app/Features/Scene/SceneViewportFeature.h +++ b/editor/app/Features/Scene/SceneViewportFeature.h @@ -1,42 +1,24 @@ #pragma once +#include "Assets/EditorIconService.h" #include "Scene/SceneViewportController.h" -#include "Viewport/SceneViewportRenderService.h" +#include "Viewport/EditorViewportRuntimeServices.h" #include #include -#include - namespace XCEngine::UI::Editor::App { class EditorCommandFocusService; -class BuiltInIcons; class EditorSceneRuntime; -} // namespace XCEngine::UI::Editor::App - -namespace XCEngine::UI::Editor::Rendering::Host { - -class UiTextureHost; - -} // namespace XCEngine::UI::Editor::Rendering::Host - -namespace XCEngine::UI::Editor::App { - -class ViewportHostService; - class SceneViewportFeature { public: void Initialize( - const std::filesystem::path& repoRoot, - Rendering::Host::UiTextureHost& textureHost, - const BuiltInIcons* builtInIcons, - ViewportHostService& viewportHostService); - void Shutdown( - Rendering::Host::UiTextureHost& textureHost, - ViewportHostService& viewportHostService); + const EditorIconService* iconService, + EditorSceneViewportRuntime& sceneViewportRuntime); + void Shutdown(); void ResetInteractionState(); void SetCommandFocusService(EditorCommandFocusService* commandFocusService); void SyncRenderRequest(EditorSceneRuntime& sceneRuntime); @@ -47,7 +29,7 @@ public: void Append(::XCEngine::UI::UIDrawList& drawList) const; private: - SceneViewportRenderService m_renderService = {}; + EditorSceneViewportRuntime* m_sceneViewportRuntime = nullptr; SceneViewportController m_controller = {}; }; diff --git a/editor/app/Features/Scene/SceneViewportSceneOverlay.cpp b/editor/app/Features/Scene/SceneViewportSceneOverlay.cpp index dbc74743..59fb8d3d 100644 --- a/editor/app/Features/Scene/SceneViewportSceneOverlay.cpp +++ b/editor/app/Features/Scene/SceneViewportSceneOverlay.cpp @@ -1,7 +1,7 @@ #include "Scene/SceneViewportSceneOverlay.h" #include "Scene/SceneViewportTransformGizmoSupport.h" -#include "Assets/BuiltInIcons.h" +#include "Assets/EditorIconService.h" #include "EditorSceneRuntime.h" #include @@ -68,14 +68,14 @@ SceneViewportGizmoSupport::SceneViewportOverlayData BuildOverlayData( return overlay; } -::XCEngine::UI::UITextureHandle ResolveCameraIcon(const BuiltInIcons* icons) { +::XCEngine::UI::UITextureHandle ResolveCameraIcon(const EditorIconService* icons) { return icons != nullptr ? icons->Resolve(BuiltInIconKind::CameraGizmo) : ::XCEngine::UI::UITextureHandle(); } ::XCEngine::UI::UITextureHandle ResolveLightIcon( - const BuiltInIcons* icons, + const EditorIconService* icons, const LightComponent& light) { if (icons == nullptr) { return {}; @@ -95,7 +95,7 @@ SceneViewportGizmoSupport::SceneViewportOverlayData BuildOverlayData( } // namespace -void SceneViewportSceneOverlay::SetBuiltInIcons(const BuiltInIcons* icons) { +void SceneViewportSceneOverlay::SetIconService(const EditorIconService* icons) { m_icons = icons; if (m_icons == nullptr) { ResetFrame(); diff --git a/editor/app/Features/Scene/SceneViewportSceneOverlay.h b/editor/app/Features/Scene/SceneViewportSceneOverlay.h index 1e6a2a41..f7e8a4be 100644 --- a/editor/app/Features/Scene/SceneViewportSceneOverlay.h +++ b/editor/app/Features/Scene/SceneViewportSceneOverlay.h @@ -7,8 +7,8 @@ namespace XCEngine::UI::Editor::App { -class BuiltInIcons; class EditorSceneRuntime; +class EditorIconService; class SceneViewportSceneOverlay { public: @@ -21,7 +21,7 @@ public: } }; - void SetBuiltInIcons(const BuiltInIcons* icons); + void SetIconService(const EditorIconService* icons); void ResetFrame(); void Refresh( EditorSceneRuntime& sceneRuntime, @@ -42,7 +42,7 @@ public: }; private: - const BuiltInIcons* m_icons = nullptr; + const EditorIconService* m_icons = nullptr; Frame m_frame = {}; }; diff --git a/editor/app/Features/Scene/SceneViewportToolOverlay.cpp b/editor/app/Features/Scene/SceneViewportToolOverlay.cpp index 2a173e0f..dcab9632 100644 --- a/editor/app/Features/Scene/SceneViewportToolOverlay.cpp +++ b/editor/app/Features/Scene/SceneViewportToolOverlay.cpp @@ -1,7 +1,5 @@ #include "Scene/SceneViewportToolOverlay.h" -#include "UiTextureHost.h" - #include #include @@ -39,16 +37,16 @@ constexpr float kToggleMinWidth = 60.0f; struct ToolButtonSpec { SceneToolMode mode = SceneToolMode::View; const char* label = ""; - const char* inactiveFile = ""; - const char* activeFile = ""; + BuiltInIconKind inactiveIcon = BuiltInIconKind::ViewMoveTool; + BuiltInIconKind activeIcon = BuiltInIconKind::ViewMoveToolActive; }; constexpr std::array kToolButtonSpecs = {{ - { SceneToolMode::View, "View", "view_move_tool.png", "view_move_tool_on.png" }, - { SceneToolMode::Translate, "Move", "move_tool.png", "move_tool_on.png" }, - { SceneToolMode::Rotate, "Rotate", "rotate_tool.png", "rotate_tool_on.png" }, - { SceneToolMode::Scale, "Scale", "scale_tool.png", "scale_tool_on.png" }, - { SceneToolMode::Transform, "Transform", "transform_tool.png", "transform_tool_on.png" } + { SceneToolMode::View, "View", BuiltInIconKind::ViewMoveTool, BuiltInIconKind::ViewMoveToolActive }, + { SceneToolMode::Translate, "Move", BuiltInIconKind::MoveTool, BuiltInIconKind::MoveToolActive }, + { SceneToolMode::Rotate, "Rotate", BuiltInIconKind::RotateTool, BuiltInIconKind::RotateToolActive }, + { SceneToolMode::Scale, "Scale", BuiltInIconKind::ScaleTool, BuiltInIconKind::ScaleToolActive }, + { SceneToolMode::Transform, "Transform", BuiltInIconKind::TransformTool, BuiltInIconKind::TransformToolActive } }}; bool ContainsPoint(const UIRect& rect, const UIPoint& point) { @@ -198,47 +196,10 @@ UIRect BuildToggleButtonRect( return kToggleIdle; } -} // namespace - -bool SceneViewportToolOverlay::Initialize( - const std::filesystem::path& repoRoot, - Rendering::Host::UiTextureHost& renderer) { - Shutdown(renderer); - - const std::filesystem::path iconRoot = - (repoRoot / "editor" / "resources" / "Icons").lexically_normal(); - bool loadedAnyTexture = false; - for (std::size_t index = 0; index < kToolButtonSpecs.size(); ++index) { - const ToolButtonSpec& path = kToolButtonSpecs[index]; - ToolTextureSet& textureSet = m_toolTextures[index]; - textureSet = {}; - textureSet.mode = path.mode; - textureSet.label = path.label; - - std::string error = {}; - loadedAnyTexture = - renderer.LoadTextureFromFile( - iconRoot / path.inactiveFile, - textureSet.inactiveTexture, - error) || loadedAnyTexture; - error.clear(); - loadedAnyTexture = - renderer.LoadTextureFromFile( - iconRoot / path.activeFile, - textureSet.activeTexture, - error) || loadedAnyTexture; - } - - return loadedAnyTexture; } -void SceneViewportToolOverlay::Shutdown(Rendering::Host::UiTextureHost& renderer) { - for (ToolTextureSet& textureSet : m_toolTextures) { - renderer.ReleaseTexture(textureSet.inactiveTexture); - renderer.ReleaseTexture(textureSet.activeTexture); - textureSet = {}; - } - +void SceneViewportToolOverlay::SetIconService(const EditorIconService* iconService) { + m_iconService = iconService; ResetFrame(); } @@ -305,7 +266,6 @@ void SceneViewportToolOverlay::BuildFrame( for (std::size_t index = 0; index < m_frame.buttons.size(); ++index) { const ToolButtonSpec& spec = kToolButtonSpecs[index]; - const ToolTextureSet& textureSet = m_toolTextures[index]; SceneViewportToolOverlayButtonFrame& button = m_frame.buttons[index]; button = {}; button.mode = spec.mode; @@ -314,9 +274,10 @@ void SceneViewportToolOverlay::BuildFrame( button.active = spec.mode == activeMode; button.hovered = index == hoveredIndex; button.pressed = index == pressedIndex; - button.texture = spec.mode == activeMode - ? textureSet.activeTexture - : textureSet.inactiveTexture; + if (m_iconService != nullptr) { + button.texture = m_iconService->Resolve( + spec.mode == activeMode ? spec.activeIcon : spec.inactiveIcon); + } } } diff --git a/editor/app/Features/Scene/SceneViewportToolOverlay.h b/editor/app/Features/Scene/SceneViewportToolOverlay.h index d0eabe4a..28367422 100644 --- a/editor/app/Features/Scene/SceneViewportToolOverlay.h +++ b/editor/app/Features/Scene/SceneViewportToolOverlay.h @@ -1,7 +1,7 @@ #pragma once #include "SceneToolState.h" -#include "HostFwd.h" +#include "Assets/EditorIconService.h" #include #include @@ -9,7 +9,6 @@ #include #include #include -#include #include namespace XCEngine::UI::Editor::App { @@ -57,10 +56,7 @@ struct SceneViewportToolOverlayFrame { class SceneViewportToolOverlay { public: - bool Initialize( - const std::filesystem::path& repoRoot, - Rendering::Host::UiTextureHost& renderer); - void Shutdown(Rendering::Host::UiTextureHost& renderer); + void SetIconService(const EditorIconService* iconService); void ResetFrame(); void BuildFrame( @@ -82,15 +78,8 @@ public: const SceneViewportToolOverlayFrame& GetFrame() const; private: - struct ToolTextureSet { - SceneToolMode mode = SceneToolMode::View; - const char* label = ""; - ::XCEngine::UI::UITextureHandle inactiveTexture = {}; - ::XCEngine::UI::UITextureHandle activeTexture = {}; - }; - - std::array m_toolTextures = {}; SceneViewportToolOverlayFrame m_frame = {}; + const EditorIconService* m_iconService = nullptr; }; void AppendSceneViewportToolOverlay( diff --git a/editor/app/Host/Interfaces/EditorHostResourceService.h b/editor/app/Host/Interfaces/EditorHostResourceService.h index c9cf46b2..806d365f 100644 --- a/editor/app/Host/Interfaces/EditorHostResourceService.h +++ b/editor/app/Host/Interfaces/EditorHostResourceService.h @@ -20,6 +20,16 @@ enum class EditorHostPngResourceKind : std::uint8_t { PlayButtonIcon, PauseButtonIcon, StepButtonIcon, + ViewMoveToolIcon, + ViewMoveToolActiveIcon, + MoveToolIcon, + MoveToolActiveIcon, + RotateToolIcon, + RotateToolActiveIcon, + ScaleToolIcon, + ScaleToolActiveIcon, + TransformToolIcon, + TransformToolActiveIcon, }; struct EditorHostResourceBytes { diff --git a/editor/app/Host/Win32/Resources/Win32EditorResourceService.cpp b/editor/app/Host/Win32/Resources/Win32EditorResourceService.cpp index e2e05da2..34916e22 100644 --- a/editor/app/Host/Win32/Resources/Win32EditorResourceService.cpp +++ b/editor/app/Host/Win32/Resources/Win32EditorResourceService.cpp @@ -34,6 +34,26 @@ int ResolvePngResourceId(EditorHostPngResourceKind kind) { return IDR_PNG_PAUSE_BUTTON_ICON; case EditorHostPngResourceKind::StepButtonIcon: return IDR_PNG_STEP_BUTTON_ICON; + case EditorHostPngResourceKind::ViewMoveToolIcon: + return IDR_PNG_VIEW_MOVE_TOOL_ICON; + case EditorHostPngResourceKind::ViewMoveToolActiveIcon: + return IDR_PNG_VIEW_MOVE_TOOL_ACTIVE_ICON; + case EditorHostPngResourceKind::MoveToolIcon: + return IDR_PNG_MOVE_TOOL_ICON; + case EditorHostPngResourceKind::MoveToolActiveIcon: + return IDR_PNG_MOVE_TOOL_ACTIVE_ICON; + case EditorHostPngResourceKind::RotateToolIcon: + return IDR_PNG_ROTATE_TOOL_ICON; + case EditorHostPngResourceKind::RotateToolActiveIcon: + return IDR_PNG_ROTATE_TOOL_ACTIVE_ICON; + case EditorHostPngResourceKind::ScaleToolIcon: + return IDR_PNG_SCALE_TOOL_ICON; + case EditorHostPngResourceKind::ScaleToolActiveIcon: + return IDR_PNG_SCALE_TOOL_ACTIVE_ICON; + case EditorHostPngResourceKind::TransformToolIcon: + return IDR_PNG_TRANSFORM_TOOL_ICON; + case EditorHostPngResourceKind::TransformToolActiveIcon: + return IDR_PNG_TRANSFORM_TOOL_ACTIVE_ICON; default: return 0; } diff --git a/editor/app/Rendering/Assets/BuiltInIcons.cpp b/editor/app/Rendering/Assets/BuiltInIcons.cpp index daa19c72..992cbb01 100644 --- a/editor/app/Rendering/Assets/BuiltInIcons.cpp +++ b/editor/app/Rendering/Assets/BuiltInIcons.cpp @@ -584,6 +584,76 @@ void BuiltInIcons::Initialize( "step_button.png", m_stepButtonIcon, errorStream); + LoadEmbeddedIconTexture( + renderer, + resourceService, + Host::EditorHostPngResourceKind::ViewMoveToolIcon, + "view_move_tool.png", + m_viewMoveToolIcon, + errorStream); + LoadEmbeddedIconTexture( + renderer, + resourceService, + Host::EditorHostPngResourceKind::ViewMoveToolActiveIcon, + "view_move_tool_on.png", + m_viewMoveToolActiveIcon, + errorStream); + LoadEmbeddedIconTexture( + renderer, + resourceService, + Host::EditorHostPngResourceKind::MoveToolIcon, + "move_tool.png", + m_moveToolIcon, + errorStream); + LoadEmbeddedIconTexture( + renderer, + resourceService, + Host::EditorHostPngResourceKind::MoveToolActiveIcon, + "move_tool_on.png", + m_moveToolActiveIcon, + errorStream); + LoadEmbeddedIconTexture( + renderer, + resourceService, + Host::EditorHostPngResourceKind::RotateToolIcon, + "rotate_tool.png", + m_rotateToolIcon, + errorStream); + LoadEmbeddedIconTexture( + renderer, + resourceService, + Host::EditorHostPngResourceKind::RotateToolActiveIcon, + "rotate_tool_on.png", + m_rotateToolActiveIcon, + errorStream); + LoadEmbeddedIconTexture( + renderer, + resourceService, + Host::EditorHostPngResourceKind::ScaleToolIcon, + "scale_tool.png", + m_scaleToolIcon, + errorStream); + LoadEmbeddedIconTexture( + renderer, + resourceService, + Host::EditorHostPngResourceKind::ScaleToolActiveIcon, + "scale_tool_on.png", + m_scaleToolActiveIcon, + errorStream); + LoadEmbeddedIconTexture( + renderer, + resourceService, + Host::EditorHostPngResourceKind::TransformToolIcon, + "transform_tool.png", + m_transformToolIcon, + errorStream); + LoadEmbeddedIconTexture( + renderer, + resourceService, + Host::EditorHostPngResourceKind::TransformToolActiveIcon, + "transform_tool_on.png", + m_transformToolActiveIcon, + errorStream); m_frameIndex = 0; m_previewLoadsThisFrame = 0; @@ -605,6 +675,16 @@ void BuiltInIcons::Shutdown() { m_renderer->ReleaseTexture(m_playButtonIcon); m_renderer->ReleaseTexture(m_pauseButtonIcon); m_renderer->ReleaseTexture(m_stepButtonIcon); + m_renderer->ReleaseTexture(m_viewMoveToolIcon); + m_renderer->ReleaseTexture(m_viewMoveToolActiveIcon); + m_renderer->ReleaseTexture(m_moveToolIcon); + m_renderer->ReleaseTexture(m_moveToolActiveIcon); + m_renderer->ReleaseTexture(m_rotateToolIcon); + m_renderer->ReleaseTexture(m_rotateToolActiveIcon); + m_renderer->ReleaseTexture(m_scaleToolIcon); + m_renderer->ReleaseTexture(m_scaleToolActiveIcon); + m_renderer->ReleaseTexture(m_transformToolIcon); + m_renderer->ReleaseTexture(m_transformToolActiveIcon); } m_renderer = nullptr; @@ -944,6 +1024,26 @@ const ::XCEngine::UI::UITextureHandle& BuiltInIcons::Resolve( return m_pauseButtonIcon; case BuiltInIconKind::StepButton: return m_stepButtonIcon; + case BuiltInIconKind::ViewMoveTool: + return m_viewMoveToolIcon; + case BuiltInIconKind::ViewMoveToolActive: + return m_viewMoveToolActiveIcon; + case BuiltInIconKind::MoveTool: + return m_moveToolIcon; + case BuiltInIconKind::MoveToolActive: + return m_moveToolActiveIcon; + case BuiltInIconKind::RotateTool: + return m_rotateToolIcon; + case BuiltInIconKind::RotateToolActive: + return m_rotateToolActiveIcon; + case BuiltInIconKind::ScaleTool: + return m_scaleToolIcon; + case BuiltInIconKind::ScaleToolActive: + return m_scaleToolActiveIcon; + case BuiltInIconKind::TransformTool: + return m_transformToolIcon; + case BuiltInIconKind::TransformToolActive: + return m_transformToolActiveIcon; default: return m_folderIcon; } diff --git a/editor/app/Rendering/Assets/BuiltInIcons.h b/editor/app/Rendering/Assets/BuiltInIcons.h index b191e01a..9f8ad44d 100644 --- a/editor/app/Rendering/Assets/BuiltInIcons.h +++ b/editor/app/Rendering/Assets/BuiltInIcons.h @@ -1,8 +1,6 @@ #pragma once -#include "HostFwd.h" - -#include +#include "Assets/EditorIconService.h" #include #include @@ -17,32 +15,19 @@ namespace XCEngine::UI::Editor::App { -enum class BuiltInIconKind : std::uint8_t { - Folder = 0, - GameObject, - Scene, - CameraGizmo, - DirectionalLightGizmo, - PointLightGizmo, - SpotLightGizmo, - PlayButton, - PauseButton, - StepButton -}; - -class BuiltInIcons { +class BuiltInIcons final : public EditorIconService { public: void Initialize( Rendering::Host::UiTextureHost& renderer, - Host::EditorHostResourceService& resourceService); - void Shutdown(); - void BeginFrame(); + Host::EditorHostResourceService& resourceService) override; + void Shutdown() override; + void BeginFrame() override; - const ::XCEngine::UI::UITextureHandle& Resolve(BuiltInIconKind kind) const; + const ::XCEngine::UI::UITextureHandle& Resolve(BuiltInIconKind kind) const override; const ::XCEngine::UI::UITextureHandle* ResolveAssetPreview( const std::filesystem::path& assetPath, - const std::filesystem::path& projectRoot); - const std::string& GetLastError() const; + const std::filesystem::path& projectRoot) override; + const std::string& GetLastError() const override; struct LoadedTexturePixels { std::vector rgbaPixels = {}; @@ -121,6 +106,16 @@ private: ::XCEngine::UI::UITextureHandle m_playButtonIcon = {}; ::XCEngine::UI::UITextureHandle m_pauseButtonIcon = {}; ::XCEngine::UI::UITextureHandle m_stepButtonIcon = {}; + ::XCEngine::UI::UITextureHandle m_viewMoveToolIcon = {}; + ::XCEngine::UI::UITextureHandle m_viewMoveToolActiveIcon = {}; + ::XCEngine::UI::UITextureHandle m_moveToolIcon = {}; + ::XCEngine::UI::UITextureHandle m_moveToolActiveIcon = {}; + ::XCEngine::UI::UITextureHandle m_rotateToolIcon = {}; + ::XCEngine::UI::UITextureHandle m_rotateToolActiveIcon = {}; + ::XCEngine::UI::UITextureHandle m_scaleToolIcon = {}; + ::XCEngine::UI::UITextureHandle m_scaleToolActiveIcon = {}; + ::XCEngine::UI::UITextureHandle m_transformToolIcon = {}; + ::XCEngine::UI::UITextureHandle m_transformToolActiveIcon = {}; std::unordered_map m_assetPreviews = {}; std::vector m_previewWorkers = {}; std::deque m_previewDecodeQueue = {}; diff --git a/editor/app/Rendering/Assets/EditorIconServiceFactory.cpp b/editor/app/Rendering/Assets/EditorIconServiceFactory.cpp new file mode 100644 index 00000000..25be3205 --- /dev/null +++ b/editor/app/Rendering/Assets/EditorIconServiceFactory.cpp @@ -0,0 +1,11 @@ +#include "Assets/EditorIconServiceFactory.h" + +#include "Assets/BuiltInIcons.h" + +namespace XCEngine::UI::Editor::App { + +std::unique_ptr CreateEditorIconService() { + return std::make_unique(); +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Rendering/Assets/EditorIconServiceFactory.h b/editor/app/Rendering/Assets/EditorIconServiceFactory.h new file mode 100644 index 00000000..4d6d5263 --- /dev/null +++ b/editor/app/Rendering/Assets/EditorIconServiceFactory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Assets/EditorIconService.h" + +#include + +namespace XCEngine::UI::Editor::App { + +std::unique_ptr CreateEditorIconService(); + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Rendering/Viewport/EditorViewportRuntimeServicesFactory.cpp b/editor/app/Rendering/Viewport/EditorViewportRuntimeServicesFactory.cpp new file mode 100644 index 00000000..31a9157d --- /dev/null +++ b/editor/app/Rendering/Viewport/EditorViewportRuntimeServicesFactory.cpp @@ -0,0 +1,11 @@ +#include "Viewport/EditorViewportRuntimeServicesFactory.h" + +#include "Viewport/ViewportHostService.h" + +namespace XCEngine::UI::Editor::App { + +std::unique_ptr CreateEditorViewportRuntimeServices() { + return std::make_unique(); +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Rendering/Viewport/EditorViewportRuntimeServicesFactory.h b/editor/app/Rendering/Viewport/EditorViewportRuntimeServicesFactory.h new file mode 100644 index 00000000..11422c84 --- /dev/null +++ b/editor/app/Rendering/Viewport/EditorViewportRuntimeServicesFactory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Viewport/EditorViewportRuntimeServices.h" + +#include + +namespace XCEngine::UI::Editor::App { + +std::unique_ptr CreateEditorViewportRuntimeServices(); + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Rendering/Viewport/SceneViewportRenderService.cpp b/editor/app/Rendering/Viewport/SceneViewportRenderService.cpp index d11f4f2a..417d7365 100644 --- a/editor/app/Rendering/Viewport/SceneViewportRenderService.cpp +++ b/editor/app/Rendering/Viewport/SceneViewportRenderService.cpp @@ -1,5 +1,7 @@ #include "Viewport/SceneViewportRenderService.h" +#include "Viewport/ViewportObjectIdPicker.h" + #include #include #include @@ -41,9 +43,9 @@ SceneViewportRenderService::SceneViewportRenderService() = default; SceneViewportRenderService::~SceneViewportRenderService() = default; -ViewportResourceRequirements +EditorViewportResourceRequirements SceneViewportRenderService::GetViewportResourceRequirements() { - ViewportResourceRequirements requirements = {}; + EditorViewportResourceRequirements requirements = {}; requirements.requiresDepthSampling = true; requirements.requiresObjectIdSurface = true; requirements.requiresSelectionMaskSurface = true; @@ -79,6 +81,10 @@ void SceneViewportRenderService::SetRenderRequest( m_renderRequest = std::move(request); } +const IViewportObjectPickerService& SceneViewportRenderService::GetObjectPicker() const { + return *this; +} + ViewportRenderResult SceneViewportRenderService::Render( ViewportRenderTargets& targets, ::XCEngine::RHI::RHIDevice& device, diff --git a/editor/app/Rendering/Viewport/SceneViewportRenderService.h b/editor/app/Rendering/Viewport/SceneViewportRenderService.h index 6408fe29..7b1949f8 100644 --- a/editor/app/Rendering/Viewport/SceneViewportRenderService.h +++ b/editor/app/Rendering/Viewport/SceneViewportRenderService.h @@ -1,9 +1,8 @@ #pragma once +#include "Viewport/EditorViewportRuntimeServices.h" #include "Viewport/ViewportContentRenderer.h" -#include "Viewport/ViewportObjectPickerService.h" #include "Viewport/SceneViewportRenderPassBundle.h" -#include "Scene/SceneViewportRenderRequest.h" #include #include @@ -28,16 +27,18 @@ namespace XCEngine::UI::Editor::App { class SceneViewportRenderService : public IViewportContentRenderer + , public EditorSceneViewportRuntime , public IViewportObjectPickerService { public: SceneViewportRenderService(); ~SceneViewportRenderService(); - static ViewportResourceRequirements GetViewportResourceRequirements(); + static EditorViewportResourceRequirements GetViewportResourceRequirements(); void Initialize(const SceneViewportShaderPaths& shaderPaths); void Shutdown(); - void SetRenderRequest(SceneViewportRenderRequest request); + void SetRenderRequest(SceneViewportRenderRequest request) override; + const IViewportObjectPickerService& GetObjectPicker() const override; ViewportRenderResult Render( ViewportRenderTargets& targets, diff --git a/editor/app/Rendering/Viewport/ViewportHostService.cpp b/editor/app/Rendering/Viewport/ViewportHostService.cpp index 677bb4e3..3d9fcfbf 100644 --- a/editor/app/Rendering/Viewport/ViewportHostService.cpp +++ b/editor/app/Rendering/Viewport/ViewportHostService.cpp @@ -1,5 +1,7 @@ #include "ViewportHostService.h" +#include "Panels/EditorPanelIds.h" +#include "Viewport/SceneViewportResourcePaths.h" #include "ViewportRenderHost.h" #include @@ -18,6 +20,14 @@ ViewportHostService::ViewportHostService() = default; ViewportHostService::~ViewportHostService() = default; +void ViewportHostService::Initialize(const std::filesystem::path& repoRoot) { + m_sceneViewportRuntime.Initialize(BuildSceneViewportShaderPaths(repoRoot)); + SetContentRenderer( + kScenePanelId, + &m_sceneViewportRuntime, + SceneViewportRenderService::GetViewportResourceRequirements()); +} + void ViewportHostService::AttachWindowRenderer( Rendering::Host::ViewportRenderHost& windowRenderer) { if (m_windowRenderer == &windowRenderer) { @@ -43,13 +53,15 @@ void ViewportHostService::SetSurfacePresentationEnabled(bool enabled) { void ViewportHostService::SetContentRenderer( std::string_view viewportId, IViewportContentRenderer* renderer, - const ViewportResourceRequirements& requirements) { + const EditorViewportResourceRequirements& requirements) { ViewportEntry& entry = GetOrCreateEntry(viewportId); entry.renderer = renderer; entry.requirements = requirements; } void ViewportHostService::Shutdown() { + SetContentRenderer(kScenePanelId, nullptr, {}); + m_sceneViewportRuntime.Shutdown(); for (auto& [viewportId, entry] : m_entries) { DestroyViewportEntry(entry); } @@ -155,7 +167,7 @@ void ViewportHostService::RetireViewportTargets(ViewportRenderTargets& targets) std::swap(m_retiredTargetsBySlot[activeSlot].back(), targets); } -ViewportFrame ViewportHostService::RequestViewport( +EditorViewportFrame ViewportHostService::RequestViewport( std::string_view viewportId, const ::XCEngine::UI::UISize& requestedSize) { ViewportEntry& entry = GetOrCreateEntry(viewportId); @@ -302,10 +314,10 @@ void ViewportHostService::ClearViewport( entry.renderTargets.objectIdFrameSerial = 0u; } -ViewportFrame ViewportHostService::BuildFrame( +EditorViewportFrame ViewportHostService::BuildFrame( const ViewportEntry& entry, const ::XCEngine::UI::UISize& requestedSize) const { - ViewportFrame frame = {}; + EditorViewportFrame frame = {}; frame.requestedSize = requestedSize; frame.renderSize = ::XCEngine::UI::UISize( static_cast(entry.renderTargets.width), @@ -322,4 +334,8 @@ ViewportFrame ViewportHostService::BuildFrame( return frame; } +EditorSceneViewportRuntime& ViewportHostService::GetSceneViewportRuntime() { + return m_sceneViewportRuntime; +} + } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Rendering/Viewport/ViewportHostService.h b/editor/app/Rendering/Viewport/ViewportHostService.h index 5b6cbb61..c4f976fe 100644 --- a/editor/app/Rendering/Viewport/ViewportHostService.h +++ b/editor/app/Rendering/Viewport/ViewportHostService.h @@ -1,6 +1,8 @@ #pragma once +#include "Viewport/EditorViewportRuntimeServices.h" #include "HostFwd.h" +#include "Viewport/SceneViewportRenderService.h" #include "Viewport/ViewportContentRenderer.h" #include "ViewportRenderTargets.h" @@ -15,33 +17,35 @@ namespace XCEngine::UI::Editor::App { -class ViewportHostService { +class ViewportHostService final : public EditorViewportRuntimeServices { public: ViewportHostService(); ~ViewportHostService(); - void AttachWindowRenderer(Rendering::Host::ViewportRenderHost& windowRenderer); - void DetachWindowRenderer(); - void SetSurfacePresentationEnabled(bool enabled); + void Initialize(const std::filesystem::path& repoRoot) override; + void Shutdown() override; + void AttachWindowRenderer(Rendering::Host::ViewportRenderHost& windowRenderer) override; + void DetachWindowRenderer() override; + void SetSurfacePresentationEnabled(bool enabled) override; void SetContentRenderer( std::string_view viewportId, IViewportContentRenderer* renderer, - const ViewportResourceRequirements& requirements = {}); + const EditorViewportResourceRequirements& requirements = {}); - void Shutdown(); - void BeginFrame(); + void BeginFrame() override; - ViewportFrame RequestViewport( + EditorViewportFrame RequestViewport( std::string_view viewportId, - const ::XCEngine::UI::UISize& requestedSize); + const ::XCEngine::UI::UISize& requestedSize) override; void RenderRequestedViewports( - const ::XCEngine::Rendering::RenderContext& renderContext); + const ::XCEngine::Rendering::RenderContext& renderContext) override; + EditorSceneViewportRuntime& GetSceneViewportRuntime() override; private: struct ViewportEntry { IViewportContentRenderer* renderer = nullptr; - ViewportResourceRequirements requirements = {}; + EditorViewportResourceRequirements requirements = {}; std::uint32_t requestedWidth = 0; std::uint32_t requestedHeight = 0; bool requestedThisFrame = false; @@ -68,7 +72,7 @@ private: float g, float b, float a); - ViewportFrame BuildFrame( + EditorViewportFrame BuildFrame( const ViewportEntry& entry, const ::XCEngine::UI::UISize& requestedSize) const; @@ -78,6 +82,7 @@ private: bool m_surfacePresentationEnabled = false; std::unordered_map m_entries = {}; std::vector> m_retiredTargetsBySlot = {}; + SceneViewportRenderService m_sceneViewportRuntime = {}; }; } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Rendering/Viewport/ViewportObjectIdPicker.h b/editor/app/Rendering/Viewport/ViewportObjectIdPicker.h index 296adb19..02d91d84 100644 --- a/editor/app/Rendering/Viewport/ViewportObjectIdPicker.h +++ b/editor/app/Rendering/Viewport/ViewportObjectIdPicker.h @@ -1,10 +1,11 @@ #pragma once +#include "Viewport/EditorViewportPicking.h" + #include #include #include #include -#include #include #include @@ -36,28 +37,6 @@ struct ViewportObjectIdReadbackRequest { std::uint32_t pixelY = 0; }; -enum class ViewportObjectIdPickStatus : std::uint8_t { - Unavailable = 0, - Success, - ReadbackFailed -}; - -struct ViewportObjectIdPickResult { - ViewportObjectIdPickStatus status = ViewportObjectIdPickStatus::Unavailable; - std::uint64_t frameSerial = 0u; - ::XCEngine::Rendering::RenderObjectId renderObjectId = - ::XCEngine::Rendering::kInvalidRenderObjectId; - std::uint64_t resolvedEntityId = 0u; - - bool HasResolvedSample() const { - return status == ViewportObjectIdPickStatus::Success; - } - - bool HasResolvedEntity() const { - return HasResolvedSample() && resolvedEntityId != 0u; - } -}; - inline bool CanPickViewportObjectId(const ViewportObjectIdPickContext& context) { return context.commandQueue != nullptr && context.texture != nullptr && diff --git a/editor/app/Rendering/Viewport/ViewportObjectPickerService.h b/editor/app/Rendering/Viewport/ViewportObjectPickerService.h index 0a9e006a..13af4c08 100644 --- a/editor/app/Rendering/Viewport/ViewportObjectPickerService.h +++ b/editor/app/Rendering/Viewport/ViewportObjectPickerService.h @@ -1,16 +1,3 @@ #pragma once -#include "Viewport/ViewportObjectIdPicker.h" - -namespace XCEngine::UI::Editor::App { - -class IViewportObjectPickerService { -public: - virtual ~IViewportObjectPickerService() = default; - - virtual ViewportObjectIdPickResult PickObject( - const ::XCEngine::UI::UISize& viewportSize, - const ::XCEngine::UI::UIPoint& viewportMousePosition) const = 0; -}; - -} // namespace XCEngine::UI::Editor::App +#include "Viewport/EditorViewportPicking.h" diff --git a/editor/app/Rendering/Viewport/ViewportTypes.h b/editor/app/Rendering/Viewport/ViewportTypes.h index a47dc0ff..c0e292bd 100644 --- a/editor/app/Rendering/Viewport/ViewportTypes.h +++ b/editor/app/Rendering/Viewport/ViewportTypes.h @@ -1,25 +1,11 @@ #pragma once -#include - -#include +#include "Viewport/EditorViewportTypes.h" namespace XCEngine::UI::Editor::App { -struct ViewportResourceRequirements { - bool requiresDepthSampling = false; - bool requiresObjectIdSurface = false; - bool requiresSelectionMaskSurface = false; -}; - -struct ViewportFrame { - ::XCEngine::UI::UITextureHandle texture = {}; - ::XCEngine::UI::UISize requestedSize = {}; - ::XCEngine::UI::UISize renderSize = {}; - bool hasTexture = false; - bool wasRequested = false; - std::string statusText = {}; -}; +using ViewportResourceRequirements = EditorViewportResourceRequirements; +using ViewportFrame = EditorViewportFrame; } // namespace XCEngine::UI::Editor::App diff --git a/tests/UI/Editor/unit/test_project_panel.cpp b/tests/UI/Editor/unit/test_project_panel.cpp index ef812f2e..0ea4951b 100644 --- a/tests/UI/Editor/unit/test_project_panel.cpp +++ b/tests/UI/Editor/unit/test_project_panel.cpp @@ -1,5 +1,5 @@ #include "Project/ProjectPanel.h" -#include "Assets/BuiltInIcons.h" +#include "Assets/EditorIconService.h" #include "SystemInteractionService.h" #include "Panels/EditorPanelIds.h" @@ -40,6 +40,33 @@ public: std::filesystem::path lastRevealPath = {}; }; +class FakeIconService final : public EditorIconService { +public: + void Initialize( + Rendering::Host::UiTextureHost&, + Host::EditorHostResourceService&) override {} + void Shutdown() override {} + void BeginFrame() override {} + + const ::XCEngine::UI::UITextureHandle& Resolve(BuiltInIconKind) const override { + return texture; + } + + const ::XCEngine::UI::UITextureHandle* ResolveAssetPreview( + const std::filesystem::path&, + const std::filesystem::path&) override { + return nullptr; + } + + const std::string& GetLastError() const override { + return error; + } + +private: + ::XCEngine::UI::UITextureHandle texture = {}; + std::string error = {}; +}; + class TemporaryRepo final { public: TemporaryRepo() { @@ -249,13 +276,13 @@ TEST(ProjectPanelTests, InjectedRuntimeCurrentFolderDrivesRenameFallbackWithoutT EXPECT_EQ(evaluation.message, "Rename project item 'FolderA'."); } -TEST(ProjectPanelTests, BuiltInIconsCanBeConfiguredBeforeRuntimeInitialization) { +TEST(ProjectPanelTests, IconServiceCanBeConfiguredBeforeRuntimeInitialization) { TemporaryRepo repo = {}; ProjectPanel panel = {}; - BuiltInIcons icons = {}; + FakeIconService icons = {}; - panel.SetBuiltInIcons(&icons); + panel.SetIconService(&icons); panel.Initialize(repo.Root()); const UIEditorHostCommandEvaluationResult evaluation =