The Battle for Wesnoth  1.19.1+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 
21 #include "gui/dialogs/message.hpp"
24 #include "gui/widgets/retval.hpp"
25 #include "filesystem.hpp"
26 #include "gettext.hpp"
27 #include "log.hpp"
29 #include "display.hpp"
30 #include "quit_confirmation.hpp"
31 #include "sdl/surface.hpp"
32 #include "../resources.hpp"
33 #include "../playmp_controller.hpp"
34 #include "sdl/input.hpp" // get_mouse_state
35 #include "video.hpp" // toggle_fullscreen
36 
37 
38 
39 #include <ios>
40 #include <set>
41 
42 static lg::log_domain log_config("config");
43 static lg::log_domain log_hotkey("hotkey");
44 #define ERR_G LOG_STREAM(err, lg::general())
45 #define WRN_G LOG_STREAM(warn, lg::general())
46 #define LOG_G LOG_STREAM(info, lg::general())
47 #define DBG_G LOG_STREAM(debug, lg::general())
48 #define ERR_CF LOG_STREAM(err, log_config)
49 #define LOG_HK LOG_STREAM(info, log_hotkey)
50 
51 namespace {
52 
53 void make_screenshot(const std::string& name, bool map_screenshot)
54 {
55  surface screenshot = display::get_singleton()->screenshot(map_screenshot);
56  if(screenshot) {
57  std::string filename = filesystem::get_screenshot_dir() + "/" + name + "_";
58  filename = filesystem::get_next_filename(filename, ".jpg");
59  gui2::dialogs::screenshot_notification::display(filename, screenshot);
60  }
61 }
62 }
63 namespace hotkey {
64 
65 static void event_queue(const SDL_Event& event, command_executor* executor);
66 
67 bool command_executor::do_execute_command(const hotkey::ui_command& cmd, bool press, bool release)
68 {
69  // hotkey release handling
70  if (release) {
71  switch(cmd.hotkey_command) {
72  // release a scroll key, un-apply scrolling in the given direction
73  case HOTKEY_SCROLL_UP:
74  scroll_up(false);
75  break;
76  case HOTKEY_SCROLL_DOWN:
77  scroll_down(false);
78  break;
79  case HOTKEY_SCROLL_LEFT:
80  scroll_left(false);
81  break;
83  scroll_right(false);
84  break;
85  default:
86  return false; // nothing else handles a hotkey release
87  }
88 
89  return true;
90  }
91 
92  // handling of hotkeys which activate even on hold events
93  switch(cmd.hotkey_command) {
96  return true;
97  case HOTKEY_SCROLL_UP:
98  scroll_up(true);
99  return true;
100  case HOTKEY_SCROLL_DOWN:
101  scroll_down(true);
102  return true;
103  case HOTKEY_SCROLL_LEFT:
104  scroll_left(true);
105  return true;
106  case HOTKEY_SCROLL_RIGHT:
107  scroll_right(true);
108  return true;
109  default:
110  break;
111  }
112 
113  if(!press) {
114  return false; // nothing else handles hotkey hold events
115  }
116 
117  // hotkey press handling
118  switch(cmd.hotkey_command) {
119  case HOTKEY_CYCLE_UNITS:
120  cycle_units();
121  break;
124  break;
125  case HOTKEY_ENDTURN:
126  end_turn();
127  break;
130  break;
132  end_unit_turn();
133  break;
134  case HOTKEY_LEADER:
135  goto_leader();
136  break;
137  case HOTKEY_UNDO:
138  undo();
139  break;
140  case HOTKEY_REDO:
141  redo();
142  break;
145  break;
148  break;
149  case HOTKEY_RENAME_UNIT:
150  rename_unit();
151  break;
152  case HOTKEY_SAVE_GAME:
153  save_game();
154  break;
155  case HOTKEY_SAVE_REPLAY:
156  save_replay();
157  break;
158  case HOTKEY_SAVE_MAP:
159  save_map();
160  break;
161  case HOTKEY_LOAD_GAME:
162  load_game();
163  break;
165  toggle_ellipses();
166  break;
167  case HOTKEY_TOGGLE_GRID:
168  toggle_grid();
169  break;
170  case HOTKEY_STATUS_TABLE:
171  status_table();
172  break;
173  case HOTKEY_RECALL:
174  recall();
175  break;
177  label_settings();
178  break;
179  case HOTKEY_RECRUIT:
180  recruit();
181  break;
182  case HOTKEY_SPEAK:
183  speak();
184  break;
185  case HOTKEY_SPEAK_ALLY:
186  whisper();
187  break;
188  case HOTKEY_SPEAK_ALL:
189  shout();
190  break;
191  case HOTKEY_CREATE_UNIT:
192  create_unit();
193  break;
194  case HOTKEY_CHANGE_SIDE:
195  change_side();
196  break;
197  case HOTKEY_KILL_UNIT:
198  kill_unit();
199  break;
201  select_teleport();
202  break;
203  case HOTKEY_PREFERENCES:
204  preferences();
205  break;
206  case HOTKEY_OBJECTIVES:
207  objectives();
208  break;
209  case HOTKEY_UNIT_LIST:
210  unit_list();
211  break;
212  case HOTKEY_STATISTICS:
213  show_statistics();
214  break;
215  case HOTKEY_STOP_NETWORK:
216  stop_network();
217  break;
219  start_network();
220  break;
222  label_terrain(true);
223  break;
225  label_terrain(false);
226  break;
227  case HOTKEY_CLEAR_LABELS:
228  clear_labels();
229  break;
231  show_enemy_moves(false);
232  break;
234  show_enemy_moves(true);
235  break;
236  case HOTKEY_DELAY_SHROUD:
238  break;
241  break;
243  continue_move();
244  break;
245  case HOTKEY_SEARCH:
246  search();
247  break;
248  case HOTKEY_HELP:
249  show_help();
250  break;
252  // although HOTKEY_HELP uses a virtual call to allow context-specific help, this one is already a specific topic
253  help::show_help("saveload");
254  break;
255  case HOTKEY_CHAT_LOG:
256  show_chat_log();
257  break;
258  case HOTKEY_USER_CMD:
259  user_command();
260  break;
261  case HOTKEY_CUSTOM_CMD:
262  custom_command();
263  break;
264  case HOTKEY_AI_FORMULA:
265  ai_formula();
266  break;
267  case HOTKEY_CLEAR_MSG:
268  clear_messages();
269  break;
270  case HOTKEY_LANGUAGE:
271  change_language();
272  break;
273  case HOTKEY_REPLAY_PLAY:
274  play_replay();
275  break;
276  case HOTKEY_REPLAY_RESET:
277  reset_replay();
278  break;
279  case HOTKEY_REPLAY_STOP:
280  stop_replay();
281  break;
284  break;
287  break;
290  break;
293  break;
296  break;
299  break;
302  break;
303  case HOTKEY_REPLAY_EXIT:
304  replay_exit();
305  break;
306  case HOTKEY_WB_TOGGLE:
308  break;
311  break;
314  break;
317  break;
320  break;
323  break;
326  break;
327  case HOTKEY_SELECT_HEX:
328  select_hex();
329  break;
330  case HOTKEY_DESELECT_HEX:
331  deselect_hex();
332  break;
333  case HOTKEY_MOVE_ACTION:
334  move_action();
335  break;
338  break;
339  case HOTKEY_TOUCH_HEX:
340  touch_hex();
341  break;
342  case HOTKEY_ACCELERATED:
344  break;
345  case LUA_CONSOLE:
346  lua_console();
347  break;
348  case HOTKEY_ZOOM_IN:
349  zoom_in();
350  break;
351  case HOTKEY_ZOOM_OUT:
352  zoom_out();
353  break;
354  case HOTKEY_ZOOM_DEFAULT:
355  zoom_default();
356  break;
358  map_screenshot();
359  break;
362  break;
363  case HOTKEY_QUIT_GAME:
365  break;
366  case HOTKEY_SURRENDER:
367  surrender_game();
368  break;
372  break;
376  break;
380  break;
384  break;
388  break;
389  case HOTKEY_ACHIEVEMENTS:
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 
410 void command_executor::show_menu(const std::vector<config>& items_arg, int xloc, int yloc, bool /*context_menu*/, display& gui)
411 {
412  std::vector<config> items = items_arg;
413  if (items.empty()) return;
414 
415  get_menu_images(gui, items);
416 
417  int res = -1;
418  {
419  SDL_Rect pos {xloc, yloc, 1, 1};
420  gui2::dialogs::drop_down_menu mmenu(pos, items, -1, true, false); // TODO: last value should be variable
421  if(mmenu.show()) {
422  res = mmenu.selected_item();
423  }
424  } // This will kill the dialog.
425  if (res < 0 || std::size_t(res) >= items.size()) return;
426 
427  std::string id = items[res]["id"];
428  const theme::menu* submenu = gui.get_theme().get_menu_item(id);
429  if (submenu) {
430  int y,x;
431  sdl::get_mouse_state(&x,&y);
432  this->show_menu(submenu->items(), x, y, submenu->is_context(), gui);
433  } else {
434  hotkey::ui_command cmd = hotkey::ui_command(id, res);
435  do_execute_command(cmd);
437  }
438 }
439 
440 void command_executor::execute_action(const std::vector<std::string>& items_arg, int /*xloc*/, int /*yloc*/, bool /*context_menu*/, display&)
441 {
442  std::vector<std::string> items = items_arg;
443  if (items.empty()) {
444  return;
445  }
446 
447  std::vector<std::string>::iterator i = items.begin();
448  while(i != items.end()) {
450  if (can_execute_command(cmd)) {
451  do_execute_command(cmd);
453  }
454  ++i;
455  }
456 }
457 
458 std::string command_executor::get_menu_image(display& disp, const std::string& command, int index) const
459 {
460  const std::string base_image_name = "icons/action/" + command + "_25.png";
461  const std::string pressed_image_name = "icons/action/" + command + "_25-pressed.png";
462 
464  const hotkey::ACTION_STATE state = get_action_state(cmd);
465 
466  const theme::menu* menu = disp.get_theme().get_menu_item(command);
467  if (menu) {
468  return "icons/arrows/short_arrow_right_25.png~CROP(3,3,18,18)"; // TODO should not be hardcoded
469  }
470 
471  if (filesystem::file_exists(game_config::path + "/images/" + base_image_name)) {
472  switch (state) {
473  case ACTION_ON:
474  case ACTION_SELECTED:
475  return pressed_image_name + "~CROP(3,3,18,18)";
476  default:
477  return base_image_name + "~CROP(3,3,18,18)";
478  }
479  }
480 
481  switch (get_action_state(cmd)) {
482  case ACTION_ON:
484  case ACTION_OFF:
486  case ACTION_SELECTED:
488  case ACTION_DESELECTED:
490  default: return get_action_image(cmd);
491  }
492 }
493 
494 void command_executor::get_menu_images(display& disp, std::vector<config>& items)
495 {
496  for(std::size_t i = 0; i < items.size(); ++i) {
497  config& item = items[i];
498 
499  const std::string& item_id = item["id"];
501 
502  //see if this menu item has an associated image
503  std::string img(get_menu_image(disp, item_id, i));
504  if (img.empty() == false) {
505  item["icon"] = img;
506  }
507 
508  const theme::menu* menu = disp.get_theme().get_menu_item(item_id);
509  if(menu) {
510  item["label"] = menu->title();
511  } else if(hk != hotkey::HOTKEY_NULL) {
512  std::string desc = hotkey::get_hotkey_command(item_id).description;
513  if(hk == HOTKEY_ENDTURN) {
514  const theme::action *b = disp.get_theme().get_action_item("button-endturn");
515  if (b) {
516  desc = b->title();
517  }
518  }
519 
520  item["label"] = desc;
521  item["details"] = hotkey::get_names(item_id);
522  }
523  }
524 }
525 
526 void mbutton_event(const SDL_Event& event, command_executor* executor)
527 {
528  event_queue(event, executor);
529 
530  /* Run mouse events immediately.
531 
532  This is necessary because the sidebar doesn't allow set_button_state() to be called after a
533  button has received the mouse press event but before it has received the mouse release event.
534  When https://github.com/wesnoth/wesnoth/pull/2872 delayed the processing of input events,
535  set_button_state() ended up being called at such a time. However, if we run the event handlers
536  now, the button (if any) hasn't received the press event yet and we can call set_button_state()
537  safely.
538 
539  See https://github.com/wesnoth/wesnoth/issues/2884 */
540 
541  run_events(executor);
542 }
543 
544 void jbutton_event(const SDL_Event& event, command_executor* executor)
545 {
546  event_queue(event, executor);
547 }
548 
549 void jhat_event(const SDL_Event& event, command_executor* executor)
550 {
551  event_queue(event, executor);
552 }
553 
554 void key_event(const SDL_Event& event, command_executor* executor)
555 {
556  if (!executor) return;
557  event_queue(event,executor);
558 }
559 
560 void keyup_event(const SDL_Event&, command_executor* executor)
561 {
562  if(!executor) return;
563  executor->handle_keyup();
564 }
565 
567 {
568  if(!executor) return;
569  bool commands_ran = executor->run_queued_commands();
570  if(commands_ran) {
571  executor->set_button_state();
572  }
573 }
574 
575 static void event_queue(const SDL_Event& event, command_executor* executor)
576 {
577  if (!executor) return;
578  executor->queue_command(event);
579  executor->set_button_state();
580 }
581 
582 void command_executor::queue_command(const SDL_Event& event, int index)
583 {
584  LOG_HK << "event 0x" << std::hex << event.type << std::dec;
585  if(event.type == SDL_TEXTINPUT) {
586  LOG_HK << "SDL_TEXTINPUT \"" << event.text.text << "\"";
587  }
588 
589  const hotkey_ptr hk = get_hotkey(event);
590  if(!hk->active() || hk->is_disabled()) {
591  return;
592  }
593 
594  const hotkey_command& command = hotkey::get_hotkey_command(hk->get_command());
595  bool keypress = (event.type == SDL_KEYDOWN || event.type == SDL_TEXTINPUT) &&
597  bool press = keypress ||
598  (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_FINGERDOWN);
599  bool release = event.type == SDL_KEYUP;
600  if(press) {
601  LOG_HK << "sending press event (keypress = " <<
602  std::boolalpha << keypress << std::noboolalpha << ")";
603  }
604  if(keypress) {
605  press_event_sent_ = true;
606  }
607 
608  command_queue_.emplace_back(command, index, press, release);
609 }
610 
612 {
613  auto ui_cmd = hotkey::ui_command(*command.command, command.index);
614  if (!can_execute_command(ui_cmd)
615  || do_execute_command(ui_cmd, command.press, command.release)) {
616  return;
617  }
618 
619  if (!command.press) {
620  return; // none of the commands here respond to a key release
621  }
622 
623  switch(command.command->command) {
624  case HOTKEY_FULLSCREEN:
626  break;
627  case HOTKEY_SCREENSHOT:
628  make_screenshot(_("Screenshot"), false);
629  break;
630  case HOTKEY_ANIMATE_MAP:
631  prefs::get().set_animate_map(!prefs::get().animate_map());
632  break;
633  case HOTKEY_MOUSE_SCROLL:
634  prefs::get().enable_mouse_scroll(!prefs::get().mouse_scroll_enabled());
635  break;
636  case HOTKEY_MUTE:
637  {
638  // look if both is not playing
639  static struct before_muted_s
640  {
641  bool playing_sound,playing_music;
642  before_muted_s() : playing_sound(false),playing_music(false){}
643  } before_muted;
644  if (prefs::get().music_on() || prefs::get().sound_on())
645  {
646  // then remember settings and mute both
647  before_muted.playing_sound = prefs::get().sound_on();
648  before_muted.playing_music = prefs::get().music_on();
649  prefs::get().set_sound(false);
650  prefs::get().set_music(false);
651  }
652  else
653  {
654  // then set settings before mute
655  prefs::get().set_sound(before_muted.playing_sound);
656  prefs::get().set_music(before_muted.playing_music);
657  }
658  }
659  break;
660  default:
661  DBG_G << "command_executor: unknown command number " << command.command->command << ", ignoring.";
662  break;
663  }
664 }
665 
667 {
668  display& disp = get_display();
669  for (const theme::menu& menu : disp.get_theme().menus()) {
670 
671  std::shared_ptr<gui::button> button = disp.find_menu_button(menu.get_id());
672  if (!button) continue;
673  bool enabled = false;
674  for (const auto& command : menu.items()) {
675 
676  ui_command command_obj = ui_command(command["id"].str());
677  bool can_execute = can_execute_command(command_obj);
678  if (can_execute) {
679  enabled = true;
680  break;
681  }
682  }
683  button->enable(enabled);
684  }
685 
686  for (const theme::action& action : disp.get_theme().actions()) {
687 
688  std::shared_ptr<gui::button> button = disp.find_action_button(action.get_id());
689  if (!button) continue;
690  bool enabled = false;
691  int i = 0;
692  for (const std::string& command : action.items()) {
693 
694  ui_command command_obj = ui_command(command);
695  std::string tooltip = action.tooltip(i);
696  if (filesystem::file_exists(game_config::path + "/images/icons/action/" + command + "_25.png" ))
697  button->set_overlay("icons/action/" + command);
698  if (!tooltip.empty())
699  button->set_tooltip_string(tooltip);
700 
701  bool can_execute = can_execute_command(command_obj);
702  i++;
703  if (!can_execute) continue;
704  enabled = true;
705 
706  ACTION_STATE state = get_action_state(command_obj);
707  switch (state) {
708  case ACTION_SELECTED:
709  case ACTION_ON:
710  button->set_check(true);
711  break;
712  case ACTION_OFF:
713  case ACTION_DESELECTED:
714  button->set_check(false);
715  break;
716  case ACTION_STATELESS:
717  break;
718  default:
719  break;
720  }
721 
722  break;
723  }
724  button->enable(enabled);
725  }
726 }
727 
728 // Removes duplicate commands caused by both SDL_KEYDOWN and SDL_TEXTINPUT triggering hotkeys.
729 // See https://github.com/wesnoth/wesnoth/issues/1736
730 std::vector<command_executor::queued_command> command_executor::filter_command_queue()
731 {
732  std::vector<queued_command> filtered_commands;
733 
734  /** A command plus "key released" flag. Otherwise, we will filter out key releases that are preceded by a keypress. */
735  using command_with_keyrelease = std::pair<const hotkey_command*, bool>;
736  std::set<command_with_keyrelease> seen_commands;
737 
738  for(const queued_command& cmd : command_queue_) {
739  command_with_keyrelease command_key(cmd.command, cmd.release);
740  if(seen_commands.find(command_key) == seen_commands.end()) {
741  seen_commands.insert(command_key);
742  filtered_commands.push_back(cmd);
743  }
744  }
745 
746  command_queue_.clear();
747 
748  return filtered_commands;
749 }
750 
752 {
753  std::vector<queued_command> commands = filter_command_queue();
754  for(const queued_command& cmd : commands) {
756  }
757 
758  return !commands.empty();
759 }
760 
762 {
764 }
765 
767 {
768  if (get_display().in_game()) {
770  } else {
772  }
773 
774 }
775 
777 {
779 }
780 
782 {
783  if(!get_display().view_locked()) {
784  get_display().set_zoom(true);
785  }
786 }
787 
789 {
790  if(!get_display().view_locked()) {
791  get_display().set_zoom(false);
792  }
793 }
794 
796 {
797  if(!get_display().view_locked()) {
799  }
800 }
801 
803 {
804  make_screenshot(_("Map-Screenshot"), true);
805 }
806 }
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
Definition: display.hpp:88
std::size_t viewing_team() const
The viewing team is the team currently viewing the game.
Definition: display.hpp:123
void recalculate_minimap()
Schedule the minimap for recalculation.
Definition: display.cpp:1610
std::shared_ptr< gui::button > find_action_button(const std::string &id)
Retrieves a pointer to a theme UI button.
Definition: display.cpp:805
std::shared_ptr< gui::button > find_menu_button(const std::string &id)
Definition: display.cpp:815
bool set_zoom(bool increase)
Zooms the display in (true) or out (false).
Definition: display.cpp:1845
surface screenshot(bool map_screenshot=false)
Capture a (map-)screenshot into a surface.
Definition: display.cpp:757
theme & get_theme()
Definition: display.hpp:387
void toggle_default_zoom()
Sets the zoom amount to the default.
Definition: display.cpp:1914
static display * get_singleton()
Returns the display object if a display object exists.
Definition: display.hpp:102
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)
void toggle_minimap_draw_units()
void toggle_minimap_draw_villages()
static prefs & get()
void enable_mouse_scroll(bool value)
void toggle_minimap_draw_terrain()
bool set_sound(bool ison)
void toggle_minimap_movement_coding()
bool music_on()
void toggle_minimap_terrain_coding()
void set_animate_map(bool value)
bool sound_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:968
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:209
Contains functions for cleanly handling SDL input.
Standard logging facilities (interface).
static bool file_exists(const bfs::path &fpath)
Definition: filesystem.cpp:324
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:551
std::string selected_menu
std::string deselected_menu
std::string unchecked_menu
std::string checked_menu
std::string path
Definition: filesystem.cpp:89
static bool sound_on()
static void make_screenshot()
static bool music_on()
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:150
@ CANCEL
Dialog was closed with the CANCEL button.
Definition: retval.hpp:38
General purpose widgets.
void show_help(const std::string &show_topic, int xloc, int yloc)
Open the help browser, show topic with id show_topic.
Definition: help.cpp:140
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:410
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
play_controller * controller
Definition: resources.cpp:21
uint32_t get_mouse_state(int *x, int *y)
A wrapper for SDL_GetMouseState that gives coordinates in draw space.
Definition: input.cpp:27
std::size_t index(const std::string &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:796
std::string::const_iterator iterator
Definition: tokenizer.hpp:25
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...
#define b