The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
command_executor.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2003 - 2025
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
18
19#include "gui/gui.hpp"
26#include "filesystem.hpp"
27#include "gettext.hpp"
28#include "log.hpp"
30#include "display.hpp"
31#include "quit_confirmation.hpp"
32#include "sdl/surface.hpp"
33#include "../resources.hpp"
34#include "../playmp_controller.hpp"
35#include "sdl/input.hpp" // get_mouse_state
36#include "video.hpp" // toggle_fullscreen
37
38#include <ios>
39#include <set>
40
41static lg::log_domain log_config("config");
42static lg::log_domain log_hotkey("hotkey");
43#define ERR_G LOG_STREAM(err, lg::general())
44#define WRN_G LOG_STREAM(warn, lg::general())
45#define LOG_G LOG_STREAM(info, lg::general())
46#define DBG_G LOG_STREAM(debug, lg::general())
47#define ERR_CF LOG_STREAM(err, log_config)
48#define LOG_HK LOG_STREAM(info, log_hotkey)
49
50namespace {
51
52void make_screenshot(const std::string& name, bool map_screenshot)
53{
54 surface screenshot = display::get_singleton()->screenshot(map_screenshot);
55 if(screenshot) {
56 std::string filename = filesystem::get_screenshot_dir() + "/" + name + "_";
58 gui2::dialogs::screenshot_notification::display(filename, screenshot);
59 }
60}
61}
62namespace hotkey {
63
64static void event_queue(const SDL_Event& event, command_executor* executor);
65
66bool command_executor::do_execute_command(const hotkey::ui_command& cmd, bool press, bool release)
67{
68 // hotkey release handling
69 if (release) {
70 switch(cmd.hotkey_command) {
71 // release a scroll key, un-apply scrolling in the given direction
73 scroll_up(false);
74 break;
76 scroll_down(false);
77 break;
79 scroll_left(false);
80 break;
82 scroll_right(false);
83 break;
84 default:
85 return false; // nothing else handles a hotkey release
86 }
87
88 return true;
89 }
90
91 // handling of hotkeys which activate even on hold events
92 switch(cmd.hotkey_command) {
95 return true;
97 scroll_up(true);
98 return true;
100 scroll_down(true);
101 return true;
103 scroll_left(true);
104 return true;
106 scroll_right(true);
107 return true;
108 default:
109 break;
110 }
111
112 if(!press) {
113 return false; // nothing else handles hotkey hold events
114 }
115
116 // hotkey press handling
117 switch(cmd.hotkey_command) {
119 cycle_units();
120 break;
123 break;
124 case HOTKEY_ENDTURN:
125 end_turn();
126 break;
129 break;
132 break;
133 case HOTKEY_LEADER:
134 goto_leader();
135 break;
136 case HOTKEY_UNDO:
137 undo();
138 break;
139 case HOTKEY_REDO:
140 redo();
141 break;
144 break;
147 break;
149 rename_unit();
150 break;
151 case HOTKEY_SAVE_GAME:
152 save_game();
153 break;
155 save_replay();
156 break;
157 case HOTKEY_SAVE_MAP:
158 save_map();
159 break;
160 case HOTKEY_LOAD_GAME:
161 load_game();
162 break;
165 break;
167 toggle_grid();
168 break;
170 status_table();
171 break;
172 case HOTKEY_RECALL:
173 recall();
174 break;
177 break;
178 case HOTKEY_RECRUIT:
179 recruit();
180 break;
181 case HOTKEY_SPEAK:
182 speak();
183 break;
185 whisper();
186 break;
187 case HOTKEY_SPEAK_ALL:
188 shout();
189 break;
191 create_unit();
192 break;
194 change_side();
195 break;
196 case HOTKEY_KILL_UNIT:
197 kill_unit();
198 break;
201 break;
203 preferences();
204 break;
206 objectives();
207 break;
208 case HOTKEY_UNIT_LIST:
209 unit_list();
210 break;
213 break;
215 stop_network();
216 break;
219 break;
221 label_terrain(true);
222 break;
224 label_terrain(false);
225 break;
227 clear_labels();
228 break;
230 show_enemy_moves(false);
231 break;
233 show_enemy_moves(true);
234 break;
237 break;
240 break;
243 break;
244 case HOTKEY_SEARCH:
245 search();
246 break;
247 case HOTKEY_HELP:
248 show_help();
249 break;
251 // although HOTKEY_HELP uses a virtual call to allow context-specific help, this one is already a specific topic
252 help::show_help("saveload");
253 break;
254 case HOTKEY_CHAT_LOG:
256 break;
257 case HOTKEY_USER_CMD:
258 user_command();
259 break;
262 break;
264 ai_formula();
265 break;
266 case HOTKEY_CLEAR_MSG:
268 break;
269 case HOTKEY_LANGUAGE:
271 break;
273 play_replay();
274 break;
276 reset_replay();
277 break;
279 stop_replay();
280 break;
283 break;
286 break;
289 break;
292 break;
295 break;
298 break;
301 break;
303 replay_exit();
304 break;
305 case HOTKEY_WB_TOGGLE:
307 break;
310 break;
313 break;
316 break;
319 break;
322 break;
325 break;
327 select_hex();
328 break;
330 deselect_hex();
331 break;
333 move_action();
334 break;
337 break;
338 case HOTKEY_TOUCH_HEX:
339 touch_hex();
340 break;
343 break;
344 case LUA_CONSOLE:
345 lua_console();
346 break;
347 case HOTKEY_ZOOM_IN:
348 zoom_in();
349 break;
350 case HOTKEY_ZOOM_OUT:
351 zoom_out();
352 break;
354 zoom_default();
355 break;
358 break;
361 break;
362 case HOTKEY_QUIT_GAME:
363 gui2::switch_theme(prefs::get().gui2_theme());
365 break;
366 case HOTKEY_SURRENDER:
368 break;
370 prefs::get().set_minimap_draw_terrain(!prefs::get().minimap_draw_terrain());
372 break;
374 prefs::get().set_minimap_terrain_coding(!prefs::get().minimap_terrain_coding());
376 break;
378 prefs::get().set_minimap_movement_coding(!prefs::get().minimap_movement_coding());
380 break;
382 prefs::get().set_minimap_draw_units(!prefs::get().minimap_draw_units());
384 break;
386 prefs::get().set_minimap_draw_villages(!prefs::get().minimap_draw_villages());
388 break;
390 {
392 ach.show();
393 }
394 break;
395 default:
396 return false;
397 }
398 return true;
399}
400
402 if(gui2::show_message(_("Surrender"), _("Do you really want to surrender the game?"), gui2::dialogs::message::yes_no_buttons) != gui2::retval::CANCEL) {
404 if(pmc && !pmc->is_linger_mode() && !pmc->is_observer()) {
406 }
407 }
408}
409
410void command_executor::show_menu(const std::vector<config>& items_arg, const point& menu_loc, bool /*context_menu*/)
411{
412 if(items_arg.empty()) {
413 return;
414 }
415
416 // FIXME: take the argument by value
417 std::vector<config> items = items_arg;
418 for(std::size_t i = 0; i < items.size(); ++i) {
419 populate_menu_item_info(items[i], i);
420 }
421
422 const auto do_command = [&](int selected_item) {
423 std::string id = items[selected_item]["id"].str();
424 do_execute_command(hotkey::ui_command(id, selected_item));
426 };
427
428 int res = -1;
429 point selection_pos;
430 {
431 rect pos(menu_loc, {1,1});
432 gui2::dialogs::drop_down_menu mmenu(pos, items, -1, true, keep_menu_open());
433
434 // Transitional API. Remove once the game UI is using GUI2.
435 // Callback will only fire if keep_menu_open is false
436 mmenu.set_legacy_menu_mode(true);
437 mmenu.set_legacy_toggle_callback(do_command);
438
439 if(mmenu.show()) {
440 res = mmenu.selected_item();
441 if(res >= 0) {
442 // Get selection coordinates for a potential submenu below
443 // And compensate for borders
444 selection_pos = mmenu.selected_item_pos() - point{1, 1};
445 }
446 }
447 } // This will kill the dialog.
448
449 if(res < 0 || std::size_t(res) >= items.size()) {
450 return;
451 }
452
453 if(const theme::menu* submenu = display::get_singleton()->get_theme().get_menu_item(items[res]["id"])) {
454 show_menu(submenu->items(), selection_pos, submenu->is_context());
455 } else {
456 do_command(res);
457 }
458}
459
460void command_executor::execute_action(const std::vector<std::string>& items_arg)
461{
462 for(const std::string& item : items_arg) {
463 auto cmd = hotkey::ui_command(item);
464 if(can_execute_command(cmd)) {
467 }
468 }
469}
470
472{
473 const std::string& command = item["id"];
474
475 // FIXME: better integrate this with GUI2
476 const std::string default_image = "icons/action/" + command + "_25.png";
477 const std::string pressed_image = "icons/action/" + command + "_25-pressed.png";
478
479 auto cmd = hotkey::ui_command(command, index);
481
482 // An image set, if present, takes precedence over toggle buttons to represent
483 // an item's state. See the editor's terrain category dropdown for an example.
484 if(filesystem::file_exists(game_config::path + "/images/" + default_image)) {
485 switch(state) {
486 case action_state::on:
488 item["icon"] = pressed_image + "~CROP(3,3,18,18)";
489 return;
490 default:
491 item["icon"] = default_image + "~CROP(3,3,18,18)";
492 return;
493 }
494 }
495
496 switch(state) {
497 case action_state::on:
498 item["checkbox"] = true;
499 break;
501 item["checkbox"] = false;
502 break;
504 item["radio"] = true;
505 break;
507 item["radio"] = false;
508 break;
510 // Do nothing
511 break;
512 }
513}
514
516{
517 const std::string& item_id = item["id"];
518 const auto& hk = hotkey::get_hotkey_command(item_id);
520
521 // Submenu
522 if(const theme::menu* menu = theme.get_menu_item(item_id)) {
523 item["icon"] = "icons/arrows/short_arrow_right_25.png~CROP(3,3,18,18)"; // TODO: should not be hardcoded
524 item["label"] = menu->title();
525 return;
526 }
527
528 // Populate icons and enable toggle buttons
529 populate_menu_controls(item, index);
530
531 if(hk.command != hotkey::HOTKEY_NULL) {
532 item["details"] = hotkey::get_names(item_id);
533
534 switch(hk.command) {
536 break; // Labels are handled by the menu item manager
537
539 if(const theme::action* b = theme.get_action_item("button-endturn")) {
540 item["label"] = b->title();
541 break;
542 }
543 [[fallthrough]];
544
545 default:
546 item["label"] = hk.description;
547 break;
548 }
549 }
550}
551
552void mbutton_event(const SDL_Event& event, command_executor* executor)
553{
554 event_queue(event, executor);
555
556 /* Run mouse events immediately.
557
558 This is necessary because the sidebar doesn't allow set_button_state() to be called after a
559 button has received the mouse press event but before it has received the mouse release event.
560 When https://github.com/wesnoth/wesnoth/pull/2872 delayed the processing of input events,
561 set_button_state() ended up being called at such a time. However, if we run the event handlers
562 now, the button (if any) hasn't received the press event yet and we can call set_button_state()
563 safely.
564
565 See https://github.com/wesnoth/wesnoth/issues/2884 */
566
567 run_events(executor);
568}
569
570void jbutton_event(const SDL_Event& event, command_executor* executor)
571{
572 event_queue(event, executor);
573}
574
575void jhat_event(const SDL_Event& event, command_executor* executor)
576{
577 event_queue(event, executor);
578}
579
580void key_event(const SDL_Event& event, command_executor* executor)
581{
582 if (!executor) return;
583 event_queue(event,executor);
584}
585
586void keyup_event(const SDL_Event&, command_executor* executor)
587{
588 if(!executor) return;
589 executor->handle_keyup();
590}
591
593{
594 if(!executor) return;
595 bool commands_ran = executor->run_queued_commands();
596 if(commands_ran) {
597 executor->set_button_state();
598 }
599}
600
601static void event_queue(const SDL_Event& event, command_executor* executor)
602{
603 if (!executor) return;
604 executor->queue_command(event);
605 executor->set_button_state();
606}
607
608void command_executor::queue_command(const SDL_Event& event, int index)
609{
610 LOG_HK << "event 0x" << std::hex << event.type << std::dec;
611 if(event.type == SDL_EVENT_TEXT_INPUT) {
612 LOG_HK << "SDL_EVENT_TEXT_INPUT \"" << event.text.text << "\"";
613 }
614
615 const hotkey_ptr hk = get_hotkey(event);
616 if(!hk->active() || hk->is_disabled()) {
617 return;
618 }
619
620 const hotkey_command& command = hotkey::get_hotkey_command(hk->get_command());
621 bool keypress = (event.type == SDL_EVENT_KEY_DOWN || event.type == SDL_EVENT_TEXT_INPUT) &&
623 bool press = keypress ||
624 (event.type == SDL_EVENT_JOYSTICK_BUTTON_DOWN || event.type == SDL_EVENT_MOUSE_BUTTON_DOWN || event.type == SDL_EVENT_FINGER_DOWN);
625 bool release = event.type == SDL_EVENT_KEY_UP;
626 if(press) {
627 LOG_HK << "sending press event (keypress = " <<
628 std::boolalpha << keypress << std::noboolalpha << ")";
629 }
630 if(keypress) {
631 press_event_sent_ = true;
632 }
633
634 command_queue_.emplace_back(command, index, press, release);
635}
636
638{
639 auto ui_cmd = hotkey::ui_command(*command.command, command.index);
640 if (!can_execute_command(ui_cmd)
641 || do_execute_command(ui_cmd, command.press, command.release)) {
642 return;
643 }
644
645 if (!command.press) {
646 return; // none of the commands here respond to a key release
647 }
648
649 switch(command.command->command) {
652 break;
654 make_screenshot(_("Screenshot"), false);
655 break;
657 prefs::get().set_animate_map(!prefs::get().animate_map());
658 break;
660 prefs::get().set_mouse_scrolling(!prefs::get().mouse_scrolling());
661 break;
662 case HOTKEY_MUTE:
663 {
664 // look if both is not playing
665 static struct before_muted_s
666 {
667 bool playing_sound,playing_music;
668 before_muted_s() : playing_sound(false),playing_music(false){}
669 } before_muted;
670 if (prefs::get().music_on() || prefs::get().sound())
671 {
672 // then remember settings and mute both
673 before_muted.playing_sound = prefs::get().sound();
674 before_muted.playing_music = prefs::get().music_on();
675 prefs::get().set_sound(false);
676 prefs::get().set_music(false);
677 }
678 else
679 {
680 // then set settings before mute
681 prefs::get().set_sound(before_muted.playing_sound);
682 prefs::get().set_music(before_muted.playing_music);
683 }
684 }
685 break;
686 default:
687 DBG_G << "command_executor: unknown command number " << command.command->command << ", ignoring.";
688 break;
689 }
690}
691
693{
694 display& disp = get_display();
695 for (const theme::menu& menu : disp.get_theme().menus()) {
696
697 std::shared_ptr<gui::button> button = disp.find_menu_button(menu.get_id());
698 if (!button) continue;
699 bool enabled = false;
700 for (const auto& command : menu.items()) {
701
702 ui_command command_obj = ui_command(command["id"].str());
703 bool can_execute = can_execute_command(command_obj);
704 if (can_execute) {
705 enabled = true;
706 break;
707 }
708 }
709 button->enable(enabled);
710 }
711
712 for (const theme::action& action : disp.get_theme().actions()) {
713
714 std::shared_ptr<gui::button> button = disp.find_action_button(action.get_id());
715 if (!button) continue;
716 bool enabled = false;
717 int i = 0;
718 for (const std::string& command : action.items()) {
719
720 ui_command command_obj = ui_command(command);
721 std::string tooltip = action.tooltip(i);
722 if (filesystem::file_exists(game_config::path + "/images/icons/action/" + command + "_25.png" ))
723 button->set_overlay("icons/action/" + command);
724 if (!tooltip.empty())
725 button->set_tooltip_string(tooltip);
726
727 bool can_execute = can_execute_command(command_obj);
728 i++;
729 if (!can_execute) continue;
730 enabled = true;
731
732 action_state state = get_action_state(command_obj);
733 switch (state) {
735 case action_state::on:
736 button->set_check(true);
737 break;
740 button->set_check(false);
741 break;
743 break;
744 default:
745 break;
746 }
747
748 break;
749 }
750 button->enable(enabled);
751 }
752}
753
754// Removes duplicate commands caused by both SDL_EVENT_KEY_DOWN and SDL_EVENT_TEXT_INPUT triggering hotkeys.
755// See https://github.com/wesnoth/wesnoth/issues/1736
756std::vector<command_executor::queued_command> command_executor::filter_command_queue()
757{
758 std::vector<queued_command> filtered_commands;
759
760 /** A command plus "key released" flag. Otherwise, we will filter out key releases that are preceded by a keypress. */
761 using command_with_keyrelease = std::pair<const hotkey_command*, bool>;
762 std::set<command_with_keyrelease> seen_commands;
763
764 for(const queued_command& cmd : command_queue_) {
765 command_with_keyrelease command_key(cmd.command, cmd.release);
766 if(seen_commands.find(command_key) == seen_commands.end()) {
767 seen_commands.insert(command_key);
768 filtered_commands.push_back(cmd);
769 }
770 }
771
772 command_queue_.clear();
773
774 return filtered_commands;
775}
776
778{
779 std::vector<queued_command> commands = filter_command_queue();
780 for(const queued_command& cmd : commands) {
782 }
783
784 return !commands.empty();
785}
786
791
796
805
810
812{
813 if(!get_display().view_locked()) {
814 get_display().set_zoom(true);
815 }
816}
817
819{
820 if(!get_display().view_locked()) {
821 get_display().set_zoom(false);
822 }
823}
824
826{
827 if(!get_display().view_locked()) {
829 }
830}
831
833{
834 make_screenshot(_("Map-Screenshot"), true);
835}
836}
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
Definition display.hpp:88
void recalculate_minimap()
Schedule the minimap for recalculation.
Definition display.cpp:1465
std::shared_ptr< gui::button > find_action_button(const std::string &id)
Retrieves a pointer to a theme UI button.
Definition display.cpp:768
std::shared_ptr< gui::button > find_menu_button(const std::string &id)
Definition display.cpp:778
bool set_zoom(bool increase)
Zooms the display in (true) or out (false).
Definition display.cpp:1643
surface screenshot(bool map_screenshot=false)
Capture a (map-)screenshot into a surface.
Definition display.cpp:723
theme & get_theme()
Definition display.hpp:382
void toggle_default_zoom()
Sets the zoom amount to the default.
Definition display.cpp:1711
static display * get_singleton()
Returns the display object if a display object exists.
Definition display.hpp:102
std::size_t viewing_team_index() const
The viewing team is the team currently viewing the game.
Definition display.hpp:117
Used by the menu_button widget.
static void display(lua_kernel_base *lk)
Display a new console, using given video and lua kernel.
@ yes_no_buttons
Shows a yes and no button.
Definition message.hpp:81
bool show(const unsigned auto_close_time=0)
Shows the window.
virtual display & get_display()=0
virtual void scroll_right(bool)
virtual void show_menu(const std::vector< config > &items_arg, const point &menu_loc, bool context_menu)
virtual void scroll_left(bool)
virtual void whiteboard_execute_all_actions()
virtual bool do_execute_command(const hotkey::ui_command &command, bool press=true, bool release=false)
virtual void whiteboard_execute_action()
virtual void show_enemy_moves(bool)
std::vector< queued_command > command_queue_
virtual void whiteboard_bump_down_action()
void execute_command_wrap(const queued_command &command)
void execute_action(const std::vector< std::string > &items_arg)
virtual action_state get_action_state(const hotkey::ui_command &) const
virtual void whiteboard_delete_action()
virtual bool keep_menu_open() const
If true, the menu will remain open after an item has been selected.
virtual void replay_show_everything()
virtual void toggle_accelerated_speed()
virtual void whiteboard_suppose_dead()
void populate_menu_item_info(config &item, int index) const
virtual void scroll_down(bool)
virtual void label_terrain(bool)
virtual void whiteboard_bump_up_action()
virtual bool can_execute_command(const hotkey::ui_command &command) const =0
std::vector< queued_command > filter_command_queue()
void queue_command(const SDL_Event &event, int index=-1)
void populate_menu_controls(config &item, int index) const
bool is_linger_mode() const
bool is_observer() const
void surrender(int side_number)
bool set_music(bool ison)
static prefs & get()
bool sound()
bool set_sound(bool ison)
bool music_on()
static void quit_to_desktop()
static void quit_to_title()
const std::vector< menu > & menus() const
Definition theme.hpp:256
const action * get_action_item(const std::string &key) const
Definition theme.cpp:940
const menu * get_menu_item(const std::string &key) const
Definition theme.cpp:931
const std::vector< action > & actions() const
Definition theme.hpp:258
#define LOG_HK
static lg::log_domain log_hotkey("hotkey")
static lg::log_domain log_config("config")
map_display and display: classes which take care of displaying the map and game-data on the screen.
Declarations for File-IO.
#define DBG_G
Definition gettext.cpp:36
static std::string _(const char *str)
Definition gettext.hpp:100
std::string tooltip
Shown when hovering over an entry in the filter's drop-down list.
Definition manager.cpp:203
Contains functions for cleanly handling SDL input.
Standard logging facilities (interface).
bool file_exists(const std::string &name)
Returns true if a file or directory with such name already exists.
std::string get_screenshot_dir()
std::string get_next_filename(const std::string &name, const std::string &extension)
Get the next free filename using "name + number (3 digits) + extension" maximum 1000 files then start...
std::string path
void switch_theme(const std::string &theme_id)
Set and activate the given gui2 theme.
Definition gui.cpp:149
void show_message(const std::string &title, const std::string &msg, const std::string &button_caption, const bool auto_close, const bool message_use_markup, const bool title_use_markup)
Shows a message to the user.
Definition message.cpp:148
@ CANCEL
Dialog was closed with the CANCEL button.
Definition retval.hpp:38
void show_help(const std::string &show_topic)
Open the help browser.
Definition help.cpp:84
Keyboard shortcuts for game actions.
void jhat_event(const SDL_Event &event, command_executor *executor)
void key_event(const SDL_Event &event, command_executor *executor)
void mbutton_event(const SDL_Event &event, command_executor *executor)
static void event_queue(const SDL_Event &event, command_executor *executor)
std::string get_names(const std::string &id)
Returns a comma-separated string of hotkey names.
std::shared_ptr< class hotkey_base > hotkey_ptr
const hotkey_ptr get_hotkey(const SDL_Event &event)
Iterate through the list of hotkeys and return a hotkey that matches the SDL_Event and the current ke...
void run_events(command_executor *executor)
void jbutton_event(const SDL_Event &event, command_executor *executor)
const hotkey_command & get_hotkey_command(std::string_view command)
Returns the hotkey_command with the given id.
void keyup_event(const SDL_Event &, command_executor *executor)
@ HOTKEY_MINIMAP_DRAW_VILLAGES
@ HOTKEY_TELEPORT_UNIT
@ HOTKEY_MOUSE_SCROLL
@ HOTKEY_TERRAIN_DESCRIPTION
@ HOTKEY_END_UNIT_TURN
@ HOTKEY_LABEL_SETTINGS
@ HOTKEY_WB_EXECUTE_ALL_ACTIONS
@ HOTKEY_WB_SUPPOSE_DEAD
@ HOTKEY_HELP_ABOUT_SAVELOAD
@ HOTKEY_SHOW_ENEMY_MOVES
@ HOTKEY_ACHIEVEMENTS
@ HOTKEY_DESELECT_HEX
@ HOTKEY_UNIT_DESCRIPTION
@ HOTKEY_UPDATE_SHROUD
@ HOTKEY_REPEAT_RECRUIT
@ HOTKEY_SCROLL_RIGHT
@ HOTKEY_LABEL_TEAM_TERRAIN
@ HOTKEY_UNIT_HOLD_POSITION
@ HOTKEY_REPLAY_NEXT_TURN
@ HOTKEY_SELECT_AND_ACTION
@ HOTKEY_REPLAY_SHOW_EVERYTHING
@ HOTKEY_REPLAY_SHOW_TEAM1
@ HOTKEY_MINIMAP_DRAW_TERRAIN
@ HOTKEY_LABEL_TERRAIN
@ HOTKEY_STOP_NETWORK
@ HOTKEY_MAP_SCREENSHOT
@ HOTKEY_CLEAR_LABELS
@ HOTKEY_CONTINUE_MOVE
@ HOTKEY_BEST_ENEMY_MOVES
@ HOTKEY_QUIT_TO_DESKTOP
@ HOTKEY_TOGGLE_ELLIPSES
@ HOTKEY_MINIMAP_CODING_TERRAIN
@ HOTKEY_WB_EXECUTE_ACTION
@ HOTKEY_MINIMAP_DRAW_UNITS
@ HOTKEY_DELAY_SHROUD
@ HOTKEY_WB_BUMP_UP_ACTION
@ HOTKEY_STATUS_TABLE
@ HOTKEY_REPLAY_NEXT_SIDE
@ HOTKEY_REPLAY_NEXT_MOVE
@ HOTKEY_REPLAY_RESET
@ HOTKEY_START_NETWORK
@ HOTKEY_REPLAY_SKIP_ANIMATION
@ HOTKEY_ZOOM_DEFAULT
@ HOTKEY_WB_BUMP_DOWN_ACTION
@ HOTKEY_REPLAY_SHOW_EACH
@ HOTKEY_CYCLE_BACK_UNITS
@ HOTKEY_WB_DELETE_ACTION
@ HOTKEY_MINIMAP_CODING_UNIT
play_controller * controller
Definition resources.cpp:21
Audio output for sound and music.
void toggle_fullscreen()
Toggle fullscreen mode.
Definition video.cpp:847
std::string filename
Filename.
Stores all information related to functions that can be bound to hotkeys.
HOTKEY_COMMAND command
The command associated with this hotkey.
Used as the main parameter for can_execute_command/do_execute_command These functions are used to exe...
hotkey::HOTKEY_COMMAND hotkey_command
The hotkey::HOTKEY_COMMAND associated with this action, HOTKEY_NULL for actions that don't allow hotk...
Holds a 2D point.
Definition point.hpp:25
An abstract description of a rectangle with integer coordinates.
Definition rect.hpp:49
#define i
#define b