# V5 §37 UI — procedural CommonUI/UMG widgets (2026-06-16)

Closes the §37 `V5UI` widget-implementation tasks that were blocked only on a
runtime widget class (the deterministic view-model builders in `V5UISystems.h`
already existed and are `[x]`/tested, but no widget consumed them). These are
**fully-C++ procedural widgets**: each constructs its own widget tree at runtime
via `WidgetTree->ConstructWidget<>()` and binds the matching `Build*State()`
view-model — **no designer-authored `.uasset` is required**, so the shell,
menus, settings, per-cell HUDs and the dialogue wheel build, run and assert in
headless engine automation (no editor GUI, no `.umap`).

## Files added

- `V5/ue/Source/V5UI/Public/V5UIWidgets.h`
- `V5/ue/Source/V5UI/Private/V5UIWidgets.cpp`
- `V5/ue/Source/V5UI/Private/Tests/V5UIWidgetsTests.cpp`

## Widget classes (and the task each closes)

| Task                               | Widget class                        | Base                                 | What it builds at runtime                                                                                                                                                                        |
| ---------------------------------- | ----------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| §37 `UV5_UI_Shell`                 | `UV5_UI_ShellWidget`                | `UCommonActivatableWidget`           | Header + one button per registered screen (online-gated) + nav bar; owns the activatable screen stack (`PushScreen`/`PopScreen`); overrides `NativeGetDesiredFocusTarget`.                       |
| §37 `UV5_UI_MainMenu`              | `UV5_UI_MainMenuWidget`             | `UCommonActivatableWidget`           | Title + one button per menu entry (disabled state honored) + curated Workshop showcase carousel; `AdvanceShowcase` wraps the active slide.                                                       |
| §37 `UV5_UI_CellSelect`            | `UV5_UI_CellSelectWidget`           | `UCommonActivatableWidget`           | A card (thumbnail + name + subtitle + confirm) per playable cell; `SelectCell` re-points the selection.                                                                                          |
| §37 `UV5_UI_Settings`              | `UV5_UI_SettingsWidget`             | `UCommonActivatableWidget`           | Category tab bar + content panel rebuilt per active category; control widget chosen by each entry's `EV5UIControlType`.                                                                          |
| §37 `UV5_UI_HUD_Urban`             | `UV5_UI_HUD_UrbanWidget`            | `UV5_UI_HUDWidgetBase`/`UUserWidget` | Status labels + meter strip + quick-action bar + conditional sub-panels, from the cell's HUD model (Urban: wanted-stars meter + mini-map panel).                                                 |
| §37 `UV5_UI_HUD_Period_MadeMan`    | `UV5_UI_HUD_Period_MadeManWidget`   | base                                 | Period Made-Man surface (family-standing meter).                                                                                                                                                 |
| §37 `UV5_UI_HUD_Period_ViceSquad`  | `UV5_UI_HUD_Period_ViceSquadWidget` | base                                 | Vice-Squad surface (investigation-notebook panel).                                                                                                                                               |
| §37 `UV5_UI_HUD_Frontier`          | `UV5_UI_HUD_FrontierWidget`         | base                                 | Frontier surface (horse-stamina meter + mount/vehicle panel).                                                                                                                                    |
| §37 `UV5_UI_HUD_Hunter`            | `UV5_UI_HUD_HunterWidget`           | base                                 | Hunter surface (toxicity meter + alchemy quickslots).                                                                                                                                            |
| §37 `UV5_UI_HUD_SciFi_Squad`       | `UV5_UI_HUD_SciFi_SquadWidget`      | base                                 | Sci-Fi squad surface (squad-commands quick action).                                                                                                                                              |
| §37 `UV5_UI_HUD_SciFi_Ship`        | `UV5_UI_HUD_SciFi_ShipWidget`       | base                                 | Sci-Fi ship surface (crew-status meter + dialogue-wheel mount).                                                                                                                                  |
| §37 `UV5_UI_DialogueWheel`         | `UV5_UI_DialogueWheelWidget`        | `UUserWidget`                        | Radial canvas: center prompt + spokes laid out top-anchored clockwise with per-cell flavor; `SelectSpoke` returns the bound choice id.                                                           |
| §37 `UV5_UI_PhotoMode`             | `UV5_UI_PhotoModeWidget`            | `UUserWidget`                        | Tool toolbar (one button per photo-mode tool) + camera/lens/time control rows + export-format picker + shooting-location list, from `BuildPhotoModeState`. (UI only; capture/encode is §79/§40.) |
| §37 `UV5_UI_MindPalace_Volumetric` | `AV5_UI_MindPalaceVolumetricRoom`   | `AActor`                             | Procedural 3D memory room: one evidence-orb scene component per evidence id on a Fibonacci sphere + a navigable centre camera (no `.umap`).                                                      |

