move the already-event-driven hotkeys into the InputMapper

The build hotkeys, T, Escape and F4 already did nothing but publish an event, so
they move across unchanged - GameWorldView was only ever the object that happened
to have focus.

The build-hotkey digit tables become a lookup returning an optional BuildingType,
which flattens the nested switch-inside-if and puts the "which digits are unbound"
answer in one place. The nativeVirtualKey handling is kept verbatim, including why
it is used instead of key().

F3 stays behind for now: it toggles m_debugDraw before publishing, so it needs a
request event that does not exist yet. Same for Space, W, S, R and Q.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JcReq7hVk4KUPhTDKWAG7K
This commit is contained in:
2026-08-05 13:38:48 +02:00
parent 1748be57fb
commit 2bff80f405
2 changed files with 71 additions and 52 deletions

View File

@@ -2314,44 +2314,6 @@ void GameWorldView::keyPressEvent(QKeyEvent* event)
// (REQ-UI-HOTKEYS); this widget reacts to those as an ordinary subscriber. // (REQ-UI-HOTKEYS); this widget reacts to those as an ordinary subscriber.
if (m_inputMapper.handleKeyPress(event)) { return; } if (m_inputMapper.handleKeyPress(event)) { return; }
// Number-key build-mode hotkeys (REQ-UI-HOTKEYS). nativeVirtualKey gives the
// physical digit independent of keyboard layout and Shift (with Shift held, key()
// for the number row can arrive as Key_Exclam etc.). VK_1..VK_9 = 0x31..0x39.
const quint32 virtualKey = event->nativeVirtualKey();
if (virtualKey >= 0x31 && virtualKey <= 0x39)
{
const int digit = static_cast<int>(virtualKey - 0x30);
const bool shift = (event->modifiers() & Qt::ShiftModifier) != 0;
std::optional<BuildingType> type;
if (!shift)
{
switch (digit)
{
case 1: type = BuildingType::Belt; break;
case 2: type = BuildingType::Splitter; break;
case 3: type = BuildingType::TunnelEntry; break; // unified tunnel mode (REQ-BLD-TUNNEL-MODE); 4 unused
}
}
else
{
switch (digit)
{
case 1: type = BuildingType::Miner; break;
case 2: type = BuildingType::Smelter; break;
case 3: type = BuildingType::Assembler; break;
case 4: type = BuildingType::Shipyard; break;
case 5: type = BuildingType::SalvageBay; break;
case 6: type = BuildingType::ReprocessingPlant; break;
}
}
if (type.has_value())
{
EventManager::getInstance()->sendEventImmediately(
std::make_shared<BuildHotkeyPressedEvent>(*type));
return;
}
}
switch (event->key()) switch (event->key())
{ {
case Qt::Key_Space: case Qt::Key_Space:
@@ -2379,25 +2341,11 @@ void GameWorldView::keyPressEvent(QKeyEvent* event)
else if (m_blueprintMode.has_value()) { exitBlueprintMode(); } else if (m_blueprintMode.has_value()) { exitBlueprintMode(); }
else { toggleDeconstructMode(); } else { toggleDeconstructMode(); }
break; break;
case Qt::Key_T:
// Request a temporary blueprint from the current selection (REQ-UI-BLUEPRINT-TEMP).
// The BlueprintPanel owns the selection and blueprint-capture logic; it decides
// whether anything placeable is selected and drives placement mode from there.
EventManager::getInstance()->sendEventImmediately(
std::make_shared<TemporaryBlueprintRequestedEvent>());
break;
case Qt::Key_Escape:
EventManager::getInstance()->sendEventImmediately(
std::make_shared<EscapeMenuRequestedEvent>());
break;
case Qt::Key_F3: case Qt::Key_F3:
m_debugDraw = !m_debugDraw; m_debugDraw = !m_debugDraw;
EventManager::getInstance()->sendEventImmediately( EventManager::getInstance()->sendEventImmediately(
std::make_shared<DebugDrawToggledEvent>(m_debugDraw)); std::make_shared<DebugDrawToggledEvent>(m_debugDraw));
break; break;
case Qt::Key_F4:
EventManager::getInstance()->addEvent(std::make_shared<TracePrintRequestedEvent>());
break;
default: default:
QOpenGLWidget::keyPressEvent(event); QOpenGLWidget::keyPressEvent(event);
break; break;

View File

@@ -1,11 +1,50 @@
#include "InputMapper.h" #include "InputMapper.h"
#include <memory> #include <memory>
#include <optional>
#include <QKeyEvent> #include <QKeyEvent>
#include "BuildHotkeyPressedEvent.h"
#include "BuildingType.h"
#include "EscapeMenuRequestedEvent.h"
#include "EventManager.h" #include "EventManager.h"
#include "PanDirectionChangedEvent.h" #include "PanDirectionChangedEvent.h"
#include "TemporaryBlueprintRequestedEvent.h"
#include "TracePrintRequestedEvent.h"
namespace
{
// The building type a number-key build hotkey selects, or nullopt for the digits
// that are unbound (REQ-UI-HOTKEYS). Plain digits pick the transport buildings,
// Shift+digit the production ones.
std::optional<BuildingType> buildHotkeyType(int digit, bool shiftHeld)
{
if (!shiftHeld)
{
switch (digit)
{
case 1: return BuildingType::Belt;
case 2: return BuildingType::Splitter;
case 3: return BuildingType::TunnelEntry; // unified tunnel mode (REQ-BLD-TUNNEL-MODE); 4 unused
}
return std::nullopt;
}
switch (digit)
{
case 1: return BuildingType::Miner;
case 2: return BuildingType::Smelter;
case 3: return BuildingType::Assembler;
case 4: return BuildingType::Shipyard;
case 5: return BuildingType::SalvageBay;
case 6: return BuildingType::ReprocessingPlant;
}
return std::nullopt;
}
} // namespace
bool InputMapper::handleKeyPress(QKeyEvent* event) bool InputMapper::handleKeyPress(QKeyEvent* event)
{ {
@@ -13,6 +52,23 @@ bool InputMapper::handleKeyPress(QKeyEvent* event)
// already held. // already held.
if (event->isAutoRepeat()) { return false; } if (event->isAutoRepeat()) { return false; }
// Number-key build-mode hotkeys (REQ-UI-HOTKEYS). nativeVirtualKey gives the
// physical digit independent of keyboard layout and Shift (with Shift held, key()
// for the number row can arrive as Key_Exclam etc.). VK_1..VK_9 = 0x31..0x39.
const quint32 virtualKey = event->nativeVirtualKey();
if (virtualKey >= 0x31 && virtualKey <= 0x39)
{
const std::optional<BuildingType> type = buildHotkeyType(
static_cast<int>(virtualKey - 0x30),
(event->modifiers() & Qt::ShiftModifier) != 0);
if (type.has_value())
{
EventManager::getInstance()->sendEventImmediately(
std::make_shared<BuildHotkeyPressedEvent>(*type));
return true;
}
}
switch (event->key()) switch (event->key())
{ {
case Qt::Key_A: case Qt::Key_A:
@@ -23,6 +79,21 @@ bool InputMapper::handleKeyPress(QKeyEvent* event)
m_panRightHeld = true; m_panRightHeld = true;
updatePanDirection(); updatePanDirection();
return true; return true;
case Qt::Key_T:
// Request a temporary blueprint from the current selection (REQ-UI-BLUEPRINT-TEMP).
// The BlueprintPanel owns the selection and blueprint-capture logic; it decides
// whether anything placeable is selected and drives placement mode from there.
EventManager::getInstance()->sendEventImmediately(
std::make_shared<TemporaryBlueprintRequestedEvent>());
return true;
case Qt::Key_Escape:
EventManager::getInstance()->sendEventImmediately(
std::make_shared<EscapeMenuRequestedEvent>());
return true;
case Qt::Key_F4:
EventManager::getInstance()->addEvent(
std::make_shared<TracePrintRequestedEvent>());
return true;
default: default:
return false; return false;
} }