The Battle for Wesnoth  1.19.8+dev
command_executor.cpp
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 
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*/, display& gui)
413 {
414  std::vector<config> items = items_arg;
415  if (items.empty()) return;
416 
417  get_menu_images(gui, 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 = gui.get_theme().get_menu_item(id);
439  if (submenu) {
440  this->show_menu(submenu->items(), selection_pos.x, selection_pos.y, submenu->is_context(), gui);
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, int /*xloc*/, int /*yloc*/, bool /*context_menu*/, display&)
449 {
450  std::vector<std::string> items = items_arg;
451  if (items.empty()) {
452  return;
453  }
454 
455  std::vector<std::string>::iterator i = items.begin();
456  while(i != items.end()) {
458  if (can_execute_command(cmd)) {
459  do_execute_command(cmd);
461  }
462  ++i;
463  }
464 }
465 
466 std::string command_executor::get_menu_image(display& disp, const std::string& command, int index) const
467 {
468  const std::string base_image_name = "icons/action/" + command + "_25.png";
469  const std::string pressed_image_name = "icons/action/" + command + "_25-pressed.png";
470 
472  const hotkey::ACTION_STATE state = get_action_state(cmd);
473 
474  const theme::menu* menu = disp.get_theme().get_menu_item(command);
475  if (menu) {
476  return "icons/arrows/short_arrow_right_25.png~CROP(3,3,18,18)"; // TODO should not be hardcoded
477  }
478 
479  if (filesystem::file_exists(game_config::path + "/images/" + base_image_name)) {
480  switch (state) {
481  case ACTION_ON:
482  case ACTION_SELECTED:
483  return pressed_image_name + "~CROP(3,3,18,18)";
484  default:
485  return base_image_name + "~CROP(3,3,18,18)";
486  }
487  }
488 
489  switch (get_action_state(cmd)) {
490  case ACTION_ON:
492  case ACTION_OFF:
494  case ACTION_SELECTED:
496  case ACTION_DESELECTED:
498  default: return get_action_image(cmd);
499  }
500 }
501 
502 void command_executor::get_menu_images(display& disp, std::vector<config>& items)
503 {
504  for(std::size_t i = 0; i < items.size(); ++i) {
505  config& item = items[i];
506 
507  const std::string& item_id = item["id"];
509 
510  //see if this menu item has an associated image
511  std::string img(get_menu_image(disp, item_id, i));
512  if (img.empty() == false) {
513  item["icon"] = img;
514  }
515 
516  const theme::menu* menu = disp.get_theme().get_menu_item(item_id);
517  if(menu) {
518  item["label"] = menu->title();
519  } else if(hk != hotkey::HOTKEY_NULL) {
520  std::string desc = hotkey::get_hotkey_command(item_id).description;
521  if(hk == HOTKEY_ENDTURN) {
522  const theme::action *b = disp.get_theme().get_action_item("button-endturn");
523  if (b) {
524  desc = b->title();
525  }
526  }
527 
528  item["label"] = desc;
529  item["details"] = hotkey::get_names(item_id);
530  }
531  }
532 }
533 
534 void mbutton_event(const SDL_Event& event, command_executor* executor)
535 {
536  event_queue(event, executor);
537 
538  /* Run mouse events immediately.
539 
540  This is necessary because the sidebar doesn't allow set_button_state() to be called after a
541  button has received the mouse press event but before it has received the mouse release event.
542  When https://github.com/wesnoth/wesnoth/pull/2872 delayed the processing of input events,
543  set_button_state() ended up being called at such a time. However, if we run the event handlers
544  now, the button (if any) hasn't received the press event yet and we can call set_button_state()
545  safely.
546 
547  See https://github.com/wesnoth/wesnoth/issues/2884 */
548 
549  run_events(executor);
550 }
551 
552 void jbutton_event(const SDL_Event& event, command_executor* executor)
553 {
554  event_queue(event, executor);
555 }
556 
557 void jhat_event(const SDL_Event& event, command_executor* executor)
558 {
559  event_queue(event, executor);
560 }
561 
562 void key_event(const SDL_Event& event, command_executor* executor)
563 {
564  if (!executor) return;
565  event_queue(event,executor);
566 }
567 
568 void keyup_event(const SDL_Event&, command_executor* executor)
569 {
570  if(!executor) return;
571  executor->handle_keyup();
572 }
573 
575 {
576  if(!executor) return;
577  bool commands_ran = executor->run_queued_commands();
578  if(commands_ran) {
579  executor->set_button_state();
580  }
581 }
582 
583 static void event_queue(const SDL_Event& event, command_executor* executor)
584 {
585  if (!executor) return;
586  executor->queue_command(event);
587  executor->set_button_state();
588 }
589 
590 void command_executor::queue_command(const SDL_Event& event, int index)
591 {
592  LOG_HK << "event 0x" << std::hex << event.type << std::dec;
593  if(event.type == SDL_TEXTINPUT) {
594  LOG_HK << "SDL_TEXTINPUT \"" << event.text.text << "\"";
595  }
596 
597  const hotkey_ptr hk = get_hotkey(event);
598  if(!hk->active() || hk->is_disabled()) {
599  return;
600  }
601 
602  const hotkey_command& command = hotkey::get_hotkey_command(hk->get_command());
603  bool keypress = (event.type == SDL_KEYDOWN || event.type == SDL_TEXTINPUT) &&
605  bool press = keypress ||
606  (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_FINGERDOWN);
607  bool release = event.type == SDL_KEYUP;
608  if(press) {
609  LOG_HK << "sending press event (keypress = " <<
610  std::boolalpha << keypress << std::noboolalpha << ")";
611  }
612  if(keypress) {
613  press_event_sent_ = true;
614  }
615 
616  command_queue_.emplace_back(command, index, press, release);
617 }
618 
620 {
621  auto ui_cmd = hotkey::ui_command(*command.command, command.index);
622  if (!can_execute_command(ui_cmd)
623  || do_execute_command(ui_cmd, command.press, command.release)) {
624  return;
625  }
626 
627  if (!command.press) {
628  return; // none of the commands here respond to a key release
629  }
630 
631  switch(command.command->command) {
632  case HOTKEY_FULLSCREEN:
634  break;
635  case HOTKEY_SCREENSHOT:
636  make_screenshot(_("Screenshot"), false);
637  break;
638  case HOTKEY_ANIMATE_MAP:
639  prefs::get().set_animate_map(!prefs::get().animate_map());
640  break;
641  case HOTKEY_MOUSE_SCROLL:
642  prefs::get().set_mouse_scrolling(!prefs::get().mouse_scrolling());
643  break;
644  case HOTKEY_MUTE:
645  {
646  // look if both is not playing
647  static struct before_muted_s
648  {
649  bool playing_sound,playing_music;
650  before_muted_s() : playing_sound(false),playing_music(false){}
651  } before_muted;
652  if (prefs::get().music_on() || prefs::get().sound())
653  {
654  // then remember settings and mute both
655  before_muted.playing_sound = prefs::get().sound();
656  before_muted.playing_music = prefs::get().music_on();
657  prefs::get().set_sound(false);
658  prefs::get().set_music(false);
659  }
660  else
661  {
662  // then set settings before mute
663  prefs::get().set_sound(before_muted.playing_sound);
664  prefs::get().set_music(before_muted.playing_music);
665  }
666  }
667  break;
668  default:
669  DBG_G << "command_executor: unknown command number " << command.command->command << ", ignoring.";
670  break;
671  }
672 }
673 
675 {
676  display& disp = get_display();
677  for (const theme::menu& menu : disp.get_theme().menus()) {
678 
679  std::shared_ptr<gui::button> button = disp.find_menu_button(menu.get_id());
680  if (!button) continue;
681  bool enabled = false;
682  for (const auto& command : menu.items()) {
683 
684  ui_command command_obj = ui_command(command["id"].str());
685  bool can_execute = can_execute_command(command_obj);
686  if (can_execute) {
687  enabled = true;
688  break;
689  }
690  }
691  button->enable(enabled);
692  }
693 
694  for (const theme::action& action : disp.get_theme().actions()) {
695 
696  std::shared_ptr<gui::button> button = disp.find_action_button(action.get_id());
697  if (!button) continue;
698  bool enabled = false;
699  int i = 0;
700  for (const std::string& command : action.items()) {
701 
702  ui_command command_obj = ui_command(command);
703  std::string tooltip = action.tooltip(i);
704  if (filesystem::file_exists(game_config::path + "/images/icons/action/" + command + "_25.png" ))
705  button->set_overlay("icons/action/" + command);
706  if (!tooltip.empty())
707  button->set_tooltip_string(tooltip);
708 
709  bool can_execute = can_execute_command(command_obj);
710  i++;
711  if (!can_execute) continue;
712  enabled = true;
713 
714  ACTION_STATE state = get_action_state(command_obj);
715  switch (state) {
716  case ACTION_SELECTED:
717  case ACTION_ON:
718  button->set_check(true);
719  break;
720  case ACTION_OFF:
721  case ACTION_DESELECTED:
722  button->set_check(false);
723  break;
724  case ACTION_STATELESS:
725  break;
726  default:
727  break;
728  }
729 
730  break;
731  }
732  button->enable(enabled);
733  }
734 }
735 
736 // Removes duplicate commands caused by both SDL_KEYDOWN and SDL_TEXTINPUT triggering hotkeys.
737 // See https://github.com/wesnoth/wesnoth/issues/1736
738 std::vector<command_executor::queued_command> command_executor::filter_command_queue()
739 {
740  std::vector<queued_command> filtered_commands;
741 
742  /** A command plus "key released" flag. Otherwise, we will filter out key releases that are preceded by a keypress. */
743  using command_with_keyrelease = std::pair<const hotkey_command*, bool>;
744  std::set<command_with_keyrelease> seen_commands;
745 
746  for(const queued_command& cmd : command_queue_) {
747  command_with_keyrelease command_key(cmd.command, cmd.release);
748  if(seen_commands.find(command_key) == seen_commands.end()) {
749  seen_commands.insert(command_key);
750  filtered_commands.push_back(cmd);
751  }
752  }
753 
754  command_queue_.clear();
755 
756  return filtered_commands;
757 }
758 
760 {
761  std::vector<queued_command> commands = filter_command_queue();
762  for(const queued_command& cmd : commands) {
764  }
765 
766  return !commands.empty();
767 }
768 
770 {
772 }
773 
775 {
776  if (get_display().in_game()) {
778  } else {
780  }
781 
782 }
783 
785 {
787 }
788 
790 {
791  if(!get_display().view_locked()) {
792  get_display().set_zoom(true);
793  }
794 }
795 
797 {
798  if(!get_display().view_locked()) {
799  get_display().set_zoom(false);
800  }
801 }
802 
804 {
805  if(!get_display().view_locked()) {
807  }
808 }
809 
811 {
812  make_screenshot(_("Map-Screenshot"), true);
813 }
814 }
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:97
void recalculate_minimap()
Schedule the minimap for recalculation.
Definition: display.cpp:1577
std::shared_ptr< gui::button > find_action_button(const std::string &id)
Retrieves a pointer to a theme UI button.
Definition: display.cpp:771
std::shared_ptr< gui::button > find_menu_button(const std::string &id)
Definition: display.cpp:781
bool set_zoom(bool increase)
Zooms the display in (true) or out (false).
Definition: display.cpp:1804
surface screenshot(bool map_screenshot=false)
Capture a (map-)screenshot into a surface.
Definition: display.cpp:726
theme & get_theme()
Definition: display.hpp:390
void toggle_default_zoom()
Sets the zoom amount to the default.
Definition: display.cpp:1872
static display * get_singleton()
Returns the display object if a display object exists.
Definition: display.hpp:111
std::size_t viewing_team_index() const
The viewing team is the team currently viewing the game.
Definition: display.hpp:126
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()
virtual void scroll_up(bool)
virtual void scroll_left(bool)
virtual void whiteboard_execute_all_actions()
void get_menu_images(display &, std::vector< config > &items)
virtual bool do_execute_command(const hotkey::ui_command &command, bool press=true, bool release=false)
virtual void whiteboard_execute_action()
void execute_action(const std::vector< std::string > &items_arg, int xloc, int yloc, bool context_menu, display &gui)
virtual void show_enemy_moves(bool)
std::vector< queued_command > command_queue_
std::string get_menu_image(display &disp, const std::string &command, int index=-1) const
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)
virtual void whiteboard_delete_action()
virtual void replay_show_everything()
virtual void toggle_accelerated_speed()
virtual void whiteboard_suppose_dead()
virtual void show_menu(const std::vector< config > &items_arg, int xloc, int yloc, bool context_menu, display &gui)
virtual void scroll_down(bool)
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
const action * get_action_item(const std::string &key) const
Definition: theme.cpp:926
const menu * get_menu_item(const std::string &key) const
Definition: theme.cpp:917
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:1029
static std::string _(const char *str)
Definition: gettext.hpp:93
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:327
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:587
std::string selected_menu
std::string deselected_menu
std::string unchecked_menu
std::string checked_menu
std::string path
Definition: filesystem.cpp:92
static void make_screenshot()
static bool sound()
static bool music_on()
void switch_theme(const std::string &current_theme)
Set and activate the given gui2 theme.
Definition: gui.cpp:135
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
General purpose widgets.
void show_help(const std::string &show_topic)
Open the help browser, show topic with id show_topic.
Definition: help.cpp:140
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:809
std::string::const_iterator iterator
Definition: tokenizer.hpp:25
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 paramneter for can_execute_command/do_execute_command These functions are used to ex...
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