diff --git a/docs/plan/XCUI_Phase_Status_2026-04-05.md b/docs/plan/XCUI_Phase_Status_2026-04-05.md index 03bdeb10..7eca3b5b 100644 --- a/docs/plan/XCUI_Phase_Status_2026-04-05.md +++ b/docs/plan/XCUI_Phase_Status_2026-04-05.md @@ -46,6 +46,7 @@ Old `editor` replacement is explicitly out of scope for this phase. - `XCUIShellChromeState` no longer carries the legacy host demo-window toggle or command id on the generic shell-state surface - `Application.h` no longer exposes that legacy demo command through generic `ShellCommandIds`, `ShellCommandBindings`, or `RegisterShellViewCommands(...)` - the legacy demo window toggle now lives as a compatibility-only command inside `ApplicationLegacyImGui.cpp` + - `Application.h` now also uses backend-neutral compatibility-host naming for the non-native window-host path, so the generic application header no longer names `LegacyImGui` in its mode enum or private host-frame method declarations - generic `Application` host-mode/member naming is now also shifting from `LegacyImGui` toward `CompatibilityHost`, so the default shell surface does not have to encode ImGui into every host-facing method name - Old `editor` replacement remains deferred; all active execution still stays inside XCUI shared code and `new_editor`. @@ -109,7 +110,7 @@ Current gap: - `new_editor` now also has an isolated `XCUIEditorCommandRouter` model with shortcut matching, enable predicates, and direct command invocation semantics covered by dedicated tests, ready for shell-frame integration. - `XCUI Demo` now exports pending per-frame command ids through `DrainPendingCommandIds()`, so editor-side hosts have a clean seam for observing demo/runtime command traffic without parsing draw data. - `XCUI Demo` and `LayoutLab` panel canvases are now being pulled behind a dedicated `IXCUIPanelCanvasHost` seam, so canvas surface presentation, hover/focus fallback state, and overlay draw hooks no longer have to stay hard-coded inside each ImGui panel implementation. -- The panel-canvas seam now also exposes explicit backend/capability metadata and a minimal `NullXCUIPanelCanvasHost`, so non-ImGui host paths have a concrete placeholder backend instead of relying on an implicit ImGui default. +- The panel-canvas seam now keeps the generic host contract on observable canvas behavior only; backend/capability identity probing has been removed from `IXCUIPanelCanvasHost`, and the minimal `NullXCUIPanelCanvasHost` remains the concrete placeholder host for non-ImGui paths. - `XCUI Demo` and `LayoutLab` panel input now also flows through an explicit `IXCUIInputSnapshotSource` seam, so panel/runtime code no longer reads `ImGuiIO` / `ImGui::IsKeyPressed` / `ImGui::IsMouseClicked` directly when the shell wants to use an ImGui adapter. - `new_editor` now also has an explicit `ImGuiXCUIInputSnapshotSource` adapter, keeping ImGui-specific input capture in the host adapter layer instead of inside panel/runtime update code. - Panel diagnostics were expanded to clearly separate preview/runtime/input state and native vs legacy paths. @@ -265,7 +266,7 @@ Current gap: - `new_editor` now also has a pure `XCUIShellChromeState` model with dedicated tests, covering shell panel visibility, hosted-preview mode, and shell view toggles without depending on ImGui or `Application`. - `XCUIShellChromeState` now also exposes effective hosted-preview state helpers and shell view-toggle command-id helpers, so shell routing code no longer has to manually combine enablement and requested preview mode. - `XCUIShellChromeState` hosted-preview modes were renamed away from `LegacyImGui`, so XCUI shell state no longer treats ImGui as the generic fallback concept. -- The panel-canvas seam now has dedicated null/imgui backend coverage, including explicit backend/capability reporting and a non-ImGui placeholder host path for future native shell adoption. +- The panel-canvas seam now has dedicated null/compat/native coverage around stable debug names, passive-session safety, externally driven native snapshots, and compat-host factory creation without relying on explicit backend/capability reporting. - The native host follow-up is now present in `new_editor`: - `NativeWindowUICompositor` provides a swapchain-native XCUI packet present path beside the legacy ImGui compositor - `Application` now defaults to that native host path and directly composes `XCUI Demo` plus `Layout Lab` into one native shell frame diff --git a/new_editor/src/XCUIBackend/ImGuiXCUIPanelCanvasHost.h b/new_editor/src/XCUIBackend/ImGuiXCUIPanelCanvasHost.h index db1db004..c06e7452 100644 --- a/new_editor/src/XCUIBackend/ImGuiXCUIPanelCanvasHost.h +++ b/new_editor/src/XCUIBackend/ImGuiXCUIPanelCanvasHost.h @@ -89,18 +89,6 @@ public: return "ImGuiXCUIPanelCanvasHost"; } - XCUIPanelCanvasHostBackend GetBackend() const override { - return XCUIPanelCanvasHostBackend::ImGui; - } - - XCUIPanelCanvasHostCapabilities GetCapabilities() const override { - XCUIPanelCanvasHostCapabilities capabilities = {}; - capabilities.supportsPointerHitTesting = true; - capabilities.supportsHostedSurfaceImages = true; - capabilities.supportsPrimitiveOverlays = true; - return capabilities; - } - XCUIPanelCanvasSession BeginCanvas(const XCUIPanelCanvasRequest& request) override { const char* childId = request.childId != nullptr && request.childId[0] != '\0' diff --git a/new_editor/src/XCUIBackend/NativeXCUIPanelCanvasHost.h b/new_editor/src/XCUIBackend/NativeXCUIPanelCanvasHost.h index 93b6a942..b59c76a4 100644 --- a/new_editor/src/XCUIBackend/NativeXCUIPanelCanvasHost.h +++ b/new_editor/src/XCUIBackend/NativeXCUIPanelCanvasHost.h @@ -132,18 +132,6 @@ public: return "NativeXCUIPanelCanvasHost"; } - XCUIPanelCanvasHostBackend GetBackend() const override { - return XCUIPanelCanvasHostBackend::Native; - } - - XCUIPanelCanvasHostCapabilities GetCapabilities() const override { - XCUIPanelCanvasHostCapabilities capabilities = {}; - capabilities.supportsHostedSurfaceImages = true; - capabilities.supportsPrimitiveOverlays = true; - capabilities.supportsExternallyDrivenSession = true; - return capabilities; - } - void SetCanvasSession(const XCUIPanelCanvasSession& session) { m_configuredSession = session; m_hasConfiguredSession = true; diff --git a/new_editor/src/XCUIBackend/NullXCUIPanelCanvasHost.h b/new_editor/src/XCUIBackend/NullXCUIPanelCanvasHost.h index 49fdc000..d694e97d 100644 --- a/new_editor/src/XCUIBackend/NullXCUIPanelCanvasHost.h +++ b/new_editor/src/XCUIBackend/NullXCUIPanelCanvasHost.h @@ -14,14 +14,6 @@ public: return "NullXCUIPanelCanvasHost"; } - XCUIPanelCanvasHostBackend GetBackend() const override { - return XCUIPanelCanvasHostBackend::Null; - } - - XCUIPanelCanvasHostCapabilities GetCapabilities() const override { - return {}; - } - XCUIPanelCanvasSession BeginCanvas(const XCUIPanelCanvasRequest& request) override { m_canvasSession = BuildPassiveXCUIPanelCanvasSession(request); return m_canvasSession; diff --git a/new_editor/src/XCUIBackend/XCUIPanelCanvasHost.h b/new_editor/src/XCUIBackend/XCUIPanelCanvasHost.h index c21fa78d..3f2cd032 100644 --- a/new_editor/src/XCUIBackend/XCUIPanelCanvasHost.h +++ b/new_editor/src/XCUIBackend/XCUIPanelCanvasHost.h @@ -4,7 +4,6 @@ #include -#include #include #include #include @@ -13,19 +12,6 @@ namespace XCEngine { namespace Editor { namespace XCUIBackend { -enum class XCUIPanelCanvasHostBackend : std::uint8_t { - Null = 0, - ImGui, - Native -}; - -struct XCUIPanelCanvasHostCapabilities { - bool supportsPointerHitTesting = false; - bool supportsHostedSurfaceImages = false; - bool supportsPrimitiveOverlays = false; - bool supportsExternallyDrivenSession = false; -}; - struct XCUIPanelCanvasRequest { const char* childId = nullptr; float height = 0.0f; @@ -98,8 +84,6 @@ public: virtual ~IXCUIPanelCanvasHost() = default; virtual const char* GetDebugName() const = 0; - virtual XCUIPanelCanvasHostBackend GetBackend() const = 0; - virtual XCUIPanelCanvasHostCapabilities GetCapabilities() const = 0; virtual XCUIPanelCanvasSession BeginCanvas(const XCUIPanelCanvasRequest& request) = 0; virtual void DrawFilledRect( const ::XCEngine::UI::UIRect& rect, diff --git a/tests/NewEditor/test_imgui_xcui_panel_canvas_host.cpp b/tests/NewEditor/test_imgui_xcui_panel_canvas_host.cpp index 41c95fd5..b95d172b 100644 --- a/tests/NewEditor/test_imgui_xcui_panel_canvas_host.cpp +++ b/tests/NewEditor/test_imgui_xcui_panel_canvas_host.cpp @@ -6,20 +6,12 @@ namespace { using XCEngine::Editor::XCUIBackend::CreateImGuiXCUIPanelCanvasHost; using XCEngine::Editor::XCUIBackend::IXCUIPanelCanvasHost; -using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostBackend; -using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostCapabilities; -TEST(NewEditorImGuiXCUIPanelCanvasHostTest, ReportsExplicitBackendAndCapabilities) { +TEST(NewEditorImGuiXCUIPanelCanvasHostTest, FactoryCreatesCompatCanvasHostWithStableDebugName) { std::unique_ptr host = CreateImGuiXCUIPanelCanvasHost(); ASSERT_NE(host, nullptr); EXPECT_STREQ(host->GetDebugName(), "ImGuiXCUIPanelCanvasHost"); - EXPECT_EQ(host->GetBackend(), XCUIPanelCanvasHostBackend::ImGui); - - const XCUIPanelCanvasHostCapabilities capabilities = host->GetCapabilities(); - EXPECT_TRUE(capabilities.supportsPointerHitTesting); - EXPECT_TRUE(capabilities.supportsHostedSurfaceImages); - EXPECT_TRUE(capabilities.supportsPrimitiveOverlays); } } // namespace diff --git a/tests/NewEditor/test_legacy_imgui_host_interop.cpp b/tests/NewEditor/test_legacy_imgui_host_interop.cpp index 2e742b45..4a313ba7 100644 --- a/tests/NewEditor/test_legacy_imgui_host_interop.cpp +++ b/tests/NewEditor/test_legacy_imgui_host_interop.cpp @@ -12,7 +12,6 @@ using XCEngine::Editor::XCUIBackend::CreateLegacyImGuiHostedPreviewPresenter; using XCEngine::Editor::XCUIBackend::CreateLegacyImGuiPanelCanvasHost; using XCEngine::Editor::XCUIBackend::CreateLegacyImGuiWindowUICompositor; using XCEngine::Editor::XCUIBackend::RenderLegacyImGuiDemoWindow; -using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostBackend; using XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameSnapshot; class ScopedImGuiContext final { @@ -30,7 +29,7 @@ public: ScopedImGuiContext& operator=(const ScopedImGuiContext&) = delete; }; -TEST(LegacyImGuiHostInteropTest, CreatesLegacyHostAdaptersWithImGuiBackends) { +TEST(LegacyImGuiHostInteropTest, CreatesLegacyHostAdaptersWithExpectedDebugNames) { auto compositor = CreateLegacyImGuiWindowUICompositor(); auto presenter = CreateLegacyImGuiHostedPreviewPresenter(); auto canvasHost = CreateLegacyImGuiPanelCanvasHost(); @@ -38,12 +37,7 @@ TEST(LegacyImGuiHostInteropTest, CreatesLegacyHostAdaptersWithImGuiBackends) { ASSERT_NE(compositor, nullptr); ASSERT_NE(presenter, nullptr); ASSERT_NE(canvasHost, nullptr); - EXPECT_EQ(canvasHost->GetBackend(), XCUIPanelCanvasHostBackend::ImGui); - - const auto capabilities = canvasHost->GetCapabilities(); - EXPECT_TRUE(capabilities.supportsPointerHitTesting); - EXPECT_TRUE(capabilities.supportsHostedSurfaceImages); - EXPECT_TRUE(capabilities.supportsPrimitiveOverlays); + EXPECT_STREQ(canvasHost->GetDebugName(), "ImGuiXCUIPanelCanvasHost"); } TEST(LegacyImGuiHostInteropTest, ApplyInputCaptureCopiesImGuiIoFlagsIntoSnapshot) { diff --git a/tests/NewEditor/test_native_xcui_panel_canvas_host.cpp b/tests/NewEditor/test_native_xcui_panel_canvas_host.cpp index 86d7e254..b0535f71 100644 --- a/tests/NewEditor/test_native_xcui_panel_canvas_host.cpp +++ b/tests/NewEditor/test_native_xcui_panel_canvas_host.cpp @@ -8,8 +8,6 @@ using XCEngine::Editor::XCUIBackend::CreateNativeXCUIPanelCanvasHost; using XCEngine::Editor::XCUIBackend::IXCUIPanelCanvasHost; using XCEngine::Editor::XCUIBackend::NativeXCUIPanelCanvasHost; using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasFrameSnapshot; -using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostBackend; -using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostCapabilities; using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasRequest; using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasSession; @@ -22,18 +20,11 @@ XCEngine::UI::UITextureHandle MakeSurfaceTextureHandle(std::uintptr_t nativeHand return texture; } -TEST(NativeXCUIPanelCanvasHostTest, FactoryReportsNativeBackendCapabilitiesAndNoSnapshotBeforeBegin) { +TEST(NativeXCUIPanelCanvasHostTest, FactoryCreatesHostWithStableDebugNameAndNoSnapshotBeforeBegin) { std::unique_ptr host = CreateNativeXCUIPanelCanvasHost(); ASSERT_NE(host, nullptr); EXPECT_STREQ(host->GetDebugName(), "NativeXCUIPanelCanvasHost"); - EXPECT_EQ(host->GetBackend(), XCUIPanelCanvasHostBackend::Native); - - const XCUIPanelCanvasHostCapabilities capabilities = host->GetCapabilities(); - EXPECT_FALSE(capabilities.supportsPointerHitTesting); - EXPECT_TRUE(capabilities.supportsHostedSurfaceImages); - EXPECT_TRUE(capabilities.supportsPrimitiveOverlays); - EXPECT_TRUE(capabilities.supportsExternallyDrivenSession); XCUIPanelCanvasFrameSnapshot snapshot = {}; EXPECT_FALSE(host->TryGetLatestFrameSnapshot(snapshot)); diff --git a/tests/NewEditor/test_xcui_demo_panel.cpp b/tests/NewEditor/test_xcui_demo_panel.cpp index 8ce6863e..a753e9fb 100644 --- a/tests/NewEditor/test_xcui_demo_panel.cpp +++ b/tests/NewEditor/test_xcui_demo_panel.cpp @@ -87,14 +87,6 @@ public: return "StubCanvasHost"; } - XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostBackend GetBackend() const override { - return XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostBackend::Null; - } - - XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostCapabilities GetCapabilities() const override { - return {}; - } - XCUIPanelCanvasSession BeginCanvas(const XCUIPanelCanvasRequest& request) override { lastRequest = request; ++beginCanvasCallCount; diff --git a/tests/NewEditor/test_xcui_layout_lab_panel.cpp b/tests/NewEditor/test_xcui_layout_lab_panel.cpp index 1553a2f2..d7f2b1db 100644 --- a/tests/NewEditor/test_xcui_layout_lab_panel.cpp +++ b/tests/NewEditor/test_xcui_layout_lab_panel.cpp @@ -69,14 +69,6 @@ public: return "StubCanvasHost"; } - XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostBackend GetBackend() const override { - return XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostBackend::Null; - } - - XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostCapabilities GetCapabilities() const override { - return {}; - } - XCUIPanelCanvasSession BeginCanvas(const XCUIPanelCanvasRequest&) override { return m_session; } diff --git a/tests/NewEditor/test_xcui_panel_canvas_host.cpp b/tests/NewEditor/test_xcui_panel_canvas_host.cpp index 695fe19f..d4228ea8 100644 --- a/tests/NewEditor/test_xcui_panel_canvas_host.cpp +++ b/tests/NewEditor/test_xcui_panel_canvas_host.cpp @@ -8,22 +8,22 @@ using XCEngine::Editor::XCUIBackend::CreateNullXCUIPanelCanvasHost; using XCEngine::Editor::XCUIBackend::BuildPassiveXCUIPanelCanvasSession; using XCEngine::Editor::XCUIBackend::IXCUIPanelCanvasHost; using XCEngine::Editor::XCUIBackend::ResolveXCUIPanelCanvasChildId; -using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostBackend; -using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasHostCapabilities; using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasRequest; using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasSession; -TEST(NewEditorXCUIPanelCanvasHostTest, NullHostReportsExplicitBackendAndCapabilities) { +TEST(NewEditorXCUIPanelCanvasHostTest, NullHostProvidesStableDebugNameAndSafePassiveSessions) { std::unique_ptr host = CreateNullXCUIPanelCanvasHost(); ASSERT_NE(host, nullptr); EXPECT_STREQ(host->GetDebugName(), "NullXCUIPanelCanvasHost"); - EXPECT_EQ(host->GetBackend(), XCUIPanelCanvasHostBackend::Null); - const XCUIPanelCanvasHostCapabilities capabilities = host->GetCapabilities(); - EXPECT_FALSE(capabilities.supportsPointerHitTesting); - EXPECT_FALSE(capabilities.supportsHostedSurfaceImages); - EXPECT_FALSE(capabilities.supportsPrimitiveOverlays); + const XCUIPanelCanvasSession session = host->BeginCanvas({}); + EXPECT_FALSE(session.validCanvas); + EXPECT_FALSE(session.hovered); + EXPECT_FALSE(session.windowFocused); + EXPECT_FLOAT_EQ(session.hostRect.width, 0.0f); + EXPECT_FLOAT_EQ(session.hostRect.height, 0.0f); + host->EndCanvas(); } TEST(NewEditorXCUIPanelCanvasHostTest, ResolveChildIdFallsBackToStableDefaultForMissingNames) {