move pan input into an InputMapper
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
This commit is contained in:
@@ -16,6 +16,7 @@ SET(HDRS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/BuilderModeExitedEvent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/BlueprintModeExitedEvent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/EscapeMenuRequestedEvent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PanDirectionChangedEvent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/DeconstructModeChangedEvent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/BuildingTypeSelectedEvent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/BuildHotkeyPressedEvent.h
|
||||
|
||||
22
src/lib/eventsystem/event/PanDirectionChangedEvent.h
Normal file
22
src/lib/eventsystem/event/PanDirectionChangedEvent.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "Event.h"
|
||||
#include "WorldCamera.h"
|
||||
|
||||
// The direction the player is currently panning the view has changed
|
||||
// (REQ-UI-SCROLL). Deliberately level-triggered: the payload is the complete
|
||||
// current direction, including PanDirection::None when panning stops, rather than
|
||||
// separate started/stopped events. A receiver that only ever saw edges would have
|
||||
// to reconstruct the state and would be left panning forever if one edge went
|
||||
// missing — which is exactly what happens when the widget loses focus mid-pan.
|
||||
//
|
||||
// Unlike the state-change events elsewhere in the UI, the receiver does cache this
|
||||
// payload instead of re-reading the value from somewhere authoritative. That is
|
||||
// correct here: input has no other source of truth to re-read from, so the
|
||||
// publisher (InputMapper) is the authority and the payload is the value.
|
||||
class PanDirectionChangedEvent : public Event
|
||||
{
|
||||
public:
|
||||
explicit PanDirectionChangedEvent(PanDirection direction) : direction(direction) {}
|
||||
const PanDirection direction;
|
||||
};
|
||||
Reference in New Issue
Block a user