# XCUI Phase Status 2026-04-05 ## Scope Current execution stays inside the XCUI module and `new_editor`. Old `editor` replacement is explicitly out of scope for this phase. ## Latest Checkpoint - Phase 1 sandbox batch committed and pushed as `67a28bd` (`Add XCUI new editor sandbox phase 1`). - Phase 2 common/runtime batch committed and pushed as `ade5be3` (`Add XCUI runtime screen layer and demo textarea`). - Phase 3 has now produced a stable mixed batch across common/runtime/editor: - schema document definition data is now retained on `UIDocumentModel` and round-trips through the UI artifact path - schema self-definition validation is now stricter around enum/document-only metadata combinations - engine runtime coverage was tightened again around `UISystem` and concrete document-host rendering - `LayoutLab` continues as the editor widget proving ground for tree/list/property-section style controls - the demo sandbox and editor bridge APIs were tightened again without touching the old editor replacement scope - `new_editor` now has an explicit two-step window compositor seam through `IWindowUICompositor` / `ImGuiWindowUICompositor`, layered on top of `IEditorHostCompositor` / `ImGuiHostCompositor` - The native-host / hosted-preview publication follow-up is now landed in `new_editor`: - `NativeWindowUICompositor` is now buildable alongside the legacy ImGui compositor - `Application` now defaults to a native XCUI host path instead of creating the ImGui shell by default - the native default path now drives `XCUIDemoRuntime` and `XCUILayoutLabRuntime` directly, composes their `UIDrawData`, and submits one swapchain packet through the native compositor - the native compositor now publishes hosted-preview textures as SRV-backed `UITextureRegistration` / `UITextureHandle` values instead of relying on ImGui-only descriptor semantics - the native shell now begins the hosted-preview queue/registry lifecycle each frame, queues native preview frames, drains them during the native render pass, and consumes published hosted-surface images directly in panel cards with live/warming placeholder states - the old ImGui shell path remains present as an explicit compatibility host instead of the default host - `XCUIInputBridge.h` no longer drags `imgui.h` through the public XCUI input seam - The default native text path is now also de-ImGuiized inside `new_editor`: - `XCUIStandaloneTextAtlasProvider` now builds and owns its atlas through a Windows/GDI raster path instead of using ImGui font-atlas internals - the standalone atlas provider now exposes both `RGBA32` and `Alpha8` views, supports non-nominal size resolution, lazily adds non-prebaked BMP glyphs, and falls back to `?` when a glyph cannot be rasterized - The default native shell path now also has a cleaner translation-unit seam: - legacy ImGui shell chrome / HUD rendering now lives in a dedicated legacy-only `Application` translation unit instead of keeping direct `ImGui::*` calls inside the main native host TU - `Application.cpp` no longer directly includes ``, even though the compatibility host path is still compiled into `new_editor` - The `new_editor` build now also has an explicit compatibility-source slice: - legacy ImGui shell sources and vendored ImGui backend sources are now grouped into a dedicated compatibility static library instead of being compiled directly as part of the main `XCNewEditor` source list - the main `XCNewEditor` target still sees ImGui headers through older editor bridge headers, but its default implementation source list is now narrower than the compatibility source list - Old `editor` replacement remains deferred; all active execution still stays inside XCUI shared code and `new_editor`. ## Three-Layer Status ### 1. Common Core - `UI::DrawData`, input event types, focus routing, style/theme resolution are in active use. - `UIDocumentCompiler` is buildable again after repairing the duplicated schema helper regression introduced by overlapping schema work. - `UIDocumentModel` / `UIDocumentResource` now retain schema definition metadata explicitly, including memory accounting and `UISchema` accessors. - `.xcschema` round-trip coverage is now present through compile, loader, artifact write, and artifact read paths. - Build-system hardening for MSVC/PDB output paths has started in root CMake, `engine/CMakeLists.txt`, `new_editor/CMakeLists.txt`, and `tests/NewEditor/CMakeLists.txt`. - Shared engine-side XCUI runtime scaffolding is now present under `engine/include/XCEngine/UI/Runtime` and `engine/src/UI/Runtime`. - Shared engine-side `UIDocumentScreenHost` now compiles `.xcui` / `.xctheme` screen documents into a runtime-facing document host path instead of leaving all document ownership in `new_editor`. - Shared text-editing primitives now live under `engine/include/XCEngine/UI/Text` and `engine/src/UI/Text`, so UTF-8 caret movement, line splitting, and multiline navigation are no longer trapped inside `XCUI Demo`. - Shared text-input controller/state now also lives under `engine/include/XCEngine/UI/Text` and `engine/src/UI/Text`, so character insertion, backspace/delete, submit, and multiline key handling no longer need to be reimplemented per host. - Shared editor collection primitive classification and metric helpers now also live under `engine/include/XCEngine/UI/Widgets` and `engine/src/UI/Widgets`, covering the current `ScrollView` / `TreeView` / `ListView` / `PropertySection` / `FieldRow` prototype taxonomy. - Shared single-selection state now also lives under `engine/include/XCEngine/UI/Widgets` and `engine/src/UI/Widgets` as `UISelectionModel`, so collection-style widget selection no longer has to stay private to `LayoutLab`. - Shared expansion state now also lives under `engine/include/XCEngine/UI/Widgets` and `engine/src/UI/Widgets` as `UIExpansionModel`, so collapsible tree/property-style widget state no longer has to stay private to `LayoutLab`. - Shared keyboard-navigation state now also lives under `engine/include/XCEngine/UI/Widgets` and `engine/src/UI/Widgets` as `UIKeyboardNavigationModel`, so list/tree/property-style widgets can share current-index, anchor, and home/end/step navigation rules instead of re-rolling them per sandbox. - Shared property-edit session state now also lives under `engine/include/XCEngine/UI/Widgets` and `engine/src/UI/Widgets` as `UIPropertyEditModel`, so editor-facing field rows can reuse begin/edit/commit/cancel transaction state instead of baking that directly into sandbox runtimes. - Core regression coverage now includes `UIContext`, layout, style, runtime screen player/system, and real document-host tests through `core_ui_tests`. Current gap: - Minimal schema self-definition support is landed, including consistency checks for enum/document-only schema metadata, but schema-driven validation for `.xcui` / `.xctheme` instances is still not implemented. - Shared widget/runtime instantiation is still thin and mostly editor-side. - Common widget primitives are still incomplete: shared text-input presentation/composition on top of the new text controller, multi-selection/focus-traversal/virtualized collection state on top of the new editor-primitive helpers, shared scroll/navigation-scope/caret-layout helpers, and promotion of the current native text-atlas path into a shared/cross-platform text subsystem. ### 2. Runtime/Game Layer - The main concrete progress here is that the retained-mode demo runtime now supports a real `TextField` input path with UTF-8 text entry and backspace handling. - The demo runtime has moved past single-line input: multiline `TextArea` behavior is now covered in the sandbox testbed. - Engine-side runtime ownership is no longer zero: `UIScreenPlayer`, `UIDocumentScreenHost`, and `UISystem` now define a shared runtime contract for loading a screen document, ticking it with input, and collecting `UI::UIDrawData`. - `UISystem` now supports layered screen composition semantics: stacked screen players, top-interactive input routing, and modal layers that block lower screens. - `UIScreenStackController::ReplaceTop` now preserves the previous top screen if the replacement screen fails to load, so runtime menu flows do not silently drop their active layer on bad assets. - `SceneRuntime` now owns a dedicated `UISceneRuntimeContext`, so game/runtime code has a first-class place to configure viewport/focus, queue `UIInputEvent`s, drive `UISystem` each `Update`, and inspect the latest UI frame result. - Runtime screen emission now also carries concrete button text in the shared document host path instead of silently dropping button labels. - `UISystemFrameResult` now also preserves viewport rect, submitted input count, frame delta, and focus state, and both `UISystem` and `UISceneRuntimeContext` now expose `ConsumeLastFrame()` so runtime/game hosts can drain the last retained frame packet without copying editor-side concepts into the shared layer. - `UIScreenPlayer` now also exposes `ConsumeLastFrame()`, so player/system/context all share the same consume-vs-borrow frame ownership semantics in the runtime layer. Current gap: - Runtime UI is now wired into `SceneRuntime`, but render submission is still limited to producing `UIDrawData`; there is no game-view/runtime presenter path that automatically draws those frames yet. - The runtime widget library is still shallow and missing the editor-grade controls that will later be shared downward. ### 3. Editor Layer - `new_editor` remains the isolated XCUI sandbox. - Native hosted preview is now working end-to-end as `RHI offscreen surface -> SRV-backed publication -> hosted surface image present` through the native shell path. - Hosted preview surface descriptors now stay on XCUI-owned value types (`UITextureHandle`, `UIPoint`, `UIRect`) instead of exposing ImGui texture/UV types through the generic preview contract. - Shared `UI::UIDrawData` image commands now carry explicit `uvMin` / `uvMax` source-rect semantics, and the native panel canvas host preserves those UVs when it records hosted surface-image preview commands. - `XCUI Demo` remains the long-lived effect and behavior testbed. - `XCUI Demo` now covers both single-line and multiline text authoring behavior, including click caret placement, delete/backspace, tab indentation, and optional text-area line numbers. - `XCUI Demo` now consumes the shared `UITextInputController` path for text editing instead of carrying a private key-handling state machine. - `LayoutLab` now includes a `ScrollView` prototype and a more editor-like three-column authored layout. - `LayoutLab` now also covers editor-facing widget prototypes: `TreeView`, `TreeItem`, `ListView`, `ListItem`, `PropertySection`, and `FieldRow`. - `LayoutLab` now consumes the shared `UIEditorCollectionPrimitives` helper layer for collection-widget tag classification, clipping flags, and default metric resolution instead of keeping that taxonomy private to the sandbox runtime. - `LayoutLab` now also consumes the shared `UISelectionModel` for click-selection persistence across collection-style widgets, and the diagnostics panel now exposes both hovered and selected element ids. - `LayoutLab` now also consumes the shared `UIExpansionModel` for tree expansion and property-section collapse, with reserved property headers, disclosure glyphs, and persisted click-toggle behavior in the sandbox runtime. - `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. - `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. - The editor bridge layer now has smoke coverage for swapchain after-UI rendering hooks and SRV-backed ImGui texture descriptor registration. - `Application` no longer owns the ImGui backend directly; window presentation now routes through `IWindowUICompositor` with an `ImGuiWindowUICompositor` implementation, which currently delegates to `IEditorHostCompositor` / `ImGuiHostCompositor`. - Hosted preview offscreen surfaces now keep compositor-returned `UITextureRegistration` / `UITextureHandle` data inside `Application` instead of storing `ImTextureID` directly. - The generic hosted-preview presenter contract no longer owns `ImGuiTransitionBackend`; the ImGui presenter now sits in a separate `ImGuiXCUIHostedPreviewPresenter` header while the native queue/surface registry remains XCUI-generic. - The generic hosted-preview frame contract no longer carries an ImGui draw-list pointer; the legacy ImGui presenter resolves its inline draw target from the active ImGui window context instead of pushing that type through the XCUI contract. - The legacy ImGui hosted-preview presenter now also accepts an explicit draw-target binding object, so presenter-side `ImGui::GetWindowDrawList()` lookup is no longer hard-coded inside the generic presenter path and can stay isolated behind the ImGui adapter layer. - `Application` shell menu toggles and global shortcuts now route through `XCUIEditorCommandRouter` instead of directly mutating shell booleans from menu callbacks, giving the editor layer a real command-routing seam. - `LayoutLab` runtime now consumes the shared `UIKeyboardNavigationModel` for abstract list/tree/property navigation actions (`previous/next/home/end/collapse/expand`), so keyboard collection traversal rules are no longer trapped in sandbox-local state. - `LayoutLab` panel input now also maps concrete arrow/home/end keys into those shared navigation actions, so keyboard traversal is reachable from the sandbox UI instead of staying runtime-only. - `XCUIDemoRuntime` now bridges pointer activation, text-edit commands, and shortcut-triggered commands through a unified command path, and `DrainPendingCommandIds()` now preserves mixed pointer/text/shortcut ordering. - `new_editor` now also has a pure `XCUIShellChromeState` model covering panel visibility, hosted-preview mode, and shell-level view toggles without depending on ImGui, `Application`, or the old editor. - `XCUIShellChromeState` hosted-preview mode naming is now backend-neutral (`HostedPresenter` / `NativeOffscreen`) instead of encoding `ImGui` into the XCUI shell model. - `new_editor` now also has a concrete `NativeWindowUICompositor` path and native-focused compositor tests, so the window compositor seam is no longer ImGui-only. - `Application` now also has a native XCUI shell path that: - becomes the default `new_editor` startup path - lays out `XCUI Demo` and `Layout Lab` as native cards directly in the swapchain window - routes shell shortcuts through the same command router without reading ImGui capture state in the default host path - drives both sandbox runtimes directly from Win32/XCUI input snapshots instead of routing through ImGui panel hosts - composes one native `UIDrawData` packet and submits it through `NativeWindowUICompositor` - `NativeXCUIPanelCanvasHost` now backs that direct shell path as an externally driven canvas/session host for native cards instead of assuming an ImGui child-window model, and it now emits native `Image` draw commands for hosted surface-image previews while preserving per-surface UVs. - `NativeWindowUICompositor` now creates and frees SRV-backed texture registrations for hosted preview surfaces, so native publication no longer depends on ImGui descriptor handles. - `Application` now runs the hosted-preview lifecycle in both legacy and native frame paths, treats published textures as XCUI-owned `UITextureHandle` state, queues native preview frames from `BuildNativeShellDrawData(...)`, and drains them during native rendering before shell chrome overlays. - `XCUIInputBridge.h` no longer includes `imgui.h`, so the public XCUI input bridge seam is now host-neutral at the header boundary. - `XCNewEditor` builds successfully to `build/new_editor/bin/Debug/XCNewEditor.exe`. Current gap: - The default shell host is now native, but the legacy ImGui shell and panel path still exists as a compatibility host and is still compiled into `new_editor`. - The default native shell path is still compiled through an `Application` translation unit that directly includes legacy ImGui host/presenter/compositor code, and `new_editor/CMakeLists.txt` still treats those legacy ImGui sources and include paths as target-global defaults. - The native shell currently proves direct runtime composition, but its shell chrome is still a bespoke `Application`-side layout rather than a fully shared XCUI-authored editor shell document. - Editor-specialized widgets are still incomplete at the shared-module level: the authored prototypes exist, but virtualization, multi-selection/focus traversal, toolbar/menu chrome, menu interaction widgets, and icon-atlas widgets are not yet extracted into reusable XCUI modules. - The default native text path now uses a standalone Windows/GDI atlas through `XCUIStandaloneTextAtlasProvider`, but that provider still lives inside `new_editor` and is not yet promoted into a shared/cross-platform text subsystem. ## Validated This Phase - `new_editor_xcui_demo_panel_tests`: `3/3` - `new_editor_xcui_demo_runtime_tests`: `12/12` - `new_editor_xcui_input_bridge_tests`: `4/4` - `new_editor_imgui_xcui_input_adapter_tests`: `2/2` - `new_editor_xcui_layout_lab_runtime_tests`: `12/12` - `new_editor_xcui_rhi_command_compiler_tests`: `7/7` - `new_editor_xcui_rhi_render_backend_tests`: `5/5` - `new_editor_xcui_standalone_text_atlas_provider_tests`: `6/6` - `new_editor_xcui_hosted_preview_presenter_tests`: `20/20` - `new_editor_imgui_window_ui_compositor_tests`: `7/7` - `new_editor_native_window_ui_compositor_tests`: `8/8` - `new_editor_xcui_editor_command_router_tests`: `5/5` - `new_editor_application_shell_command_bindings_tests`: `11/11` - `new_editor_xcui_shell_chrome_state_tests`: `11/11` - `new_editor_xcui_panel_canvas_host_tests`: `4/4` - `new_editor_imgui_xcui_panel_canvas_host_tests`: `1/1` - `new_editor_native_xcui_panel_canvas_host_tests`: `4/4` - `new_editor_xcui_layout_lab_panel_tests`: `3/3` - `XCNewEditor` Debug target builds successfully - `XCNewEditor.exe` native-default smoke run stayed alive for `5s` - `core_ui_tests`: `52 total` (`50` passed, `2` skipped because `KeyCode::Delete` currently aliases `Backspace`) - `scene_tests`: `68/68` - `core_ui_style_tests`: `5/5` - `ui_resource_tests`: `11/11` - `editor_tests` targeted bridge smoke: `3/3` ## Landed This Phase - Demo runtime `TextField` with UTF-8 text insertion, caret state, and backspace. - Demo runtime multiline `TextArea` path in the sandbox and test coverage for caret movement / multiline input. - Common-core `UITextEditing` extraction now owns UTF-8 offset stepping, codepoint counting, line splitting, and vertical caret motion with dedicated `core_ui_tests` coverage. - Common-core `UITextInputController` extraction now owns per-field text state, character insertion, enter-submit, and multiline keyboard editing behavior with dedicated `core_ui_tests` coverage. - Common-core `UIEditorCollectionPrimitives` extraction now owns the editor collection tag taxonomy and default metric resolution used by current `LayoutLab` widget prototypes, with dedicated `core_ui_tests` coverage. - Common-core `UISelectionModel` extraction now owns reusable single-selection state for collection-style widgets, with dedicated `core_ui_tests` coverage. - Common-core `UIExpansionModel` extraction now owns reusable expansion/collapse state for tree/property-style widgets, with dedicated `core_ui_tests` coverage. - Common-core `UIKeyboardNavigationModel` extraction now owns reusable current-index/anchor navigation state for collection-style widgets, with dedicated `core_ui_tests` coverage. - Common-core `UIPropertyEditModel` extraction now owns reusable property-field edit session state, including staged values and commit/cancel behavior, with dedicated `core_ui_tests` coverage. - Runtime frame ownership was tightened again: - `UIScreenPlayer::ConsumeLastFrame()` now exposes consume-style packet ownership at the player layer - `UISystemFrameResult` now carries viewport rect, submitted input event count, frame delta, and focus state - `UISystem::ConsumeLastFrame()` moves the retained packet out of the runtime layer - `UISceneRuntimeContext::ConsumeLastFrame()` forwards the same shared runtime seam upward - Demo runtime text editing was extended with: - click-to-place caret - `Delete` support - `Tab` / `Shift+Tab` indentation for text areas - optional text-area line-number gutter rendering - Demo authored resources updated to exercise the input field. - LayoutLab `ScrollView` prototype with clipping and hover rejection outside clipped content. - LayoutLab editor-widget prototypes for tree/list/property-style sections with dedicated runtime coverage. - LayoutLab click-selection now persists through the shared `UISelectionModel`, including selected-state diagnostics and reusable visual selection feedback on cards, collection rows, and field rows. - LayoutLab tree expansion and property-section collapse now persist through the shared `UIExpansionModel`, including reserved property headers, disclosure glyphs, and runtime coverage for collapsed/expanded visibility. - `XCUIDemoRuntime` now exposes `DrainPendingCommandIds()` so hosts can observe emitted runtime commands in order across pointer/text interactions without scraping UI text or draw-command payloads. - `XCUIDemoRuntime` command recording was tightened so pointer activation, text editing, and shortcut-triggered commands now share one bridge path and preserve mixed ordering in `DrainPendingCommandIds()`. - Schema document support extended with: - retained `UISchemaDefinition` data on `UIDocumentModel` - artifact schema version bump for UI documents - loader/resource accessors and memory accounting - schema compile/load/artifact regression coverage - schema consistency rules for: - `allowedValues` only on `enum` - `documentKind` / `restrictDocumentKind` only on `document` - explicit `documentKind` required when `restrictDocumentKind=true` - Engine runtime layer added: - `UIScreenPlayer` - `UIDocumentScreenHost` - `UISceneRuntimeContext` - `UIScreenStackController` - `UISystem` - layered screen composition and modal blocking semantics - Runtime/game integration scaffolding now includes reusable `HUD/menu/modal` stack helpers on top of `UISystem`. - `UIScreenStackController` replacement now rolls back safely on failure instead of popping the active top layer first. - `SceneRuntime` now exposes XCUI runtime ownership directly: - `GetUISystem()` - `GetUIScreenStackController()` - `GetLastUIFrame()` - `SetUIViewportRect(...)` - `SetUIFocused(...)` - `QueueUIInputEvent(...)` - `ClearQueuedUIInputEvents()` - automatic `UISystem` ticking during `SceneRuntime::Update(...)` - Runtime document-host draw emission now preserves button labels for shared screen rendering. - RHI image path improvements: - clipped image UV adjustment - mirrored image UV preservation - explicit image UV/source-rect submission through `UI::UIDrawData` - external texture binding reuse - per-batch scissor application - Editor bridge helpers now expose: - an `afterUiRender` swapchain callback hook in `D3D12WindowRenderer` - SRV-view based texture descriptor registration in `ImGuiBackendBridge` - smoke tests for window renderer, ImGui backend bridge, and console sink registration - `new_editor` host presentation now has a first-class compositor seam: - `IWindowUICompositor` - `ImGuiWindowUICompositor` - `IEditorHostCompositor` - `ImGuiHostCompositor` - `Application` frame/present flow routed through the compositor instead of direct `m_imguiBackend` ownership - The window-level XCUI compositor seam now also has a dedicated regression target around `ImGuiWindowUICompositor`, covering initialization, render-frame ordering, Win32 message forwarding, texture registration forwarding, and shutdown safety. - The window compositor and hosted-preview seams gained more edge-case coverage around no-UI render passes, compositor re-initialization/rebinding, partial logical-size fallback, and descriptor reuse for repeated queued-frame keys. - `new_editor` now has a dedicated `XCUIEditorCommandRouter` test target covering command registration, replacement, enable predicates, accelerator matching, and policy gates around focus/keyboard capture/text input. - `Application` now integrates `XCUIEditorCommandRouter` into the shell itself: - `View` menu items invoke routed commands instead of directly mutating shell state - shell-level shortcuts now flow from `XCUIWin32InputSource` through `XCUIInputBridge` into command matching - hosted-preview mode toggles still trigger presenter reconfiguration through the routed command bindings - `new_editor` panel canvas ownership is now being split behind `IXCUIPanelCanvasHost`, with an `ImGuiXCUIPanelCanvasHost` adapter carrying the legacy path so panel code stops directly owning `ImGui::Image` / `ImGui::InvisibleButton` / draw-list preview plumbing. - `XCUIDemoPanel` and `XCUILayoutLabPanel` no longer create an ImGui hosted-preview presenter or ImGui panel canvas host implicitly; default construction now stays on null/explicitly injected backends until the outer shell binds a concrete host adapter. - `Application` now binds `ImGuiXCUIPanelCanvasHost` explicitly at the shell composition root, so the current ImGui panel host path is visible as a host-layer decision instead of a panel-layer fallback. - `XCUIDemoPanel` and `XCUILayoutLabPanel` no longer read ImGui input directly; both now consume an injected `IXCUIInputSnapshotSource`, and the new `ImGuiXCUIInputSnapshotSource` keeps the current ImGui-backed input path isolated behind an explicit adapter. - `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 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 - `NativeXCUIPanelCanvasHost` now drives externally configured native card sessions for that shell path and records hosted surface-image preview commands with preserved UVs - new native compositor/native canvas-host tests now cover the new host seam - `XCUIInputBridge.h` no longer includes `imgui.h`, so XCUI input translation is no longer coupled to ImGui at the public header boundary. - `SceneRuntime` layered XCUI routing now has dedicated regression coverage for: - top-interactive layer input ownership - blocking/modal layer suppression of lower layers - hidden top-layer pass-through back to visible underlying layers - Shared `UITextInputController` coverage now includes more caret-boundary / modifier branches; the remaining `Delete` distinction stays blocked on `KeyCode::Delete` and `KeyCode::Backspace` still sharing the same enum value. - Window compositor texture registration now also flows back into `Application` as XCUI-owned `UITextureRegistration` / `UITextureHandle` data instead of exposing raw `ImTextureID` there. - Hosted preview contracts were tightened again: - generic preview surface metadata stays on XCUI-owned value types - `ImGuiTransitionBackend` moved behind `ImGuiXCUIHostedPreviewPresenter` - generic preview frame submission no longer carries an ImGui draw-list pointer - the ImGui presenter now resolves inline draw targets through an explicit ImGui-only binding seam - panel/runtime callers still preserve the same legacy and native-preview behavior - Native hosted-preview publication milestone is now wired through the default shell path: - `NativeWindowUICompositor` publishes hosted preview textures as SRV-backed XCUI registrations and frees them through the compositor seam - `Application::BeginHostedPreviewFrameLifecycle(...)` now resets queue/registry state for both legacy and native frame paths - hosted-preview surface readiness now keys on published texture availability instead of ImGui-style descriptor validity - `BuildNativeShellDrawData(...)` now queues native preview frames for `XCUI Demo` / `LayoutLab`, while shell cards consume the previously published hosted-surface image with warming/live placeholder text - native compositor and shell-command tests now cover the new publication / lifecycle guards - `LayoutLab` now resolves editor collection widget taxonomy and metrics through shared `UIEditorCollectionPrimitives` helpers instead of duplicating the same tag and metric rules inside the sandbox runtime. - `LayoutLab` runtime now consumes shared keyboard-navigation semantics for list/tree/property traversal, while the remaining panel-level key mapping is tracked as an editor-host integration gap rather than a runtime gap. - `LayoutLab` panel now maps concrete arrow/home/end keys into the shared navigation model, with dedicated panel-level coverage proving that the sandbox UI can actually drive the runtime navigation seam end-to-end. - `new_editor` panel/shell diagnostics improvements for hosted preview state. - XCUI asset document loading changed to prefer direct source compilation before `ResourceManager` fallback for the sandbox path, fixing the LayoutLab crash. - `UIDocumentCompiler.cpp` repaired enough to restore full local builds after the duplicated schema-helper regression. - MSVC debug build hardening was tightened again so large parallel `engine` rebuilds stop tripping over compile-PDB contention. - `XCUIStandaloneTextAtlasProvider` no longer uses ImGui font-atlas/internal baking helpers: - atlas ownership now stays inside a standalone provider implementation built on Windows/GDI glyph rasterization - default editor atlas prewarms the current supported nominal sizes, exposes both `RGBA32` and `Alpha8` atlas views, lazily inserts non-prebaked BMP glyphs, and falls back to `?` for unrasterizable codepoints - standalone atlas coverage now includes reset/rebuild, non-nominal size resolution, lazy glyph insertion/fallback behavior, and smoke use without any ImGui context - Legacy shell chrome / HUD rendering is now split out of the main `Application.cpp` translation unit: - the direct `ImGui::*` shell rendering path now lives in a dedicated legacy-only `Application` implementation file - the main `Application.cpp` native host path no longer directly includes ``, reducing default-path compile-time coupling before the larger compat-target split - `new_editor` build composition is now split into main/native and compatibility slices: - the main `XCNewEditor` target no longer compiles legacy ImGui shell/panel/backend source files directly - legacy ImGui shell/panel/backend sources plus vendored ImGui sources now build behind a dedicated compatibility static library that the main executable links ## Phase Risks Still Open - Schema instance validation is still open beyond `.xcschema` self-definition and artifact round-trip coverage. - `ScrollView` is still authored/static; no wheel-driven scrolling or virtualization yet. - The default native shell path still compiles through an `Application.cpp` unit that directly pulls in ImGui compatibility host code, so the native default path is not yet isolated at the translation-unit boundary. - `new_editor/CMakeLists.txt` still builds the legacy ImGui host/compositor/backend sources and include directories as target-global defaults instead of a compatibility-only slice. - The default native text path now owns its atlas without ImGui, but the provider is still Windows-only and remains trapped inside `new_editor` instead of a shared/cross-platform text layer. - Hosted-preview compatibility presentation still depends on an ImGui-only inline presenter path when not using the queued native surface path. - Editor widget coverage is still prototype-driven inside `LayoutLab`; it has not yet been promoted into a full reusable shared widget/runtime layer with command routing, virtualization, and property-edit transactions. ## Execution-Plan Alignment - Against `XCUI完整架构设计与执行计划.md`, current `new_editor` progress should be treated as an early `Phase 8` foothold rather than full `Milestone E` completion: - landed: `NativeWindowUICompositor`, native shell packet composition, native hosted-preview publication, XCUI-owned texture registrations, native panel surface-image presentation, standalone native text-atlas ownership inside `new_editor` - not yet landed: default-path translation-unit isolation from legacy ImGui host code, promotion of the native text-atlas path into a shared/cross-platform text subsystem, shared XCUI-authored editor shell chrome - That means the next de-ImGui push should not keep centering on hosted-preview publication; that milestone is now effectively closed for the default native shell path. - The real remaining default-path blockers are: - isolate legacy ImGui shell/compositor/presenter wiring from the default `Application` build path - stop treating ImGui include paths and backend sources as the default `new_editor` compilation surface - harden and promote `XCUIStandaloneTextAtlasProvider` / editor font bootstrap into a shared native text subsystem - move native shell chrome out of bespoke `Application` layout code and into a shared XCUI shell model or authored shell document ## Next Phase 1. Expand runtime/game-layer ownership from the current `SceneRuntime` UI context into scene-declared HUD/menu bootstrapping, draw submission, and higher-level runtime UI policies. 2. Promote the current editor-facing widget prototypes out of authored `LayoutLab` content and into reusable XCUI widget/runtime modules, then continue with toolbar/menu chrome, shell-state adoption, virtualization, and broader focus/multi-selection behavior. 3. Isolate legacy ImGui shell/compositor/presenter wiring from the default native path first, starting with `Application` translation-unit separation and a `new_editor` build split that stops treating ImGui include paths and sources as the default compilation surface. 4. Promote the current standalone native text/font path out of `new_editor`, harden its atlas invalidation/caching contract, and remove the remaining default-path ImGui text/bootstrap ownership around compatibility-only code. 5. Promote the native shell chrome and card layout out of bespoke `Application` code into a shared XCUI/editor-layer shell model or authored shell document. 6. Continue phased validation, commit, push, and plan refresh after each stable batch.