Files
XCEngine/docs/plan/XCUI_Phase_Status_2026-04-05.md

15 KiB

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
  • 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.
  • 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, real tree/list/property widget state on top of the new editor-primitive helpers, and native image/source-rect level APIs.

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 UIInputEvents, 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.

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 working as RHI offscreen surface -> ImGui shell texture embed.
  • 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.
  • 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.
  • 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.
  • XCNewEditor builds successfully to build/new_editor/bin/Debug/XCNewEditor.exe.

Current gap:

  • The shell is still ImGui-hosted.
  • Legacy hosted preview still depends on an active ImGui window context for inline presentation.
  • Editor-specialized widgets are still incomplete at the shared-module level: the authored prototypes exist, but virtualization, multi-selection/tree expansion state, command routing, property editing models, toolbar/menu chrome, and icon-atlas widgets are not yet extracted into reusable XCUI modules.

Validated This Phase

  • new_editor_xcui_demo_runtime_tests: 7/7
  • new_editor_xcui_layout_lab_runtime_tests: 7/7
  • new_editor_xcui_rhi_command_compiler_tests: 6/6
  • new_editor_xcui_rhi_render_backend_tests: 5/5
  • new_editor_xcui_hosted_preview_presenter_tests: 12/12
  • XCNewEditor Debug target builds successfully
  • core_ui_tests: 30/30
  • scene_tests: 65/65
  • 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.
  • 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.
  • 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
    • 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
  • 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
    • panel/runtime callers still preserve the same legacy and native-preview behavior
  • 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.
  • 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.

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.
  • Image widgets still do not have source-rect/atlas-subregion level API in the high-level draw command model.
  • Editor shell still depends on ImGui as host chrome.
  • Editor widget coverage is still prototype-driven inside LayoutLab; it has not yet been promoted into a reusable shared widget/runtime layer.

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 and more native shell-owned chrome.
  3. Add a native XCUI host compositor on the existing window-level compositor seam so new_editor can present without going through ImGui-owned draw data.
  4. Reduce remaining ImGui leakage in hosted preview surfaces and panel contracts now that the compositor seam is in place.
  5. Continue phased validation, commit, push, and plan refresh after each stable batch.