First slice of pulling key handling out of GameWorldView. The widget no longer holds A/D key state; the mapper owns it and publishes the resulting direction as PanDirectionChangedEvent, which the view consumes like any other event. The event is level-triggered on purpose — the payload is the complete current direction, PanDirection::None included — so a receiver never reconstructs state from edges and cannot be left panning by a missing key-up. It is also the one place in the UI where caching an event payload is right rather than wrong: input has no other authority to re-read from, so the mapper is the source of truth. Both points are written down on the event, since they look like violations of the surrounding conventions otherwise. Holding the state in one object is what makes releaseAll() possible; restart uses it, and it is what a focusOutEvent will call to fix the stuck-pan bug in a follow-up. Bindings stay hard-coded. Only the ownership moved, so behaviour is unchanged, including both keys held cancelling out. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JcReq7hVk4KUPhTDKWAG7K
71 lines
1.6 KiB
C++
71 lines
1.6 KiB
C++
#include "InputMapper.h"
|
|
|
|
#include <memory>
|
|
|
|
#include <QKeyEvent>
|
|
|
|
#include "EventManager.h"
|
|
#include "PanDirectionChangedEvent.h"
|
|
|
|
bool InputMapper::handleKeyPress(QKeyEvent* event)
|
|
{
|
|
// Auto-repeat says nothing new about which keys are down, and a held action is
|
|
// already held.
|
|
if (event->isAutoRepeat()) { return false; }
|
|
|
|
switch (event->key())
|
|
{
|
|
case Qt::Key_A:
|
|
m_panLeftHeld = true;
|
|
updatePanDirection();
|
|
return true;
|
|
case Qt::Key_D:
|
|
m_panRightHeld = true;
|
|
updatePanDirection();
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool InputMapper::handleKeyRelease(QKeyEvent* event)
|
|
{
|
|
if (event->isAutoRepeat()) { return false; }
|
|
|
|
switch (event->key())
|
|
{
|
|
case Qt::Key_A:
|
|
m_panLeftHeld = false;
|
|
updatePanDirection();
|
|
return true;
|
|
case Qt::Key_D:
|
|
m_panRightHeld = false;
|
|
updatePanDirection();
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void InputMapper::releaseAll()
|
|
{
|
|
m_panLeftHeld = false;
|
|
m_panRightHeld = false;
|
|
updatePanDirection();
|
|
}
|
|
|
|
void InputMapper::updatePanDirection()
|
|
{
|
|
// Holding both keys cancels out rather than favouring one.
|
|
PanDirection direction = PanDirection::None;
|
|
if (m_panLeftHeld != m_panRightHeld)
|
|
{
|
|
direction = m_panLeftHeld ? PanDirection::Left : PanDirection::Right;
|
|
}
|
|
|
|
if (direction == m_panDirection) { return; }
|
|
m_panDirection = direction;
|
|
EventManager::getInstance()->sendEventImmediately(
|
|
std::make_shared<PanDirectionChangedEvent>(direction));
|
|
}
|