Pyrogenesis  trunk
Classes | Namespaces | Functions | Variables
Hotkey.cpp File Reference
#include "precompiled.h"
#include "Hotkey.h"
#include <boost/tokenizer.hpp>
#include "lib/external_libraries/libsdl.h"
#include "ps/CConsole.h"
#include "ps/CLogger.h"
#include "ps/CStr.h"
#include "ps/ConfigDB.h"
#include "ps/Globals.h"
#include "ps/KeyName.h"
Include dependency graph for Hotkey.cpp:

Classes

struct  anonymous_namespace{Hotkey.cpp}::PressedHotkey
 
struct  anonymous_namespace{Hotkey.cpp}::ReleasedHotkey
 

Namespaces

 anonymous_namespace{Hotkey.cpp}
 

Functions

static void LoadConfigBindings (CConfigDB &configDB)
 
void LoadHotkeys (CConfigDB &configDB)
 
void UnloadHotkeys ()
 
bool isPressed (const SKey &key)
 
InReaction HotkeyStateChange (const SDL_Event_ *ev)
 Updates g_HotkeyMap. More...
 
InReaction HotkeyInputPrepHandler (const SDL_Event_ *ev)
 Detects hotkeys that should fire. More...
 
InReaction HotkeyInputActualHandler (const SDL_Event_ *ev)
 Actually fires hotkeys. More...
 
bool EventWillFireHotkey (const SDL_Event_ *ev, const CStr &keyname)
 
void ResetActiveHotkeys ()
 Resets all currently active hotkeys (and clears in-flight hotkeys). More...
 
bool HotkeyIsPressed (const CStr &keyname)
 

Variables

static bool unified [UNIFIED_LAST - UNIFIED_SHIFT]
 
std::unordered_map< int, KeyMappingg_HotkeyMap
 
std::unordered_map< std::string, bool > anonymous_namespace{Hotkey.cpp}::g_HotkeyStatus
 
std::vector< PressedHotkey > anonymous_namespace{Hotkey.cpp}::newPressedHotkeys
 
size_t anonymous_namespace{Hotkey.cpp}::closestMapMatch = 0
 
const SDL_Event_anonymous_namespace{Hotkey.cpp}::currentEvent
 
std::vector< PressedHotkey > anonymous_namespace{Hotkey.cpp}::pressedHotkeys
 
std::vector< SDL_Scancode_anonymous_namespace{Hotkey.cpp}::activeScancodes
 

Function Documentation

◆ EventWillFireHotkey()

bool EventWillFireHotkey ( const SDL_Event_ ev,
const CStr &  keyname 
)
Returns
whether the event
Parameters
evwill fire the hotkey
keyname.

◆ HotkeyInputActualHandler()

InReaction HotkeyInputActualHandler ( const SDL_Event_ ev)

Actually fires hotkeys.

◆ HotkeyInputPrepHandler()

InReaction HotkeyInputPrepHandler ( const SDL_Event_ ev)

Detects hotkeys that should fire.

This allows using EventWillFireHotkey, (and then possibly preventing those hotkeys from firing by handling the event).

Hotkey behaviour spec (see also tests):

  • If both 'F' and 'Ctrl+F' are hotkeys, and Ctrl & F keys are down, then the more specific one only is fired ('Ctrl+F' here).
  • If 'Ctrl+F' and 'Ctrl+A' are both hotkeys, both may fire simulatenously (respectively without Ctrl).
    • However, per the first point, 'Ctrl+Shift+F' would fire alone in that situation.
  • "Press" is sent once, when the hotkey is initially triggered.
  • "Up" is sent once, when the hotkey is released or superseded by a more specific hotkey.
  • "Down" is sent repeatedly, and is also sent alongside the inital "Press".
    • As a special case (see below), "Down" is not sent alongside "PressSilent".
  • If 'Ctrl+F' is active, and 'Ctrl' is released, 'F' must become active again.
    • However, the "Press" event is not fired. Instead, "PressSilent" is.
    • Likewise, once 'F' is released, the "Up" event will be a "UpSilent". (the reason is that it is unexpected to trigger a press on key release).
  • Hotkeys are allowed to fire with extra keys (e.g. Ctrl+F+A still triggers 'Ctrl+F').
  • If 'F' and 'Ctrl+F' trigger the same hotkey, adding 'Ctrl' and releasing 'Ctrl' will trigger new 'Press' events. The "Up" event is only sent when both Ctrl & F are released.
    • This is somewhat unexpected/buggy, but it makes the implementation easier and is easily avoidable for players.
  • Wheel scrolling is 'instantaneous' behaviour and is essentially entirely separate from the above.
    • It won't untrigger other hotkeys, and fires/releases on the same 'key event'. Note that mouse buttons/wheel inputs can fire hotkeys, in combinations with keys. ...Yes, this is all surprisingly complex.

◆ HotkeyIsPressed()

bool HotkeyIsPressed ( const CStr &  keyname)
Returns
whether the hotkey is currently pressed (i.e. active).

◆ HotkeyStateChange()

InReaction HotkeyStateChange ( const SDL_Event_ ev)

Updates g_HotkeyMap.

◆ isPressed()

bool isPressed ( const SKey key)

◆ LoadConfigBindings()

static void LoadConfigBindings ( CConfigDB configDB)
static

◆ LoadHotkeys()

void LoadHotkeys ( CConfigDB configDB)

◆ ResetActiveHotkeys()

void ResetActiveHotkeys ( )

Resets all currently active hotkeys (and clears in-flight hotkeys).

You should call this when something grabs key input, e.g. an input box, as those prevent keydown/keyup messages from reaching the hotkey system, and can lead to hotkeys being stuck active. NB: active hotkeys are released immediately and "HotkeyUp" message sent.

◆ UnloadHotkeys()

void UnloadHotkeys ( )

Variable Documentation

◆ g_HotkeyMap

std::unordered_map<int, KeyMapping> g_HotkeyMap

◆ unified

bool unified[UNIFIED_LAST - UNIFIED_SHIFT]
static