The Battle for Wesnoth  1.19.13+dev
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 
17 #include "hotkey/hotkey_item.hpp"
18 
19 #include "gui/gui.hpp"
22 #include "gui/dialogs/message.hpp"
25 #include "gui/widgets/retval.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 
39 
40 #include <ios>
41 #include <set>
42 
43 static lg::log_domain log_config("config");
44 static lg::log_domain log_hotkey("hotkey");
45 #define ERR_G LOG_STREAM(err, lg::general())
46 #define WRN_G LOG_STREAM(warn, lg::general())
47 #define LOG_G LOG_STREAM(info, lg::general())
48 #define DBG_G LOG_STREAM(debug, lg::general())
49 #define ERR_CF LOG_STREAM(err, log_config)
50 #define LOG_HK LOG_STREAM(info, log_hotkey)
51 
52 namespace {
53 
54 void make_screenshot(const std::string& name, bool map_screenshot)
55 {
56  surface screenshot = display::get_singleton()->screenshot(map_screenshot);
57  if(screenshot) {
58  std::string filename = filesystem::get_screenshot_dir() + "/" + name + "_";
60  gui2::dialogs::screenshot_notification::display(filename, screenshot);
61  }
62 }
63 }
64 namespace hotkey {
65 
66 static void event_queue(const SDL_Event& event, command_executor* executor);
67 
68 bool command_executor::do_execute_command(const hotkey::ui_command& cmd, bool press, bool release)
69 {
70  // hotkey release handling
71  if (release) {
72  switch(cmd.hotkey_command) {
73  // release a scroll key, un-apply scrolling in the given direction
74  case HOTKEY_SCROLL_UP:
75  scroll_up(false);
76  break;
77  case HOTKEY_SCROLL_DOWN:
78  scroll_down(false);
79  break;
80  case HOTKEY_SCROLL_LEFT:
81  scroll_left(false);
82  break;
84  scroll_right(false);
85  break;
86  default:
87  return false; // nothing else handles a hotkey release
88  }
89 
90  return true;
91  }
92 
93  // handling of hotkeys which activate even on hold events
94  switch(cmd.hotkey_command) {
97  return true;
98  case HOTKEY_SCROLL_UP:
99  scroll_up(true);
100  return true;
101  case HOTKEY_SCROLL_DOWN:
102  scroll_down(true);
103  return true;
104  case HOTKEY_SCROLL_LEFT:
105  scroll_left(true);
106  return true;
107  case HOTKEY_SCROLL_RIGHT:
108  scroll_right(true);
109  return true;
110  default:
111  break;
112  }
113 
114  if(!press) {
115  return false; // nothing else handles hotkey hold events
116  }
117 
118  // hotkey press handling
119  switch(cmd.hotkey_command) {
120  case HOTKEY_CYCLE_UNITS:
121  cycle_units();
122  break;
125  break;
126  case HOTKEY_ENDTURN:
127  end_turn();
128  break;
131  break;
133  end_unit_turn();
134  break;
135  case HOTKEY_LEADER:
136  goto_leader();
137  break;
138  case HOTKEY_UNDO:
139  undo();
140  break;
141  case HOTKEY_REDO:
142  redo();
143  break;
146  break;
149  break;
150  case HOTKEY_RENAME_UNIT:
151  rename_unit();
152  break;
153  case HOTKEY_SAVE_GAME:
154  save_game();
155  break;
156  case HOTKEY_SAVE_REPLAY:
157  save_replay();
158  break;
159  case HOTKEY_SAVE_MAP:
160  save_map();
161  break;
162  case HOTKEY_LOAD_GAME:
163  load_game();
164  break;
166  toggle_ellipses();
167  break;
168  case HOTKEY_TOGGLE_GRID:
169  toggle_grid();
170  break;
171  case HOTKEY_STATUS_TABLE:
172  status_table();
173  break;
174  case HOTKEY_RECALL:
175  recall();
176  break;
178  label_settings();
179  break;
180  case HOTKEY_RECRUIT:
181  recruit();
182  break;
183  case HOTKEY_SPEAK:
184  speak();
185  break;
186  case HOTKEY_SPEAK_ALLY:
187  whisper();
188  break;
189  case HOTKEY_SPEAK_ALL:
190  shout();
191  break;
192  case HOTKEY_CREATE_UNIT:
193  create_unit();
194  break;
195  case HOTKEY_CHANGE_SIDE:
196  change_side();
197  break;
198  case HOTKEY_KILL_UNIT:
199  kill_unit();
200  break;
202  select_teleport();
203  break;
204  case HOTKEY_PREFERENCES:
205  preferences();
206  break;
207  case HOTKEY_OBJECTIVES:
208  objectives();
209  break;
210  case HOTKEY_UNIT_LIST:
211  unit_list();
212  break;
213  case HOTKEY_STATISTICS:
214  show_statistics();
215  break;
216  case HOTKEY_STOP_NETWORK:
217  stop_network();
218  break;
220  start_network();
221  break;
223  label_terrain(true);
224  break;
226  label_terrain(false);
227  break;
228  case HOTKEY_CLEAR_LABELS:
229  clear_labels();
230  break;
232  show_enemy_moves(false);
233  break;
235  show_enemy_moves(true);
236  break;
237  case HOTKEY_DELAY_SHROUD:
239  break;
242  break;
244  continue_move();
245  break;
246  case HOTKEY_SEARCH:
247  search();
248  break;
249  case HOTKEY_HELP:
250  show_help();
251  break;
253  // although HOTKEY_HELP uses a virtual call to allow context-specific help, this one is already a specific topic
254  help::show_help("saveload");
255  break;
256  case HOTKEY_CHAT_LOG:
257  show_chat_log();
258  break;
259  case HOTKEY_USER_CMD:
260  user_command();
261  break;
262  case HOTKEY_CUSTOM_CMD:
263  custom_command();
264  break;
265  case HOTKEY_AI_FORMULA:
266  ai_formula();
267  break;
268  case HOTKEY_CLEAR_MSG:
269  clear_messages();
270  break;
271  case HOTKEY_LANGUAGE:
272  change_language();
273  break;
274  case HOTKEY_REPLAY_PLAY:
275  play_replay();
276  break;
277  case HOTKEY_REPLAY_RESET:
278  reset_replay();
279  break;
280  case HOTKEY_REPLAY_STOP:
281  stop_replay();
282  break;
285  break;
288  break;
291  break;
294  break;
297  break;
300  break;
303  break;
304  case HOTKEY_REPLAY_EXIT:
305  replay_exit();
306  break;
307  case HOTKEY_WB_TOGGLE:
309  break;
312  break;
315  break;
318  break;
321  break;
324  break;
327  break;
328  case HOTKEY_SELECT_HEX:
329  select_hex();
330  break;
331  case HOTKEY_DESELECT_HEX:
332  deselect_hex();
333  break;
334  case HOTKEY_MOVE_ACTION:
335  move_action();
336  break;
339  break;
340  case HOTKEY_TOUCH_HEX:
341  touch_hex();
342  break;
343  case HOTKEY_ACCELERATED:
345  break;
346  case LUA_CONSOLE:
347  lua_console();
348  break;
349  case HOTKEY_ZOOM_IN:
350  zoom_in();
351  break;
352  case HOTKEY_ZOOM_OUT:
353  zoom_out();
354  break;
355  case HOTKEY_ZOOM_DEFAULT:
356  zoom_default();
357  break;
359  map_screenshot();
360  break;
363  break;
364  case HOTKEY_QUIT_GAME:
365  gui2::switch_theme(prefs::get().gui2_theme());
367  break;
368  case HOTKEY_SURRENDER:
369  surrender_game();
370  break;
372  prefs::get().set_minimap_draw_terrain(!prefs::get().minimap_draw_terrain());
374  break;
376  prefs::get().set_minimap_terrain_coding(!prefs::get().minimap_terrain_coding());
378  break;
380  prefs::get().set_minimap_movement_coding(!prefs::get().minimap_movement_coding());
382  break;
384  prefs::get().set_minimap_draw_units(!prefs::get().minimap_draw_units());
386  break;
388  prefs::get().set_minimap_draw_villages(!prefs::get().minimap_draw_villages());
390  break;
391  case HOTKEY_ACHIEVEMENTS:
392  {
394  ach.show();
395  }
396  break;
397  default:
398  return false;
399  }
400  return true;
401 }
402 
404  if(gui2::show_message(_("Surrender"), _("Do you really want to surrender the game?"), gui2::dialogs::message::yes_no_buttons) != gui2::retval::CANCEL) {
406  if(pmc && !pmc->is_linger_mode() && !pmc->is_observer()) {
408  }
409  }
410 }
411 
412 void command_executor::show_menu(const std::vector<config>& items_arg, int xloc, int yloc, bool /*context_menu*/)
413 {
414  std::vector<config> items = items_arg;
415  if (items.empty()) return;
416 
417  get_menu_images(items);
418 
419  int res = -1;
420  point selection_pos;
421  {
422  SDL_Rect pos {xloc, yloc, 1, 1};
423  gui2::dialogs::drop_down_menu mmenu(pos, items, -1, true, false); // TODO: last value should be variable
424  if(mmenu.show()) {
425  res = mmenu.selected_item();
426  if(res >= 0) {
427  // Get selection coordinates for a potential submenu below
428  selection_pos = mmenu.selected_item_pos();
429  // Compensate for borders
430  selection_pos.x--;
431  selection_pos.y--;
432  }
433  }
434  } // This will kill the dialog.
435  if (res < 0 || std::size_t(res) >= items.size()) return;
436 
437  std::string id = items[res]["id"];
438  const theme::menu* submenu = display::get_singleton()->get_theme().get_menu_item(id);
439  if (submenu) {
440  this->show_menu(submenu->items(), selection_pos.x, selection_pos.y, submenu->is_context());
441  } else {
442  hotkey::ui_command cmd = hotkey::ui_command(id, res);
443  do_execute_command(cmd);
445  }
446 }
447 
448 void command_executor::execute_action(const std::vector<std::string>& items_arg)
449 {
450  for(const std::string& item : items_arg) {
451  auto cmd = hotkey::ui_command(item);
452  if(can_execute_command(cmd)) {
453  do_execute_command(cmd);
455  }
456  }
457 }
458 
459 std::string command_executor::get_menu_image(const std::string& command, int index) const
460 {
461  const std::string base_image_name = "icons/action/" + command + "_25.png";
462  const std::string pressed_image_name = "icons/action/" + command + "_25-pressed.png";
463 
465  const hotkey::ACTION_STATE state = get_action_state(cmd);
466 
467  const theme::menu* menu = display::get_singleton()->get_theme().get_menu_item(command);
468  if (menu) {
469  return "icons/arrows/short_arrow_right_25.png~CROP(3,3,18,18)"; // TODO should not be hardcoded
470  }
471 
472  if (filesystem::file_exists(game_config::path + "/images/" + base_image_name)) {
473  switch (state) {
474  case ACTION_ON:
475  case ACTION_SELECTED:
476  return pressed_image_name + "~CROP(3,3,18,18)";
477  default:
478  return base_image_name + "~CROP(3,3,18,18)";
479  }
480  }
481 
482  switch (get_action_state(cmd)) {
483  case ACTION_ON:
485  case ACTION_OFF:
487  case ACTION_SELECTED:
489  case ACTION_DESELECTED:
491  default: return get_action_image(cmd);
492  }
493 }
494 
495 void command_executor::get_menu_images(std::vector<config>& items)
496 {
497  for(std::size_t i = 0; i < items.size(); ++i) {
498  config& item = items[i];
499 
500  const std::string& item_id = item["id"];
502 
503  //see if this menu item has an associated image
504  std::string img(get_menu_image(item_id, i));
505  if (img.empty() == false) {
506  item["icon"] = img;
507  }
508 
510  const theme::menu* menu = theme.get_menu_item(item_id);
511  if(menu) {
512  item["label"] = menu->title();
513  } else if(hk != hotkey::HOTKEY_NULL) {
514  std::string desc = hotkey::get_hotkey_command(item_id).description;
515  if(hk == HOTKEY_ENDTURN) {
516  const theme::action *b = theme.get_action_item("button-endturn");
517  if (b) {
518  desc = b->title();
519  }
520  }
521 
522  item["label"] = desc;
523  item["details"] = hotkey::get_names(item_id);
524  }
525  }
526 }
527 
528 void mbutton_event(const SDL_Event& event, command_executor* executor)
529 {
530  event_queue(event, executor);
531 
532  /* Run mouse events immediately.
533 
534  This is necessary because the sidebar doesn't allow set_button_state() to be called after a
535  button has received the mouse press event but before it has received the mouse release event.
536  When https://github.com/wesnoth/wesnoth/pull/2872 delayed the processing of input events,
537  set_button_state() ended up being called at such a time. However, if we run the event handlers
538  now, the button (if any) hasn't received the press event yet and we can call set_button_state()
539  safely.
540 
541  See https://github.com/wesnoth/wesnoth/issues/2884 */
542 
543  run_events(executor);
544 }
545 
546 void jbutton_event(const SDL_Event& event, command_executor* executor)
547 {
548  event_queue(event, executor);
549 }
550 
551 void jhat_event(const SDL_Event& event, command_executor* executor)
552 {
553  event_queue(event, executor);
554 }
555 
556 void key_event(const SDL_Event& event, command_executor* executor)
557 {
558  if (!executor) return;
559  event_queue(event,executor);
560 }
561 
562 void keyup_event(const SDL_Event&, command_executor* executor)
563 {
564  if(!executor) return;
565  executor->handle_keyup();
566 }
567 
569 {
570  if(!executor) return;
571  bool commands_ran = executor->run_queued_commands();
572  if(commands_ran) {
573  executor->set_button_state();
574  }
575 }
576 
577 static void event_queue(const SDL_Event& event, command_executor* executor)
578 {
579  if (!executor) return;
580  executor->queue_command(event);
581  executor->set_button_state();
582 }
583 
584 void command_executor::queue_command(const SDL_Event& event, int index)
585 {
586  LOG_HK << "event 0x" << std::hex << event.type << std::dec;
587  if(event.type == SDL_TEXTINPUT) {
588  LOG_HK << "SDL_TEXTINPUT \"" << event.text.text << "\"";
589  }
590 
591  const hotkey_ptr hk = get_hotkey(event);
592  if(!hk->active() || hk->is_disabled()) {
593  return;
594  }
595 
596  const hotkey_command& command = hotkey::get_hotkey_command(hk->get_command());
597  bool keypress = (event.type == SDL_KEYDOWN || event.type == SDL_TEXTINPUT) &&
599  bool press = keypress ||
600  (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_FINGERDOWN);
601  bool release = event.type == SDL_KEYUP;
602  if(press) {
603  LOG_HK << "sending press event (keypress = " <<
604  std::boolalpha << keypress << std::noboolalpha << ")";
605  }
606  if(keypress) {
607  press_event_sent_ = true;
608  }
609 
610  command_queue_.emplace_back(command, index, press, release);
611 }
612 
614 {
615  auto ui_cmd = hotkey::ui_command(*command.command, command.index);
616  if (!can_execute_command(ui_cmd)
617  || do_execute_command(ui_cmd, command.press, command.release)) {
618  return;
619  }
620 
621  if (!command.press) {
622  return; // none of the commands here respond to a key release
623  }
624 
625  switch(command.command->command) {
626  case HOTKEY_FULLSCREEN:
628  break;
629  case HOTKEY_SCREENSHOT:
630  make_screenshot(_("Screenshot"), false);
631  break;
632  case HOTKEY_ANIMATE_MAP:
633  prefs::get().set_animate_map(!prefs::get().animate_map());
634  break;
635  case HOTKEY_MOUSE_SCROLL:
636  prefs::get().set_mouse_scrolling(!prefs::get().mouse_scrolling());
637  break;
638  case HOTKEY_MUTE:
639  {
640  // look if both is not playing
641  static struct before_muted_s
642  {
643  bool playing_sound,playing_music;
644  before_muted_s() : playing_sound(false),playing_music(false){}
645  } before_muted;
646  if (prefs::get().music_on() || prefs::get().sound())
647  {
648  // then remember settings and mute both
649  before_muted.playing_sound = prefs::get().sound();
650  before_muted.playing_music = prefs::get().music_on();
651  prefs::get().set_sound(false);
652  prefs::get().set_music(false);
653  }
654  else
655  {
656  // then set settings before mute
657  prefs::get().set_sound(before_muted.playing_sound);
658  prefs::get().set_music(before_muted.playing_music);
659  }
660  }
661  break;
662  default:
663  DBG_G << "command_executor: unknown command number " << command.command->command << ", ignoring.";
664  break;
665  }
666 }
667 
669 {
670  display& disp = get_display();
671  for (const theme::menu& menu : disp.get_theme().menus()) {
672 
673  std::shared_ptr<gui::button> button = disp.find_menu_button(menu.get_id());
674  if (!button) continue;
675  bool enabled = false;
676  for (const auto& command : menu.items()) {
677 
678  ui_command command_obj = ui_command(command["id"].str());
679  bool can_execute = can_execute_command(command_obj);
680  if (can_execute) {
681  enabled = true;
682  break;
683  }
684  }
685  button->enable(enabled);
686  }
687 
688  for (const theme::action& action : disp.get_theme().actions()) {
689 
690  std::shared_ptr<gui::button> button = disp.find_action_button(action.get_id());
691  if (!button) continue;
692  bool enabled = false;
693  int i = 0;
694  for (const std::string& command : action.items()) {
695 
696  ui_command command_obj = ui_command(command);
697  std::string tooltip = action.tooltip(i);
698  if (filesystem::file_exists(game_config::path + "/images/icons/action/" + command + "_25.png" ))
699  button->set_overlay("icons/action/" + command);
700  if (!tooltip.empty())
701  button->set_tooltip_string(tooltip);
702 
703  bool can_execute = can_execute_command(command_obj);
704  i++;
705  if (!can_execute) continue;
706  enabled = true;
707 
708  ACTION_STATE state = get_action_state(command_obj);
709  switch (state) {
710  case ACTION_SELECTED:
711  case ACTION_ON:
712  button->set_check(true);
713  break;
714  case ACTION_OFF:
715  case ACTION_DESELECTED:
716  button->set_check(false);
717  break;
718  case ACTION_STATELESS:
719  break;
720  default:
721  break;
722  }
723 
724  break;
725  }
726  button->enable(enabled);
727  }
728 }
729 
730 // Removes duplicate commands caused by both SDL_KEYDOWN and SDL_TEXTINPUT triggering hotkeys.
731 // See https://github.com/wesnoth/wesnoth/issues/1736
732 std::vector<command_executor::queued_command> command_executor::filter_command_queue()
733 {
734  std::vector<queued_command> filtered_commands;
735 
736  /** A command plus "key released" flag. Otherwise, we will filter out key releases that are preceded by a keypress. */
737  using command_with_keyrelease = std::pair<const hotkey_command*, bool>;
738  std::set<command_with_keyrelease> seen_commands;
739 
740  for(const queued_command& cmd : command_queue_) {
741  command_with_keyrelease command_key(cmd.command, cmd.release);
742  if(seen_commands.find(command_key) == seen_commands.end()) {
743  seen_commands.insert(command_key);
744  filtered_commands.push_back(cmd);
745  }
746  }
747 
748  command_queue_.clear();
749 
750  return filtered_commands;
751 }
752 
754 {
755  std::vector<queued_command> commands = filter_command_queue();
756  for(const queued_command& cmd : commands) {
758  }
759 
760  return !commands.empty();
761 }
762 
764 {
766 }
767 
769 {
770  if (get_display().in_game()) {
772  } else {
774  }
775 
776 }
777 
779 {
781 }
782 
784 {
785  if(!get_display().view_locked()) {
786  get_display().set_zoom(true);
787  }
788 }
789 
791 {
792  if(!get_display().view_locked()) {
793  get_display().set_zoom(false);
794  }
795 }
796 
798 {
799  if(!get_display().view_locked()) {
801  }
802 }
803 
805 {
806  make_screenshot(_("Map-Screenshot"), true);
807 }
808 }
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:158
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:1455
std::shared_ptr< gui::button > find_action_button(const std::string &id)
Retrieves a pointer to a theme UI button.
Definition: display.cpp:759
std::shared_ptr< gui::button > find_menu_button(const std::string &id)
Definition: display.cpp:769
bool set_zoom(bool increase)
Zooms the display in (true) or out (false).
Definition: display.cpp:1682
surface screenshot(bool map_screenshot=false)
Capture a (map-)screenshot into a surface.
Definition: display.cpp:714
theme & get_theme()
Definition: display.hpp:381
void toggle_default_zoom()
Sets the zoom amount to the default.
Definition: display.cpp:1750
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 replay_skip_animation()
std::string get_menu_image(const std::string &command, int index=-1) const
virtual void scroll_up(bool)
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 ACTION_STATE get_action_state(const hotkey::ui_command &) const
virtual void toggle_shroud_updates()
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 void whiteboard_delete_action()
virtual void replay_show_everything()
virtual void toggle_accelerated_speed()
virtual void whiteboard_suppose_dead()
virtual void scroll_down(bool)
virtual void show_menu(const std::vector< config > &items_arg, int xloc, int yloc, bool context_menu)
void get_menu_images(std::vector< config > &items)
virtual void label_terrain(bool)
virtual void whiteboard_bump_up_action()
virtual void unit_hold_position()
virtual void terrain_description()
virtual void recalculate_minimap()
virtual std::string get_action_image(const hotkey::ui_command &) const
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)
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::string & title() const
Definition: theme.hpp:229
bool is_context() const
Definition: theme.hpp:227
const std::vector< config > & items() const
Definition: theme.hpp:237
Definition: theme.hpp:44
const action * get_action_item(const std::string &key) const
Definition: theme.cpp:924
const menu * get_menu_item(const std::string &key) const
Definition: theme.cpp:915
const std::vector< action > & actions() const
Definition: theme.hpp:259
const std::vector< menu > & menus() const
Definition: theme.hpp:257
#define LOG_HK
static lg::log_domain log_hotkey("hotkey")
#define DBG_G
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.
std::size_t i
Definition: function.cpp:1032
static std::string _(const char *str)
Definition: gettext.hpp:97
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).
static bool file_exists(const bfs::path &fpath)
Definition: filesystem.cpp:341
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...
Definition: filesystem.cpp:601
std::string selected_menu
std::string deselected_menu
std::string unchecked_menu
std::string checked_menu
std::string path
Definition: filesystem.cpp:106
static bool sound()
static bool music_on()
void switch_theme(const std::string &theme_id)
Set and activate the given gui2 theme.
Definition: gui.cpp:150
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, show topic with id show_topic.
Definition: help.cpp:139
Keyboard shortcuts for game actions.
void jhat_event(const SDL_Event &event, command_executor *executor)
const hotkey_command & get_hotkey_command(const std::string &command)
returns the hotkey_command with the given name
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
Definition: hotkey_item.hpp:27
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)
void keyup_event(const SDL_Event &, command_executor *executor)
@ HOTKEY_MINIMAP_DRAW_VILLAGES
@ HOTKEY_FULLSCREEN
@ HOTKEY_OBJECTIVES
@ HOTKEY_ANIMATE_MAP
@ HOTKEY_SCREENSHOT
@ HOTKEY_TELEPORT_UNIT
@ HOTKEY_SPEAK_ALLY
@ HOTKEY_ACCELERATED
@ 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_REPLAY_PLAY
@ HOTKEY_SCROLL_LEFT
@ HOTKEY_SAVE_GAME
@ HOTKEY_SPEAK_ALL
@ HOTKEY_SHOW_ENEMY_MOVES
@ HOTKEY_ACHIEVEMENTS
@ HOTKEY_DESELECT_HEX
@ HOTKEY_UNIT_DESCRIPTION
@ HOTKEY_UPDATE_SHROUD
@ HOTKEY_REPEAT_RECRUIT
@ HOTKEY_REPLAY_STOP
@ HOTKEY_KILL_UNIT
@ HOTKEY_SCROLL_RIGHT
@ HOTKEY_SAVE_REPLAY
@ HOTKEY_LABEL_TEAM_TERRAIN
@ HOTKEY_UNIT_HOLD_POSITION
@ HOTKEY_REPLAY_NEXT_TURN
@ HOTKEY_TOGGLE_GRID
@ 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_CUSTOM_CMD
@ HOTKEY_STOP_NETWORK
@ HOTKEY_MAP_SCREENSHOT
@ HOTKEY_CLEAR_LABELS
@ HOTKEY_CONTINUE_MOVE
@ HOTKEY_BEST_ENEMY_MOVES
@ HOTKEY_QUIT_TO_DESKTOP
@ HOTKEY_TOGGLE_ELLIPSES
@ HOTKEY_RENAME_UNIT
@ HOTKEY_MINIMAP_CODING_TERRAIN
@ HOTKEY_LOAD_GAME
@ HOTKEY_WB_EXECUTE_ACTION
@ HOTKEY_MINIMAP_DRAW_UNITS
@ HOTKEY_CHANGE_SIDE
@ HOTKEY_CYCLE_UNITS
@ HOTKEY_DELAY_SHROUD
@ HOTKEY_WB_BUMP_UP_ACTION
@ HOTKEY_CREATE_UNIT
@ HOTKEY_REPLAY_EXIT
@ HOTKEY_PREFERENCES
@ HOTKEY_STATUS_TABLE
@ HOTKEY_REPLAY_NEXT_SIDE
@ HOTKEY_MOVE_ACTION
@ HOTKEY_REPLAY_NEXT_MOVE
@ HOTKEY_REPLAY_RESET
@ HOTKEY_TOUCH_HEX
@ HOTKEY_START_NETWORK
@ HOTKEY_WB_TOGGLE
@ HOTKEY_STATISTICS
@ HOTKEY_UNIT_LIST
@ HOTKEY_SCROLL_DOWN
@ HOTKEY_REPLAY_SKIP_ANIMATION
@ HOTKEY_ZOOM_DEFAULT
@ HOTKEY_WB_BUMP_DOWN_ACTION
@ HOTKEY_SCROLL_UP
@ HOTKEY_SELECT_HEX
@ HOTKEY_QUIT_GAME
@ HOTKEY_AI_FORMULA
@ HOTKEY_REPLAY_SHOW_EACH
@ HOTKEY_CYCLE_BACK_UNITS
@ HOTKEY_WB_DELETE_ACTION
@ HOTKEY_MINIMAP_CODING_UNIT
std::string img(const std::string &src, const std::string &align, bool floating)
Generates a Help markup tag corresponding to an image.
Definition: markup.cpp:31
play_controller * controller
Definition: resources.cpp:21
std::size_t index(std::string_view str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:70
void toggle_fullscreen()
Toggle fullscreen mode.
Definition: video.cpp:825
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
#define b