Pyrogenesis trunk
Hotkey.h
Go to the documentation of this file.
1/* Copyright (C) 2023 Wildfire Games.
2 * This file is part of 0 A.D.
3 *
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef INCLUDED_HOTKEY
19#define INCLUDED_HOTKEY
20
21/**
22 * @file
23 * Hotkey system.
24 *
25 * Hotkeys consist of a name (an arbitrary string), and a key mapping.
26 * The names and mappings are loaded from the config system (any
27 * config setting with the name prefix "hotkey.").
28 * When a hotkey is pressed one SDL_HOTKEYPRESS is triggered. While the key is
29 * kept down repeated SDL_HOTKEYDOWN events are triggered at an interval
30 * determined by the OS. When a hotkey is released an SDL_HOTKEYUP event is
31 * triggered. All with the hotkey name stored in ev.user.data1 as a const char*.
32 */
33
34#include "CStr.h"
35#include "lib/input.h"
36
37#include <unordered_map>
38#include <vector>
39
40// SDL_Scancode is an enum, we'll use an explicit int to avoid including SDL in this header.
41using SDL_Scancode_ = int;
42
43// 0x8000 is SDL_USEREVENT, this is static_asserted in Hotkey.cpp
44// We do this to avoid including SDL in this header.
45const uint SDL_USEREVENT_ = 0x8000;
51
52constexpr SDL_Scancode_ UNUSED_HOTKEY_CODE = 0; // == SDL_SCANCODE_UNKNOWN
53
54struct SKey
55{
56 SDL_Scancode_ code; // scancode or MOUSE_ or UNIFIED_ value
57 bool operator<(const SKey& o) const { return code < o.code; }
58 bool operator==(const SKey& o) const { return code == o.code; }
59};
60
61// Hotkey data associated with an externally-specified 'primary' keycode
63{
64 CStr name; // name of the hotkey
65 SKey primary; // the primary key
66 std::vector<SKey> required; // list of non-primary keys that must also be active
67};
68
69typedef std::vector<SHotkeyMapping> KeyMapping;
70
71// A mapping of scancodes onto the hotkeys that are associated with that key.
72// (A hotkey triggered by a combination of multiple keys will be in this map
73// multiple times.)
74extern std::unordered_map<SDL_Scancode_, KeyMapping> g_HotkeyMap;
75
76class CConfigDB;
77extern void LoadHotkeys(CConfigDB& configDB);
78extern void UnloadHotkeys();
79
80/**
81 * Updates g_HotkeyMap.
82 */
84
85/**
86 * Detects hotkeys that should fire. This allows using EventWillFireHotkey,
87 * (and then possibly preventing those hotkeys from firing by handling the event).
88 */
90/**
91 * Actually fires hotkeys.
92 */
94
95/**
96 * @return whether the event @param ev will fire the hotkey @param keyname.
97 */
98extern bool EventWillFireHotkey(const SDL_Event_* ev, const CStr& keyname);
99
100/**
101 * Resets all currently active hotkeys (and clears in-flight hotkeys).
102 * You should call this when something grabs key input, e.g. an input box,
103 * as those prevent keydown/keyup messages from reaching the hotkey system,
104 * and can lead to hotkeys being stuck active.
105 * NB: active hotkeys are released immediately and "HotkeyUp" message sent.
106 */
107extern void ResetActiveHotkeys();
108
109/**
110 * @return whether the hotkey is currently pressed (i.e. active).
111 */
112extern bool HotkeyIsPressed(const CStr& keyname);
113
114#endif // INCLUDED_HOTKEY
bool HotkeyIsPressed(const CStr &keyname)
Definition: Hotkey.cpp:478
bool EventWillFireHotkey(const SDL_Event_ *ev, const CStr &keyname)
Definition: Hotkey.cpp:453
const uint SDL_HOTKEYPRESS_SILENT
Definition: Hotkey.h:49
void LoadHotkeys(CConfigDB &configDB)
Definition: Hotkey.cpp:135
constexpr SDL_Scancode_ UNUSED_HOTKEY_CODE
Definition: Hotkey.h:52
int SDL_Scancode_
Definition: Hotkey.h:41
void UnloadHotkeys()
Definition: Hotkey.cpp:141
const uint SDL_HOTKEYUP
Definition: Hotkey.h:48
const uint SDL_HOTKEYDOWN
Definition: Hotkey.h:47
std::unordered_map< SDL_Scancode_, KeyMapping > g_HotkeyMap
Definition: Hotkey.cpp:33
InReaction HotkeyStateChange(const SDL_Event_ *ev)
Updates g_HotkeyMap.
Definition: Hotkey.cpp:164
InReaction HotkeyInputActualHandler(const SDL_Event_ *ev)
Actually fires hotkeys.
Definition: Hotkey.cpp:349
const uint SDL_HOTKEYPRESS
Definition: Hotkey.h:46
const uint SDL_USEREVENT_
Definition: Hotkey.h:45
const uint SDL_HOTKEYUP_SILENT
Definition: Hotkey.h:50
void ResetActiveHotkeys()
Resets all currently active hotkeys (and clears in-flight hotkeys).
Definition: Hotkey.cpp:463
std::vector< SHotkeyMapping > KeyMapping
Definition: Hotkey.h:69
InReaction HotkeyInputPrepHandler(const SDL_Event_ *ev)
Detects hotkeys that should fire.
Definition: Hotkey.cpp:173
Definition: ConfigDB.h:67
InReaction
Definition: input.h:35
Definition: libsdl.h:53
Definition: Hotkey.h:63
SKey primary
Definition: Hotkey.h:65
std::vector< SKey > required
Definition: Hotkey.h:66
CStr name
Definition: Hotkey.h:64
Definition: Hotkey.h:55
bool operator==(const SKey &o) const
Definition: Hotkey.h:58
SDL_Scancode_ code
Definition: Hotkey.h:56
bool operator<(const SKey &o) const
Definition: Hotkey.h:57
unsigned int uint
Definition: types.h:42