This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

211 lines
11 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef KEYBINDINGMAP_H
#define KEYBINDINGMAP_H
#ifdef _WIN32
#pragma once
#endif
#include "../tier1/utlvector.h"
// more flexible than default pointers to members code required for casting
// member function pointers
//#pragma pointers_to_members( full_generality, virtual_inheritance )
namespace vgui {
class Panel;
enum {
MODIFIER_SHIFT = (1 << 0),
MODIFIER_CONTROL = (1 << 1),
MODIFIER_ALT = (1 << 2),
};
//-----------------------------------------------------------------------------
// Purpose: An actual keybinding, where bindingname references a bindingmap
// mentioned below
//-----------------------------------------------------------------------------
struct BoundKey_t {
BoundKey_t();
BoundKey_t(const BoundKey_t &src);
~BoundKey_t();
BoundKey_t &operator=(const BoundKey_t &src);
bool isbuiltin; // whether this was by the #DECLARE macros or via
// code/parsing a config file
char const *bindingname; // what it's bound to
int keycode; // vgui keycode
int modifiers; // which modifiers
};
//-----------------------------------------------------------------------------
// Purpose: Single item in a message map
// Contains the information to map a string message name with
//parameters to a function call
//-----------------------------------------------------------------------------
struct KeyBindingMap_t {
KeyBindingMap_t();
KeyBindingMap_t(const KeyBindingMap_t &src);
~KeyBindingMap_t();
char const *bindingname; // for the script file
ALIGN16 MessageFunc_t func;
char const *helpstring; // e.g., #KeybindingPasteHelp
char const *docstring; // e.g., #KeybindingPasteHelp
bool passive; // dispatch command, but still chain
};
#define DECLARE_KEYBINDINGMAP(className) \
static void KB_AddToMap( \
char const *bindingname, ButtonCode_t defaultcode, \
int default_modifiers, vgui::MessageFunc_t function, \
char const *helpstring, char const *docstring, bool passive) { \
vgui::PanelKeyBindingMap *map = \
vgui::FindOrAddPanelKeyBindingMap(GetPanelClassName()); \
\
vgui::KeyBindingMap_t entry; \
entry.bindingname = bindingname; \
\
entry.func = function; \
\
entry.helpstring = helpstring; \
entry.docstring = docstring; \
\
entry.passive = passive; \
\
map->entries.AddToTail(entry); \
\
vgui::BoundKey_t kb; \
kb.isbuiltin = true; \
kb.bindingname = bindingname; \
kb.keycode = defaultcode; \
kb.modifiers = default_modifiers; \
map->defaultkeys.AddToTail(kb); \
map->boundkeys.AddToTail(kb); \
} \
\
static void KB_ChainToMap(void) { \
static bool chained = false; \
if (chained) return; \
chained = true; \
vgui::PanelKeyBindingMap *map = \
vgui::FindOrAddPanelKeyBindingMap(GetPanelClassName()); \
map->pfnClassName = &GetPanelClassName; \
if (map && GetPanelBaseClassName() && GetPanelBaseClassName()[0]) { \
map->baseMap = \
vgui::FindOrAddPanelKeyBindingMap(GetPanelBaseClassName()); \
} \
} \
\
static void KB_AddBoundKey(char const *bindingname, int keycode, \
int modifiers) { \
vgui::PanelKeyBindingMap *map = \
vgui::FindOrAddPanelKeyBindingMap(GetPanelClassName()); \
vgui::BoundKey_t kb; \
kb.isbuiltin = true; \
kb.bindingname = bindingname; \
kb.keycode = keycode; \
kb.modifiers = modifiers; \
map->defaultkeys.AddToTail(kb); \
map->boundkeys.AddToTail(kb); \
} \
\
class className##_RegisterKBMap; \
friend class className##_RegisterKBMap; \
class className##_RegisterKBMap { \
public: \
className##_RegisterKBMap() { className::KB_ChainToMap(); } \
}; \
className##_RegisterKBMap m_RegisterClassKB; \
\
virtual vgui::PanelKeyBindingMap *GetKBMap() { \
static vgui::PanelKeyBindingMap *s_pMap = \
vgui::FindOrAddPanelKeyBindingMap(GetPanelClassName()); \
return s_pMap; \
}
#define _KBMapFuncCommonFunc(name, keycode, modifiers, function, help, doc, \
passive) \
class PanelKBMapFunc_##name; \
friend class PanelKBMapFunc_##name; \
class PanelKBMapFunc_##name { \
public: \
static void InitVar() { \
static bool bAdded = false; \
if (!bAdded) { \
bAdded = true; \
KB_AddToMap(#name, keycode, modifiers, \
(vgui::MessageFunc_t)&ThisClass::function, help, \
doc, passive); \
} \
} \
PanelKBMapFunc_##name() { PanelKBMapFunc_##name::InitVar(); } \
}; \
PanelKBMapFunc_##name m_##name##_register;
#define _KBBindKeyCommon(name, keycode, modifiers, _classname) \
class PanelKBBindFunc_##_classname; \
friend class PanelKBBindFunc_##_classname; \
class PanelKBBindFunc_##_classname { \
public: \
static void InitVar() { \
static bool bAdded = false; \
if (!bAdded) { \
bAdded = true; \
KB_AddBoundKey(#name, keycode, modifiers); \
} \
} \
PanelKBBindFunc_##_classname() { \
PanelKBBindFunc_##_classname::InitVar(); \
} \
}; \
PanelKBBindFunc_##_classname m_##_classname##_bindkey_register;
#define KEYBINDING_FUNC(name, keycode, modifiers, function, help, doc) \
_KBMapFuncCommonFunc(name, keycode, modifiers, function, help, doc, \
false); \
virtual void function()
#define KEYBINDING_FUNC_NODECLARE(name, keycode, modifiers, function, help, \
doc) \
_KBMapFuncCommonFunc(name, keycode, modifiers, function, help, doc, false);
#define KEYBINDING_FUNC_PASSIVE(name, keycode, modifiers, function, help, doc) \
_KBMapFuncCommonFunc(name, keycode, modifiers, function, help, doc, true); \
virtual void function()
#define KEYBINDING_FUNC_PASSIVE_NODECLARE(name, keycode, modifiers, function, \
help, doc) \
_KBMapFuncCommonFunc(name, keycode, modifiers, function, help, doc, true);
// For definding additional (non-default) keybindings
#define KEYBINDING_ADDBINDING(name, keycode, modifiers) \
_KBBindKeyCommon(name, keycode, modifiers, name);
#define KEYBINDING_ADDBINDING_MULTIPLE(name, keycode, modifiers, _classname) \
_KBBindKeyCommon(name, keycode, modifiers, _classname);
// mapping, one per class
struct PanelKeyBindingMap {
PanelKeyBindingMap() {
baseMap = NULL;
pfnClassName = NULL;
processed = false;
}
CUtlVector<KeyBindingMap_t> entries;
bool processed;
PanelKeyBindingMap *baseMap;
CUtlVector<BoundKey_t> defaultkeys;
CUtlVector<BoundKey_t> boundkeys;
char const *(*pfnClassName)(void);
};
PanelKeyBindingMap *FindPanelKeyBindingMap(char const *className);
PanelKeyBindingMap *FindOrAddPanelKeyBindingMap(char const *className);
} // namespace vgui
#endif // KEYBINDINGMAP_H