The Battle for Wesnoth  1.17.23+dev
editor_controller.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2023
3  by Tomasz Sniatowski <kailoran@gmail.com>
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 
16 #define GETTEXT_DOMAIN "wesnoth-editor"
17 
19 
20 #include "editor/action/action.hpp"
24 
27 
29 
30 #include "preferences/editor.hpp"
31 
34 #include "gui/dialogs/message.hpp"
38 #include "gui/widgets/retval.hpp"
39 #include "wml_exception.hpp"
40 
41 #include "resources.hpp"
42 #include "reports.hpp"
43 
44 #include "cursor.hpp"
45 #include "desktop/clipboard.hpp"
46 #include "floating_label.hpp"
47 #include "game_board.hpp"
48 #include "preferences/game.hpp"
49 #include "gettext.hpp"
50 #include "picture.hpp"
51 #include "preferences/display.hpp"
52 #include "sound.hpp"
53 #include "units/unit.hpp"
55 #include "game_config_manager.hpp"
56 #include "quit_confirmation.hpp"
57 #include "sdl/input.hpp" // get_mouse_button_mask
58 
59 #include <functional>
60 
61 namespace {
62 static std::vector<std::string> saved_windows_;
63 }
64 
65 namespace editor {
66 
68 
70  : controller_base()
71  , mouse_handler_base()
72  , quit_confirmation(std::bind(&editor_controller::quit_confirm, this))
73  , active_menu_(editor::MAP)
74  , reports_(new reports())
75  , gui_(new editor_display(*this, *reports_))
76  , tods_()
77  , context_manager_(new context_manager(*gui_.get(), game_config_, clear_id ? "" : editor_controller::current_addon_id_))
78  , toolkit_(nullptr)
79  , tooltip_manager_()
80  , floating_label_manager_(nullptr)
81  , help_manager_(nullptr)
82  , do_quit_(false)
83  , quit_mode_(EXIT_ERROR)
84  , music_tracks_()
85 {
86  if(clear_id) {
88  }
89 
90  init_gui();
91  toolkit_.reset(new editor_toolkit(*gui_.get(), key_, game_config_, *context_manager_.get()));
93  context_manager_->locs_ = toolkit_->get_palette_manager()->location_palette_.get();
94  context_manager_->switch_context(0, true);
99 
100  gui().queue_rerender();
101 }
102 
104 {
105  gui_->change_display_context(&get_current_map_context());
106  gui_->add_redraw_observer(std::bind(&editor_controller::display_redraw_callback, this, std::placeholders::_1));
111 // halo_manager_.reset(new halo::manager(*gui_));
112 // resources::halo = halo_manager_.get();
113 // ^ These lines no longer necessary, the gui owns its halo manager.
114 // TODO: Should the editor map contexts actually own the halo manager and swap them in and out from the gui?
115 // Note that if that is what happens it might not actually be a good idea for the gui to own the halo manager, so that it can be swapped out
116 // without deleting it.
117 }
118 
120 {
121  for (const config &schedule : game_config.child_range("editor_times")) {
122 
123  const std::string& schedule_id = schedule["id"];
124  const std::string& schedule_name = schedule["name"];
125  if (schedule_id.empty()) {
126  ERR_ED << "Missing ID attribute in a TOD Schedule.";
127  continue;
128  }
129 
130  tods_map::iterator times = tods_.find(schedule_id);
131  if (times == tods_.end()) {
132  std::pair<tods_map::iterator, bool> new_times =
133  tods_.emplace(schedule_id, std::pair(schedule_name, std::vector<time_of_day>()));
134 
135  times = new_times.first;
136  } else {
137  ERR_ED << "Duplicate TOD Schedule identifiers.";
138  continue;
139  }
140 
141  for (const config &time : schedule.child_range("time")) {
142  times->second.second.emplace_back(time);
143  }
144 
145  }
146 
147  if (tods_.empty()) {
148  ERR_ED << "No editor time-of-day defined";
149  }
150 }
151 
153 {
154  const std::string tag_name = "editor_music";
155  if (game_config.child_range(tag_name).size() == 0) {
156  ERR_ED << "No editor music defined";
157  }
158  else {
159  for (const config& editor_music : game_config.child_range(tag_name)) {
160  for (const config& music : editor_music.child_range("music")) {
161  sound::music_track track(music);
162  if (track.file_path().empty())
163  WRN_ED << "Music track " << track.id() << " not found.";
164  else
165  music_tracks_.emplace_back(music);
166  }
167  }
168  }
169 }
170 
172 {
173  resources::tod_manager = nullptr;
174  resources::filter_con = nullptr;
175 
176  resources::classification = nullptr;
177 }
178 
180 {
181  try {
182  while (!do_quit_) {
183  play_slice();
184  }
185  } catch (const editor_exception& e) {
186  gui2::show_transient_message(_("Fatal error"), e.what());
187  return EXIT_ERROR;
188  } catch (const wml_exception& e) {
189  e.show();
190  }
191  return quit_mode_;
192 }
193 
195 }
196 
197 void editor_controller::do_screenshot(const std::string& screenshot_filename /* = "map_screenshot.png" */)
198 {
199  try {
200  surface screenshot = gui().screenshot(true);
201  if(!screenshot || image::save_image(screenshot, screenshot_filename) != image::save_result::success) {
202  ERR_ED << "Screenshot creation failed!";
203  }
204  } catch (const wml_exception& e) {
205  e.show();
206  }
207 }
208 
210 {
211  std::string modified;
212  std::size_t amount = context_manager_->modified_maps(modified);
213 
214  std::string message;
215  if (amount == 0) {
216  message = _("Do you really want to quit?");
217  } else if (amount == 1 && get_current_map_context().modified()) {
218  message = _("Do you really want to quit? Changes to this map since the last save will be lost.");
219  } else {
220  message = _("Do you really want to quit? The following maps were modified and all changes since the last save will be lost:");
221  message += "\n" + modified;
222  }
223  return quit_confirmation::show_prompt(message);
224 }
225 
227 {
228  if (tods_.empty()) {
229  gui2::show_error_message(_("No editor time-of-day found."));
230  return;
231  }
232 
234 
235  if(gui2::dialogs::custom_tod::execute(manager.times(), manager.get_current_time())) {
236  // TODO save the new tod here
237  }
238 
239  gui_->update_tod();
240 
241  context_manager_->refresh_all();
242 }
243 
245 {
246  using namespace hotkey; //reduce hotkey:: clutter
247  int index = cmd.index;
248  switch(cmd.hotkey_command) {
249  case HOTKEY_NULL:
250  if (index >= 0) {
251  unsigned i = static_cast<unsigned>(index);
252 
253  switch (active_menu_) {
254  case editor::MAP:
255  if (i < context_manager_->open_maps()) {
256  return true;
257  }
258  return false;
259  case editor::LOAD_MRU:
260  case editor::PALETTE:
261  case editor::AREA:
262  case editor::ADDON:
263  case editor::SIDE:
264  case editor::TIME:
265  case editor::SCHEDULE:
267  case editor::MUSIC:
268  case editor::LOCAL_TIME:
269  case editor::UNIT_FACING:
270  return true;
271  }
272  }
273  return false;
275  return true;
277  return toolkit_->get_palette_manager()->can_scroll_up();
279  return toolkit_->get_palette_manager()->can_scroll_down();
280  case HOTKEY_ZOOM_IN:
281  return !gui_->zoom_at_max();
282  case HOTKEY_ZOOM_OUT:
283  return !gui_->zoom_at_min();
284  case HOTKEY_ZOOM_DEFAULT:
285  case HOTKEY_FULLSCREEN:
286  case HOTKEY_SCREENSHOT:
288  case HOTKEY_TOGGLE_GRID:
289  case HOTKEY_MOUSE_SCROLL:
290  case HOTKEY_ANIMATE_MAP:
291  case HOTKEY_MUTE:
292  case HOTKEY_PREFERENCES:
293  case HOTKEY_HELP:
294  case HOTKEY_QUIT_GAME:
295  case HOTKEY_SCROLL_UP:
296  case HOTKEY_SCROLL_DOWN:
297  case HOTKEY_SCROLL_LEFT:
298  case HOTKEY_SCROLL_RIGHT:
299  return true; //general hotkeys we can always do
300 
302  return !get_current_map_context().units().empty();
303 
304  case HOTKEY_STATUS_TABLE:
305  return !get_current_map_context().teams().empty();
306 
308  return gui().mouseover_hex().valid();
309 
310  // unit tool related
311  case HOTKEY_DELETE_UNIT:
312  case HOTKEY_RENAME_UNIT:
319  {
320  map_location loc = gui_->mouseover_hex();
321  const unit_map& units = get_current_map_context().units();
322  return (toolkit_->is_mouse_action_set(HOTKEY_EDITOR_TOOL_UNIT) &&
323  units.find(loc) != units.end());
324  }
325  case HOTKEY_UNDO:
327  case HOTKEY_REDO:
339  return true;
340 
341  case HOTKEY_EDITOR_PBL:
343  return true;
347 
350  return !get_current_map_context().teams().empty();
351 
352  // brushes
360 
362  return true;
364  return toolkit_->get_palette_manager()->active_palette().supports_swap();
368  {
369  std::string dummy;
370  return context_manager_->modified_maps(dummy) > 1;
371  }
377  return true;
379  return !get_current_map_context().get_filename().empty()
381 
382  // Tools
383  // Pure map editing tools this can be used all the time.
388  return true;
389  // WWL dependent tools which don't rely on defined sides.
396  return !get_current_map_context().teams().empty();
397 
401  return !get_current_map_context().is_pure_map() &&
403 
405  return !get_current_map_context().is_pure_map() &&
407  && !get_current_map_context().map().selection().empty();
408 
413  return !get_current_map_context().map().selection().empty()
414  && !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
416  return (get_current_map_context().map().selection().size() > 1
417  && !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE));
421  return !context_manager_->clipboard_empty();
426  return !context_manager_->clipboard_empty()
427  && toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
430  return !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
432  return !get_current_map_context().map().selection().empty()
434  && !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
451  return true;
455  return true;
456  default:
457  return false;
458  }
459 }
460 
462 {
463  using namespace hotkey;
464  int index = cmd.index;
465  switch (cmd.hotkey_command) {
466 
468  {
470  get_current_map_context().units().find(gui_->mouseover_hex());
471  return un->loyal() ? ACTION_ON : ACTION_OFF;
472 
473  }
475  {
477  get_current_map_context().units().find(gui_->mouseover_hex());
478  return un->can_recruit() ? ACTION_ON : ACTION_OFF;
479  }
481  {
483  get_current_map_context().units().find(gui_->mouseover_hex());
484  return (!un->unrenamable()) ? ACTION_ON : ACTION_OFF;
485  }
486  //TODO remove hardcoded hotkey names
488  return context_manager_->is_active_transitions_hotkey("editor-auto-update-transitions")
491  return context_manager_->is_active_transitions_hotkey("editor-partial-update-transitions")
494  return context_manager_->is_active_transitions_hotkey("editor-no-update-transitions")
497  return toolkit_->is_active_brush("brush-1") ? ACTION_ON : ACTION_OFF;
499  return toolkit_->is_active_brush("brush-2") ? ACTION_ON : ACTION_OFF;
501  return toolkit_->is_active_brush("brush-3") ? ACTION_ON : ACTION_OFF;
503  return toolkit_->is_active_brush("brush-nw-se") ? ACTION_ON : ACTION_OFF;
505  return toolkit_->is_active_brush("brush-sw-ne") ? ACTION_ON : ACTION_OFF;
506 
507  case HOTKEY_TOGGLE_GRID:
513  return get_current_map_context().map().selection().empty() ?
524  return toolkit_->is_mouse_action_set(cmd.hotkey_command) ? ACTION_ON : ACTION_OFF;
526  return gui_->debug_flag_set(display::DEBUG_COORDINATES) ? ACTION_ON : ACTION_OFF;
528  return gui_->debug_flag_set(display::DEBUG_TERRAIN_CODES) ? ACTION_ON : ACTION_OFF;
530  return gui_->debug_flag_set(display::DEBUG_NUM_BITMAPS) ? ACTION_ON : ACTION_OFF;
531 
542  case HOTKEY_ZOOM_DEFAULT:
543  return (gui_->get_zoom_factor() == 1.0) ? hotkey::ACTION_ON : hotkey::ACTION_OFF;
544 
545  case HOTKEY_NULL:
546  switch (active_menu_) {
547  case editor::MAP:
548  return index == context_manager_->current_context_index()
550  case editor::LOAD_MRU:
551  return ACTION_STATELESS;
552  case editor::PALETTE:
553  return ACTION_STATELESS;
554  case editor::AREA:
557  case editor::ADDON:
558  return ACTION_STATELESS;
559  case editor::SIDE:
560  return static_cast<std::size_t>(index) == gui_->playing_team()
562  case editor::TIME:
565  case editor::LOCAL_TIME:
567  get_current_map_context().get_active_area())
569  case editor::MUSIC:
571  ? ACTION_ON : ACTION_OFF;
572  case editor::SCHEDULE:
573  {
574  tods_map::const_iterator it = tods_.begin();
575  std::advance(it, index);
576  const std::vector<time_of_day>& times1 = it->second.second;
577  const std::vector<time_of_day>& times2 = get_current_map_context().get_time_manager()->times();
578  return (times1 == times2) ? ACTION_SELECTED : ACTION_DESELECTED;
579  }
581  {
582  tods_map::const_iterator it = tods_.begin();
583  std::advance(it, index);
584  const std::vector<time_of_day>& times1 = it->second.second;
585  int active_area = get_current_map_context().get_active_area();
586  const std::vector<time_of_day>& times2 = get_current_map_context().get_time_manager()->times(active_area);
587  return (times1 == times2) ? ACTION_SELECTED : ACTION_DESELECTED;
588  }
589  case editor::UNIT_FACING:
590  {
592  assert(un != get_current_map_context().units().end());
593  return un->facing() == index ? ACTION_SELECTED : ACTION_DESELECTED;
594  }
595  }
596  return ACTION_ON;
597  default:
598  return command_executor::get_action_state(cmd);
599  }
600 }
601 
602 bool editor_controller::do_execute_command(const hotkey::ui_command& cmd, bool press, bool release)
603 {
605  SCOPE_ED;
606  using namespace hotkey;
607  int index = cmd.index;
608 
609  // nothing here handles release; fall through to base implementation
610  if (!press) {
611  return hotkey::command_executor::do_execute_command(cmd, press, release);
612  }
613 
614  switch (command) {
615  case HOTKEY_NULL:
616  switch (active_menu_) {
617  case MAP:
618  if (index >= 0) {
619  unsigned i = static_cast<unsigned>(index);
620  if (i < context_manager_->size()) {
621  context_manager_->switch_context(index);
622  toolkit_->hotkey_set_mouse_action(HOTKEY_EDITOR_TOOL_PAINT);
623  return true;
624  }
625  }
626  return false;
627  case LOAD_MRU:
628  if (index >= 0) {
629  context_manager_->load_mru_item(static_cast<unsigned>(index));
630  }
631  return true;
632  case PALETTE:
633  toolkit_->get_palette_manager()->set_group(index);
634  return true;
635  case SIDE:
636  gui_->set_team(index, true);
637  gui_->set_playing_team(index);
638  toolkit_->get_palette_manager()->draw_contents();
639  return true;
640  case AREA:
641  {
643  const std::set<map_location>& area =
645  std::vector<map_location> locs(area.begin(), area.end());
647  gui_->scroll_to_tiles(locs.begin(), locs.end());
648  return true;
649  }
650  case ADDON:
651  return true;
652  case TIME:
653  {
655  gui_->update_tod();
656  return true;
657  }
658  case LOCAL_TIME:
659  {
661  return true;
662  }
663  case MUSIC:
664  {
665  //TODO mark the map as changed
668  std::vector<config> items;
669  items.emplace_back("id", "editor-playlist");
670  std::shared_ptr<gui::button> b = gui_->find_menu_button("menu-playlist");
671  show_menu(items, b->location().x +1, b->location().y + b->height() +1, false, *gui_);
672  return true;
673  }
674  case SCHEDULE:
675  {
676  tods_map::iterator iter = tods_.begin();
677  std::advance(iter, index);
678  get_current_map_context().replace_schedule(iter->second.second);
679  // TODO: test again after the assign-schedule menu is fixed. Should work, though.
680  gui_->update_tod();
681  return true;
682  }
683  case LOCAL_SCHEDULE:
684  {
685  tods_map::iterator iter = tods_.begin();
686  std::advance(iter, index);
687  get_current_map_context().replace_local_schedule(iter->second.second);
688  return true;
689  }
690  case UNIT_FACING:
691  {
693  assert(un != get_current_map_context().units().end());
694  un->set_facing(map_location::DIRECTION(index));
695  un->anim_comp().set_standing();
696  return true;
697  }
698  }
699  return true;
700 
701  //Zoom
702  case HOTKEY_ZOOM_IN:
703  gui_->set_zoom(true);
705  toolkit_->set_mouseover_overlay(*gui_);
706  return true;
707  case HOTKEY_ZOOM_OUT:
708  gui_->set_zoom(false);
710  toolkit_->set_mouseover_overlay(*gui_);
711  return true;
712  case HOTKEY_ZOOM_DEFAULT:
713  gui_->toggle_default_zoom();
715  toolkit_->set_mouseover_overlay(*gui_);
716  return true;
717 
718  //Palette
720  //TODO this code waits for the gui2 dialog to get ready
721  // std::vector< std::pair< std::string, std::string >> blah_items;
722  // toolkit_->get_palette_manager()->active_palette().expand_palette_groups_menu(blah_items);
723  // int selected = 1; //toolkit_->get_palette_manager()->active_palette().get_selected;
724  // gui2::teditor_select_palette_group::execute(selected, blah_items);
725  return true;
727  toolkit_->get_palette_manager()->scroll_up();
728  return true;
730  toolkit_->get_palette_manager()->scroll_down();
731  return true;
732 
733  case HOTKEY_QUIT_GAME:
735  do_quit_ = true;
737  }
738  return true;
741  return true;
743  context_manager_->save_all_maps(true);
744  do_quit_ = true;
746  return true;
749  return true;
751  toolkit_->get_palette_manager()->active_palette().swap();
752  return true;
754  if (dynamic_cast<const editor_action_chain*>(get_current_map_context().last_undo_action()) != nullptr) {
756  context_manager_->refresh_after_action();
757  } else {
758  undo();
759  }
760  return true;
761 
762  //Tool Selection
771  toolkit_->hotkey_set_mouse_action(command);
772  return true;
773 
774  case HOTKEY_EDITOR_PBL:
775  if(current_addon_id_ == "") {
777  context_manager_->set_addon_id(current_addon_id_);
778  }
779 
780  if(current_addon_id_ != "") {
781  context_manager_->edit_pbl();
782  }
783  return true;
784 
786  if(current_addon_id_ == "") {
788  context_manager_->set_addon_id(current_addon_id_);
789  }
790 
791  if(current_addon_id_ != "") {
792  context_manager_->change_addon_id();
793  }
794  return true;
795 
797  add_area();
798  return true;
799 
801  change_unit_id();
802  return true;
803 
804  return true;
806  {
807  map_location loc = gui_->mouseover_hex();
809  bool unrenamable = un->unrenamable();
810  un->set_unrenamable(!unrenamable);
811  }
812  return true;
814  {
815  map_location loc = gui_->mouseover_hex();
817  bool canrecruit = un->can_recruit();
818  un->set_can_recruit(!canrecruit);
819  un->anim_comp().set_standing();
820  }
821  return true;
822  case HOTKEY_DELETE_UNIT:
823  {
824  map_location loc = gui_->mouseover_hex();
825  perform_delete(std::make_unique<editor_action_unit_delete>(loc));
826  }
827  return true;
828  case HOTKEY_EDITOR_CLIPBOARD_PASTE: //paste is somewhat different as it might be "one action then revert to previous mode"
829  toolkit_->hotkey_set_mouse_action(command);
830  return true;
831 
832  //Clipboard
834  context_manager_->get_clipboard().rotate_60_cw();
835  toolkit_->update_mouse_action_highlights();
836  return true;
838  context_manager_->get_clipboard().rotate_60_ccw();
839  toolkit_->update_mouse_action_highlights();
840  return true;
842  context_manager_->get_clipboard().flip_horizontal();
843  toolkit_->update_mouse_action_highlights();
844  return true;
846  context_manager_->get_clipboard().flip_vertical();
847  toolkit_->update_mouse_action_highlights();
848  return true;
849 
850  //Brushes
852  toolkit_->cycle_brush();
853  return true;
855  toolkit_->set_brush("brush-1");
856  return true;
858  toolkit_->set_brush("brush-2");
859  return true;
861  toolkit_->set_brush("brush-3");
862  return true;
864  toolkit_->set_brush("brush-nw-se");
865  return true;
867  toolkit_->set_brush("brush-sw-ne");
868  return true;
869 
871  copy_selection();
872  return true;
874  cut_selection();
875  return true;
877  context_manager_->rename_area_dialog();
878  return true;
880  save_area();
881  return true;
884  return true;
886  if(!get_current_map_context().map().everything_selected()) {
887  context_manager_->perform_refresh(editor_action_select_all());
888  return true;
889  }
890  [[fallthrough]];
893  return true;
895  context_manager_->perform_refresh(editor_action_select_none());
896  return true;
898  context_manager_->fill_selection();
899  return true;
902  get_current_map_context().map().selection()));
903  return true;
904 
906  context_manager_->edit_scenario_dialog();
907  return true;
908 
911  get_current_map_context().get_active_area());
912  return true;
913 
914  // map specific
916  context_manager_->close_current_context();
917  // Copy behaviour from when switching windows to always reset the active tool to the Paint Tool
918  // This avoids the situation of having a scenario-specific tool active in a map context which can cause a crash if used
919  // Not elegant but at least avoids a potential crash and is consistent with existing behaviour
920  toolkit_->hotkey_set_mouse_action(HOTKEY_EDITOR_TOOL_PAINT);
921  return true;
923  context_manager_->load_map_dialog();
924  return true;
926  context_manager_->revert_map();
927  return true;
929  context_manager_->new_map_dialog();
930  return true;
932  if(current_addon_id_ == "") {
934  context_manager_->set_addon_id(current_addon_id_);
935  }
936 
937  if(current_addon_id_ != "") {
938  context_manager_->new_scenario_dialog();
939  }
940  return true;
942  save_map();
943  return true;
945  context_manager_->save_all_maps();
946  return true;
948  context_manager_->save_map_as_dialog();
949  return true;
951  if(current_addon_id_ == "") {
953  context_manager_->set_addon_id(current_addon_id_);
954  }
955 
956  if(current_addon_id_ != "") {
957  context_manager_->save_scenario_as_dialog();
958  }
959  return true;
961  context_manager_->generate_map_dialog();
962  return true;
964  context_manager_->apply_mask_dialog();
965  return true;
967  context_manager_->create_mask_to_dialog();
968  return true;
970  context_manager_->resize_map_dialog();
971  return true;
972 
973  // Side specific ones
975  if(get_current_map_context().teams().size() >= 9) {
976  size_t new_side_num = get_current_map_context().teams().size() + 1;
977  toolkit_->get_palette_manager()->location_palette_->add_item(std::to_string(new_side_num));
978  }
980  gui_->init_flags();
981  return true;
983  gui_->set_team(0, true);
984  gui_->set_playing_team(0);
986  return true;
988  context_manager_->edit_side_dialog(gui_->viewing_team());
989  return true;
990 
991  // Transitions
993  context_manager_->set_update_transitions_mode(2);
994  return true;
996  context_manager_->set_update_transitions_mode(1);
997  return true;
999  context_manager_->set_update_transitions_mode(0);
1000  return true;
1002  if(context_manager_->toggle_update_transitions()) {
1003  return true;
1004  }
1005  [[fallthrough]];
1007  context_manager_->refresh_all();
1008  return true;
1009  // Refresh
1010  case HOTKEY_EDITOR_REFRESH:
1011  context_manager_->reload_map();
1012  return true;
1015  return true;
1016 
1020  gui().invalidate_all();
1021  return true;
1025  gui().invalidate_all();
1026  return true;
1030  gui().invalidate_all();
1031  return true;
1033  location_palette* lp = dynamic_cast<location_palette*>(&toolkit_->get_palette_manager()->active_palette());
1034  if (lp) {
1035  perform_delete(std::make_unique<editor_action_starting_position>(map_location(), lp->selected_item()));
1036  // No idea if this is the right thing to call, but it ensures starting
1037  // position labels get removed on delete.
1038  context_manager_->refresh_after_action();
1039  }
1040  return true;
1041  }
1042  default:
1043  return hotkey::command_executor::do_execute_command(cmd, press, release);
1044  }
1045 }
1046 
1048 {
1049  help::show_help("..editor");
1050 }
1051 
1052 void editor_controller::show_menu(const std::vector<config>& items_arg, int xloc, int yloc, bool context_menu, display& disp)
1053 {
1054  if(context_menu) {
1055  if(!get_current_map_context().map().on_board_with_border(gui().hex_clicked_on(xloc, yloc))) {
1056  return;
1057  }
1058  }
1059 
1060  std::vector<config> items;
1061  for(const auto& c : items_arg) {
1062  const std::string& id = c["id"];
1063 
1065 
1066  if((can_execute_command(cmd) && (!context_menu || in_context_menu(cmd)))
1068  {
1069  items.emplace_back("id", id);
1070  }
1071  }
1072 
1073  // No point in showing an empty menu.
1074  if(items.empty()) {
1075  return;
1076  }
1077 
1078  // Based on the ID of the first entry, we fill the menu contextually.
1079  const std::string& first_id = items.front()["id"];
1080 
1081  if(first_id == "EDITOR-LOAD-MRU-PLACEHOLDER") {
1083  context_manager_->expand_load_mru_menu(items, 0);
1084  }
1085 
1086  if(first_id == "editor-switch-map") {
1088  context_manager_->expand_open_maps_menu(items, 0);
1089  }
1090 
1091  if(first_id == "editor-palette-groups") {
1093  toolkit_->get_palette_manager()->active_palette().expand_palette_groups_menu(items, 0);
1094  }
1095 
1096  if(first_id == "editor-switch-side") {
1098  context_manager_->expand_sides_menu(items, 0);
1099  }
1100 
1101  if(first_id == "editor-switch-area") {
1103  context_manager_->expand_areas_menu(items, 0);
1104  }
1105 
1106  if(first_id == "editor-pbl") {
1108  }
1109 
1110  if(!items.empty() && items.front()["id"] == "editor-switch-time") {
1112  context_manager_->expand_time_menu(items, 0);
1113  }
1114 
1115  if(first_id == "editor-assign-local-time") {
1117  context_manager_->expand_local_time_menu(items, 0);
1118  }
1119 
1120  if(first_id == "menu-unit-facings") {
1122  auto pos = items.erase(items.begin());
1123  int dir = 0;
1124  std::generate_n(std::inserter<std::vector<config>>(items, pos), static_cast<int>(map_location::NDIRECTIONS), [&dir]() -> config {
1126  });
1127  }
1128 
1129  if(first_id == "editor-playlist") {
1131  auto pos = items.erase(items.begin());
1132  std::transform(music_tracks_.begin(), music_tracks_.end(), std::inserter<std::vector<config>>(items, pos), [](const sound::music_track& track) -> config {
1133  return config {"label", track.title().empty() ? track.id() : track.title()};
1134  });
1135  }
1136 
1137  if(first_id == "editor-assign-schedule") {
1139  auto pos = items.erase(items.begin());
1140  std::transform(tods_.begin(), tods_.end(), std::inserter<std::vector<config>>(items, pos), [](const tods_map::value_type& tod) -> config {
1141  return config {"label", tod.second.first};
1142  });
1143  }
1144 
1145  if(first_id == "editor-assign-local-schedule") {
1147  auto pos = items.erase(items.begin());
1148  std::transform(tods_.begin(), tods_.end(), std::inserter<std::vector<config>>(items, pos), [](const tods_map::value_type& tod) -> config {
1149  return config {"label", tod.second.first};
1150  });
1151  }
1152 
1153  command_executor::show_menu(items, xloc, yloc, context_menu, disp);
1154 }
1155 
1157 {
1158  gui_->clear_help_string();
1159  gui2::dialogs::preferences_dialog::display();
1160 
1161  gui_->queue_rerender();
1162 }
1163 
1165 {
1167  gui_->invalidate_all();
1168 }
1169 
1171 {
1172  map_location loc = gui_->mouseover_hex();
1173  const unit_map & units = get_current_map_context().units();
1174  const unit_map::const_unit_iterator un = units.find(loc);
1175  if(un != units.end()) {
1176  help::show_unit_help(un->type_id(), un->type().show_variations_in_help(), false);
1177  } else {
1178  help::show_help("..units");
1179  }
1180 }
1181 
1182 
1184 {
1185  if (!get_current_map_context().map().selection().empty()) {
1186  context_manager_->get_clipboard() = map_fragment(get_current_map_context().map(), get_current_map_context().map().selection());
1187  context_manager_->get_clipboard().center_by_mass();
1188  }
1189 }
1190 
1192 {
1193  map_location loc = gui_->mouseover_hex();
1194  unit_map& units = get_current_map_context().units();
1195  const unit_map::unit_iterator& un = units.find(loc);
1196 
1197  const std::string title(N_("Change Unit ID"));
1198  const std::string label(N_("ID:"));
1199 
1200  if(un != units.end()) {
1201  std::string id = un->id();
1202  if (gui2::dialogs::edit_text::execute(title, label, id)) {
1203  un->set_id(id);
1204  }
1205  }
1206 }
1207 
1209 {
1210  map_location loc = gui_->mouseover_hex();
1211  unit_map& units = get_current_map_context().units();
1212  const unit_map::unit_iterator& un = units.find(loc);
1213 
1214  const std::string title(N_("Rename Unit"));
1215  const std::string label(N_("Name:"));
1216 
1217  if(un != units.end()) {
1218  std::string name = un->name();
1219  if(gui2::dialogs::edit_text::execute(title, label, name)) {
1220  //TODO we may not want a translated name here.
1221  un->set_name(name);
1222  }
1223  }
1224 }
1225 
1227 {
1229 }
1230 
1232 {
1233  copy_selection();
1235 }
1236 
1238 {
1239  const std::set<map_location>& area = get_current_map_context().map().selection();
1241 }
1242 
1244 {
1245  const std::set<map_location>& area = get_current_map_context().map().selection();
1247 }
1248 
1250 {
1251  std::stringstream ssx, ssy;
1252  std::set<map_location>::const_iterator i = get_current_map_context().map().selection().begin();
1253  if (i != get_current_map_context().map().selection().end()) {
1254  ssx << "x = " << i->wml_x();
1255  ssy << "y = " << i->wml_y();
1256  ++i;
1257  while (i != get_current_map_context().map().selection().end()) {
1258  ssx << ", " << i->wml_x();
1259  ssy << ", " << i->wml_y();
1260  ++i;
1261  }
1262  ssx << "\n" << ssy.str() << "\n";
1263  desktop::clipboard::copy_to_clipboard(ssx.str(), false);
1264  }
1265 }
1266 
1267 void editor_controller::perform_delete(std::unique_ptr<editor_action> action)
1268 {
1269  if (action) {
1271  }
1272 }
1273 
1274 void editor_controller::perform_refresh_delete(std::unique_ptr<editor_action> action, bool drag_part /* =false */)
1275 {
1276  if (action) {
1277  context_manager_->perform_refresh(*action, drag_part);
1278  }
1279 }
1280 
1282 {
1284  context_manager_->refresh_all();
1285 }
1286 
1288 {
1289  set_button_state();
1290  toolkit_->adjust_size();
1292 }
1293 
1295 {
1297  context_manager_->refresh_after_action();
1298 }
1299 
1301 {
1303  context_manager_->refresh_after_action();
1304 }
1305 
1306 void editor_controller::mouse_motion(int x, int y, const bool /*browse*/,
1307  bool update, map_location /*new_loc*/)
1308 {
1309  if (mouse_handler_base::mouse_motion_default(x, y, update)) return;
1310  map_location hex_clicked = gui().hex_clicked_on(x, y);
1311  if (get_current_map_context().map().on_board_with_border(drag_from_hex_) && is_dragging()) {
1312  std::unique_ptr<editor_action> a;
1313  bool partial = false;
1314  // last_undo is a non-owning pointer. Although it could have other uses, it seems to be
1315  // mainly (only?) used for printing debugging information.
1316  auto last_undo = get_current_map_context().last_undo_action();
1317  if (dragging_left_ && (sdl::get_mouse_button_mask() & SDL_BUTTON(1)) != 0) {
1318  if (!get_current_map_context().map().on_board_with_border(hex_clicked)) return;
1319  a = get_mouse_action().drag_left(*gui_, x, y, partial, last_undo);
1320  } else if (dragging_right_ && (sdl::get_mouse_button_mask() & SDL_BUTTON(3)) != 0) {
1321  if (!get_current_map_context().map().on_board_with_border(hex_clicked)) return;
1322  a = get_mouse_action().drag_right(*gui_, x, y, partial, last_undo);
1323  }
1324  //Partial means that the mouse action has modified the
1325  //last undo action and the controller shouldn't add
1326  //anything to the undo stack (hence a different perform_ call)
1327  if (a != nullptr) {
1328  if (partial) {
1330  } else {
1332  }
1333  context_manager_->refresh_after_action(true);
1334  }
1335  } else {
1336  get_mouse_action().move(*gui_, hex_clicked);
1337  }
1338  gui().highlight_hex(hex_clicked);
1339 }
1340 
1341 void editor_controller::touch_motion(int /* x */, int /* y */, const bool /* browse */, bool /* update */, map_location /* new_loc */)
1342 {
1343  // Not implemented at all. Sorry, it's a very low priority for iOS port.
1344 }
1345 
1347 {
1348  return get_current_map_context().map().on_board_with_border(gui().hex_clicked_on(x,y));
1349 }
1350 
1351 bool editor_controller::right_click_show_menu(int /*x*/, int /*y*/, const bool /*browse*/)
1352 {
1354 }
1355 
1356 bool editor_controller::left_click(int x, int y, const bool browse)
1357 {
1358  toolkit_->clear_mouseover_overlay();
1359  if (mouse_handler_base::left_click(x, y, browse))
1360  return true;
1361 
1362  LOG_ED << "Left click, after generic handling";
1363  map_location hex_clicked = gui().hex_clicked_on(x, y);
1364  if (!get_current_map_context().map().on_board_with_border(hex_clicked))
1365  return true;
1366 
1367  LOG_ED << "Left click action " << hex_clicked;
1368  auto a = get_mouse_action().click_left(*gui_, x, y);
1369  if(a) {
1370  perform_refresh_delete(std::move(a), true);
1371  set_button_state();
1372  }
1373 
1374  return false;
1375 }
1376 
1377 void editor_controller::left_drag_end(int x, int y, const bool /*browse*/)
1378 {
1379  auto a = get_mouse_action().drag_end_left(*gui_, x, y);
1380  perform_delete(std::move(a));
1381 }
1382 
1383 void editor_controller::left_mouse_up(int x, int y, const bool /*browse*/)
1384 {
1385  auto a = get_mouse_action().up_left(*gui_, x, y);
1386  if(a) {
1387  perform_delete(std::move(a));
1388  set_button_state();
1389  }
1390  toolkit_->set_mouseover_overlay();
1391  context_manager_->refresh_after_action();
1392 }
1393 
1394 bool editor_controller::right_click(int x, int y, const bool browse)
1395 {
1396  toolkit_->clear_mouseover_overlay();
1397  if (mouse_handler_base::right_click(x, y, browse)) return true;
1398  LOG_ED << "Right click, after generic handling";
1399  map_location hex_clicked = gui().hex_clicked_on(x, y);
1400  if (!get_current_map_context().map().on_board_with_border(hex_clicked)) return true;
1401  LOG_ED << "Right click action " << hex_clicked;
1402  auto a = get_mouse_action().click_right(*gui_, x, y);
1403  if(a) {
1404  perform_refresh_delete(std::move(a), true);
1405  set_button_state();
1406  }
1407  return false;
1408 }
1409 
1410 void editor_controller::right_drag_end(int x, int y, const bool /*browse*/)
1411 {
1412  auto a = get_mouse_action().drag_end_right(*gui_, x, y);
1413  perform_delete(std::move(a));
1414 }
1415 
1416 void editor_controller::right_mouse_up(int x, int y, const bool browse)
1417 {
1418  // Call base method to handle context menus.
1419  mouse_handler_base::right_mouse_up(x, y, browse);
1420 
1421  auto a = get_mouse_action().up_right(*gui_, x, y);
1422  if(a) {
1423  perform_delete(std::move(a));
1424  set_button_state();
1425  }
1426  toolkit_->set_mouseover_overlay();
1427  context_manager_->refresh_after_action();
1428 }
1429 
1431 {
1432  const map_location& loc = gui().mouseover_hex();
1433  if (get_current_map_context().map().on_board(loc) == false)
1434  return;
1435 
1438 }
1439 
1440 void editor_controller::process_keyup_event(const SDL_Event& event)
1441 {
1442  auto a = get_mouse_action().key_event(gui(), event);
1443  perform_refresh_delete(std::move(a));
1444  toolkit_->set_mouseover_overlay();
1445 }
1446 
1448  return this;
1449 }
1450 
1452 {
1454 }
1455 
1457 {
1459 }
1460 
1462 {
1464 }
1465 
1467 {
1469 }
1470 
1472 {
1473  return toolkit_->get_palette_manager()->active_palette().action_pressed();
1474 }
1475 
1476 } //end namespace editor
Editor action classes.
Editor action classes.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:161
child_itors child_range(config_key_type key)
Definition: config.cpp:277
void set_scroll_up(bool on)
void set_scroll_left(bool on)
virtual bool in_context_menu(const hotkey::ui_command &cmd) const
virtual void play_slice(bool is_delay_enabled=true)
void set_scroll_right(bool on)
const game_config_view & game_config_
void set_scroll_down(bool on)
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
Definition: display.hpp:87
void toggle_debug_flag(DEBUG_FLAG flag)
Definition: display.hpp:996
const map_location hex_clicked_on(int x, int y) const
given x,y co-ordinates of an onscreen pixel, will return the location of the hex that this pixel corr...
Definition: display.cpp:562
virtual void highlight_hex(map_location hex)
Definition: display.cpp:1555
@ DEBUG_COORDINATES
Overlays x,y coords on tiles.
Definition: display.hpp:968
@ DEBUG_NUM_BITMAPS
Overlays number of bitmaps on tiles.
Definition: display.hpp:974
@ DEBUG_TERRAIN_CODES
Overlays terrain codes on tiles.
Definition: display.hpp:971
void invalidate_all()
Function to invalidate all tiles.
Definition: display.cpp:3140
surface screenshot(bool map_screenshot=false)
Capture a (map-)screenshot into a surface.
Definition: display.cpp:762
void queue_rerender()
Marks everything for rendering including all tiles and sidebar.
Definition: display.cpp:2328
void set_debug_flag(DEBUG_FLAG flag, bool value)
Definition: display.hpp:991
const map_location & mouseover_hex() const
Definition: display.hpp:307
Container action wrapping several actions into one.
Definition: action.hpp:88
Paint the same terrain on a number of locations on the map.
Definition: action.hpp:266
Randomize terrain in an area.
Definition: action.hpp:399
The editor_controller class contains the mouse and keyboard event handling routines for the editor.
const std::unique_ptr< context_manager > context_manager_
void preferences() override
Show the preferences dialog.
void refresh_image_cache()
Reload images.
void right_drag_end(int x, int y, const bool browse) override
Called whenever the right mouse drag has "ended".
bool can_execute_command(const hotkey::ui_command &command) const override
command_executor override
bool quit_confirm()
Show a quit confirmation dialog and returns true if the user pressed 'yes'.
void scroll_up(bool on) override
Handle hotkeys to scroll map.
void cut_selection()
Cut the selection from the current map to the clipboard.
void display_redraw_callback(display &)
Callback function passed to display to be called on queue_rerender.
std::unique_ptr< font::floating_label_context > floating_label_manager_
void show_menu(const std::vector< config > &items_arg, int xloc, int yloc, bool context_menu, display &disp) override
controller_base override
void undo() override
Undos an action in the current map context.
void left_mouse_up(int x, int y, const bool browse) override
Called when the left mouse button is up.
bool left_click(int x, int y, const bool browse) override
Overridden in derived classes, called on a left click (mousedown).
bool allow_mouse_wheel_scroll(int x, int y) override
Derived classes can override this to disable mousewheel scrolling under some circumstances,...
void touch_motion(int x, int y, const bool browse, bool update=false, map_location new_loc=map_location::null_location()) override
virtual std::vector< std::string > additional_actions_pressed() override
void perform_refresh_delete(std::unique_ptr< editor_action > action, bool drag_part=false)
Peform an action on the current map_context, then refresh the display and delete the pointer.
void init_tods(const game_config_view &game_config)
init the available time-of-day settings
const mouse_action & get_mouse_action() const
Get the current mouse action.
map_context & get_current_map_context() const
std::unique_ptr< editor_toolkit > toolkit_
void scroll_right(bool on) override
void init_music(const game_config_view &game_config)
init background music for the editor
const std::unique_ptr< editor_display > gui_
The display object used and owned by the editor.
bool do_execute_command(const hotkey::ui_command &command, bool press=true, bool release=false) override
command_executor override
void export_selection_coords()
Export the WML-compatible list of selected tiles to the system clipboard.
void redo() override
Redos an action in the current map context.
editor_display & gui() override
Reference to the used display objects.
hotkey::ACTION_STATE get_action_state(const hotkey::ui_command &command) const override
command_executor override
void perform_delete(std::unique_ptr< editor_action > action)
Perform an action, then delete the action object.
void right_mouse_up(int x, int y, const bool browse) override
Called when the right mouse button is up.
virtual hotkey::command_executor * get_hotkey_command_executor() override
Optionally get a command executor to handle context menu events.
void mouse_motion(int x, int y, const bool browse, bool update, map_location new_loc=map_location::null_location()) override
Called when a mouse motion event takes place.
EXIT_STATUS main_loop()
Editor main loop.
editor_controller(const editor_controller &)=delete
void custom_tods_dialog()
Display the settings dialog, used to control e.g.
void do_screenshot(const std::string &screenshot_filename="map_screenshot.png")
Takes a screenshot.
void toggle_grid() override
Grid toggle.
void scroll_left(bool on) override
bool right_click(int x, int y, const bool browse) override
Overridden in derived classes, called on a right click (mousedown).
void save_area()
Save the current selection to the active area.
void process_keyup_event(const SDL_Event &event) override
Process keyup (always).
void copy_selection()
Copy the selection on the current map to the clipboard.
void init_gui()
init the display object and general set-up
std::unique_ptr< help::help_manager > help_manager_
std::vector< sound::music_track > music_tracks_
bool right_click_show_menu(int x, int y, const bool browse) override
Called in the default right_click when the context menu is about to be shown, can be used for preproc...
static std::string current_addon_id_
void add_area()
Add a new area to the current context, filled with the selection if any.
void scroll_down(bool on) override
void left_drag_end(int x, int y, const bool browse) override
Called whenever the left mouse drag has "ended".
bool do_quit_
Quit main loop flag.
void save_map() override
Save the map, open dialog if not named yet.
bool everything_selected() const
Definition: editor_map.cpp:207
const std::set< map_location > & selection() const
Return the selection set.
Definition: editor_map.hpp:149
List of starting locations and location ids.
const std::string & selected_item() const
Return the currently selected item.
void save_area(const std::set< map_location > &area)
void new_area(const std::set< map_location > &area)
void perform_partial_action(const editor_action &action)
Performs a partial action, assumes that the top undo action has been modified to maintain coherent st...
void remove_side()
removes the last side from the scenario
void set_active_area(int index)
bool modified() const
virtual const unit_map & units() const override
Const units accessor.
void set_local_starting_time(int time)
int get_active_area() const
void new_side()
Adds a new side to the map.
editor_action * last_undo_action()
void redo()
Re-does a previously undid action, and puts it back in the undo stack.
void set_starting_time(int time)
bool select_area(int index)
Select the nth tod area.
bool can_redo() const
bool can_undo() const
void perform_action(const editor_action &action)
Performs an action (thus modifying the map).
void undo()
Un-does the last action, and puts it in the redo stack for a possible redo.
void replace_schedule(const std::vector< time_of_day > &schedule)
bool is_in_playlist(std::string track_id)
void remove_area(int index)
void replace_local_schedule(const std::vector< time_of_day > &schedule)
Replace the [time]s of the currently active area.
const tod_manager * get_time_manager() const
void partial_undo()
Un-does a single step from a undo action chain.
virtual const editor_map & map() const override
Const map accessor.
void add_to_playlist(const sound::music_track &track)
const std::string & get_filename() const
void set_starting_position_labels(display &disp)
map_labels & get_labels()
virtual const std::vector< team > & teams() const override
Const teams accessor.
bool is_pure_map() const
A map fragment – a collection of locations and information abut them.
virtual std::unique_ptr< editor_action > click_left(editor_display &disp, int x, int y)=0
A click, possibly the beginning of a drag.
virtual std::unique_ptr< editor_action > click_right(editor_display &disp, int x, int y)=0
A click, possibly the beginning of a drag.
virtual std::unique_ptr< editor_action > drag_end_right(editor_display &disp, int x, int y)
virtual bool has_context_menu() const
virtual std::unique_ptr< editor_action > up_left(editor_display &disp, int x, int y)
virtual void move(editor_display &disp, const map_location &hex)
Mouse move (not a drag).
virtual std::unique_ptr< editor_action > up_right(editor_display &disp, int x, int y)
virtual std::unique_ptr< editor_action > key_event(editor_display &disp, const SDL_Event &e)
Function called by the controller on a key event for the current mouse action.
virtual std::unique_ptr< editor_action > drag_left(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Drag operation.
virtual std::unique_ptr< editor_action > drag_right(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Drag operation.
virtual bool supports_brushes() const
Whether we need the brush bar, is used to grey it out.
virtual std::unique_ptr< editor_action > drag_end_left(editor_display &disp, int x, int y)
The end of dragging.
bool dragging_right_
RMB drag init flag.
bool dragging_left_
LMB drag init flag.
map_location drag_from_hex_
Drag start or mouse-down map location.
A class grating read only view to a vector of config objects, viewed as one config with all children ...
bool on_board_with_border(const map_location &loc) const
Definition: map.cpp:390
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) const
Definition: map.cpp:98
virtual bool do_execute_command(const hotkey::ui_command &command, bool press=true, bool release=false)
void recalculate_labels()
Definition: label.cpp:245
Implements a quit confirmation dialog.
static bool show_prompt(const std::string &message)
static bool quit()
Shows the quit confirmation if needed.
static void quit_to_desktop()
Internal representation of music tracks.
const std::string & file_path() const
const std::string & id() const
const std::vector< time_of_day > & times(const map_location &loc=map_location::null_location()) const
std::vector< std::string > get_area_ids() const
const std::set< map_location > & get_area_by_index(int index) const
int get_current_time(const map_location &loc=map_location::null_location()) const
int get_current_area_time(int index) const
Container associating units to locations.
Definition: map.hpp:99
unit_iterator end()
Definition: map.hpp:429
bool empty() const
Definition: map.hpp:446
unit_iterator find(std::size_t id)
Definition: map.cpp:301
Editor action classes.
#define LOG_ED
#define ERR_ED
#define SCOPE_ED
#define WRN_ED
std::size_t i
Definition: function.cpp:968
#define N_(String)
Definition: gettext.hpp:101
static std::string _(const char *str)
Definition: gettext.hpp:93
std::string label
What to show in the filter's drop-down list.
Definition: manager.cpp:217
Contains functions for cleanly handling SDL input.
CURSOR_TYPE get()
Definition: cursor.cpp:216
@ NORMAL
Definition: cursor.hpp:29
void set(CURSOR_TYPE type)
Use the default parameter to reset cursors.
Definition: cursor.cpp:176
void copy_to_clipboard(const std::string &text, const bool)
Copies text to the clipboard.
Definition: clipboard.cpp:34
static void update()
Manage the empty-palette in the editor.
Definition: action.cpp:31
@ EXIT_ERROR
Definition: editor_main.hpp:28
@ EXIT_NORMAL
Definition: editor_main.hpp:25
@ EXIT_RELOAD_DATA
Definition: editor_main.hpp:27
const t_translation::terrain_code & get_selected_bg_terrain()
static std::vector< std::string > saved_windows_
std::string initialize_addon()
Definition: editor_main.cpp:32
Game configuration data as global variables.
Definition: build_info.cpp:63
void show_unit_list(display &gui)
Definition: unit_list.cpp:199
void show_transient_message(const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup)
Shows a transient message to the user.
void show_error_message(const std::string &msg, bool message_use_markup)
Shows an error message to the user.
Definition: message.cpp:204
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:144
void show_terrain_description(const terrain_type &t)
Definition: help.cpp:81
void show_unit_help(const std::string &show_topic, bool has_variations, bool hidden, int xloc, int yloc)
Open the help browser, show unit with id unit_id.
Definition: help.cpp:155
Keyboard shortcuts for game actions.
const hotkey_command & get_hotkey_command(const std::string &command)
returns the hotkey_command with the given name
@ HOTKEY_EDITOR_TOOL_VILLAGE
@ HOTKEY_MINIMAP_DRAW_VILLAGES
@ HOTKEY_EDITOR_BRUSH_NW_SE
@ HOTKEY_EDITOR_REFRESH
@ HOTKEY_FULLSCREEN
@ HOTKEY_EDITOR_SELECT_NONE
@ HOTKEY_ANIMATE_MAP
@ HOTKEY_SCREENSHOT
@ HOTKEY_EDITOR_CLIPBOARD_ROTATE_CCW
@ HOTKEY_MOUSE_SCROLL
@ HOTKEY_EDITOR_PALETTE_GROUPS
@ HOTKEY_TERRAIN_DESCRIPTION
@ HOTKEY_EDITOR_PALETTE_UPSCROLL
@ HOTKEY_EDITOR_SIDE_REMOVE
@ HOTKEY_EDITOR_BRUSH_NEXT
@ HOTKEY_EDITOR_TOOL_LABEL
@ HOTKEY_EDITOR_CLIPBOARD_ROTATE_CW
@ HOTKEY_EDITOR_BRUSH_3
@ HOTKEY_SCROLL_LEFT
@ HOTKEY_EDITOR_CLIPBOARD_PASTE
@ HOTKEY_EDITOR_PARTIAL_UNDO
@ HOTKEY_EDITOR_UNIT_TOGGLE_CANRECRUIT
@ HOTKEY_EDITOR_PALETTE_ITEM_SWAP
@ HOTKEY_EDITOR_TOOL_PAINT
@ HOTKEY_EDITOR_MAP_CLOSE
@ HOTKEY_EDITOR_MAP_GENERATE
@ HOTKEY_EDITOR_SELECTION_FLIP
@ HOTKEY_EDITOR_SCHEDULE
@ HOTKEY_EDITOR_TOOL_FILL
@ HOTKEY_EDITOR_SCENARIO_SAVE_AS
@ HOTKEY_EDITOR_PLAYLIST
@ HOTKEY_EDITOR_MAP_SAVE_AS
@ HOTKEY_UNIT_DESCRIPTION
@ HOTKEY_SCROLL_RIGHT
@ HOTKEY_EDITOR_SELECT_ALL
@ HOTKEY_EDITOR_DRAW_COORDINATES
@ HOTKEY_EDITOR_TOOL_NEXT
@ HOTKEY_EDITOR_SELECTION_EXPORT
@ HOTKEY_EDITOR_PARTIAL_UPDATE_TRANSITIONS
@ HOTKEY_EDITOR_MAP_CREATE_MASK_TO
@ HOTKEY_TOGGLE_GRID
@ HOTKEY_EDITOR_SELECTION_CUT
@ HOTKEY_EDITOR_UNIT_CHANGE_ID
@ HOTKEY_MINIMAP_DRAW_TERRAIN
@ HOTKEY_EDITOR_DRAW_NUM_OF_BITMAPS
@ HOTKEY_MAP_SCREENSHOT
@ HOTKEY_EDITOR_AREA_ADD
@ HOTKEY_EDITOR_BRUSH_SW_NE
@ HOTKEY_EDITOR_TOOL_UNIT
@ HOTKEY_QUIT_TO_DESKTOP
@ HOTKEY_EDITOR_CHANGE_ADDON_ID
@ HOTKEY_EDITOR_CUSTOM_TODS
@ HOTKEY_EDITOR_REFRESH_IMAGE_CACHE
@ HOTKEY_EDITOR_SELECTION_FILL
@ HOTKEY_EDITOR_CLIPBOARD_FLIP_VERTICAL
@ HOTKEY_EDITOR_MAP_SAVE_ALL
@ HOTKEY_EDITOR_BRUSH_1
@ HOTKEY_EDITOR_SELECTION_ROTATE
@ HOTKEY_EDITOR_MAP_LOAD
@ HOTKEY_RENAME_UNIT
@ HOTKEY_EDITOR_BRUSH_2
@ HOTKEY_EDITOR_TOOL_STARTING_POSITION
@ HOTKEY_MINIMAP_CODING_TERRAIN
@ HOTKEY_EDITOR_NO_UPDATE_TRANSITIONS
@ HOTKEY_EDITOR_SELECTION_COPY
@ HOTKEY_MINIMAP_DRAW_UNITS
@ HOTKEY_EDITOR_PALETTE_DOWNSCROLL
@ HOTKEY_EDITOR_UNIT_TOGGLE_LOYAL
@ HOTKEY_EDITOR_MAP_APPLY_MASK
@ HOTKEY_EDITOR_LOCAL_TIME
@ HOTKEY_EDITOR_UNIT_FACING
@ HOTKEY_PREFERENCES
@ HOTKEY_STATUS_TABLE
@ HOTKEY_DELETE_UNIT
@ HOTKEY_EDITOR_SIDE_NEW
@ HOTKEY_EDITOR_SELECTION_RANDOMIZE
@ HOTKEY_EDITOR_SCENARIO_NEW
@ HOTKEY_EDITOR_MAP_SWITCH
@ HOTKEY_EDITOR_SELECT_INVERSE
@ HOTKEY_EDITOR_TOGGLE_TRANSITIONS
@ HOTKEY_UNIT_LIST
@ HOTKEY_SCROLL_DOWN
@ HOTKEY_EDITOR_AUTO_UPDATE_TRANSITIONS
@ HOTKEY_ZOOM_DEFAULT
@ HOTKEY_EDITOR_AREA_RENAME
@ HOTKEY_EDITOR_MAP_RESIZE
@ HOTKEY_SCROLL_UP
@ HOTKEY_EDITOR_DRAW_TERRAIN_CODES
@ HOTKEY_EDITOR_AREA_REMOVE
@ HOTKEY_QUIT_GAME
@ HOTKEY_EDITOR_UPDATE_TRANSITIONS
@ HOTKEY_EDITOR_TOOL_SELECT
@ HOTKEY_EDITOR_MAP_NEW
@ HOTKEY_EDITOR_MAP_SAVE
@ HOTKEY_EDITOR_AREA_SAVE
@ HOTKEY_EDITOR_REMOVE_LOCATION
@ HOTKEY_EDITOR_SIDE_EDIT
@ HOTKEY_EDITOR_TOOL_ITEM
@ TITLE_SCREEN__RELOAD_WML
@ HOTKEY_EDITOR_UNIT_TOGGLE_RENAMEABLE
@ HOTKEY_EDITOR_SCENARIO_EDIT
@ HOTKEY_EDITOR_MAP_REVERT
@ HOTKEY_EDITOR_CLIPBOARD_FLIP_HORIZONTAL
@ HOTKEY_MINIMAP_CODING_UNIT
void flush_cache()
Purges all image caches.
Definition: picture.cpp:225
save_result save_image(const locator &i_locator, const std::string &filename)
Definition: picture.cpp:949
int show_menu(lua_State *L)
Displays a popup menu at the current mouse position Best used from a [set_menu_item],...
Definition: lua_gui2.cpp:185
const std::vector< std::string > items
void set_draw_num_of_bitmaps(bool value)
Definition: editor.cpp:57
bool draw_terrain_codes()
Definition: editor.cpp:37
bool draw_hex_coordinates()
Definition: editor.cpp:45
bool draw_num_of_bitmaps()
Definition: editor.cpp:53
void set_draw_hex_coordinates(bool value)
Definition: editor.cpp:49
void set_draw_terrain_codes(bool value)
Definition: editor.cpp:41
bool minimap_movement_coding()
Definition: general.cpp:835
bool minimap_draw_villages()
Definition: general.cpp:865
void set_grid(bool ison)
Definition: general.cpp:570
bool minimap_terrain_coding()
Definition: general.cpp:845
bool minimap_draw_terrain()
Definition: general.cpp:875
bool minimap_draw_units()
Definition: general.cpp:855
bool grid()
Definition: general.cpp:565
Unit and team statistics.
::tod_manager * tod_manager
Definition: resources.cpp:30
game_classification * classification
Definition: resources.cpp:35
filter_context * filter_con
Definition: resources.cpp:24
uint32_t get_mouse_button_mask()
Returns the current mouse button mask.
Definition: input.cpp:49
void play_music_once(const std::string &file)
Definition: sound.cpp:603
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:72
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:87
std::string::const_iterator iterator
Definition: tokenizer.hpp:25
@ partial
There are still moves and/or attacks possible, but the unit doesn't fit in the "unmoved" status.
structure which will hide all current floating labels, and cause floating labels instantiated after i...
The help implementation caches data parsed from the game_config.
Definition: help.hpp:40
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...
int index
When this action was the result of a menu click, this is the index of the clicked item in the menu.
Encapsulates the map of the game.
Definition: location.hpp:38
DIRECTION
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:40
bool valid() const
Definition: location.hpp:89
static std::string write_translated_direction(DIRECTION dir)
Definition: location.cpp:162
Helper class, don't construct this directly.
mock_char c
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define e
#define a
#define b