acdream/tests
Erik 01b98ca30c feat(plugin-ui): Slice A - movable, collapsible plugin shelf
Owner request (docs/plans/2026-09-06-plugin-shelf-and-dat-icons.md, Slice A):
the plugin shelf was pinned to the right screen edge every tick, had no drag
or hide affordance, and never persisted position. It is now a registered
retained window ("plugin-shelf") that gets drag, the UI lock, and
RetailWindowLayoutPersistence position/visibility/collapsed persistence for
free, the same way every other retained window does.

Design decisions where the plan left room:

- Grip + collapse toggle are drawn, not child elements. A real child for the
  toggle would have to live outside any WindowMoveHandle grip subtree (nesting
  it inside lets UiRoot's drag-handle promotion swallow the press before the
  button ever sees a click - `handleWindow is not null` outranks
  `HandlesClick` in UiRoot.OnMouseDown), and a grip element as a plain sibling
  changes UiElement.Children's shape, which the pre-existing single-button
  shelf tests assert directly (`Assert.Single(shelf.Children)`). Keeping the
  whole shelf Draggable=true and excluding just the toggle's pixel rect from
  an overridden HandlesClick (computed live from UiRoot.MouseX/MouseY, the
  only call site) gets grip-drags/buttons-and-toggle-don't without adding any
  child or touching the existing tests' shape assumptions.
- Availability (has plugin windows) vs the user's requested-visible intent
  are split the same way PluginWindowVisibilityController already splits it
  for individual plugin windows, but applied SYNCHRONOUSLY (not via
  VisibleSource) so Visible updates immediately after Add()/unregister with
  no dependency on a Tick ever running - required to keep the pre-Slice-A
  unregistered-shelf test (ShelfAndMinimizeButtonsHideAndRestoreWithoutUnregisteringWindow)
  green, since it never calls root.Tick().
- "The shelf was moved" (drag or a differing restored layout) is tracked via
  the shelf's own RetailWindowHandle.Moved event, captured through
  WindowManager.WindowRegistered the moment MountPlugins registers it - so
  unregistered/legacy use (the two other pre-existing tests) never sets this
  and behaves exactly as before.
- The one-time right-edge dock (no saved layout) fires on the first OnTick
  with a real parent width, replacing the old per-tick pin; Reflow's
  anchor math then preserves the top-right corner while still docked or the
  top-left corner once positioned, on any width change (entry add/remove,
  collapse, or a parent-height-driven column rewrap).

Caption finding: the Configure Keyboard row for InputAction.TogglePluginManager
resolves its label live from the installed DAT's action-map string table
(KeyboardConfigController.BuildActionRow, RetailActionMapRow.LabelHash) -
there is no "Plugin Manager" string literal anywhere in our code to rename to
"Plugin Shelf". The row keeps showing retail's own authored name; only the
acdream-side action semantics changed.

Tests added to PluginSidePanelTests.cs (all 7 fail to even compile against
the pre-Slice-A PluginSidePanel, verified by temporarily reverting the source
files and re-running): default right-edge dock; top-right corner preserved
across a Reflow-driven width change while docked; grip drag moves the shelf
and top-left survives the next reflow once positioned; drag refused under
UiLocked; collapse via the real toggle click round-trips through
CaptureWindowState/RestoreWindowState; Show/Hide toggle sequence and a hidden
shelf staying hidden when a new plugin window registers; a full
RetailWindowLayoutPersistence round trip of X/Y/Visible/Collapsed onto a
fresh shelf instance. All 3 pre-existing tests remain green unmodified.

Verified: dotnet build src/AcDream.App (Release) green; the full App test
suite passes 7294/97 skipped/36 pre-existing unrelated failures (identical
failure set confirmed present on HEAD before this change - installed-DAT
live-mount probes, Linux-only pacing/credential tests, and known alpha-flush
COUNT-only conformance divergences, none touching plugin UI).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 13:11:43 +02:00
..
AcDream.App.Tests feat(plugin-ui): Slice A - movable, collapsible plugin shelf 2026-09-06 13:11:43 +02:00
AcDream.Bake.Tests Optimize prepared asset package v2 2026-08-27 20:09:09 +02:00
AcDream.Cli.Tests build: make release restore reproducible 2026-08-18 10:29:00 +02:00
AcDream.Content.Tests fix(rendering): carry retail SetSurface state to detail draws 2026-09-05 02:03:13 +02:00
AcDream.Core.Net.Tests fix: complete retail parity stability pass 2026-08-28 20:01:39 +02:00
AcDream.Core.Tests fix(physics): port ordered part-array building transit 2026-09-05 20:28:52 +02:00
AcDream.Core.Tests.Fixtures.HelloPlugin feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
AcDream.Headless.Tests fix(overhaul): integrate reviewed debt-free retirement #475 2026-09-05 11:05:07 +02:00
AcDream.Launcher.Core.Tests fix(rendering): carry retail SetSurface state to detail draws 2026-09-05 02:03:13 +02:00
AcDream.Launcher.Core.Tests.Fixtures.ConsolelessSupervisorParent build: make release restore reproducible 2026-08-18 10:29:00 +02:00
AcDream.Launcher.Core.Tests.Fixtures.ConsoleSignalChild build: make release restore reproducible 2026-08-18 10:29:00 +02:00
AcDream.Launcher.Core.Tests.Fixtures.InstallLeaseHolder feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
AcDream.Launcher.Tests Optimize prepared asset package v2 2026-08-27 20:09:09 +02:00
AcDream.Platform.Tests feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
AcDream.Plugin.Tests.Fixtures.HostPlugin feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
AcDream.Plugin.Tests.Fixtures.InvalidRenderPackInternal feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
AcDream.Plugin.Tests.Fixtures.InvalidRenderPackMultiple feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
AcDream.Plugins.MossTank.Tests feat(mosstank): add VTank-style automation PoC 2026-08-27 18:57:21 +02:00
AcDream.RenderPackValidator.Tests feat(render): shader ABI v2 - AtmosphericFrame gains clock/wind blocks; caster pass binds it (Campaign VM VM6a) 2026-08-23 00:30:02 +02:00
AcDream.Runtime.Tests fix(overhaul): integrate reviewed debt-free retirement #475 2026-09-05 11:05:07 +02:00
AcDream.UI.Abstractions.Tests fix: complete retail parity stability pass 2026-08-28 20:01:39 +02:00
Fixtures/campaign-la feat(plugins): enforce apiVersion; launcher plugins default ON with "none" opt-out 2026-08-20 21:28:04 +02:00
Directory.Build.props fix: retail text and golden-string tests must not follow the machine's locale 2026-08-19 19:56:09 +02:00
TestCultureInitializer.cs fix: retail text and golden-string tests must not follow the machine's locale 2026-08-19 19:56:09 +02:00