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:
@@ -31,7 +31,9 @@ struct MouseBindingEntry
|
||||
|
||||
// Resolution is first-match-wins over these tables, so an entry that must beat another
|
||||
// on the same input is listed above it -- CancelBeltLine before ExitMode on the right
|
||||
// mouse button. Everything else is disjoint by availability.
|
||||
// mouse button. Everything else is disjoint by availability: Q carries three actions
|
||||
// whose availability rules partition the situations between them, so their order here is
|
||||
// the order the reader meets them and nothing more (REQ-UI-HOTKEYS).
|
||||
const KeyBindingEntry KEY_BINDINGS[] = {
|
||||
{ControlAction::Move, Qt::Key_A, Qt::NoModifier},
|
||||
{ControlAction::Move, Qt::Key_D, Qt::NoModifier},
|
||||
@@ -48,8 +50,9 @@ const KeyBindingEntry KEY_BINDINGS[] = {
|
||||
// nothing and is what puts "R" and "Shift+R" on the row.
|
||||
{ControlAction::Rotate, Qt::Key_R, Qt::NoModifier},
|
||||
{ControlAction::Rotate, Qt::Key_R, Qt::ShiftModifier},
|
||||
{ControlAction::EnterDeconstruct, Qt::Key_Q, Qt::NoModifier},
|
||||
{ControlAction::ExitMode, Qt::Key_Q, Qt::NoModifier},
|
||||
{ControlAction::ClearSelection, Qt::Key_Q, Qt::NoModifier},
|
||||
{ControlAction::EnterDeconstruct, Qt::Key_Q, Qt::NoModifier},
|
||||
{ControlAction::OpenMenu, Qt::Key_Escape, Qt::NoModifier},
|
||||
};
|
||||
|
||||
@@ -114,9 +117,21 @@ bool isControlActionAvailable(ControlAction action, const ControlContext& contex
|
||||
case ControlAction::SelectArea:
|
||||
case ControlAction::AddToSelection:
|
||||
case ControlAction::AddAreaToSelection:
|
||||
case ControlAction::EnterDeconstruct:
|
||||
return context.mode == BuildMode::None;
|
||||
|
||||
// The three cases of Q, in the order REQ-UI-HOTKEYS evaluates them: it leaves the
|
||||
// active mode, else clears the selection, else enters deconstruct mode. A selection
|
||||
// and a build mode never coexist (REQ-UI-SELECTION-EXCLUSIVE), so the first two are
|
||||
// already disjoint; what the empty-selection condition below adds is the third step,
|
||||
// which is why entering deconstruct mode by key takes two presses while something is
|
||||
// selected -- the Deconstruct button still gets there in one click.
|
||||
case ControlAction::ClearSelection:
|
||||
return context.mode == BuildMode::None
|
||||
&& context.selection != ControlSelection::None;
|
||||
case ControlAction::EnterDeconstruct:
|
||||
return context.mode == BuildMode::None
|
||||
&& context.selection == ControlSelection::None;
|
||||
|
||||
// Both need something a blueprint can be made of; a selection of ships or debris
|
||||
// leaves them inert (REQ-UI-HOTKEYS).
|
||||
case ControlAction::CopyTemporary:
|
||||
@@ -209,13 +224,16 @@ std::vector<ControlAction> getContextActions(const ControlContext& context)
|
||||
return filterAvailable({ControlAction::ToggleDeconstruct,
|
||||
ControlAction::DeconstructArea, ControlAction::ExitMode},
|
||||
context);
|
||||
// ClearSelection is listed last for the same reason ExitMode is above: the row that
|
||||
// backs the player out of the context sits at the bottom of the context's rows
|
||||
// wherever there is one (REQ-UI-CONTROLS-CONTENT).
|
||||
case ControlContextKind::Selection:
|
||||
return filterAvailable({ControlAction::Select, ControlAction::SelectArea,
|
||||
ControlAction::AddToSelection,
|
||||
ControlAction::AddAreaToSelection,
|
||||
ControlAction::EnterDeconstruct,
|
||||
ControlAction::CopyTemporary,
|
||||
ControlAction::CreateBlueprint},
|
||||
ControlAction::CreateBlueprint,
|
||||
ControlAction::ClearSelection},
|
||||
context);
|
||||
case ControlContextKind::General:
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user