The Battle for Wesnoth  1.19.1+dev
hotkey_command.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2024
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include "global.hpp"
19 #include "tooltips.hpp"
20 #include "tstring.hpp"
21 
22 #include <bitset>
23 #include <functional>
24 #include <map>
25 
26 class config;
27 
28 namespace hotkey {
29 
30 /**
31  * Available hotkey scopes. The scope is used to allow command from
32  * non-overlapping areas of the game share the same key
33  */
34 enum scope {
39 };
40 
41 // For some reason std::bitset::operator| is not constexpr, so we'll construct the bitset with these values
42 // FIXME: unify these with the enum above. Right now these are the proper bitmasks to initialize a bitset,
43 // while the values above are used as indices to access the bits of the bitset.
44 constexpr uint32_t scope_game = 1 << SCOPE_GAME;
45 constexpr uint32_t scope_editor = 1 << SCOPE_EDITOR;
46 constexpr uint32_t scope_main = 1 << SCOPE_MAIN_MENU;
47 
67 
68  // Replay
74 
75  // Controls
78 
79  // Camera movement
81 
82  // Dialog control
84 
85  // Whiteboard commands
91 
92  // Misc.
99 
100  // Minimap
103 
104  /* Gui2 specific hotkeys. */
117 
119 
120  /* Editor commands */
124 
125  // Palette
128 
134 
135  // Unit
138 
139  // Brushes
142 
143  // Tools
148 
149  // Select
151  // Clipboard
155  // Selection
161 
162  // Map
171 
172  // Transitions
175 
176  // Refresh
179 
180  // Draw
182 
183  // Side
187 
188  // Area
193 
194  // Addons
199 
200  // Scenario
204 
205  /* This item must stay at the end since it is used as terminator for iterating. */
207 };
208 
223  HKCAT_PLACEHOLDER // Keep this one last
224 };
225 
226 /** Gets the display name for a given hotkey category. */
228 
229 typedef std::bitset<SCOPE_COUNT> hk_scopes;
230 
231 /**
232  * hotkey_command uses t_string which might cause bugs when used at program startup,
233  * so use this for the master hotkey list (and only there).
234  */
235 struct hotkey_command_temp;
236 
237 /**
238  * Stores all information related to functions that can be bound to hotkeys.
239  * this is currently a semi struct: it haves a constructor, but only const-public members.
240  */
242 {
243  hotkey_command() = delete;
244 
245  /** Constructs a new command from a temporary static hotkey object. */
246  hotkey_command(const hotkey_command_temp& temp_command);
247 
248  /** @todo: see if we can remove this with c++20. Aggregate initialization with try_emplace?*/
249  hotkey_command(HOTKEY_COMMAND cmd, const std::string& id, const t_string& desc, bool hidden, bool toggle, hk_scopes scope, HOTKEY_CATEGORY category, const t_string& tooltip);
250 
251  hotkey_command(const hotkey_command&) = default;
253 
254  /** The command associated with this hotkey. Does not need to be unique. */
256 
257  /** The unique ID. */
258  std::string id;
259 
260  // since the wml_menu hotkey_command s can have different textdomains we need t_string now.
262 
263  /** If hidden then don't show the command in the hotkey preferences. */
264  bool hidden;
265 
266  /**
267  * Toggle hotkeys have some restrictions on what can be bound to them.
268  * They require a binding that has two states, "pressed" and "released"
269  */
270  bool toggle;
271 
272  /** The visibility scope of the command. */
274 
275  /** The category of the command. */
277 
279 
280  /** checks weather this is the null hotkey_command */
281  bool null() const;
282 
283  /** returns the command that is treated as null */
284  static const hotkey_command& null_command();
285 
286  /**
287  * the execute_command argument was changed from HOTKEY_COMMAND to hotkey_command,
288  * to be able to call it with HOTKEY_COMMAND, this function was created
289  */
291 };
292 
294 {
295 public:
296  scope_changer();
297  explicit scope_changer(hk_scopes new_scopes, bool restore = true);
298  ~scope_changer();
299 private:
301  const bool restore_;
302 };
303 
304 /**
305  * returns a container that contains all currently active hotkey_commands.
306  * everything that wants a hotkey, must be in this container
307  */
308 const std::map<std::string_view, hotkey::hotkey_command>& get_hotkey_commands();
309 
310 /** returns the hotkey_command with the given name */
311 NOT_DANGLING const hotkey_command& get_hotkey_command(const std::string& command);
312 
313 bool is_scope_active(scope s);
315 
316 bool has_hotkey_command(const std::string& id);
317 
318 /**
319  * RAII helper class to control the lifetime of a WML hotkey_command.
320  */
322 {
323 public:
324  wml_hotkey_record() = default;
325 
326  /** Don't allow copying so objects don't get erased early. */
329 
330  /** But we *do* want move semantics. */
333 
334  /** Registers a hotkey_command for a WML hotkey with the given ID if one does not already exist. */
335  wml_hotkey_record(const std::string& id, const t_string& description, const config& default_hotkey);
336 
338 
339 private:
340  /** Handles removing the associated hotkey_command on this object's destruction. */
341  std::function<void()> cleanup_{};
342 };
343 
344 void init_hotkey_commands();
345 }
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
RAII helper class to control the lifetime of a WML hotkey_command.
wml_hotkey_record(const wml_hotkey_record &)=delete
Don't allow copying so objects don't get erased early.
const wml_hotkey_record & operator=(const wml_hotkey_record &)=delete
std::function< void()> cleanup_
Handles removing the associated hotkey_command on this object's destruction.
wml_hotkey_record(wml_hotkey_record &&)=default
But we do want move semantics.
wml_hotkey_record & operator=(wml_hotkey_record &&)=default
#define NOT_DANGLING
Definition: global.hpp:61
Keyboard shortcuts for game actions.
const hotkey_command & get_hotkey_command(const std::string &command)
returns the hotkey_command with the given name
bool has_hotkey_command(const std::string &id)
constexpr uint32_t scope_game
void init_hotkey_commands()
const std::map< std::string_view, hotkey::hotkey_command > & get_hotkey_commands()
returns a container that contains all currently active hotkey_commands.
std::bitset< SCOPE_COUNT > hk_scopes
bool is_scope_active(scope s)
scope
Available hotkey scopes.
constexpr uint32_t scope_main
t_string get_translatable_category_name(HOTKEY_CATEGORY category)
Gets the display name for a given hotkey category.
constexpr uint32_t scope_editor
@ HOTKEY_EDITOR_TOOL_VILLAGE
@ HOTKEY_MINIMAP_DRAW_VILLAGES
@ HOTKEY_EDITOR_BRUSH_NW_SE
@ HOTKEY_EDITOR_REFRESH
@ HOTKEY_FULLSCREEN
@ HOTKEY_EDITOR_SELECT_NONE
@ HOTKEY_OBJECTIVES
@ HOTKEY_ANIMATE_MAP
@ HOTKEY_SCREENSHOT
@ HOTKEY_TELEPORT_UNIT
@ HOTKEY_SPEAK_ALLY
@ HOTKEY_ACCELERATED
@ HOTKEY_EDITOR_CLIPBOARD_ROTATE_CCW
@ HOTKEY_MOUSE_SCROLL
@ HOTKEY_EDITOR_PALETTE_GROUPS
@ HOTKEY_TERRAIN_DESCRIPTION
@ HOTKEY_EDITOR_PALETTE_UPSCROLL
@ HOTKEY_END_UNIT_TURN
@ HOTKEY_EDITOR_PALETTE_ITEMS_CLEAR
@ HOTKEY_LABEL_SETTINGS
@ HOTKEY_EDITOR_SIDE_REMOVE
@ HOTKEY_WB_EXECUTE_ALL_ACTIONS
@ HOTKEY_WB_SUPPOSE_DEAD
@ HOTKEY_EDITOR_BRUSH_NEXT
@ HOTKEY_HELP_ABOUT_SAVELOAD
@ HOTKEY_EDITOR_TOOL_LABEL
@ HOTKEY_EDITOR_CLIPBOARD_ROTATE_CW
@ HOTKEY_REPLAY_PLAY
@ HOTKEY_EDITOR_BRUSH_3
@ HOTKEY_SCROLL_LEFT
@ HOTKEY_SAVE_GAME
@ HOTKEY_EDITOR_CLIPBOARD_PASTE
@ HOTKEY_EDITOR_PARTIAL_UNDO
@ HOTKEY_SPEAK_ALL
@ HOTKEY_EDITOR_UNIT_TOGGLE_CANRECRUIT
@ HOTKEY_EDITOR_PALETTE_ITEM_SWAP
@ HOTKEY_EDITOR_TOOL_PAINT
@ HOTKEY_EDITOR_MAP_CLOSE
@ HOTKEY_EDITOR_MAP_GENERATE
@ HOTKEY_SHOW_ENEMY_MOVES
@ HOTKEY_EDITOR_SELECTION_FLIP
@ HOTKEY_EDITOR_SCHEDULE
@ HOTKEY_ACHIEVEMENTS
@ HOTKEY_DESELECT_HEX
@ HOTKEY_EDITOR_TOOL_FILL
@ TITLE_SCREEN__MULTIPLAYER
@ HOTKEY_EDITOR_SCENARIO_SAVE_AS
@ HOTKEY_EDITOR_PLAYLIST
@ TITLE_SCREEN__ADDONS
@ HOTKEY_EDITOR_MAP_SAVE_AS
@ HOTKEY_UNIT_DESCRIPTION
@ HOTKEY_UPDATE_SHROUD
@ HOTKEY_REPEAT_RECRUIT
@ TITLE_SCREEN__CREDITS
@ HOTKEY_REPLAY_STOP
@ HOTKEY_KILL_UNIT
@ HOTKEY_SCROLL_RIGHT
@ HOTKEY_SAVE_REPLAY
@ HOTKEY_EDITOR_SELECT_ALL
@ HOTKEY_LABEL_TEAM_TERRAIN
@ HOTKEY_EDITOR_DRAW_COORDINATES
@ HOTKEY_UNIT_HOLD_POSITION
@ HOTKEY_EDITOR_TOOL_NEXT
@ TITLE_SCREEN__EDITOR
@ HOTKEY_EDITOR_SELECTION_EXPORT
@ HOTKEY_EDITOR_PARTIAL_UPDATE_TRANSITIONS
@ HOTKEY_EDITOR_MAP_CREATE_MASK_TO
@ HOTKEY_REPLAY_NEXT_TURN
@ HOTKEY_TOGGLE_GRID
@ HOTKEY_EDITOR_SELECTION_CUT
@ HOTKEY_EDITOR_UNIT_CHANGE_ID
@ HOTKEY_SURRENDER
@ HOTKEY_SELECT_AND_ACTION
@ HOTKEY_CLEAR_MSG
@ HOTKEY_REPLAY_SHOW_EVERYTHING
@ HOTKEY_REPLAY_SHOW_TEAM1
@ HOTKEY_MINIMAP_DRAW_TERRAIN
@ HOTKEY_LABEL_TERRAIN
@ HOTKEY_EDITOR_DRAW_NUM_OF_BITMAPS
@ HOTKEY_CUSTOM_CMD
@ HOTKEY_STOP_NETWORK
@ HOTKEY_MAP_SCREENSHOT
@ HOTKEY_CLEAR_LABELS
@ HOTKEY_EDITOR_AREA_ADD
@ HOTKEY_EDITOR_BRUSH_SW_NE
@ HOTKEY_EDITOR_TOOL_UNIT
@ HOTKEY_EDITOR_BRUSH_DEFAULT
@ HOTKEY_CONTINUE_MOVE
@ HOTKEY_BEST_ENEMY_MOVES
@ HOTKEY_QUIT_TO_DESKTOP
@ HOTKEY_EDITOR_CHANGE_ADDON_ID
@ HOTKEY_EDITOR_CUSTOM_TODS
@ HOTKEY_EDITOR_REFRESH_IMAGE_CACHE
@ HOTKEY_EDITOR_SELECTION_FILL
@ HOTKEY_TOGGLE_ELLIPSES
@ HOTKEY_EDITOR_CLIPBOARD_FLIP_VERTICAL
@ HOTKEY_EDITOR_MAP_SAVE_ALL
@ HOTKEY_EDITOR_BRUSH_1
@ HOTKEY_EDITOR_SELECTION_ROTATE
@ HOTKEY_EDITOR_MAP_LOAD
@ HOTKEY_RENAME_UNIT
@ HOTKEY_EDITOR_BRUSH_2
@ HOTKEY_EDITOR_TOOL_STARTING_POSITION
@ HOTKEY_MINIMAP_CODING_TERRAIN
@ HOTKEY_EDITOR_NO_UPDATE_TRANSITIONS
@ HOTKEY_LOAD_GAME
@ TITLE_SCREEN__TEST
@ HOTKEY_WB_EXECUTE_ACTION
@ HOTKEY_EDITOR_SELECTION_COPY
@ HOTKEY_MINIMAP_DRAW_UNITS
@ HOTKEY_CHANGE_SIDE
@ HOTKEY_EDITOR_PALETTE_DOWNSCROLL
@ HOTKEY_EDITOR_UNIT_TOGGLE_LOYAL
@ TITLE_SCREEN__PREVIOUS_TIP
@ HOTKEY_CYCLE_UNITS
@ HOTKEY_DELAY_SHROUD
@ HOTKEY_WB_BUMP_UP_ACTION
@ HOTKEY_EDITOR_MAP_APPLY_MASK
@ HOTKEY_EDITOR_LOCAL_TIME
@ HOTKEY_CREATE_UNIT
@ HOTKEY_REPLAY_EXIT
@ HOTKEY_EDITOR_UNIT_FACING
@ HOTKEY_PREFERENCES
@ HOTKEY_STATUS_TABLE
@ HOTKEY_REPLAY_NEXT_SIDE
@ HOTKEY_DELETE_UNIT
@ HOTKEY_MOVE_ACTION
@ HOTKEY_REPLAY_NEXT_MOVE
@ HOTKEY_REPLAY_RESET
@ HOTKEY_EDITOR_EDIT_UNIT
@ HOTKEY_TOUCH_HEX
@ HOTKEY_EDITOR_SIDE_NEW
@ HOTKEY_EDITOR_SELECTION_RANDOMIZE
@ HOTKEY_START_NETWORK
@ HOTKEY_WB_TOGGLE
@ HOTKEY_EDITOR_SCENARIO_NEW
@ TITLE_SCREEN__CORES
@ HOTKEY_EDITOR_MAP_SWITCH
@ HOTKEY_STATISTICS
@ HOTKEY_EDITOR_SELECT_INVERSE
@ HOTKEY_EDITOR_TOGGLE_TRANSITIONS
@ HOTKEY_UNIT_LIST
@ HOTKEY_SCROLL_DOWN
@ HOTKEY_EDITOR_AUTO_UPDATE_TRANSITIONS
@ HOTKEY_REPLAY_SKIP_ANIMATION
@ HOTKEY_ZOOM_DEFAULT
@ HOTKEY_EDITOR_MAP_INFO
@ HOTKEY_WB_BUMP_DOWN_ACTION
@ TITLE_SCREEN__CAMPAIGN
@ HOTKEY_EDITOR_AREA_RENAME
@ HOTKEY_EDITOR_MAP_RESIZE
@ HOTKEY_SCROLL_UP
@ HOTKEY_EDITOR_DRAW_TERRAIN_CODES
@ HOTKEY_EDITOR_AREA_REMOVE
@ HOTKEY_SELECT_HEX
@ HOTKEY_QUIT_GAME
@ HOTKEY_EDITOR_UPDATE_TRANSITIONS
@ HOTKEY_EDITOR_TOOL_SELECT
@ HOTKEY_EDITOR_MAP_NEW
@ HOTKEY_EDITOR_MAP_SAVE
@ HOTKEY_EDITOR_AREA_SAVE
@ HOTKEY_EDITOR_REMOVE_LOCATION
@ HOTKEY_EDITOR_SIDE_EDIT
@ HOTKEY_AI_FORMULA
@ HOTKEY_EDITOR_SELECT_ADDON
@ HOTKEY_EDITOR_TOOL_ITEM
@ TITLE_SCREEN__RELOAD_WML
@ HOTKEY_REPLAY_SHOW_EACH
@ TITLE_SCREEN__NEXT_TIP
@ HOTKEY_CYCLE_BACK_UNITS
@ HOTKEY_EDITOR_UNIT_TOGGLE_RENAMEABLE
@ HOTKEY_EDITOR_SCENARIO_EDIT
@ HOTKEY_EDITOR_OPEN_ADDON
@ HOTKEY_EDITOR_MAP_REVERT
@ HOTKEY_WB_DELETE_ACTION
@ HOTKEY_EDITOR_CLIPBOARD_FLIP_HORIZONTAL
@ HOTKEY_MINIMAP_CODING_UNIT
Stores all information related to functions that can be bound to hotkeys.
bool toggle
Toggle hotkeys have some restrictions on what can be bound to them.
HOTKEY_COMMAND command
The command associated with this hotkey.
std::string id
The unique ID.
hk_scopes scope
The visibility scope of the command.
bool hidden
If hidden then don't show the command in the hotkey preferences.
static const hotkey_command & null_command()
returns the command that is treated as null
HOTKEY_CATEGORY category
The category of the command.
static const hotkey_command & get_command_by_command(HOTKEY_COMMAND command)
the execute_command argument was changed from HOTKEY_COMMAND to hotkey_command, to be able to call it...
hotkey_command(const hotkey_command &)=default
hotkey_command & operator=(const hotkey_command &)=default
static map_location::DIRECTION s