From d5ab44b9bf86a76231be0b9b49949ccc7ecc37c3 Mon Sep 17 00:00:00 2001 From: mlangkabel Date: Wed, 5 Aug 2026 19:58:08 +0200 Subject: [PATCH] move the remaining hotkeys into the InputMapper --- src/lib/eventsystem/event/CMakeLists.txt | 5 ++ .../event/DebugDrawToggleRequestedEvent.h | 12 +++ .../event/GhostRotationRequestedEvent.h | 13 +++ .../event/ModeCancelRequestedEvent.h | 13 +++ .../event/PauseToggleRequestedEvent.h | 12 +++ .../event/SpeedStepRequestedEvent.h | 14 ++++ src/ui/GameWorldView.cpp | 81 ++++++++++--------- src/ui/GameWorldView.h | 17 ++++ src/ui/InputMapper.cpp | 31 +++++++ 9 files changed, 160 insertions(+), 38 deletions(-) create mode 100644 src/lib/eventsystem/event/DebugDrawToggleRequestedEvent.h create mode 100644 src/lib/eventsystem/event/GhostRotationRequestedEvent.h create mode 100644 src/lib/eventsystem/event/ModeCancelRequestedEvent.h create mode 100644 src/lib/eventsystem/event/PauseToggleRequestedEvent.h create mode 100644 src/lib/eventsystem/event/SpeedStepRequestedEvent.h diff --git a/src/lib/eventsystem/event/CMakeLists.txt b/src/lib/eventsystem/event/CMakeLists.txt index f82197f..b6c692b 100644 --- a/src/lib/eventsystem/event/CMakeLists.txt +++ b/src/lib/eventsystem/event/CMakeLists.txt @@ -17,6 +17,11 @@ SET(HDRS ${CMAKE_CURRENT_SOURCE_DIR}/BlueprintModeExitedEvent.h ${CMAKE_CURRENT_SOURCE_DIR}/EscapeMenuRequestedEvent.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}/BuildingTypeSelectedEvent.h ${CMAKE_CURRENT_SOURCE_DIR}/BuildHotkeyPressedEvent.h diff --git a/src/lib/eventsystem/event/DebugDrawToggleRequestedEvent.h b/src/lib/eventsystem/event/DebugDrawToggleRequestedEvent.h new file mode 100644 index 0000000..83f2e4f --- /dev/null +++ b/src/lib/eventsystem/event/DebugDrawToggleRequestedEvent.h @@ -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; +}; diff --git a/src/lib/eventsystem/event/GhostRotationRequestedEvent.h b/src/lib/eventsystem/event/GhostRotationRequestedEvent.h new file mode 100644 index 0000000..3318e84 --- /dev/null +++ b/src/lib/eventsystem/event/GhostRotationRequestedEvent.h @@ -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; +}; diff --git a/src/lib/eventsystem/event/ModeCancelRequestedEvent.h b/src/lib/eventsystem/event/ModeCancelRequestedEvent.h new file mode 100644 index 0000000..42b5530 --- /dev/null +++ b/src/lib/eventsystem/event/ModeCancelRequestedEvent.h @@ -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; +}; diff --git a/src/lib/eventsystem/event/PauseToggleRequestedEvent.h b/src/lib/eventsystem/event/PauseToggleRequestedEvent.h new file mode 100644 index 0000000..a0bc8dc --- /dev/null +++ b/src/lib/eventsystem/event/PauseToggleRequestedEvent.h @@ -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; +}; diff --git a/src/lib/eventsystem/event/SpeedStepRequestedEvent.h b/src/lib/eventsystem/event/SpeedStepRequestedEvent.h new file mode 100644 index 0000000..70f5249 --- /dev/null +++ b/src/lib/eventsystem/event/SpeedStepRequestedEvent.h @@ -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; +}; diff --git a/src/ui/GameWorldView.cpp b/src/ui/GameWorldView.cpp index 595dba2..9c272df 100644 --- a/src/ui/GameWorldView.cpp +++ b/src/ui/GameWorldView.cpp @@ -2311,46 +2311,12 @@ void GameWorldView::keyPressEvent(QKeyEvent* event) return; } - // Keys the input mapper owns are turned into actions and published from there - // (REQ-UI-HOTKEYS); this widget reacts to those as an ordinary subscriber. + // Keys are turned into actions and published by the input mapper + // (REQ-UI-HOTKEYS); this widget reacts to those as an ordinary subscriber, so + // nothing is handled here directly. 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(m_debugDraw)); - break; - default: - QOpenGLWidget::keyPressEvent(event); - break; - } + QOpenGLWidget::keyPressEvent(event); } void GameWorldView::keyReleaseEvent(QKeyEvent* event) @@ -3113,6 +3079,45 @@ void GameWorldView::handleEvent(std::shared_ptr m_panDirection = event->direction; } +void GameWorldView::handleEvent(std::shared_ptr /*event*/) +{ + if (m_gameSpeedMultiplier > 0.0) + { + m_prevNonZeroSpeed = m_gameSpeedMultiplier; + setGameSpeed(0.0); + } + else + { + setGameSpeed(m_prevNonZeroSpeed); + } +} + +void GameWorldView::handleEvent(std::shared_ptr event) +{ + stepSpeed(event->delta); +} + +void GameWorldView::handleEvent(std::shared_ptr event) +{ + rotateGhost(event->clockwise); +} + +void GameWorldView::handleEvent(std::shared_ptr /*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 /*event*/) +{ + m_debugDraw = !m_debugDraw; + EventManager::getInstance()->sendEventImmediately( + std::make_shared(m_debugDraw)); +} + void GameWorldView::handleEvent(std::shared_ptr event) { // Other widgets (MainWindow, SelectedBuildingPanel) request commands via this diff --git a/src/ui/GameWorldView.h b/src/ui/GameWorldView.h index 1aa8858..5085d09 100644 --- a/src/ui/GameWorldView.h +++ b/src/ui/GameWorldView.h @@ -31,8 +31,13 @@ #include "EventHandler.h" #include "ExitBlueprintModeRequestedEvent.h" #include "ExitBuilderModeRequestedEvent.h" +#include "DebugDrawToggleRequestedEvent.h" +#include "GhostRotationRequestedEvent.h" #include "InputMapper.h" +#include "ModeCancelRequestedEvent.h" #include "PanDirectionChangedEvent.h" +#include "PauseToggleRequestedEvent.h" +#include "SpeedStepRequestedEvent.h" #include "DebugDrawToggledEvent.h" #include "ArtifactCountChangedEvent.h" #include "BeamFiredEvent.h" @@ -83,6 +88,11 @@ class GameWorldView : public QOpenGLWidget, ExitBlueprintModeRequestedEvent, SpeedChangeRequestedEvent, PanDirectionChangedEvent, + PauseToggleRequestedEvent, + SpeedStepRequestedEvent, + GhostRotationRequestedEvent, + ModeCancelRequestedEvent, + DebugDrawToggleRequestedEvent, CommandRequestedEvent> { Q_OBJECT @@ -105,6 +115,8 @@ public: protected: void initializeGL() 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 keyReleaseEvent(QKeyEvent* event) override; // 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 event) override; void handleEvent(std::shared_ptr event) override; void handleEvent(std::shared_ptr event) override; + void handleEvent(std::shared_ptr event) override; + void handleEvent(std::shared_ptr event) override; + void handleEvent(std::shared_ptr event) override; + void handleEvent(std::shared_ptr event) override; + void handleEvent(std::shared_ptr event) override; void handleEvent(std::shared_ptr event) override; // Enqueue a sim command onto the CommandManager (the single mutation path). diff --git a/src/ui/InputMapper.cpp b/src/ui/InputMapper.cpp index 3a5f473..ba0ac2a 100644 --- a/src/ui/InputMapper.cpp +++ b/src/ui/InputMapper.cpp @@ -7,9 +7,14 @@ #include "BuildHotkeyPressedEvent.h" #include "BuildingType.h" +#include "DebugDrawToggleRequestedEvent.h" #include "EscapeMenuRequestedEvent.h" #include "EventManager.h" +#include "GhostRotationRequestedEvent.h" +#include "ModeCancelRequestedEvent.h" #include "PanDirectionChangedEvent.h" +#include "PauseToggleRequestedEvent.h" +#include "SpeedStepRequestedEvent.h" #include "TemporaryBlueprintRequestedEvent.h" #include "TracePrintRequestedEvent.h" @@ -79,6 +84,28 @@ bool InputMapper::handleKeyPress(QKeyEvent* event) m_panRightHeld = true; updatePanDirection(); return true; + case Qt::Key_Space: + EventManager::getInstance()->sendEventImmediately( + std::make_shared()); + return true; + case Qt::Key_W: + EventManager::getInstance()->sendEventImmediately( + std::make_shared(+1)); + return true; + case Qt::Key_S: + EventManager::getInstance()->sendEventImmediately( + std::make_shared(-1)); + return true; + case Qt::Key_R: + // Shift reverses the rotation direction (REQ-BLD-ROTATE). + EventManager::getInstance()->sendEventImmediately( + std::make_shared( + (event->modifiers() & Qt::ShiftModifier) != 0)); + return true; + case Qt::Key_Q: + EventManager::getInstance()->sendEventImmediately( + std::make_shared()); + 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 @@ -86,6 +113,10 @@ bool InputMapper::handleKeyPress(QKeyEvent* event) EventManager::getInstance()->sendEventImmediately( std::make_shared()); return true; + case Qt::Key_F3: + EventManager::getInstance()->sendEventImmediately( + std::make_shared()); + return true; case Qt::Key_Escape: EventManager::getInstance()->sendEventImmediately( std::make_shared());