resolve keyboard shortcuts through one action table instead of a switch
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
This commit is contained in:
@@ -95,6 +95,15 @@ public:
|
||||
QPoint getBlueprintGhostTile() const;
|
||||
void setBlueprintGhostTile(QPoint tile);
|
||||
|
||||
// Whether the ghost under the cursor would hand its settings to the building
|
||||
// already there rather than place anything (REQ-UI-BLUEPRINT-TRANSFER). Classifying
|
||||
// it needs the factory state, so the caller resolves it and stores the answer here,
|
||||
// as with setGhostValidity. Kept here rather than recomputed per reader so the
|
||||
// click, the ghost's colour, and the controls panel cannot disagree about what the
|
||||
// cursor is over.
|
||||
bool isHoveredGhostTransfer() const;
|
||||
void setHoveredGhostTransfer(bool transfer);
|
||||
|
||||
// --- deconstruct mode -----------------------------------------------------
|
||||
const std::optional<BuildingId>& getDeconstructHoverBuildingId() const;
|
||||
void setDeconstructHoverBuildingId(std::optional<BuildingId> id);
|
||||
@@ -118,6 +127,7 @@ private:
|
||||
|
||||
Blueprint m_blueprint;
|
||||
QPoint m_blueprintGhostTile;
|
||||
bool m_hoveredGhostIsTransfer = false;
|
||||
|
||||
std::optional<BuildingId> m_deconstructHoverBuildingId;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user