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
94 lines
4.1 KiB
C++
94 lines
4.1 KiB
C++
#include "ControlActionText.h"
|
|
|
|
#include <QCoreApplication>
|
|
#include <QKeySequence>
|
|
|
|
namespace
|
|
{
|
|
|
|
// tr() for a file of free functions. Q_DECLARE_TR_FUNCTIONS expands with access
|
|
// specifiers, so it needs a class rather than a namespace; this struct exists only to
|
|
// carry it and give the strings a single lupdate context.
|
|
struct Strings
|
|
{
|
|
Q_DECLARE_TR_FUNCTIONS(ControlActionText)
|
|
};
|
|
|
|
QString getMouseBadge(MouseBinding binding)
|
|
{
|
|
switch (binding)
|
|
{
|
|
case MouseBinding::LeftClick: return Strings::tr("LMB");
|
|
case MouseBinding::LeftDrag: return Strings::tr("LMB drag");
|
|
case MouseBinding::CtrlLeftClick: return Strings::tr("Ctrl+LMB");
|
|
case MouseBinding::CtrlLeftDrag: return Strings::tr("Ctrl+LMB drag");
|
|
case MouseBinding::RightClick: return Strings::tr("RMB");
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
} // namespace
|
|
|
|
QString getControlBindingBadge(const ControlBinding& binding)
|
|
{
|
|
if (binding.isMouse) { return getMouseBadge(binding.mouse); }
|
|
|
|
// QKeySequence spells the modifiers and the key together and localizes them, which
|
|
// is what makes this stay correct once keys are rebindable: the chip is generated
|
|
// from the binding rather than typed next to it.
|
|
return QKeySequence(binding.key | static_cast<int>(binding.modifiers))
|
|
.toString(QKeySequence::NativeText);
|
|
}
|
|
|
|
QString getControlActionLabel(ControlAction action, const ControlContext& context)
|
|
{
|
|
switch (action)
|
|
{
|
|
case ControlAction::None: return QString();
|
|
case ControlAction::Move: return Strings::tr("Move");
|
|
case ControlAction::GameSpeed: return Strings::tr("Game speed");
|
|
case ControlAction::TogglePause: return Strings::tr("Toggle pause");
|
|
case ControlAction::PasteTemporary: return Strings::tr("Paste last");
|
|
case ControlAction::OpenBlueprints: return Strings::tr("Blueprints");
|
|
case ControlAction::OpenMenu: return Strings::tr("Menu");
|
|
// A click on empty space clears and a click on an object replaces; naming only the
|
|
// first would be a half-truth once something is selected.
|
|
case ControlAction::Select:
|
|
return context.selection == ControlSelection::None
|
|
? Strings::tr("Select")
|
|
: Strings::tr("Select / clear selection");
|
|
case ControlAction::SelectArea: return Strings::tr("Select area");
|
|
case ControlAction::AddToSelection: return Strings::tr("Add / remove from selection");
|
|
case ControlAction::AddAreaToSelection: return Strings::tr("Add area to selection");
|
|
case ControlAction::EnterDeconstruct: return Strings::tr("Deconstruct mode");
|
|
case ControlAction::CopyTemporary: return Strings::tr("Copy to temporary blueprint");
|
|
case ControlAction::CreateBlueprint: return Strings::tr("Create blueprint");
|
|
case ControlAction::ClearSelection: return Strings::tr("Clear selection");
|
|
case ControlAction::Place: return Strings::tr("Place");
|
|
case ControlAction::ApplySettings: return Strings::tr("Apply settings");
|
|
case ControlAction::PlaceBeltLine: return Strings::tr("Place belt line");
|
|
case ControlAction::Rotate: return Strings::tr("Rotate");
|
|
case ControlAction::CancelBeltLine: return Strings::tr("Cancel belt line");
|
|
case ControlAction::ExitMode:
|
|
return context.mode == BuildMode::Deconstruct
|
|
? Strings::tr("Exit deconstruct mode")
|
|
: Strings::tr("Exit placement");
|
|
case ControlAction::ToggleDeconstruct: return Strings::tr("Toggle deconstruct");
|
|
case ControlAction::DeconstructArea: return Strings::tr("Deconstruct area");
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
QString getControlContextName(ControlContextKind kind)
|
|
{
|
|
switch (kind)
|
|
{
|
|
case ControlContextKind::General: return Strings::tr("GENERAL");
|
|
case ControlContextKind::Selection: return Strings::tr("SELECTION");
|
|
case ControlContextKind::Build: return Strings::tr("BUILD MODE");
|
|
case ControlContextKind::Blueprint: return Strings::tr("BLUEPRINT MODE");
|
|
case ControlContextKind::Deconstruct: return Strings::tr("DECONSTRUCT MODE");
|
|
}
|
|
return QString();
|
|
}
|