The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
editor_controller.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2017 by Tomasz Sniatowski <kailoran@gmail.com>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 #define GETTEXT_DOMAIN "wesnoth-editor"
15 
17 
18 #include "editor/action/action.hpp"
22 
25 
27 
28 #include "preferences/editor.hpp"
29 
32 #include "gui/dialogs/message.hpp"
36 #include "gui/widgets/window.hpp"
37 #include "wml_exception.hpp"
38 
39 #include "resources.hpp"
40 #include "reports.hpp"
41 
42 #include "desktop/clipboard.hpp"
43 #include "floating_label.hpp"
44 #include "game_board.hpp"
45 #include "preferences/game.hpp"
46 #include "gettext.hpp"
47 #include "preferences/display.hpp"
48 #include "sound.hpp"
49 #include "units/unit.hpp"
51 
52 #include "quit_confirmation.hpp"
53 
54 #include "utils/functional.hpp"
55 
56 namespace {
57 static std::vector<std::string> saved_windows_;
58 }
59 
60 namespace editor {
61 
63  : controller_base(game_config)
64  , mouse_handler_base()
65  , quit_confirmation(std::bind(&editor_controller::quit_confirm, this))
66  , active_menu_(editor::MAP)
67  , reports_(new reports())
68  , gui_(new editor_display(*this, *reports_, controller_base::get_theme(game_config, "editor")))
69  , tods_()
70  , context_manager_(new context_manager(*gui_.get(), game_config_))
71  , toolkit_(nullptr)
72  , tooltip_manager_()
73  , floating_label_manager_(nullptr)
74  , help_manager_(nullptr)
75  , do_quit_(false)
76  , quit_mode_(EXIT_ERROR)
77  , music_tracks_()
78 {
79  init_gui();
80  toolkit_.reset(new editor_toolkit(*gui_.get(), key_, game_config_, *context_manager_.get()));
81  help_manager_.reset(new help::help_manager(&game_config));
82  context_manager_->switch_context(0, true);
83  init_tods(game_config);
84  init_music(game_config);
87 
88  gui().create_buttons();
90 }
91 
93 {
94  gui_->change_display_context(&get_current_map_context());
96  gui_->add_redraw_observer(std::bind(&editor_controller::display_redraw_callback, this, _1));
101 // halo_manager_.reset(new halo::manager(*gui_));
102 // resources::halo = halo_manager_.get();
103 // ^ These lines no longer necessary, the gui owns its halo manager.
104 // TODO: Should the editor map contexts actually own the halo manager and swap them in and out from the gui?
105 // 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
106 // without deleting it.
107 }
108 
110 {
111  for (const config &schedule : game_config.child_range("editor_times")) {
112 
113  const std::string& schedule_id = schedule["id"];
114  const std::string& schedule_name = schedule["name"];
115  if (schedule_id.empty()) {
116  ERR_ED << "Missing ID attribute in a TOD Schedule." << std::endl;
117  continue;
118  }
119 
120  tods_map::iterator times = tods_.find(schedule_id);
121  if (times == tods_.end()) {
122  std::pair<tods_map::iterator, bool> new_times =
123  tods_.emplace(schedule_id, std::make_pair(schedule_name, std::vector<time_of_day>()));
124 
125  times = new_times.first;
126  } else {
127  ERR_ED << "Duplicate TOD Schedule identifiers." << std::endl;
128  continue;
129  }
130 
131  for (const config &time : schedule.child_range("time")) {
132  times->second.second.emplace_back(time);
133  }
134 
135  }
136 
137  if (tods_.empty()) {
138  ERR_ED << "No editor time-of-day defined" << std::endl;
139  }
140 }
141 
143 {
144  const std::string tag_name = "editor_music";
145  if (!game_config.has_child(tag_name))
146  ERR_ED << "No editor music defined" << std::endl;
147  else {
148  for (const config& editor_music : game_config.child_range(tag_name)) {
149  for (const config& music : editor_music.child_range("music")) {
150  sound::music_track track(music);
151  if (track.file_path().empty())
152  WRN_ED << "Music track " << track.id() << " not found." << std::endl;
153  else
154  music_tracks_.emplace_back(music);
155  }
156  }
157  }
158 }
159 
161 {
162  resources::units = nullptr;
163  resources::tod_manager = nullptr;
164  resources::filter_con = nullptr;
165 
166  resources::classification = nullptr;
167 }
168 
170 {
171  try {
172  while (!do_quit_) {
173  play_slice();
174  }
175  } catch (editor_exception& e) {
176  gui2::show_transient_message(_("Fatal error"), e.what());
177  return EXIT_ERROR;
178  } catch (wml_exception& e) {
179  e.show();
180  }
181  return quit_mode_;
182 }
183 
185 }
186 
187 void editor_controller::do_screenshot(const std::string& screenshot_filename /* = "map_screenshot.bmp" */)
188 {
189  try {
190  if (!gui().screenshot(screenshot_filename,true)) {
191  ERR_ED << "Screenshot creation failed!\n";
192  }
193  } catch (wml_exception& e) {
194  e.show();
195  }
196 }
197 
199 {
200  std::string modified;
201  size_t amount = context_manager_->modified_maps(modified);
202 
203  std::string message;
204  if (amount == 0) {
205  message = _("Do you really want to quit?");
206  } else if (amount == 1 && get_current_map_context().modified()) {
207  message = _("Do you really want to quit? Changes to this map since the last save will be lost.");
208  } else {
209  message = _("Do you really want to quit? The following maps were modified and all changes since the last save will be lost:");
210  message += "\n" + modified;
211  }
212  return quit_confirmation::show_prompt(message);
213 }
214 
216 {
217  if (tods_.empty()) {
218  gui2::show_error_message(_("No editor time-of-day found."));
219  return;
220  }
221 
223 
224  if(gui2::dialogs::custom_tod::execute(manager.times(), manager.get_current_time())) {
225  // TODO save the new tod here
226  }
227 
228  gui_->update_tod();
229 
230  context_manager_->refresh_all();
231 }
232 
234 {
235  using namespace hotkey; //reduce hotkey:: clutter
236  switch (cmd.id) {
237  case HOTKEY_NULL:
238  if (index >= 0) {
239  unsigned i = static_cast<unsigned>(index);
240 
241  switch (active_menu_) {
242  case editor::MAP:
243  if (i < context_manager_->open_maps()) {
244  return true;
245  }
246  return false;
247  case editor::LOAD_MRU:
248  case editor::PALETTE:
249  case editor::AREA:
250  case editor::SIDE:
251  case editor::TIME:
252  case editor::SCHEDULE:
254  case editor::MUSIC:
255  case editor::LOCAL_TIME:
256  case editor::UNIT_FACING:
257  return true;
258  }
259  }
260  return false;
262  return true;
264  return toolkit_->get_palette_manager()->can_scroll_up();
266  return toolkit_->get_palette_manager()->can_scroll_down();
267  case HOTKEY_ZOOM_IN:
268  return !gui_->zoom_at_max();
269  case HOTKEY_ZOOM_OUT:
270  return !gui_->zoom_at_min();
271  case HOTKEY_ZOOM_DEFAULT:
272  case HOTKEY_FULLSCREEN:
273  case HOTKEY_SCREENSHOT:
275  case HOTKEY_TOGGLE_GRID:
276  case HOTKEY_MOUSE_SCROLL:
277  case HOTKEY_ANIMATE_MAP:
278  case HOTKEY_MUTE:
279  case HOTKEY_PREFERENCES:
280  case HOTKEY_HELP:
281  case HOTKEY_QUIT_GAME:
282  case HOTKEY_SCROLL_UP:
283  case HOTKEY_SCROLL_DOWN:
284  case HOTKEY_SCROLL_LEFT:
285  case HOTKEY_SCROLL_RIGHT:
286  return true; //general hotkeys we can always do
287 
290 
291  case HOTKEY_STATUS_TABLE:
292  return !get_current_map_context().get_teams().empty();
293 
295  return gui().mouseover_hex().valid();
296 
297  // unit tool related
298  case HOTKEY_DELETE_UNIT:
299  case HOTKEY_RENAME_UNIT:
307  {
308  map_location loc = gui_->mouseover_hex();
310  return (toolkit_->is_mouse_action_set(HOTKEY_EDITOR_TOOL_UNIT) &&
311  units.find(loc) != units.end());
312  }
313  case HOTKEY_UNDO:
315  case HOTKEY_REDO:
327  return true;
328 
332 
335  return !get_current_map_context().get_teams().empty();
336 
337  // brushes
345 
347  return true;
349  return toolkit_->get_palette_manager()->active_palette().supports_swap();
353  {
355  return context_manager_->modified_maps(dummy) > 1;
356  }
362  return true;
364  return !get_current_map_context().get_filename().empty()
366 
367  // Tools
368  // Pure map editing tools this can be used all the time.
373  return true;
374  // WWL dependent tools which don't rely on defined sides.
381  return !get_current_map_context().get_teams().empty();
382 
386  return !get_current_map_context().is_pure_map() &&
388 
390  return !get_current_map_context().is_pure_map() &&
392  && !context_manager_->get_map().selection().empty();
393 
398  return !context_manager_->get_map().selection().empty()
399  && !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
401  return (context_manager_->get_map().selection().size() > 1
402  && !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE));
406  return false; //not implemented
408  return !context_manager_->clipboard_empty();
413  return !context_manager_->clipboard_empty()
414  && toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
417  return !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
419  return !get_current_map_context().get_map().selection().empty()
421  && !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
438  return true;
440  return false; //not implemented
444  return true;
445  default:
446  return false;
447  }
448 }
449 
451  using namespace hotkey;
452  switch (command) {
453 
455  {
457  get_current_map_context().get_units().find(gui_->mouseover_hex());
458  return un->loyal() ? ACTION_ON : ACTION_OFF;
459 
460  }
462  {
464  get_current_map_context().get_units().find(gui_->mouseover_hex());
465  return un->can_recruit() ? ACTION_ON : ACTION_OFF;
466  }
468  {
470  get_current_map_context().get_units().find(gui_->mouseover_hex());
471  return (!un->unrenamable()) ? ACTION_ON : ACTION_OFF;
472  }
473  //TODO remove hardcoded hotkey names
475  return context_manager_->is_active_transitions_hotkey("editor-auto-update-transitions")
478  return context_manager_->is_active_transitions_hotkey("editor-partial-update-transitions")
481  return context_manager_->is_active_transitions_hotkey("editor-no-update-transitions")
484  return toolkit_->is_active_brush("brush-1") ? ACTION_ON : ACTION_OFF;
486  return toolkit_->is_active_brush("brush-2") ? ACTION_ON : ACTION_OFF;
488  return toolkit_->is_active_brush("brush-3") ? ACTION_ON : ACTION_OFF;
490  return toolkit_->is_active_brush("brush-nw-se") ? ACTION_ON : ACTION_OFF;
492  return toolkit_->is_active_brush("brush-sw-ne") ? ACTION_ON : ACTION_OFF;
493 
494  case HOTKEY_TOGGLE_GRID:
500  return get_current_map_context().get_map().selection().empty() ?
511  return toolkit_->is_mouse_action_set(command) ? ACTION_ON : ACTION_OFF;
513  return gui_->get_draw_coordinates() ? ACTION_ON : ACTION_OFF;
515  return gui_->get_draw_terrain_codes() ? ACTION_ON : ACTION_OFF;
517  return gui_->get_draw_num_of_bitmaps() ? ACTION_ON : ACTION_OFF;
518 
529  case HOTKEY_ZOOM_DEFAULT:
530  return (gui_->get_zoom_factor() == 1.0) ? hotkey::ACTION_ON : hotkey::ACTION_OFF;
531 
532  case HOTKEY_NULL:
533  switch (active_menu_) {
534  case editor::MAP:
535  return index == context_manager_->current_context_index()
537  case editor::LOAD_MRU:
538  return ACTION_STATELESS;
539  case editor::PALETTE:
540  return ACTION_STATELESS;
541  case editor::AREA:
542  return index == get_current_map_context().get_active_area()
544  case editor::SIDE:
545  return static_cast<size_t>(index) == gui_->playing_team()
547  case editor::TIME:
550  case editor::LOCAL_TIME:
552  get_current_map_context().get_active_area())
554  case editor::MUSIC:
556  ? ACTION_ON : ACTION_OFF;
557  case editor::SCHEDULE:
558  {
559  tods_map::const_iterator it = tods_.begin();
560  std::advance(it, index);
561  const std::vector<time_of_day>& times1 = it->second.second;
562  const std::vector<time_of_day>& times2 = get_current_map_context().get_time_manager()->times();
563  return (times1 == times2) ? ACTION_SELECTED : ACTION_DESELECTED;
564  }
566  {
567  tods_map::const_iterator it = tods_.begin();
568  std::advance(it, index);
569  const std::vector<time_of_day>& times1 = it->second.second;
570  int active_area = get_current_map_context().get_active_area();
571  const std::vector<time_of_day>& times2 = get_current_map_context().get_time_manager()->times(active_area);
572  return (times1 == times2) ? ACTION_SELECTED : ACTION_DESELECTED;
573  }
574  case editor::UNIT_FACING:
575  {
577  assert(un != get_current_map_context().get_units().end());
578  return un->facing() == index ? ACTION_SELECTED : ACTION_DESELECTED;
579  }
580  }
581  return ACTION_ON;
582  default:
583  return command_executor::get_action_state(command, index);
584  }
585 }
586 
588 {
589  hotkey::HOTKEY_COMMAND command = cmd.id;
590  SCOPE_ED;
591  using namespace hotkey;
592 
593  // nothing here handles release; fall through to base implementation
594  if (!press) {
595  return hotkey::command_executor::execute_command(cmd, index, press);
596  }
597 
598  switch (command) {
599  case HOTKEY_NULL:
600  switch (active_menu_) {
601  case MAP:
602  if (index >= 0) {
603  unsigned i = static_cast<unsigned>(index);
604  if (i < context_manager_->size()) {
605  context_manager_->switch_context(index);
606  toolkit_->hotkey_set_mouse_action(HOTKEY_EDITOR_TOOL_PAINT);
607  return true;
608  }
609  }
610  return false;
611  case LOAD_MRU:
612  if (index >= 0) {
613  context_manager_->load_mru_item(static_cast<unsigned>(index));
614  }
615  return true;
616  case PALETTE:
617  toolkit_->get_palette_manager()->set_group(index);
618  return true;
619  case SIDE:
620  gui_->set_team(index, true);
621  gui_->set_playing_team(index);
622  toolkit_->get_palette_manager()->draw_contents();
623  return true;
624  case AREA:
625  {
627  const std::set<map_location>& area =
629  std::vector<map_location> locs(area.begin(), area.end());
631  gui_->scroll_to_tiles(locs.begin(), locs.end());
632  return true;
633  }
634  case TIME:
635  {
637  gui_->update_tod();
638  return true;
639  }
640  case LOCAL_TIME:
641  {
643  return true;
644  }
645  case MUSIC:
646  {
647  //TODO mark the map as changed
650  std::vector<config> items;
651  items.emplace_back(config {"id", "editor-playlist"});
652  std::shared_ptr<gui::button> b = gui_->find_menu_button("menu-playlist");
653  show_menu(items, b->location().x +1, b->location().y + b->height() +1, false, *gui_);
654  return true;
655  }
656  case SCHEDULE:
657  {
658  tods_map::iterator iter = tods_.begin();
659  std::advance(iter, index);
660  get_current_map_context().replace_schedule(iter->second.second);
661  // TODO: test again after the assign-schedule menu is fixed. Should work, though.
662  gui_->update_tod();
663  return true;
664  }
665  case LOCAL_SCHEDULE:
666  {
667  tods_map::iterator iter = tods_.begin();
668  std::advance(iter, index);
669  get_current_map_context().replace_local_schedule(iter->second.second);
670  return true;
671  }
672  case UNIT_FACING:
673  {
675  assert(un != get_current_map_context().get_units().end());
676  un->set_facing(map_location::DIRECTION(index));
677  un->anim_comp().set_standing();
678  return true;
679  }
680  }
681  return true;
682 
683  //Zoom
684  case HOTKEY_ZOOM_IN:
685  gui_->set_zoom(true);
687  toolkit_->set_mouseover_overlay(*gui_);
688  return true;
689  case HOTKEY_ZOOM_OUT:
690  gui_->set_zoom(false);
692  toolkit_->set_mouseover_overlay(*gui_);
693  return true;
694  case HOTKEY_ZOOM_DEFAULT:
695  gui_->set_default_zoom();
697  toolkit_->set_mouseover_overlay(*gui_);
698  return true;
699 
700  //Palette
702  {
703  //TODO this code waits for the gui2 dialog to get ready
704 // std::vector< std::pair< std::string, std::string > > blah_items;
705 // toolkit_->get_palette_manager()->active_palette().expand_palette_groups_menu(blah_items);
706 // int selected = 1; //toolkit_->get_palette_manager()->active_palette().get_selected;
707 // gui2::teditor_select_palette_group::execute(selected, blah_items, gui_->video());
708  }
709  return true;
711  toolkit_->get_palette_manager()->scroll_up();
712  return true;
714  toolkit_->get_palette_manager()->scroll_down();
715  return true;
716 
717  case HOTKEY_QUIT_GAME:
719  do_quit_ = true;
721  }
722  return true;
725  return true;
727  context_manager_->save_all_maps(true);
728  do_quit_ = true;
730  return true;
733  return true;
735  toolkit_->get_palette_manager()->active_palette().swap();
736  return true;
738  if (dynamic_cast<const editor_action_chain*>(get_current_map_context().last_undo_action()) != nullptr) {
740  context_manager_->refresh_after_action();
741  } else {
742  undo();
743  }
744  return true;
745 
746  //Tool Selection
755  toolkit_->hotkey_set_mouse_action(command);
756  return true;
757 
759  add_area();
760  return true;
761 
763  change_unit_id();
764  return true;
765 
767  {
768  map_location loc = gui_->mouseover_hex();
770  const std::set<std::string>& recruit_set = toolkit_->get_palette_manager()->unit_palette_->get_selected_bg_items();
771  std::vector<std::string> recruits(recruit_set.begin(), recruit_set.end());
772  un->set_recruits(recruits);
773  }
774  return true;
776  {
777  map_location loc = gui_->mouseover_hex();
779  bool unrenamable = un->unrenamable();
780  un->set_unrenamable(!unrenamable);
781  }
782  return true;
784  {
785  map_location loc = gui_->mouseover_hex();
787  bool canrecruit = un->can_recruit();
788  un->set_can_recruit(!canrecruit);
789  un->anim_comp().set_standing();
790  }
791  return true;
792  case HOTKEY_DELETE_UNIT:
793  {
794  map_location loc = gui_->mouseover_hex();
796  }
797  return true;
798  case HOTKEY_EDITOR_CLIPBOARD_PASTE: //paste is somewhat different as it might be "one action then revert to previous mode"
799  toolkit_->hotkey_set_mouse_action(command);
800  return true;
801 
802  //Clipboard
804  context_manager_->get_clipboard().rotate_60_cw();
805  toolkit_->update_mouse_action_highlights();
806  return true;
808  context_manager_->get_clipboard().rotate_60_ccw();
809  toolkit_->update_mouse_action_highlights();
810  return true;
812  context_manager_->get_clipboard().flip_horizontal();
813  toolkit_->update_mouse_action_highlights();
814  return true;
816  context_manager_->get_clipboard().flip_vertical();
817  toolkit_->update_mouse_action_highlights();
818  return true;
819 
820  //Brushes
822  toolkit_->cycle_brush();
823  return true;
825  toolkit_->set_brush("brush-1");
826  return true;
828  toolkit_->set_brush("brush-2");
829  return true;
831  toolkit_->set_brush("brush-3");
832  return true;
834  toolkit_->set_brush("brush-nw-se");
835  return true;
837  toolkit_->set_brush("brush-sw-ne");
838  return true;
839 
841  copy_selection();
842  return true;
844  cut_selection();
845  return true;
847  context_manager_->rename_area_dialog();
848  return true;
850  save_area();
851  return true;
854  return true;
856  if(!context_manager_->get_map().everything_selected()) {
857  context_manager_->perform_refresh(editor_action_select_all());
858  return true;
859  }
860  FALLTHROUGH;
863  return true;
865  context_manager_->perform_refresh(editor_action_select_none());
866  return true;
868  context_manager_->fill_selection();
869  return true;
872  context_manager_->get_map().selection()));
873  return true;
874 
876  context_manager_->edit_scenario_dialog();
877  return true;
878 
881  get_current_map_context().get_active_area());
882  return true;
883 
884  // map specific
886  context_manager_->close_current_context();
887  return true;
889  context_manager_->load_map_dialog();
890  return true;
892  context_manager_->revert_map();
893  return true;
895  context_manager_->new_map_dialog();
896  return true;
898  context_manager_->new_scenario_dialog();
899  return true;
901  save_map();
902  return true;
904  context_manager_->save_all_maps();
905  return true;
907  context_manager_->save_map_as_dialog();
908  return true;
910  context_manager_->save_scenario_as_dialog();
911  return true;
913  context_manager_->generate_map_dialog();
914  return true;
916  context_manager_->apply_mask_dialog();
917  return true;
919  context_manager_->create_mask_to_dialog();
920  return true;
922  context_manager_->resize_map_dialog();
923  return true;
924 
925  // Side specific ones
928  gui_->init_flags();
929  return true;
931  gui_->set_team(0, true);
932  gui_->set_playing_team(0);
934  return true;
936  context_manager_->edit_side_dialog(gui_->viewing_team());
937  return true;
938 
939  // Transitions
941  context_manager_->set_update_transitions_mode(2);
942  return true;
944  context_manager_->set_update_transitions_mode(1);
945  return true;
947  context_manager_->set_update_transitions_mode(0);
948  return true;
950  if(context_manager_->toggle_update_transitions()) {
951  return true;
952  }
953  FALLTHROUGH;
955  context_manager_->refresh_all();
956  return true;
957  // Refresh
959  context_manager_->reload_map();
960  return true;
963  return true;
964 
966  gui().set_draw_coordinates(!gui().get_draw_coordinates());
967  preferences::editor::set_draw_hex_coordinates(gui().get_draw_coordinates());
968  gui().invalidate_all();
969  return true;
971  gui().set_draw_terrain_codes(!gui().get_draw_terrain_codes());
972  preferences::editor::set_draw_terrain_codes(gui().get_draw_terrain_codes());
973  gui().invalidate_all();
974  return true;
976  gui().set_draw_num_of_bitmaps(!gui().get_draw_num_of_bitmaps());
977  preferences::editor::set_draw_num_of_bitmaps(gui().get_draw_num_of_bitmaps());
978  gui().invalidate_all();
979  return true;
981  location_palette* lp = dynamic_cast<location_palette*>(&toolkit_->get_palette_manager()->active_palette());
982  if (lp) {
984  }
985  return true;
986  }
987  default:
988  return hotkey::command_executor::execute_command(cmd, index, press);
989  }
990 }
991 
993 {
994  help::show_help("..editor");
995 }
996 
997 void editor_controller::show_menu(const std::vector<config>& items_arg, int xloc, int yloc, bool context_menu, display& disp)
998 {
999  if(context_menu) {
1000  if(!context_manager_->get_map().on_board_with_border(gui().hex_clicked_on(xloc, yloc))) {
1001  return;
1002  }
1003  }
1004 
1005  std::vector<config> items;
1006  for(const auto& c : items_arg) {
1007  const std::string& id = c["id"];
1009 
1010  if((can_execute_command(command) && (!context_menu || in_context_menu(command.id)))
1011  || command.id == hotkey::HOTKEY_NULL)
1012  {
1013  items.emplace_back(config {"id", id});
1014  }
1015  }
1016 
1017  // No point in showing an empty menu.
1018  if(items.empty()) {
1019  return;
1020  }
1021 
1022  // Based on the ID of the first entry, we fill the menu contextually.
1023  const std::string& first_id = items.front()["id"];
1024 
1025  if(first_id == "EDITOR-LOAD-MRU-PLACEHOLDER") {
1027  context_manager_->expand_load_mru_menu(items, 0);
1028  }
1029 
1030  if(first_id == "editor-switch-map") {
1032  context_manager_->expand_open_maps_menu(items, 0);
1033  }
1034 
1035  if(first_id == "editor-palette-groups") {
1037  toolkit_->get_palette_manager()->active_palette().expand_palette_groups_menu(items, 0);
1038  }
1039 
1040  if(first_id == "editor-switch-side") {
1042  context_manager_->expand_sides_menu(items, 0);
1043  }
1044 
1045  if(first_id == "editor-switch-area") {
1047  context_manager_->expand_areas_menu(items, 0);
1048  }
1049 
1050  if(!items.empty() && items.front()["id"] == "editor-switch-time") {
1052  context_manager_->expand_time_menu(items, 0);
1053  }
1054 
1055  if(first_id == "editor-assign-local-time") {
1057  context_manager_->expand_local_time_menu(items, 0);
1058  }
1059 
1060  if(first_id == "menu-unit-facings") {
1062  auto pos = items.erase(items.begin());
1063  int dir = 0;
1064  std::generate_n(std::inserter<std::vector<config>>(items, pos), int(map_location::NDIRECTIONS), [&dir]() -> config {
1066  });
1067  }
1068 
1069  if(first_id == "editor-playlist") {
1071  auto pos = items.erase(items.begin());
1072  std::transform(music_tracks_.begin(), music_tracks_.end(), std::inserter<std::vector<config>>(items, pos), [](const sound::music_track& track) -> config {
1073  return config {"label", track.title().empty() ? track.id() : track.title()};
1074  });
1075  }
1076 
1077  if(first_id == "editor-assign-schedule") {
1079  auto pos = items.erase(items.begin());
1080  std::transform(tods_.begin(), tods_.end(), std::inserter<std::vector<config>>(items, pos), [](const tods_map::value_type& tod) -> config {
1081  return config {"label", tod.second.first};
1082  });
1083  }
1084 
1085  if(first_id == "editor-assign-local-schedule") {
1087  auto pos = items.erase(items.begin());
1088  std::transform(tods_.begin(), tods_.end(), std::inserter<std::vector<config>>(items, pos), [](const tods_map::value_type& tod) -> config {
1089  return config {"label", tod.second.first};
1090  });
1091  }
1092 
1093  command_executor::show_menu(items, xloc, yloc, context_menu, disp);
1094 }
1095 
1097 {
1098  gui_->video().clear_all_help_strings();
1100 
1101  gui_->redraw_everything();
1102 }
1103 
1105 {
1107  gui_->invalidate_all();
1108 }
1109 
1111 {
1112  map_location loc = gui_->mouseover_hex();
1114  const unit_map::const_unit_iterator un = units.find(loc);
1115  if(un != units.end()) {
1116  help::show_unit_help(un->type_id(), un->type().show_variations_in_help(), false);
1117  } else {
1118  help::show_help("..units");
1119  }
1120 }
1121 
1122 
1124 {
1125  if (!context_manager_->get_map().selection().empty()) {
1126  context_manager_->get_clipboard() = map_fragment(context_manager_->get_map(), context_manager_->get_map().selection());
1127  context_manager_->get_clipboard().center_by_mass();
1128  }
1129 }
1130 
1132 {
1133  map_location loc = gui_->mouseover_hex();
1135  const unit_map::unit_iterator& un = units.find(loc);
1136 
1137  const std::string title(N_("Change Unit ID"));
1138  const std::string label(N_("ID:"));
1139 
1140  if(un != units.end()) {
1141  std::string id = un->id();
1142  if (gui2::dialogs::edit_text::execute(title, label, id)) {
1143  un->set_id(id);
1144  }
1145  }
1146 }
1147 
1149 {
1150  map_location loc = gui_->mouseover_hex();
1152  const unit_map::unit_iterator& un = units.find(loc);
1153 
1154  const std::string title(N_("Rename Unit"));
1155  const std::string label(N_("Name:"));
1156 
1157  if(un != units.end()) {
1158  std::string name = un->name();
1159  if(gui2::dialogs::edit_text::execute(title, label, name)) {
1160  //TODO we may not want a translated name here.
1161  un->set_name(name);
1162  }
1163  }
1164 }
1165 
1167 {
1169 }
1170 
1172 {
1173  copy_selection();
1174  context_manager_->perform_refresh(editor_action_paint_area(context_manager_->get_map().selection(), get_selected_bg_terrain()));
1175 }
1176 
1178 {
1179  const std::set<map_location>& area = context_manager_->get_map().selection();
1181 }
1182 
1184 {
1185  const std::set<map_location>& area = context_manager_->get_map().selection();
1187 }
1188 
1190 {
1191  std::stringstream ssx, ssy;
1192  std::set<map_location>::const_iterator i = context_manager_->get_map().selection().begin();
1193  if (i != context_manager_->get_map().selection().end()) {
1194  ssx << "x = " << i->wml_x();
1195  ssy << "y = " << i->wml_y();
1196  ++i;
1197  while (i != context_manager_->get_map().selection().end()) {
1198  ssx << ", " << i->wml_x();
1199  ssy << ", " << i->wml_y();
1200  ++i;
1201  }
1202  ssx << "\n" << ssy.str() << "\n";
1203  desktop::clipboard::copy_to_clipboard(ssx.str(), false);
1204  }
1205 }
1206 
1208 {
1209  if (action) {
1210  const editor_action_ptr action_auto(action);
1212  }
1213 }
1214 
1215 void editor_controller::perform_refresh_delete(editor_action* action, bool drag_part /* =false */)
1216 {
1217  if (action) {
1218  const editor_action_ptr action_auto(action);
1219  context_manager_->perform_refresh(*action, drag_part);
1220  }
1221 }
1222 
1224 {
1226  context_manager_->refresh_all();
1227 }
1228 
1230 {
1231  set_button_state();
1232  toolkit_->adjust_size();
1233  toolkit_->get_palette_manager()->draw_contents();
1235 }
1236 
1238 {
1240  context_manager_->refresh_after_action();
1241 }
1242 
1244 {
1246  context_manager_->refresh_after_action();
1247 }
1248 
1249 void editor_controller::mouse_motion(int x, int y, const bool /*browse*/,
1250  bool update, map_location /*new_loc*/)
1251 {
1252  if (mouse_handler_base::mouse_motion_default(x, y, update)) return;
1253  map_location hex_clicked = gui().hex_clicked_on(x, y);
1254  if (context_manager_->get_map().on_board_with_border(drag_from_hex_) && is_dragging()) {
1255  editor_action* a = nullptr;
1256  bool partial = false;
1258  if (dragging_left_ && (SDL_GetMouseState(nullptr, nullptr) & SDL_BUTTON(1)) != 0) {
1259  if (!context_manager_->get_map().on_board_with_border(hex_clicked)) return;
1260  a = get_mouse_action().drag_left(*gui_, x, y, partial, last_undo);
1261  } else if (dragging_right_ && (SDL_GetMouseState(nullptr, nullptr) & SDL_BUTTON(3)) != 0) {
1262  if (!context_manager_->get_map().on_board_with_border(hex_clicked)) return;
1263  a = get_mouse_action().drag_right(*gui_, x, y, partial, last_undo);
1264  }
1265  //Partial means that the mouse action has modified the
1266  //last undo action and the controller shouldn't add
1267  //anything to the undo stack (hence a different perform_ call)
1268  if (a != nullptr) {
1269  const editor_action_ptr aa(a);
1270  if (partial) {
1272  } else {
1274  }
1275  context_manager_->refresh_after_action(true);
1276  }
1277  } else {
1278  get_mouse_action().move(*gui_, hex_clicked);
1279  }
1280  gui().highlight_hex(hex_clicked);
1281 }
1282 
1284 {
1285  return context_manager_->get_map().on_board_with_border(gui().hex_clicked_on(x,y));
1286 }
1287 
1288 bool editor_controller::right_click_show_menu(int /*x*/, int /*y*/, const bool /*browse*/)
1289 {
1291 }
1292 
1293 bool editor_controller::left_click(int x, int y, const bool browse)
1294 {
1295  toolkit_->clear_mouseover_overlay();
1296  if (mouse_handler_base::left_click(x, y, browse))
1297  return true;
1298 
1299  LOG_ED << "Left click, after generic handling\n";
1300  map_location hex_clicked = gui().hex_clicked_on(x, y);
1301  if (!context_manager_->get_map().on_board_with_border(hex_clicked))
1302  return true;
1303 
1304  LOG_ED << "Left click action " << hex_clicked << "\n";
1306  perform_refresh_delete(a, true);
1307  if (a) set_button_state();
1308 
1309  return false;
1310 }
1311 
1312 void editor_controller::left_drag_end(int x, int y, const bool /*browse*/)
1313 {
1315  perform_delete(a);
1316 }
1317 
1318 void editor_controller::left_mouse_up(int x, int y, const bool /*browse*/)
1319 {
1321  perform_delete(a);
1322  if (a) set_button_state();
1323  toolkit_->set_mouseover_overlay();
1324  context_manager_->refresh_after_action();
1325 }
1326 
1327 bool editor_controller::right_click(int x, int y, const bool browse)
1328 {
1329  toolkit_->clear_mouseover_overlay();
1330  if (mouse_handler_base::right_click(x, y, browse)) return true;
1331  LOG_ED << "Right click, after generic handling\n";
1332  map_location hex_clicked = gui().hex_clicked_on(x, y);
1333  if (!context_manager_->get_map().on_board_with_border(hex_clicked)) return true;
1334  LOG_ED << "Right click action " << hex_clicked << "\n";
1336  perform_refresh_delete(a, true);
1337  if (a) set_button_state();
1338  return false;
1339 }
1340 
1341 void editor_controller::right_drag_end(int x, int y, const bool /*browse*/)
1342 {
1344  perform_delete(a);
1345 }
1346 
1347 void editor_controller::right_mouse_up(int x, int y, const bool browse)
1348 {
1349  // Call base method to handle context menus.
1350  mouse_handler_base::right_mouse_up(x, y, browse);
1351 
1353  perform_delete(a);
1354  if (a) set_button_state();
1355  toolkit_->set_mouseover_overlay();
1356  context_manager_->refresh_after_action();
1357 }
1358 
1360 {
1361  const map_location& loc = gui().mouseover_hex();
1362  if (context_manager_->get_map().on_board(loc) == false)
1363  return;
1364 
1365  const terrain_type& type = context_manager_->get_map().get_terrain_info(loc);
1367 }
1368 
1369 void editor_controller::process_keyup_event(const SDL_Event& event)
1370 {
1371  editor_action* a = get_mouse_action().key_event(gui(), event);
1373  toolkit_->set_mouseover_overlay();
1374 }
1375 
1377  return this;
1378 }
1379 
1381 {
1383 }
1384 
1386 {
1388 }
1389 
1391 {
1393 }
1394 
1396 {
1398 }
1399 
1401 {
1402  return toolkit_->get_palette_manager()->active_palette().action_pressed();
1403 }
1404 
1405 } //end namespace editor
void perform_refresh_delete(editor_action *action, bool drag_part=false)
Peform an action on the current map_context, then refresh the display and delete the pointer...
Randomize terrain in an area.
Definition: action.hpp:441
void undo()
Un-does the last action, and puts it in the redo stack for a possible redo.
void set_grid(bool ison)
Definition: display.cpp:73
virtual editor_action * click_left(editor_display &disp, int x, int y)=0
A click, possibly the beginning of a drag.
void set_scroll_up(bool on)
void set_preference_display_settings()
Definition: display.cpp:47
::tod_manager * tod_manager
Definition: resources.cpp:30
void copy_selection()
Copy the selection on the current map to the clipboard.
static std::string write_translated_direction(DIRECTION dir)
Definition: location.cpp:160
void set_draw_num_of_bitmaps(bool value)
Setter for the terrain code debug overlay on tiles.
Definition: display.hpp:361
void set_scroll_down(bool on)
unit_iterator end()
Definition: map.hpp:415
const char * what() const NOEXCEPT
Definition: exceptions.hpp:37
bool minimap_draw_units()
Definition: general.cpp:924
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:116
A map fragment – a collection of locations and information abut them.
std::vector< char_t > string
void add_to_playlist(const sound::music_track &track)
size_t index(const utf8::string &str, const size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
Select the entire map.
std::unique_ptr< font::floating_label_context > floating_label_manager_
HOTKEY_COMMAND id
the names are strange: the "hotkey::HOTKEY_COMMAND" is named id, and the string to identify the objec...
const t_translation::terrain_code & get_selected_bg_terrain()
virtual bool has_context_menu() const
bool dragging_right_
RMB drag init flag.
void set_draw_terrain_codes(bool value)
Setter for the terrain code debug overlay on tiles.
Definition: display.hpp:356
void set(CURSOR_TYPE type)
Use the default parameter to reset cursors.
Definition: cursor.cpp:154
void save_map() override
Save the map, open dialog if not named yet.
void export_selection_coords()
Export the WML-compatible list of selected tiles to the system clipboard.
int dummy
Definition: lstrlib.cpp:1125
std::unique_ptr< editor_action > editor_action_ptr
Action pointer typedef.
game_classification * classification
Definition: resources.cpp:36
void show_terrain_description(const terrain_type &t)
Definition: help.cpp:63
void do_screenshot(const std::string &screenshot_filename="map_screenshot.bmp")
Takes a screenshot.
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.
bool quit_confirm()
Show a quit confirmation dialog and returns true if the user pressed 'yes'.
bool draw_num_of_bitmaps()
Definition: editor.cpp:53
Editor action classes.
void save_area(const std::set< map_location > &area)
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
void new_side()
Adds a new side to the map.
std::unique_ptr< editor_toolkit > toolkit_
void custom_tods_dialog()
Display the settings dialog, used to control e.g.
void process_keyup_event(const SDL_Event &event) override
Process keyup (always).
void left_drag_end(int x, int y, const bool browse) override
Called whenever the left mouse drag has "ended".
#define a
bool minimap_movement_coding()
Definition: general.cpp:904
int get_current_area_time(int index) const
editor_display & gui() override
Reference to the used display objects.
This file contains the window object, this object is a top level container which has the event manage...
bool can_execute_command(const hotkey::hotkey_command &command, int index=-1) const override
command_executor override
child_itors child_range(config_key_type key)
Definition: config.cpp:343
virtual bool supports_brushes() const
Whether we need the brush bar, is used to grey it out.
void new_area(const std::set< map_location > &area)
void show_unit_list(display &gui)
Definition: unit_list.cpp:198
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...
void set_active_area(int index)
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, const bool restore_background)
Shows a transient message to the user.
void redraw_everything()
Invalidates entire screen, including all tiles and sidebar.
Definition: display.cpp:2415
map_labels & get_labels()
bool modified() const
#define LOG_ED
void save_area()
Save the current selection to the active area.
void preferences() override
Show the preferences dialog.
static bool show_prompt(const std::string &message)
Stores all information related to functions that can be bound to hotkeys.
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:589
void add_area()
Add a new area to the current context, filled with the selection if any.
const std::string & title() const
void play_slice(bool is_delay_enabled=true)
STL namespace.
void redo()
Re-does a previously undid action, and puts it back in the undo stack.
virtual editor_action * drag_left(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Drag operation.
const std::string & get_filename() const
#define SCOPE_ED
const std::vector< std::string > items
void play_music_once(const std::string &file)
Definition: sound.cpp:565
The editor_controller class contains the mouse and keyboard event handling routines for the editor...
bool draw_terrain_codes()
Definition: editor.cpp:37
Set starting position action.
Definition: action.hpp:340
void partial_undo()
Un-does a single step from a undo action chain.
Keyboard shortcuts for game actions.
Unit and team statistics.
void remove_area(int index)
void flush_cache()
Definition: image.cpp:217
#define b
const std::string & selected_item() const
Return the currently selected item.
#define WRN_ED
bool minimap_draw_villages()
Definition: general.cpp:934
const std::unique_ptr< editor_display > gui_
The display object used and owned by the editor.
map_context & get_current_map_context() const
void show_menu(const std::vector< config > &items_arg, int xloc, int yloc, bool context_menu, display &disp) override
controller_base override
void right_mouse_up(int x, int y, const bool browse) override
Called when the right mouse button is up.
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:89
tod_manager * get_time_manager()
virtual editor_action * up_left(editor_display &disp, int x, int y)
void right_drag_end(int x, int y, const bool browse) override
Called whenever the right mouse drag has "ended".
void set_local_starting_time(int time)
TODO.
const map_location & mouseover_hex() const
Definition: display.hpp:281
bool is_pure_map() const
virtual 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.
bool everything_selected() const
Definition: editor_map.cpp:210
bool valid() const
Definition: location.hpp:72
void init_tods(const config &game_config)
init the available time-of-day settings
void remove_side()
removes the last side from the scenario
Implements a quit confirmation dialog.
virtual editor_action * drag_right(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Drag operation.
filter_context * filter_con
Definition: resources.cpp:23
void set_draw_coordinates(bool value)
Setter for the x,y debug overlay on tiles.
Definition: display.hpp:351
void undo() override
Undos an action in the current map context.
bool execute_command(const hotkey::hotkey_command &command, int index=-1, bool press=true) override
command_executor override
editor_map & get_map()
Map accessor.
Definition: map_context.hpp:92
virtual hotkey::command_executor * get_hotkey_command_executor() override
Optionally get a command executor to handle context menu events.
map_location drag_from_hex_
Drag start map location.
void replace_schedule(const std::vector< time_of_day > &schedule)
virtual editor_action * click_right(editor_display &disp, int x, int y)=0
A click, possibly the beginning of a drag.
Editor action classes.
void set_starting_time(int time)
TODO.
int show_menu(lua_State *L)
Displays a popup menu at the current mouse position Best used from a [set_menu_item], to show a submenu.
Definition: lua_gui2.cpp:408
editor_action * last_undo_action()
bool draw_hex_coordinates()
Definition: editor.cpp:45
virtual editor_action * up_right(editor_display &disp, int x, int y)
void create_buttons()
Definition: display.cpp:900
void refresh_image_cache()
Reload images.
Manage the empty-palette in the editor.
Definition: action.cpp:29
void perform_action(const editor_action &action)
Performs an action (thus modifying the map).
bool can_undo() const
void invalidate_all()
Function to invalidate all tiles.
Definition: display.cpp:3013
const std::string & file_path() const
Paint the same terrain on a number of locations on the map.
Definition: action.hpp:284
bool dragging_left_
LMB drag init flag.
static bool quit()
Shows the quit confirmation if needed.
void show()
Shows the error in a dialog.
bool has_child(config_key_type key) const
Determine whether a config has a child or not.
Definition: config.cpp:393
Encapsulates the map of the game.
Definition: location.hpp:40
Helper class, don't construct this directly.
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...
size_t size(const utf8::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:86
void recalculate_labels()
Definition: label.cpp:244
void set_starting_position_labels(display &disp)
static void display(const config &game_cfg, const preferences::PREFERENCE_VIEW initial_view=preferences::VIEW_DEFAULT)
The display function – see modal_dialog for more information.
std::vector< team > & get_teams()
Get the team from the current map context object.
static void quit_to_desktop()
void init_gui()
init the display object and general set-up
void scroll_right(bool on) override
bool can_redo() const
std::vector< std::string > get_area_ids() const
void left_mouse_up(int x, int y, const bool browse) override
Called when the left mouse button is up.
virtual void highlight_hex(map_location hex)
Definition: display.cpp:1637
Game configuration data as global variables.
Definition: build_info.cpp:53
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:126
const config & game_config_
unit_map & get_units()
Get the unit map from the current map context object.
structure which will hide all current floating labels, and cause floating labels instantiated after i...
Base class for all editor actions.
Definition: action_base.hpp:40
Internal representation of music tracks.
virtual std::vector< std::string > additional_actions_pressed() override
const std::set< map_location > & get_area_by_index(int index) const
void set_scroll_right(bool on)
size_t i
Definition: function.cpp:933
CURSOR_TYPE get()
Definition: cursor.cpp:194
void cut_selection()
Cut the selection from the current map to the clipboard.
DIRECTION
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:42
void display_redraw_callback(display &)
Callback function passed to display to be called on each redraw_everything run.
editor_controller(const editor_controller &)=delete
std::vector< sound::music_track > music_tracks_
#define N_(String)
Definition: gettext.hpp:97
const std::set< map_location > & selection() const
Return the selection set.
Definition: editor_map.hpp:149
void toggle_grid() override
Grid toggle.
const mouse_action & get_mouse_action() const
Get the current mouse action.
void perform_delete(editor_action *action)
Perform an action, then delete the action object.
bool allow_mouse_wheel_scroll(int x, int y) override
Derived classes can override this to disable mousewheel scrolling under some circumstances, e.g.
void scroll_left(bool on) override
virtual bool execute_command(const hotkey_command &command, int index=-1, bool press=true)
bool empty() const
Definition: map.hpp:432
bool grid()
Definition: general.cpp:506
bool left_click(int x, int y, const bool browse) override
Overridden in derived classes, called on a left click (mousedown).
bool do_quit_
Quit main loop flag.
void set_scroll_left(bool on)
EXIT_STATUS main_loop()
Editor main loop.
void copy_to_clipboard(const std::string &text, const bool)
Copies text to the clipboard.
Definition: clipboard.cpp:35
int get_current_time(const map_location &loc=map_location::null_location()) const
bool minimap_draw_terrain()
Definition: general.cpp:944
virtual editor_action * drag_end_left(editor_display &disp, int x, int y)
The end of dragging.
void set_draw_terrain_codes(bool value)
Definition: editor.cpp:41
std::unique_ptr< help::help_manager > help_manager_
virtual void move(editor_display &disp, const map_location &hex)
Mouse move (not a drag).
#define ERR_ED
const std::vector< time_of_day > & times(const map_location &loc=map_location::null_location()) const
bool is_in_playlist(std::string track_id)
Remove a unit from the map.
Definition: action_unit.hpp:63
void replace_local_schedule(const std::vector< time_of_day > &schedule)
Replace the [time]s of the currently active area.
Container associating units to locations.
Definition: map.hpp:99
int get_active_area() const
static const char * name(const std::vector< SDL_Joystick * > &joysticks, const size_t index)
Definition: joystick.cpp:48
void set_draw_num_of_bitmaps(bool value)
Definition: editor.cpp:57
void init_music(const config &game_config)
init background music for the editor
void show_error_message(const std::string &msg, bool message_use_markup)
Shows an error message to the user.
Definition: message.cpp:205
#define e
void set_draw_hex_coordinates(bool value)
Definition: editor.cpp:49
unit_iterator find(size_t id)
Definition: map.cpp:311
const std::unique_ptr< context_manager > context_manager_
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:93
mock_char c
void scroll_down(bool on) override
const hotkey_command & get_hotkey_command(const std::string &command)
returns the hotkey_command with the given name
Editor action classes.
void scroll_up(bool on) override
Handle hotkeys to scroll map.
bool right_click(int x, int y, const bool browse) override
Overridden in derived classes, called on a right click (mousedown).
static std::vector< std::string > saved_windows_
virtual bool in_context_menu(hotkey::HOTKEY_COMMAND command) const
std::string::const_iterator iterator
Definition: tokenizer.hpp:24
unit_map * units
Definition: resources.cpp:34
void redo() override
Redos an action in the current map context.
virtual editor_action * drag_end_right(editor_display &disp, int x, int y)
bool select_area(int index)
Select the nth tod area.
hotkey::ACTION_STATE get_action_state(hotkey::HOTKEY_COMMAND command, int index) const override
command_executor override
const std::string & id() const
bool minimap_terrain_coding()
Definition: general.cpp:914