Files
dota_factory/src/ui/InputMapper.h

60 lines
2.6 KiB
C++

#pragma once
#include <QString>
#include "BuildingType.h"
#include "ControlAction.h"
#include "WorldCamera.h"
class QKeyEvent;
// Turns raw key events into the game's semantic actions and publishes them
// (REQ-UI-HOTKEYS). Widgets react to the action, never to the key, so the two can
// be rebound independently later.
//
// Which key means what is not decided here: the caller hands in a ControlContext and
// ControlAction.h resolves the press against it, so this file only knows what each
// action means once resolved. That is what keeps the controls panel and the key
// handling from drifting apart -- both read the one table (REQ-UI-CONTROLS-ACCURACY).
//
// Two output shapes, chosen by the nature of the action rather than by taste:
//
// * Discrete actions — one press, one thing happens — fire an event as they
// always have.
// * Continuous actions, currently just panning, are held state. They also travel
// as events, but level-triggered ones carrying the complete current value (see
// PanDirectionChangedEvent), so a receiver never has to reconstruct state from
// edges.
//
// Holding the state here rather than in the widgets is what makes releaseAll()
// possible: one call clears every held action at once, which is how a lost key-up
// (focus moving to a modal mid-pan) stops being a stuck input.
class InputMapper
{
public:
// The build hotkey that selects the given building type, spelled for display on
// its build button's badge (REQ-UI-BUILD-COST): "1" for a plain digit, "⇧1" for
// a Shift+digit, and an empty string for a building type with no build hotkey.
// Lives here so the badge and the key handling read the same binding table.
static QString getBuildHotkeyLabel(BuildingType type);
// Both return true when the key was consumed; the caller passes anything else
// on to its base class so unrelated shortcuts keep working. `context` is the
// player's current situation, which decides what a key does (REQ-UI-CONTROLS-CONTENT).
bool handleKeyPress(QKeyEvent* event, const ControlContext& context);
bool handleKeyRelease(QKeyEvent* event, const ControlContext& context);
// Drops all held-key state, publishing the resulting change. Call when the
// receiving widget can no longer expect key-up events.
void releaseAll();
private:
// Recomputes the pan direction from the held keys and publishes it if it
// changed. Holding both keys cancels out.
void updatePanDirection();
bool m_panLeftHeld = false;
bool m_panRightHeld = false;
PanDirection m_panDirection = PanDirection::None;
};