move the remaining hotkeys into the InputMapper

This commit is contained in:
2026-08-05 19:58:08 +02:00
parent bb1ffab8fc
commit d5ab44b9bf
9 changed files with 160 additions and 38 deletions

View File

@@ -17,6 +17,11 @@ SET(HDRS
${CMAKE_CURRENT_SOURCE_DIR}/BlueprintModeExitedEvent.h ${CMAKE_CURRENT_SOURCE_DIR}/BlueprintModeExitedEvent.h
${CMAKE_CURRENT_SOURCE_DIR}/EscapeMenuRequestedEvent.h ${CMAKE_CURRENT_SOURCE_DIR}/EscapeMenuRequestedEvent.h
${CMAKE_CURRENT_SOURCE_DIR}/PanDirectionChangedEvent.h ${CMAKE_CURRENT_SOURCE_DIR}/PanDirectionChangedEvent.h
${CMAKE_CURRENT_SOURCE_DIR}/PauseToggleRequestedEvent.h
${CMAKE_CURRENT_SOURCE_DIR}/SpeedStepRequestedEvent.h
${CMAKE_CURRENT_SOURCE_DIR}/GhostRotationRequestedEvent.h
${CMAKE_CURRENT_SOURCE_DIR}/ModeCancelRequestedEvent.h
${CMAKE_CURRENT_SOURCE_DIR}/DebugDrawToggleRequestedEvent.h
${CMAKE_CURRENT_SOURCE_DIR}/DeconstructModeChangedEvent.h ${CMAKE_CURRENT_SOURCE_DIR}/DeconstructModeChangedEvent.h
${CMAKE_CURRENT_SOURCE_DIR}/BuildingTypeSelectedEvent.h ${CMAKE_CURRENT_SOURCE_DIR}/BuildingTypeSelectedEvent.h
${CMAKE_CURRENT_SOURCE_DIR}/BuildHotkeyPressedEvent.h ${CMAKE_CURRENT_SOURCE_DIR}/BuildHotkeyPressedEvent.h

View File

@@ -0,0 +1,12 @@
#pragma once
#include "Event.h"
// The player asked to toggle the debug overlays (REQ-UI-HOTKEYS). The request to
// flip the flag; DebugDrawToggledEvent is the announcement that it was flipped and
// what it now is. Splitting the two keeps the flag itself in one owner.
class DebugDrawToggleRequestedEvent : public Event
{
public:
DebugDrawToggleRequestedEvent() = default;
};

View File

@@ -0,0 +1,13 @@
#pragma once
#include "Event.h"
// The player asked to rotate the placement ghost (REQ-BLD-ROTATE, REQ-UI-HOTKEYS).
// Sent whether or not a builder or blueprint mode is actually active; deciding
// there is nothing to rotate is the receiver's job.
class GhostRotationRequestedEvent : public Event
{
public:
explicit GhostRotationRequestedEvent(bool clockwise) : clockwise(clockwise) {}
const bool clockwise;
};

View File

@@ -0,0 +1,13 @@
#pragma once
#include "Event.h"
// The player pressed the one "get me out of the current mode" key (REQ-UI-HOTKEYS).
// Intentionally says only that, not which mode to leave: which of builder,
// blueprint placement, or deconstruct is active — and that the key falls through to
// entering deconstruct mode when none of them is — is state only the receiver has.
class ModeCancelRequestedEvent : public Event
{
public:
ModeCancelRequestedEvent() = default;
};

View File

@@ -0,0 +1,12 @@
#pragma once
#include "Event.h"
// The player asked to pause or unpause (REQ-UI-HOTKEYS). Carries no speed: which
// speed to restore on unpause is the receiver's business, since it is the one that
// remembers what was running before the pause.
class PauseToggleRequestedEvent : public Event
{
public:
PauseToggleRequestedEvent() = default;
};

View File

@@ -0,0 +1,14 @@
#pragma once
#include "Event.h"
// The player asked to step the game speed one notch (REQ-UI-HOTKEYS): +1 faster,
// -1 slower. A relative step rather than a target speed, because the ladder of
// available speeds belongs to the receiver — contrast SpeedChangeRequestedEvent,
// which names an absolute multiplier and is what the speed buttons send.
class SpeedStepRequestedEvent : public Event
{
public:
explicit SpeedStepRequestedEvent(int delta) : delta(delta) {}
const int delta;
};

View File

@@ -2311,46 +2311,12 @@ void GameWorldView::keyPressEvent(QKeyEvent* event)
return; return;
} }
// Keys the input mapper owns are turned into actions and published from there // Keys are turned into actions and published by the input mapper
// (REQ-UI-HOTKEYS); this widget reacts to those as an ordinary subscriber. // (REQ-UI-HOTKEYS); this widget reacts to those as an ordinary subscriber, so
// nothing is handled here directly.
if (m_inputMapper.handleKeyPress(event)) { return; } if (m_inputMapper.handleKeyPress(event)) { return; }
switch (event->key())
{
case Qt::Key_Space:
if (m_gameSpeedMultiplier > 0.0)
{
m_prevNonZeroSpeed = m_gameSpeedMultiplier;
setGameSpeed(0.0);
}
else
{
setGameSpeed(m_prevNonZeroSpeed);
}
break;
case Qt::Key_W:
stepSpeed(+1);
break;
case Qt::Key_S:
stepSpeed(-1);
break;
case Qt::Key_R:
rotateGhost(event->modifiers() & Qt::ShiftModifier);
break;
case Qt::Key_Q:
if (m_builderType.has_value()) { exitBuilderMode(); }
else if (m_blueprintMode.has_value()) { exitBlueprintMode(); }
else { toggleDeconstructMode(); }
break;
case Qt::Key_F3:
m_debugDraw = !m_debugDraw;
EventManager::getInstance()->sendEventImmediately(
std::make_shared<DebugDrawToggledEvent>(m_debugDraw));
break;
default:
QOpenGLWidget::keyPressEvent(event); QOpenGLWidget::keyPressEvent(event);
break;
}
} }
void GameWorldView::keyReleaseEvent(QKeyEvent* event) void GameWorldView::keyReleaseEvent(QKeyEvent* event)
@@ -3113,6 +3079,45 @@ void GameWorldView::handleEvent(std::shared_ptr<const PanDirectionChangedEvent>
m_panDirection = event->direction; m_panDirection = event->direction;
} }
void GameWorldView::handleEvent(std::shared_ptr<const PauseToggleRequestedEvent> /*event*/)
{
if (m_gameSpeedMultiplier > 0.0)
{
m_prevNonZeroSpeed = m_gameSpeedMultiplier;
setGameSpeed(0.0);
}
else
{
setGameSpeed(m_prevNonZeroSpeed);
}
}
void GameWorldView::handleEvent(std::shared_ptr<const SpeedStepRequestedEvent> event)
{
stepSpeed(event->delta);
}
void GameWorldView::handleEvent(std::shared_ptr<const GhostRotationRequestedEvent> event)
{
rotateGhost(event->clockwise);
}
void GameWorldView::handleEvent(std::shared_ptr<const ModeCancelRequestedEvent> /*event*/)
{
// One key backs out of whichever mode is active, and enters deconstruct mode
// when none is (REQ-UI-HOTKEYS).
if (m_builderType.has_value()) { exitBuilderMode(); }
else if (m_blueprintMode.has_value()) { exitBlueprintMode(); }
else { toggleDeconstructMode(); }
}
void GameWorldView::handleEvent(std::shared_ptr<const DebugDrawToggleRequestedEvent> /*event*/)
{
m_debugDraw = !m_debugDraw;
EventManager::getInstance()->sendEventImmediately(
std::make_shared<DebugDrawToggledEvent>(m_debugDraw));
}
void GameWorldView::handleEvent(std::shared_ptr<const CommandRequestedEvent> event) void GameWorldView::handleEvent(std::shared_ptr<const CommandRequestedEvent> event)
{ {
// Other widgets (MainWindow, SelectedBuildingPanel) request commands via this // Other widgets (MainWindow, SelectedBuildingPanel) request commands via this

View File

@@ -31,8 +31,13 @@
#include "EventHandler.h" #include "EventHandler.h"
#include "ExitBlueprintModeRequestedEvent.h" #include "ExitBlueprintModeRequestedEvent.h"
#include "ExitBuilderModeRequestedEvent.h" #include "ExitBuilderModeRequestedEvent.h"
#include "DebugDrawToggleRequestedEvent.h"
#include "GhostRotationRequestedEvent.h"
#include "InputMapper.h" #include "InputMapper.h"
#include "ModeCancelRequestedEvent.h"
#include "PanDirectionChangedEvent.h" #include "PanDirectionChangedEvent.h"
#include "PauseToggleRequestedEvent.h"
#include "SpeedStepRequestedEvent.h"
#include "DebugDrawToggledEvent.h" #include "DebugDrawToggledEvent.h"
#include "ArtifactCountChangedEvent.h" #include "ArtifactCountChangedEvent.h"
#include "BeamFiredEvent.h" #include "BeamFiredEvent.h"
@@ -83,6 +88,11 @@ class GameWorldView : public QOpenGLWidget,
ExitBlueprintModeRequestedEvent, ExitBlueprintModeRequestedEvent,
SpeedChangeRequestedEvent, SpeedChangeRequestedEvent,
PanDirectionChangedEvent, PanDirectionChangedEvent,
PauseToggleRequestedEvent,
SpeedStepRequestedEvent,
GhostRotationRequestedEvent,
ModeCancelRequestedEvent,
DebugDrawToggleRequestedEvent,
CommandRequestedEvent> CommandRequestedEvent>
{ {
Q_OBJECT Q_OBJECT
@@ -105,6 +115,8 @@ public:
protected: protected:
void initializeGL() override; void initializeGL() override;
void paintGL() override; void paintGL() override;
// Only forwards to the input mapper; every key this widget acts on reaches it
// as a published action instead (REQ-UI-HOTKEYS).
void keyPressEvent(QKeyEvent* event) override; void keyPressEvent(QKeyEvent* event) override;
void keyReleaseEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override;
// Key-up never arrives for a key that was still held when focus moved away — // Key-up never arrives for a key that was still held when focus moved away —
@@ -127,6 +139,11 @@ private:
void handleEvent(std::shared_ptr<const ExitBlueprintModeRequestedEvent> event) override; void handleEvent(std::shared_ptr<const ExitBlueprintModeRequestedEvent> event) override;
void handleEvent(std::shared_ptr<const SpeedChangeRequestedEvent> event) override; void handleEvent(std::shared_ptr<const SpeedChangeRequestedEvent> event) override;
void handleEvent(std::shared_ptr<const PanDirectionChangedEvent> event) override; void handleEvent(std::shared_ptr<const PanDirectionChangedEvent> event) override;
void handleEvent(std::shared_ptr<const PauseToggleRequestedEvent> event) override;
void handleEvent(std::shared_ptr<const SpeedStepRequestedEvent> event) override;
void handleEvent(std::shared_ptr<const GhostRotationRequestedEvent> event) override;
void handleEvent(std::shared_ptr<const ModeCancelRequestedEvent> event) override;
void handleEvent(std::shared_ptr<const DebugDrawToggleRequestedEvent> event) override;
void handleEvent(std::shared_ptr<const CommandRequestedEvent> event) override; void handleEvent(std::shared_ptr<const CommandRequestedEvent> event) override;
// Enqueue a sim command onto the CommandManager (the single mutation path). // Enqueue a sim command onto the CommandManager (the single mutation path).

View File

@@ -7,9 +7,14 @@
#include "BuildHotkeyPressedEvent.h" #include "BuildHotkeyPressedEvent.h"
#include "BuildingType.h" #include "BuildingType.h"
#include "DebugDrawToggleRequestedEvent.h"
#include "EscapeMenuRequestedEvent.h" #include "EscapeMenuRequestedEvent.h"
#include "EventManager.h" #include "EventManager.h"
#include "GhostRotationRequestedEvent.h"
#include "ModeCancelRequestedEvent.h"
#include "PanDirectionChangedEvent.h" #include "PanDirectionChangedEvent.h"
#include "PauseToggleRequestedEvent.h"
#include "SpeedStepRequestedEvent.h"
#include "TemporaryBlueprintRequestedEvent.h" #include "TemporaryBlueprintRequestedEvent.h"
#include "TracePrintRequestedEvent.h" #include "TracePrintRequestedEvent.h"
@@ -79,6 +84,28 @@ bool InputMapper::handleKeyPress(QKeyEvent* event)
m_panRightHeld = true; m_panRightHeld = true;
updatePanDirection(); updatePanDirection();
return true; return true;
case Qt::Key_Space:
EventManager::getInstance()->sendEventImmediately(
std::make_shared<PauseToggleRequestedEvent>());
return true;
case Qt::Key_W:
EventManager::getInstance()->sendEventImmediately(
std::make_shared<SpeedStepRequestedEvent>(+1));
return true;
case Qt::Key_S:
EventManager::getInstance()->sendEventImmediately(
std::make_shared<SpeedStepRequestedEvent>(-1));
return true;
case Qt::Key_R:
// Shift reverses the rotation direction (REQ-BLD-ROTATE).
EventManager::getInstance()->sendEventImmediately(
std::make_shared<GhostRotationRequestedEvent>(
(event->modifiers() & Qt::ShiftModifier) != 0));
return true;
case Qt::Key_Q:
EventManager::getInstance()->sendEventImmediately(
std::make_shared<ModeCancelRequestedEvent>());
return true;
case Qt::Key_T: case Qt::Key_T:
// Request a temporary blueprint from the current selection (REQ-UI-BLUEPRINT-TEMP). // Request a temporary blueprint from the current selection (REQ-UI-BLUEPRINT-TEMP).
// The BlueprintPanel owns the selection and blueprint-capture logic; it decides // The BlueprintPanel owns the selection and blueprint-capture logic; it decides
@@ -86,6 +113,10 @@ bool InputMapper::handleKeyPress(QKeyEvent* event)
EventManager::getInstance()->sendEventImmediately( EventManager::getInstance()->sendEventImmediately(
std::make_shared<TemporaryBlueprintRequestedEvent>()); std::make_shared<TemporaryBlueprintRequestedEvent>());
return true; return true;
case Qt::Key_F3:
EventManager::getInstance()->sendEventImmediately(
std::make_shared<DebugDrawToggleRequestedEvent>());
return true;
case Qt::Key_Escape: case Qt::Key_Escape:
EventManager::getInstance()->sendEventImmediately( EventManager::getInstance()->sendEventImmediately(
std::make_shared<EscapeMenuRequestedEvent>()); std::make_shared<EscapeMenuRequestedEvent>());