1 /*
2    Copyright (C) 2003 - 2018 by David White <dave@whitevine.net>
3    Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY.
11 
12    See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 #include "tooltips.hpp"
18 #include "tstring.hpp"
19 
20 #include <bitset>
21 #include <list>
22 #include <map>
23 #include <vector>
24 
25 class config;
26 
27 namespace hotkey {
28 
29 /**
30  * Available hotkey scopes. The scope is used to allow command from
31  * non-overlapping areas of the game share the same key
32  */
33 enum scope {
34 	SCOPE_MAIN_MENU,
35 	SCOPE_GAME,
36 	SCOPE_EDITOR,
37 	SCOPE_COUNT,
38 };
39 
40 enum HOTKEY_COMMAND {
41 	HOTKEY_CYCLE_UNITS, HOTKEY_CYCLE_BACK_UNITS,
42 	HOTKEY_UNIT_HOLD_POSITION,
43 	HOTKEY_END_UNIT_TURN, HOTKEY_LEADER,
44 	HOTKEY_UNDO, HOTKEY_REDO,
45 	HOTKEY_ZOOM_IN, HOTKEY_ZOOM_OUT, HOTKEY_ZOOM_DEFAULT,
46 	HOTKEY_FULLSCREEN, HOTKEY_SCREENSHOT, HOTKEY_MAP_SCREENSHOT, HOTKEY_ACCELERATED,
47 	HOTKEY_TERRAIN_DESCRIPTION,
48 	HOTKEY_UNIT_DESCRIPTION, HOTKEY_RENAME_UNIT, HOTKEY_DELETE_UNIT,
49 	HOTKEY_SAVE_GAME, HOTKEY_SAVE_REPLAY, HOTKEY_SAVE_MAP, HOTKEY_LOAD_GAME,
50 	HOTKEY_RECRUIT, HOTKEY_REPEAT_RECRUIT, HOTKEY_RECALL, HOTKEY_ENDTURN,
51 	HOTKEY_TOGGLE_ELLIPSES, HOTKEY_TOGGLE_GRID, HOTKEY_STATUS_TABLE, HOTKEY_MUTE, HOTKEY_MOUSE_SCROLL,
52 	HOTKEY_SPEAK, HOTKEY_CREATE_UNIT, HOTKEY_CHANGE_SIDE, HOTKEY_KILL_UNIT, HOTKEY_PREFERENCES,
53 	HOTKEY_OBJECTIVES, HOTKEY_UNIT_LIST, HOTKEY_STATISTICS, HOTKEY_STOP_NETWORK, HOTKEY_START_NETWORK, HOTKEY_SURRENDER, HOTKEY_QUIT_GAME, HOTKEY_QUIT_TO_DESKTOP,
54 	HOTKEY_LABEL_TEAM_TERRAIN, HOTKEY_LABEL_TERRAIN, HOTKEY_CLEAR_LABELS,HOTKEY_SHOW_ENEMY_MOVES, HOTKEY_BEST_ENEMY_MOVES,
55 	HOTKEY_DELAY_SHROUD, HOTKEY_UPDATE_SHROUD, HOTKEY_CONTINUE_MOVE,
56 	HOTKEY_SEARCH, HOTKEY_SPEAK_ALLY, HOTKEY_SPEAK_ALL, HOTKEY_HELP,
57 	HOTKEY_CHAT_LOG, HOTKEY_LANGUAGE, HOTKEY_ANIMATE_MAP,
58 
59 	// Replay
60 	HOTKEY_REPLAY_PLAY, HOTKEY_REPLAY_RESET, HOTKEY_REPLAY_STOP, HOTKEY_REPLAY_NEXT_TURN,
61 	HOTKEY_REPLAY_NEXT_SIDE, HOTKEY_REPLAY_NEXT_MOVE, HOTKEY_REPLAY_SHOW_EVERYTHING,
62 	HOTKEY_REPLAY_SHOW_EACH, HOTKEY_REPLAY_SHOW_TEAM1,
63 	HOTKEY_REPLAY_SKIP_ANIMATION,
64 	HOTKEY_REPLAY_EXIT,
65 
66 	// Controls
67 	HOTKEY_SELECT_HEX, HOTKEY_DESELECT_HEX,
68 	HOTKEY_MOVE_ACTION, HOTKEY_SELECT_AND_ACTION, HOTKEY_TOUCH_HEX,
69 
70 	// Camera movement
71 	HOTKEY_SCROLL_UP, HOTKEY_SCROLL_DOWN, HOTKEY_SCROLL_LEFT, HOTKEY_SCROLL_RIGHT,
72 
73 	// Dialog control
74 	HOTKEY_CANCEL, HOTKEY_OKAY,
75 
76 	// Whiteboard commands
77 	HOTKEY_WB_TOGGLE,
78 	HOTKEY_WB_EXECUTE_ACTION, HOTKEY_WB_EXECUTE_ALL_ACTIONS,
79 	HOTKEY_WB_DELETE_ACTION,
80 	HOTKEY_WB_BUMP_UP_ACTION, HOTKEY_WB_BUMP_DOWN_ACTION,
81 	HOTKEY_WB_SUPPOSE_DEAD,
82 
83 	// Misc.
84 	HOTKEY_USER_CMD,
85 	HOTKEY_CUSTOM_CMD,
86 	HOTKEY_AI_FORMULA,
87 	HOTKEY_CLEAR_MSG,
88 	HOTKEY_LABEL_SETTINGS,
89 
90 	// Minimap
91 	HOTKEY_MINIMAP_CODING_TERRAIN, HOTKEY_MINIMAP_CODING_UNIT,
92 	HOTKEY_MINIMAP_DRAW_UNITS, HOTKEY_MINIMAP_DRAW_VILLAGES, HOTKEY_MINIMAP_DRAW_TERRAIN,
93 
94 	/* Gui2 specific hotkeys. */
95 	TITLE_SCREEN__RELOAD_WML,
96 	TITLE_SCREEN__NEXT_TIP,
97 	TITLE_SCREEN__PREVIOUS_TIP,
98 	TITLE_SCREEN__TUTORIAL,
99 	TITLE_SCREEN__CAMPAIGN,
100 	TITLE_SCREEN__MULTIPLAYER,
101 	TITLE_SCREEN__ADDONS,
102 	TITLE_SCREEN__CORES,
103 	TITLE_SCREEN__EDITOR,
104 	TITLE_SCREEN__CREDITS,
105 	TITLE_SCREEN__TEST,
106 	GLOBAL__HELPTIP,
107 	LUA_CONSOLE,
108 
109 	HOTKEY_WML,
110 
111 	/* Editor commands */
112 	HOTKEY_EDITOR_CUSTOM_TODS,
113 	HOTKEY_EDITOR_PARTIAL_UNDO,
114 
115 	// Palette
116 	HOTKEY_EDITOR_PALETTE_ITEM_SWAP, HOTKEY_EDITOR_PALETTE_ITEMS_CLEAR,
117 	HOTKEY_EDITOR_PALETTE_GROUPS, HOTKEY_EDITOR_PALETTE_UPSCROLL, HOTKEY_EDITOR_PALETTE_DOWNSCROLL,
118 
119 	HOTKEY_EDITOR_REMOVE_LOCATION,
120 	HOTKEY_EDITOR_PLAYLIST,
121 	HOTKEY_EDITOR_SCHEDULE,
122 	HOTKEY_EDITOR_LOCAL_TIME,
123 	HOTKEY_EDITOR_UNIT_FACING,
124 
125 	// Unit
126 	HOTKEY_EDITOR_UNIT_TOGGLE_CANRECRUIT, HOTKEY_EDITOR_UNIT_TOGGLE_RENAMEABLE,
127 	HOTKEY_EDITOR_UNIT_CHANGE_ID, HOTKEY_EDITOR_UNIT_TOGGLE_LOYAL,
128 	HOTKEY_EDITOR_UNIT_RECRUIT_ASSIGN,
129 
130 	// Brushes
131 	HOTKEY_EDITOR_BRUSH_NEXT, HOTKEY_EDITOR_BRUSH_DEFAULT,
132 	HOTKEY_EDITOR_BRUSH_1, HOTKEY_EDITOR_BRUSH_2, HOTKEY_EDITOR_BRUSH_3, HOTKEY_EDITOR_BRUSH_SW_NE, HOTKEY_EDITOR_BRUSH_NW_SE,
133 
134 	// Tools
135 	HOTKEY_EDITOR_TOOL_NEXT,
136 	HOTKEY_EDITOR_TOOL_PAINT, HOTKEY_EDITOR_TOOL_FILL,
137 	HOTKEY_EDITOR_TOOL_SELECT, HOTKEY_EDITOR_TOOL_STARTING_POSITION, HOTKEY_EDITOR_TOOL_LABEL,
138 	HOTKEY_EDITOR_TOOL_UNIT, HOTKEY_EDITOR_TOOL_VILLAGE, HOTKEY_EDITOR_TOOL_ITEM, HOTKEY_EDITOR_TOOL_SOUNDSOURCE,
139 
140 	// Select
141 	HOTKEY_EDITOR_SELECT_ALL, HOTKEY_EDITOR_SELECT_INVERSE,	HOTKEY_EDITOR_SELECT_NONE,
142 	// Clipboard
143 	HOTKEY_EDITOR_CLIPBOARD_PASTE,
144 	HOTKEY_EDITOR_CLIPBOARD_ROTATE_CW, HOTKEY_EDITOR_CLIPBOARD_ROTATE_CCW,
145 	HOTKEY_EDITOR_CLIPBOARD_FLIP_HORIZONTAL, HOTKEY_EDITOR_CLIPBOARD_FLIP_VERTICAL,
146 	// Selection
147 	HOTKEY_EDITOR_SELECTION_CUT, HOTKEY_EDITOR_SELECTION_COPY,
148 	HOTKEY_EDITOR_SELECTION_ROTATE, HOTKEY_EDITOR_SELECTION_FLIP,
149 	HOTKEY_EDITOR_SELECTION_FILL,
150 	HOTKEY_EDITOR_SELECTION_EXPORT,
151 	HOTKEY_EDITOR_SELECTION_GENERATE, HOTKEY_EDITOR_SELECTION_RANDOMIZE,
152 
153 	// Map
154 	HOTKEY_EDITOR_MAP_NEW, HOTKEY_EDITOR_MAP_LOAD, HOTKEY_EDITOR_MAP_SAVE,
155 	HOTKEY_EDITOR_MAP_SAVE_AS, HOTKEY_EDITOR_MAP_SAVE_ALL,
156 	HOTKEY_EDITOR_MAP_REVERT, HOTKEY_EDITOR_MAP_INFO,
157 	HOTKEY_EDITOR_MAP_CLOSE,
158 	HOTKEY_EDITOR_MAP_SWITCH,
159 	HOTKEY_EDITOR_MAP_RESIZE, HOTKEY_EDITOR_MAP_ROTATE,
160 	HOTKEY_EDITOR_MAP_GENERATE, HOTKEY_EDITOR_MAP_APPLY_MASK,
161 	HOTKEY_EDITOR_MAP_CREATE_MASK_TO,
162 
163 	// Transitions
164 	HOTKEY_EDITOR_UPDATE_TRANSITIONS, HOTKEY_EDITOR_TOGGLE_TRANSITIONS,
165 	HOTKEY_EDITOR_AUTO_UPDATE_TRANSITIONS, HOTKEY_EDITOR_PARTIAL_UPDATE_TRANSITIONS, HOTKEY_EDITOR_NO_UPDATE_TRANSITIONS,
166 
167 	// Refresh
168 	HOTKEY_EDITOR_REFRESH,
169 	HOTKEY_EDITOR_REFRESH_IMAGE_CACHE,
170 
171 	// Draw
172 	HOTKEY_EDITOR_DRAW_COORDINATES, HOTKEY_EDITOR_DRAW_TERRAIN_CODES, HOTKEY_EDITOR_DRAW_NUM_OF_BITMAPS,
173 
174 	// Side
175 	HOTKEY_EDITOR_SIDE_NEW,
176 	HOTKEY_EDITOR_SIDE_EDIT,
177 	HOTKEY_EDITOR_SIDE_REMOVE,
178 
179 	// Area
180 	HOTKEY_EDITOR_AREA_REMOVE,
181 	HOTKEY_EDITOR_AREA_ADD,
182 	HOTKEY_EDITOR_AREA_SAVE,
183 	HOTKEY_EDITOR_AREA_RENAME,
184 
185 	// Scenario
186 	HOTKEY_EDITOR_SCENARIO_EDIT,
187 	HOTKEY_EDITOR_SCENARIO_NEW,
188 	HOTKEY_EDITOR_SCENARIO_SAVE_AS,
189 
190 	/* This item must stay at the end since it is used as terminator for iterating. */
191 	HOTKEY_NULL
192 };
193 
194 enum HOTKEY_CATEGORY {
195 	HKCAT_GENERAL,
196 	HKCAT_SAVING,
197 	HKCAT_MAP,
198 	HKCAT_UNITS,
199 	HKCAT_CHAT,
200 	HKCAT_REPLAY,
201 	HKCAT_WHITEBOARD,
202 	HKCAT_SCENARIO,
203 	HKCAT_PALETTE,
204 	HKCAT_TOOLS,
205 	HKCAT_CLIPBOARD,
206 	HKCAT_DEBUG,
207 	HKCAT_CUSTOM,
208 	HKCAT_PLACEHOLDER // Keep this one last
209 };
210 
211 using category_name_map_t = std::map<HOTKEY_CATEGORY, std::string>;
212 
213 /**
214  * Returns the map of hotkey categories and their display names.
215  *
216  * These aren't translated and need be converted to a t_string before
217  * being displayed to the player.
218  */
219 const category_name_map_t& get_category_names();
220 
221 /** Returns a list of all the hotkeys belonging to the given category. */
222 std::list<HOTKEY_COMMAND> get_hotkeys_by_category(HOTKEY_CATEGORY category);
223 
224 typedef std::bitset<SCOPE_COUNT> hk_scopes;
225 
226 /// Do not use this outside hotkeys.cpp.
227 /// hotkey_command uses t_string which might cause bugs when used at program startup,
228 /// so use this for the master hotkey list (and only there).
229 struct hotkey_command_temp
230 {
231 	HOTKEY_COMMAND id;
232 
233 	std::string command;
234 
235 	/// description, tooltip are untranslated
236 	std::string description;
237 
238 	bool hidden;
239 
240 	hk_scopes scope;
241 	HOTKEY_CATEGORY category;
242 
243 	std::string tooltip;
244 };
245 
246 /// Stores all information related to functions that can be bound to hotkeys.
247 /// this is currently a semi struct: it haves a constructor, but only const-public members.
248 struct hotkey_command
249 {
250 	hotkey_command() = delete;
251 
252 	/** Constuct a new command from a temporary static hotkey object. */
253 	hotkey_command(const hotkey_command_temp& temp_command);
254 
255 	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);
256 
257 	hotkey_command(const hotkey_command&) = default;
258 	hotkey_command& operator=(const hotkey_command&) = default;
259 
260 	/// the names are strange: the "hotkey::HOTKEY_COMMAND" is named id, and the string to identify the object is called "command"
261 	/// there is some inconstancy with that names in this file.
262 	/// This binds the command to a function. Does not need to be unique.
263 	HOTKEY_COMMAND id;
264 
265 	/// The command is unique.
266 	std::string command;
267 
268 	// since the wml_menu hotkey_command s can have different textdomains we need t_string now.
269 	t_string description;
270 
271 	/// If hidden then don't show the command in the hotkey preferences.
272 	bool hidden;
273 
274 	/// Toggle hotkeys have some restrictions on what can be bound to them.
275 	/// They require a binding that has two states, "pressed" and "released".
276 	bool toggle;
277 
278 	/// The visibility scope of the command.
279 	hk_scopes scope;
280 
281 	/// The category of the command.
282 	HOTKEY_CATEGORY category;
283 
284 	t_string tooltip;
285 
286 	/// checks weather this is the null hotkey_command
287 	bool null() const;
288 
289 	/// returns the command that is treated as null
290 	static const hotkey_command& null_command();
291 
292 	/// the execute_command argument was changed from HOTKEY_COMMAND to hotkey_command,
293 	/// to be able to call it with HOTKEY_COMMAND, this function was created
294 	static const hotkey_command& get_command_by_command(HOTKEY_COMMAND command);
295 };
296 
297 class scope_changer {
298 public:
299 	scope_changer();
300 	~scope_changer();
301 private:
302 	hk_scopes prev_scope_active_;
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 const std::vector<hotkey_command>& get_hotkey_commands();
308 
309 /// returns the hotkey_command with the given name
310 const hotkey_command& get_hotkey_command(const std::string& command);
311 
312 /// returns the hotkey_command that is treated as null.
313 const hotkey_command& get_hotkey_null();
314 
315 void deactivate_all_scopes();
316 void set_scope_active(scope s, bool set = true);
317 void set_active_scopes(hk_scopes s);
318 bool is_scope_active(scope s);
319 bool is_scope_active(hk_scopes s);
320 
321 ///
322 bool has_hotkey_command(const std::string& id);
323 
324 /// adds a new wml hotkey to the list, but only if there is no hotkey with that id yet on the list.
325 /// the object that is created here will be deleted in "delete_all_wml_hotkeys()"
326 void add_wml_hotkey(const std::string& id, const t_string& description, const config& default_hotkey);
327 
328 /// deletes all wml hotkeys, should be called after a game has ended
329 void delete_all_wml_hotkeys();
330 ///removes a wml hotkey with the given id, returns true if the deletion was successful
331 bool remove_wml_hotkey(const std::string& id);
332 
333 const std::string& get_description(const std::string& command);
334 const std::string& get_tooltip(const std::string& command);
335 
336 void init_hotkey_commands();
337 
338 void clear_hotkey_commands();
339 
340 /// returns get_hotkey_command(command).id
341 HOTKEY_COMMAND get_id(const std::string& command);
342 }
343