The controls panel needs to say what each key does right now, and a panel that
keeps its own list of that is a list that goes stale. So the list moves into
lib/core/ControlAction.h: which actions exist, what each is bound to, and when
each does something. InputMapper stops deciding that and switches on the
resolved action instead, so the panel and the key handling cannot disagree
about what Q means -- there is only one place that says.
The table declares; it never performs. It holds no simulation access, fires no
events, and names nothing: display strings live in the ui target, which formats
the bindings this hands it, so a badge is rendered from the real binding rather
than typed beside it. What an action *does* stays exactly where it was.
ControlContext is the snapshot the rules read, which is what keeps this
testable without a world. Two of its facts come from BlueprintLibrary, which is
built after the world view and so arrives by setter; one comes from the new
hovered-transfer flag on BuildModeController, resolved once on mouse-move
through the same classifier the click and the ghost colour already use.
Behaviour is unchanged, deliberately. Ctrl still separates the chords and every
other modifier is still ignored, so Shift+A pans as before; matching modifiers
exactly would have silently swallowed those presses. Build hotkeys and F3/F4
stay outside the table -- the first are advertised on the build buttons and
already derive their badges from the handler's own table, the second are
development controls the panel must never offer.
The tests are the point of putting this in lib: every row's bindings must
resolve back to that row's action in that same context, which fails the moment
a shown row and its handler part ways.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
The cards were assembled from plain labels carrying whole blocks of text.
Replace those with the widget vocabulary the requirements describe, so a part
means the same thing wherever it appears and a card is a list of parts rather
than a string builder.
The parts, all free of Simulation and GameConfig -- they take prepared values,
and the contents work out what those are:
- StatRow, BarRow, SectionBox: label/value line, captioned fill bar, captioned
group. The bar is one part for three things: construction progress,
production progress, and HP.
- ItemChip / ItemChipRow: buffered items as icon, count and sub-line
(REQ-UI-SINGLE-SELECTION). An input chip carries its per-cycle amount, an
output chip its count against the buffer capacity. The chips are rebuilt only
when the set of items changes, so a 30 Hz refresh moves numbers rather than
widgets.
- RecipeSummaryRow: inputs, arrow, outputs, cycle time (REQ-UI-RECIPE-SUMMARY),
which is now the panel's only display of the cycle time.
- CountRow, StatusPill, EmptyNote.
Behaviour that changed with them:
- The station card shows damage, range and fire rate as the requirement asks
(REQ-UI-STATION-STATS-PANEL) rather than the combined DPS it showed before.
- A ship's behaviour moves from a stats row into the card header
(REQ-UI-SHIP-BEHAVIOR). ShipStatsPanel keeps setBehavior for the balancing
tool's inspect window, which has no header to put it in.
- A construction site's card shows a progress bar and the "no buffers until
built" note (REQ-UI-SELECTION-CARD), and now also its recipe summary, since
that is configuration and a site carries it (REQ-BLD-SITE-CONFIG). Costing a
shipyard site's schematic needed computeShipyardRequiredMaterials to take a
stored configuration as well as a live building -- one overload, so the
module sum still exists once.
ShipStatsPanel is rebuilt on StatRow, BarRow and SectionBox, so the selection
card, the layout dialog's design preview and the balancing tool read alike.
Those three parts are compiled into the balancing target, which does not link
the ui library; keeping them sim-free is what makes that possible, and the
build enforces it.
Build clean, 541 tests pass, app and balancing tool both run with no Qt
warnings. Visual check pending.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JcReq7hVk4KUPhTDKWAG7K