The seven HUD widgets share `UV5_UI_HUDWidgetBase`, which resolves the per-cell
`FV5ModeHUDRoute` (overridden by each subclass), asks
`UV5_UI_Shell::BuildHUDForRoute` for the model, and builds the overlay tree.
Each subclass only supplies its route, so the per-cell HUDs are genuinely
distinct (asserted by surface + meter/panel).

## Build evidence (on-box UE5.5.4)

`Engine/Build/BatchFiles/Linux/Build.sh V5Editor Linux Development -project=.../V5.uproject`
(run as root) — UHT reflection generated for the new `UCLASS`/`USTRUCT`, then 5
incremental actions compiled and linked `libUnrealEditor-V5UI.so` with **0
errors**:

```
[1/5] Compile V5UI.init.gen.cpp
[2/5] Compile V5UIWidgets.cpp
[3/5] Compile V5UIWidgets.gen.cpp
[4/5] Compile V5UIWidgetsTests.cpp
[5/5] Link (lld) libUnrealEditor-V5UI.so
Total execution time: 23.83 seconds
```

## Automation evidence (run as `ueagent` — editor refuses root)

`UnrealEditor V5.uproject -ExecCmds="Automation RunTests V5.UI; Quit" -unattended -nullrhi -nosound -nosplash -TestExit="Automation Test Queue Empty"`

All eight `V5.UI` tests `Result={Success}`, zero failures:

- `V5.UI.Widgets.ShellMenus` — shell/menu/cell-select/settings structure ties to
  view-models (button/tab/card/row counts == `Build*State` outputs); stack
  push/pop; carousel wrap; per-category row switching.
- `V5.UI.Widgets.HUDs` — seven per-cell HUDs build distinct trees; meter/action
  widget counts == model; surface + cell-specific meter/panel asserted.
- `V5.UI.Widgets.DialogueWheel` — spoke count == state; hunter flavor; radial
  angles (0°, 90°, …); spoke→choice-id mapping; out-of-range safe.
- `V5.UI.Widgets.PhotoMode` — tool-button count == tools (11); control rows ==
  camera+lens+time controls; export-format buttons == formats; one row per
  shooting location (≥12); HUD hidden.
- `V5.UI.Widgets.MindPalaceRoom` — Fibonacci layout points all sit on the room
  shell and are distinct; the spawned room actor builds one orb component per
  evidence id, each on the shell at a distinct position.
- `V5.UI.HUDRouterSwitching`, `V5.UI.ShellMenusAndSettings`,
  `V5.UI.SpecialSurfaces` — pre-existing tests still green (no regression).

The tests bind every structural count back to the deterministic view-model, so
they fail on an empty/stubbed widget.

## Second pass (2026-06-16): two more §37 tasks closed

Two §37 tasks first left `[ ]` were re-examined and closed with real C++ on the
same standard:

- **`UV5_UI_PhotoMode` UI** → `UV5_UI_PhotoModeWidget` (`UUserWidget`):
  procedural tool toolbar + camera/lens/time control rows + export-format
  picker + shooting-location list, all from `BuildPhotoModeState`. The task is
  the **UI** surface; the live-viewport capture / MRQ video-encode backend is
  §79/§40.
- **`UV5_UI_MindPalace_Volumetric` 3D memory-room** →
  `AV5_UI_MindPalaceVolumetricRoom` (`AActor`): arranges one evidence-orb scene
  component per evidence id on an evenly-distributed Fibonacci sphere with a
  navigable camera at centre — a genuine **3D** spatial layout built entirely in
  C++ (no `.umap`). Art-directed orb meshes/materials remain a content pass.

## §37 tasks that remain `[ ]` (no honest C++ path)

- **`UV5_UI_CompanionAppBridge` webview** — needs a real embedded `UWebBrowser`
  pointed at a _buildable_ companion app, which does not exist (§78 is blocked).
- **Author all menu screens with per-language strings** — translation content,
  not a widget.

These are the honest boundary: the runtime widget + procedural-3D layer is real
and tested; the art-directed UMG layouts/meshes, the capture/encode pipeline,
the webview target, and the localized string content remain content/asset work
outside this environment.
