clear the selection with Q, and drop it on entering a build mode
Implements the requirements committed in 731b887.
Q becomes a three-way branch in the action table, which is the layer that owns
what an input does: ExitMode while a mode is active, the new ClearSelection
while something is selected, EnterDeconstruct otherwise. The three partition
the situations between them, so resolution stays first-match-wins over
available actions and the handler never re-derives the precedence -- which is
why ClearSelection gets its own event rather than joining ModeCancel on Q.
GameWorldView clears the selection at each of the three events that enter a
mode; those are the only ways in, whichever button or key the player used. No
clear is needed where ModeCancel falls through to deconstruct mode: Q resolves
to ClearSelection while anything is selected, so there is nothing left by then.
The Selection context's Q row reads "Clear selection", sits last as the row
that hands the context back does everywhere, and carries the exit badge
styling -- one key that backs out should look the same wherever it appears.
Requirements follow that last point in REQ-UI-CONTROLS-CARD and
REQ-UI-CONTROLS-CONTENT.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ne3mejABZoLWKLh8fgpM3x
This commit is contained in:
@@ -198,19 +198,29 @@ TEST_CASE("ControlAction: contexts are named by mode and selection", "[controls]
|
||||
== ControlContextKind::Deconstruct);
|
||||
}
|
||||
|
||||
TEST_CASE("ControlAction: Q enters deconstruct mode, or leaves the active one",
|
||||
// The three cases of Q, in the order REQ-UI-HOTKEYS evaluates them.
|
||||
TEST_CASE("ControlAction: Q leaves the active mode, else clears, else deconstructs",
|
||||
"[controls]")
|
||||
{
|
||||
REQUIRE(resolveKeyAction(Qt::Key_Q, Qt::NoModifier, generalContext())
|
||||
== ControlAction::EnterDeconstruct);
|
||||
REQUIRE(resolveKeyAction(Qt::Key_Q, Qt::NoModifier, selectionContext())
|
||||
== ControlAction::EnterDeconstruct);
|
||||
REQUIRE(resolveKeyAction(Qt::Key_Q, Qt::NoModifier, builderContext(BuildingType::Belt))
|
||||
== ControlAction::ExitMode);
|
||||
REQUIRE(resolveKeyAction(Qt::Key_Q, Qt::NoModifier, blueprintContext())
|
||||
== ControlAction::ExitMode);
|
||||
REQUIRE(resolveKeyAction(Qt::Key_Q, Qt::NoModifier, deconstructContext())
|
||||
== ControlAction::ExitMode);
|
||||
|
||||
// Whatever the selection holds: clearing it is not a buildings-only action.
|
||||
ControlContext fieldSelection = selectionContext(false);
|
||||
fieldSelection.selection = ControlSelection::FieldObjects;
|
||||
REQUIRE(resolveKeyAction(Qt::Key_Q, Qt::NoModifier, selectionContext())
|
||||
== ControlAction::ClearSelection);
|
||||
REQUIRE(resolveKeyAction(Qt::Key_Q, Qt::NoModifier, fieldSelection)
|
||||
== ControlAction::ClearSelection);
|
||||
|
||||
// Only with nothing to clear and no mode to leave does Q enter deconstruct mode --
|
||||
// which is what makes it two presses from a selection.
|
||||
REQUIRE(resolveKeyAction(Qt::Key_Q, Qt::NoModifier, generalContext())
|
||||
== ControlAction::EnterDeconstruct);
|
||||
}
|
||||
|
||||
TEST_CASE("ControlAction: Ctrl distinguishes the chords, other modifiers do not",
|
||||
@@ -320,9 +330,14 @@ TEST_CASE("ControlAction: selection rows appear only once something is selected"
|
||||
REQUIRE(contains(general, ControlAction::EnterDeconstruct));
|
||||
REQUIRE_FALSE(contains(general, ControlAction::AddToSelection));
|
||||
REQUIRE_FALSE(contains(general, ControlAction::CreateBlueprint));
|
||||
REQUIRE_FALSE(contains(general, ControlAction::ClearSelection));
|
||||
|
||||
REQUIRE(contains(selection, ControlAction::AddToSelection));
|
||||
REQUIRE(contains(selection, ControlAction::AddAreaToSelection));
|
||||
REQUIRE(contains(selection, ControlAction::CreateBlueprint));
|
||||
REQUIRE(contains(selection, ControlAction::EnterDeconstruct));
|
||||
// Q clears here instead of entering deconstruct mode, and its row sits last, as the
|
||||
// row that hands the context back does in every context (REQ-UI-CONTROLS-CONTENT).
|
||||
REQUIRE(contains(selection, ControlAction::ClearSelection));
|
||||
REQUIRE_FALSE(contains(selection, ControlAction::EnterDeconstruct));
|
||||
REQUIRE(selection.back() == ControlAction::ClearSelection);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user