Skip to content

[UI] Add a retained-mode runtime UI with layout, input, and accessibility #144

Description

@proggeramlug

Parent: #126
Corresponds to EN-030 in docs/tickets.md

Problem

Bloom has drawing/text/input primitives but no reusable runtime UI layer. Each game must reimplement layout, focus, clipping, input routing, text editing, scaling, and widget state. Unity-like simplicity requires a supported game UI—not necessarily an editor UI.

Outcome

A retained/immediate-hybrid runtime UI module with deterministic layout, batched rendering, pointer/keyboard/gamepad navigation, text input, clipping, styling, accessibility metadata, and platform-safe scaling.

Architecture

Tree and identity

  • Stable widget IDs and parent/child tree.
  • Reconciliation/update model that works within Perry's supported TypeScript and avoids per-frame object churn.
  • Explicit retained state for focus, scroll, selection, text edit, animation, and user data.
  • Safe destruction/reparenting during event handling.

Layout

  • Minimum flex row/column, absolute overlay, padding/margin/gap, min/max/fixed/percent sizing, alignment, and scroll containers.
  • Measure/layout pass handles text and images without recursive instability.
  • DPI/safe-area/logical-pixel model is consistent across desktop, mobile, web, TV, and watch constraints.
  • Pixel snapping and fractional scale behavior are defined.

Input/events

  • Hit testing respects transform, clip, z-order, visibility, and disabled state.
  • Capture/bubble or another documented deterministic propagation model.
  • Pointer capture, hover/press/click/drag/scroll.
  • Keyboard focus, tab order, gamepad/remote directional navigation.
  • UTF-8 text entry, composition/IME where platform support exists, selection, clipboard capability, and password-safe display behavior.

Rendering

  • Batch quads/images/glyphs; nested clipping uses scissor and bounded stencil only when needed.
  • UI composition point relative to HDR/tonemap/post-FX is explicit; default HUD text remains crisp and color-correct.
  • Support atlas/font/image residency changes without stale handles.
  • Debug overlay shows bounds, clips, focus, event target, batch count, and overdraw.

Accessibility

  • Widget role, label, value, state, and action metadata in the core model.
  • Implement native accessibility bridges where feasible; capability-report unsupported targets rather than discarding metadata.

Minimum widgets

Panel/stack, image, text, button, toggle, slider, progress, text field, scroll view/list, and focus/navigation container. Complex data grids/editor widgets are out of scope.

Acceptance criteria

  • A settings/menu/HUD sample works with mouse, touch, keyboard, and gamepad/remote navigation using the same UI tree.
  • Nested layout/clip/scroll goldens pass at multiple DPIs, aspect ratios, and safe areas.
  • Focus, pointer capture, destruction-during-event, and overlapping widget ordering are unit-tested.
  • UTF-8 entry/selection works on native and web; unavailable IME/clipboard features report capability.
  • 1,000 mostly unchanged widgets allocate no or a documented minimal amount per steady-state frame and render in bounded batches.
  • UI stays crisp under 3D render scaling/TSR and is not unintentionally blurred by scene post-processing.
  • Public documentation builds a button/list/menu without requiring native FFI knowledge.

Likely files

  • new src/ui/ module
  • batched UI renderer/native hooks under native/shared/src/
  • text/input/platform bridge modules
  • examples and golden tests

Non-goals

  • Unreal/Unity editor UI.
  • HTML/CSS compatibility.
  • Shipping every native accessibility bridge in the first PR; metadata and capability contract are required.

Dependencies

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions