The Battle for Wesnoth  1.17.12+dev
editor_controller.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2022
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  : controller_base()
69  , mouse_handler_base()
70  , quit_confirmation(std::bind(&editor_controller::quit_confirm, this))
71  , active_menu_(editor::MAP)
72  , reports_(new reports())
73  , gui_(new editor_display(*this, *reports_))
74  , tods_()
75  , context_manager_(new context_manager(*gui_.get(), game_config_))
76  , toolkit_(nullptr)
77  , tooltip_manager_()
78  , floating_label_manager_(nullptr)
79  , help_manager_(nullptr)
80  , do_quit_(false)
81  , quit_mode_(EXIT_ERROR)
82  , music_tracks_()
83 {
84  init_gui();
85  toolkit_.reset(new editor_toolkit(*gui_.get(), key_, game_config_, *context_manager_.get()));
86  help_manager_.reset(new help::help_manager(&game_config_));
87  context_manager_->locs_ = toolkit_->get_palette_manager()->location_palette_.get();
88  context_manager_->switch_context(0, true);
89  init_tods(game_config_);
90  init_music(game_config_);
93 
94  gui().queue_rerender();
95 }
96 
98 {
99  gui_->change_display_context(&get_current_map_context());
100  gui_->add_redraw_observer(std::bind(&editor_controller::display_redraw_callback, this, std::placeholders::_1));
105 // halo_manager_.reset(new halo::manager(*gui_));
106 // resources::halo = halo_manager_.get();
107 // ^ These lines no longer necessary, the gui owns its halo manager.
108 // TODO: Should the editor map contexts actually own the halo manager and swap them in and out from the gui?
109 // 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
110 // without deleting it.
111 }
112 
114 {
115  for (const config &schedule : game_config.child_range("editor_times")) {
116 
117  const std::string& schedule_id = schedule["id"];
118  const std::string& schedule_name = schedule["name"];
119  if (schedule_id.empty()) {
120  ERR_ED << "Missing ID attribute in a TOD Schedule.";
121  continue;
122  }
123 
124  tods_map::iterator times = tods_.find(schedule_id);
125  if (times == tods_.end()) {
126  std::pair<tods_map::iterator, bool> new_times =
127  tods_.emplace(schedule_id, std::pair(schedule_name, std::vector<time_of_day>()));
128 
129  times = new_times.first;
130  } else {
131  ERR_ED << "Duplicate TOD Schedule identifiers.";
132  continue;
133  }
134 
135  for (const config &time : schedule.child_range("time")) {
136  times->second.second.emplace_back(time);
137  }
138 
139  }
140 
141  if (tods_.empty()) {
142  ERR_ED << "No editor time-of-day defined";
143  }
144 }
145 
147 {
148  const std::string tag_name = "editor_music";
149  if (game_config.child_range(tag_name).size() == 0) {
150  ERR_ED << "No editor music defined";
151  }
152  else {
153  for (const config& editor_music : game_config.child_range(tag_name)) {
154  for (const config& music : editor_music.child_range("music")) {
155  sound::music_track track(music);
156  if (track.file_path().empty())
157  WRN_ED << "Music track " << track.id() << " not found.";
158  else
159  music_tracks_.emplace_back(music);
160  }
161  }
162  }
163 }
164 
166 {
167  resources::tod_manager = nullptr;
168  resources::filter_con = nullptr;
169 
170  resources::classification = nullptr;
171 }
172 
174 {
175  try {
176  while (!do_quit_) {
177  play_slice();
178  }
179  } catch (const editor_exception& e) {
180  gui2::show_transient_message(_("Fatal error"), e.what());
181  return EXIT_ERROR;
182  } catch (const wml_exception& e) {
183  e.show();
184  }
185  return quit_mode_;
186 }
187 
189 }
190 
191 void editor_controller::do_screenshot(const std::string& screenshot_filename /* = "map_screenshot.png" */)
192 {
193  try {
194  surface screenshot = gui().screenshot(true);
195  if(!screenshot || image::save_image(screenshot, screenshot_filename) != image::save_result::success) {
196  ERR_ED << "Screenshot creation failed!";
197  }
198  } catch (const wml_exception& e) {
199  e.show();
200  }
201 }
202 
204 {
205  std::string modified;
206  std::size_t amount = context_manager_->modified_maps(modified);
207 
208  std::string message;
209  if (amount == 0) {
210  message = _("Do you really want to quit?");
211  } else if (amount == 1 && get_current_map_context().modified()) {
212  message = _("Do you really want to quit? Changes to this map since the last save will be lost.");
213  } else {
214  message = _("Do you really want to quit? The following maps were modified and all changes since the last save will be lost:");
215  message += "\n" + modified;
216  }
217  return quit_confirmation::show_prompt(message);
218 }
219 
221 {
222  if (tods_.empty()) {
223  gui2::show_error_message(_("No editor time-of-day found."));
224  return;
225  }
226 
228 
229  if(gui2::dialogs::custom_tod::execute(manager.times(), manager.get_current_time())) {
230  // TODO save the new tod here
231  }
232 
233  gui_->update_tod();
234 
235  context_manager_->refresh_all();
236 }
237 
239 {
240  using namespace hotkey; //reduce hotkey:: clutter
241  switch(cmd.command) {
242  case HOTKEY_NULL:
243  if (index >= 0) {
244  unsigned i = static_cast<unsigned>(index);
245 
246  switch (active_menu_) {
247  case editor::MAP:
248  if (i < context_manager_->open_maps()) {
249  return true;
250  }
251  return false;
252  case editor::LOAD_MRU:
253  case editor::PALETTE:
254  case editor::AREA:
255  case editor::SIDE:
256  case editor::TIME:
257  case editor::SCHEDULE:
259  case editor::MUSIC:
260  case editor::LOCAL_TIME:
261  case editor::UNIT_FACING:
262  return true;
263  }
264  }
265  return false;
267  return true;
269  return toolkit_->get_palette_manager()->can_scroll_up();
271  return toolkit_->get_palette_manager()->can_scroll_down();
272  case HOTKEY_ZOOM_IN:
273  return !gui_->zoom_at_max();
274  case HOTKEY_ZOOM_OUT:
275  return !gui_->zoom_at_min();
276  case HOTKEY_ZOOM_DEFAULT:
277  case HOTKEY_FULLSCREEN:
278  case HOTKEY_SCREENSHOT:
280  case HOTKEY_TOGGLE_GRID:
281  case HOTKEY_MOUSE_SCROLL:
282  case HOTKEY_ANIMATE_MAP:
283  case HOTKEY_MUTE:
284  case HOTKEY_PREFERENCES:
285  case HOTKEY_HELP:
286  case HOTKEY_QUIT_GAME:
287  case HOTKEY_SCROLL_UP:
288  case HOTKEY_SCROLL_DOWN:
289  case HOTKEY_SCROLL_LEFT:
290  case HOTKEY_SCROLL_RIGHT:
291  return true; //general hotkeys we can always do
292 
294  return !get_current_map_context().units().empty();
295 
296  case HOTKEY_STATUS_TABLE:
297  return !get_current_map_context().teams().empty();
298 
300  return gui().mouseover_hex().valid();
301 
302  // unit tool related
303  case HOTKEY_DELETE_UNIT:
304  case HOTKEY_RENAME_UNIT:
311  {
312  map_location loc = gui_->mouseover_hex();
313  const unit_map& units = get_current_map_context().units();
314  return (toolkit_->is_mouse_action_set(HOTKEY_EDITOR_TOOL_UNIT) &&
315  units.find(loc) != units.end());
316  }
317  case HOTKEY_UNDO:
319  case HOTKEY_REDO:
331  return true;
332 
336 
339  return !get_current_map_context().teams().empty();
340 
341  // brushes
349 
351  return true;
353  return toolkit_->get_palette_manager()->active_palette().supports_swap();
357  {
358  std::string dummy;
359  return context_manager_->modified_maps(dummy) > 1;
360  }
366  return true;
368  return !get_current_map_context().get_filename().empty()
370 
371  // Tools
372  // Pure map editing tools this can be used all the time.
377  return true;
378  // WWL dependent tools which don't rely on defined sides.
385  return !get_current_map_context().teams().empty();
386 
390  return !get_current_map_context().is_pure_map() &&
392 
394  return !get_current_map_context().is_pure_map() &&
396  && !get_current_map_context().map().selection().empty();
397 
402  return !get_current_map_context().map().selection().empty()
403  && !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
405  return (get_current_map_context().map().selection().size() > 1
406  && !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE));
410  return !context_manager_->clipboard_empty();
415  return !context_manager_->clipboard_empty()
416  && toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
419  return !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
421  return !get_current_map_context().map().selection().empty()
423  && !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
440  return true;
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().units().find(gui_->mouseover_hex());
458  return un->loyal() ? ACTION_ON : ACTION_OFF;
459 
460  }
462  {
464  get_current_map_context().units().find(gui_->mouseover_hex());
465  return un->can_recruit() ? ACTION_ON : ACTION_OFF;
466  }
468  {
470  get_current_map_context().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().map().selection().empty() ?
511  return toolkit_->is_mouse_action_set(command) ? ACTION_ON : ACTION_OFF;
513  return gui_->debug_flag_set(display::DEBUG_COORDINATES) ? ACTION_ON : ACTION_OFF;
515  return gui_->debug_flag_set(display::DEBUG_TERRAIN_CODES) ? ACTION_ON : ACTION_OFF;
517  return gui_->debug_flag_set(display::DEBUG_NUM_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<std::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().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 
587 bool editor_controller::do_execute_command(const hotkey::hotkey_command& cmd, int index, bool press, bool release)
588 {
589  hotkey::HOTKEY_COMMAND command = cmd.command;
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::do_execute_command(cmd, index, press, release);
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("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().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_->toggle_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);
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 
766  return true;
768  {
769  map_location loc = gui_->mouseover_hex();
771  bool unrenamable = un->unrenamable();
772  un->set_unrenamable(!unrenamable);
773  }
774  return true;
776  {
777  map_location loc = gui_->mouseover_hex();
779  bool canrecruit = un->can_recruit();
780  un->set_can_recruit(!canrecruit);
781  un->anim_comp().set_standing();
782  }
783  return true;
784  case HOTKEY_DELETE_UNIT:
785  {
786  map_location loc = gui_->mouseover_hex();
787  perform_delete(std::make_unique<editor_action_unit_delete>(loc));
788  }
789  return true;
790  case HOTKEY_EDITOR_CLIPBOARD_PASTE: //paste is somewhat different as it might be "one action then revert to previous mode"
791  toolkit_->hotkey_set_mouse_action(command);
792  return true;
793 
794  //Clipboard
796  context_manager_->get_clipboard().rotate_60_cw();
797  toolkit_->update_mouse_action_highlights();
798  return true;
800  context_manager_->get_clipboard().rotate_60_ccw();
801  toolkit_->update_mouse_action_highlights();
802  return true;
804  context_manager_->get_clipboard().flip_horizontal();
805  toolkit_->update_mouse_action_highlights();
806  return true;
808  context_manager_->get_clipboard().flip_vertical();
809  toolkit_->update_mouse_action_highlights();
810  return true;
811 
812  //Brushes
814  toolkit_->cycle_brush();
815  return true;
817  toolkit_->set_brush("brush-1");
818  return true;
820  toolkit_->set_brush("brush-2");
821  return true;
823  toolkit_->set_brush("brush-3");
824  return true;
826  toolkit_->set_brush("brush-nw-se");
827  return true;
829  toolkit_->set_brush("brush-sw-ne");
830  return true;
831 
833  copy_selection();
834  return true;
836  cut_selection();
837  return true;
839  context_manager_->rename_area_dialog();
840  return true;
842  save_area();
843  return true;
846  return true;
848  if(!get_current_map_context().map().everything_selected()) {
849  context_manager_->perform_refresh(editor_action_select_all());
850  return true;
851  }
852  [[fallthrough]];
855  return true;
857  context_manager_->perform_refresh(editor_action_select_none());
858  return true;
860  context_manager_->fill_selection();
861  return true;
864  get_current_map_context().map().selection()));
865  return true;
866 
868  context_manager_->edit_scenario_dialog();
869  return true;
870 
873  get_current_map_context().get_active_area());
874  return true;
875 
876  // map specific
878  context_manager_->close_current_context();
879  // Copy behaviour from when switching windows to always reset the active tool to the Paint Tool
880  // This avoids the situation of having a scenario-specific tool active in a map context which can cause a crash if used
881  // Not elegant but at least avoids a potential crash and is consistent with existing behaviour
882  toolkit_->hotkey_set_mouse_action(HOTKEY_EDITOR_TOOL_PAINT);
883  return true;
885  context_manager_->load_map_dialog();
886  return true;
888  context_manager_->revert_map();
889  return true;
891  context_manager_->new_map_dialog();
892  return true;
894  context_manager_->new_scenario_dialog();
895  return true;
897  save_map();
898  return true;
900  context_manager_->save_all_maps();
901  return true;
903  context_manager_->save_map_as_dialog();
904  return true;
906  context_manager_->save_scenario_as_dialog();
907  return true;
909  context_manager_->generate_map_dialog();
910  return true;
912  context_manager_->apply_mask_dialog();
913  return true;
915  context_manager_->create_mask_to_dialog();
916  return true;
918  context_manager_->resize_map_dialog();
919  return true;
920 
921  // Side specific ones
923  if(get_current_map_context().teams().size() >= 9) {
924  size_t new_side_num = get_current_map_context().teams().size() + 1;
925  toolkit_->get_palette_manager()->location_palette_->add_item(std::to_string(new_side_num));
926  }
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 
968  gui().invalidate_all();
969  return true;
973  gui().invalidate_all();
974  return true;
978  gui().invalidate_all();
979  return true;
981  location_palette* lp = dynamic_cast<location_palette*>(&toolkit_->get_palette_manager()->active_palette());
982  if (lp) {
983  perform_delete(std::make_unique<editor_action_starting_position>(map_location(), lp->selected_item()));
984  // No idea if this is the right thing to call, but it ensures starting
985  // position labels get removed on delete.
986  context_manager_->refresh_after_action();
987  }
988  return true;
989  }
990  default:
991  return hotkey::command_executor::do_execute_command(cmd, index, press, release);
992  }
993 }
994 
996 {
997  help::show_help("..editor");
998 }
999 
1000 void editor_controller::show_menu(const std::vector<config>& items_arg, int xloc, int yloc, bool context_menu, display& disp)
1001 {
1002  if(context_menu) {
1003  if(!get_current_map_context().map().on_board_with_border(gui().hex_clicked_on(xloc, yloc))) {
1004  return;
1005  }
1006  }
1007 
1008  std::vector<config> items;
1009  for(const auto& c : items_arg) {
1010  const std::string& id = c["id"];
1012 
1013  if((can_execute_command(command) && (!context_menu || in_context_menu(command.command)))
1014  || command.command == hotkey::HOTKEY_NULL)
1015  {
1016  items.emplace_back("id", id);
1017  }
1018  }
1019 
1020  // No point in showing an empty menu.
1021  if(items.empty()) {
1022  return;
1023  }
1024 
1025  // Based on the ID of the first entry, we fill the menu contextually.
1026  const std::string& first_id = items.front()["id"];
1027 
1028  if(first_id == "EDITOR-LOAD-MRU-PLACEHOLDER") {
1030  context_manager_->expand_load_mru_menu(items, 0);
1031  }
1032 
1033  if(first_id == "editor-switch-map") {
1035  context_manager_->expand_open_maps_menu(items, 0);
1036  }
1037 
1038  if(first_id == "editor-palette-groups") {
1040  toolkit_->get_palette_manager()->active_palette().expand_palette_groups_menu(items, 0);
1041  }
1042 
1043  if(first_id == "editor-switch-side") {
1045  context_manager_->expand_sides_menu(items, 0);
1046  }
1047 
1048  if(first_id == "editor-switch-area") {
1050  context_manager_->expand_areas_menu(items, 0);
1051  }
1052 
1053  if(!items.empty() && items.front()["id"] == "editor-switch-time") {
1055  context_manager_->expand_time_menu(items, 0);
1056  }
1057 
1058  if(first_id == "editor-assign-local-time") {
1060  context_manager_->expand_local_time_menu(items, 0);
1061  }
1062 
1063  if(first_id == "menu-unit-facings") {
1065  auto pos = items.erase(items.begin());
1066  int dir = 0;
1067  std::generate_n(std::inserter<std::vector<config>>(items, pos), static_cast<int>(map_location::NDIRECTIONS), [&dir]() -> config {
1069  });
1070  }
1071 
1072  if(first_id == "editor-playlist") {
1074  auto pos = items.erase(items.begin());
1075  std::transform(music_tracks_.begin(), music_tracks_.end(), std::inserter<std::vector<config>>(items, pos), [](const sound::music_track& track) -> config {
1076  return config {"label", track.title().empty() ? track.id() : track.title()};
1077  });
1078  }
1079 
1080  if(first_id == "editor-assign-schedule") {
1082  auto pos = items.erase(items.begin());
1083  std::transform(tods_.begin(), tods_.end(), std::inserter<std::vector<config>>(items, pos), [](const tods_map::value_type& tod) -> config {
1084  return config {"label", tod.second.first};
1085  });
1086  }
1087 
1088  if(first_id == "editor-assign-local-schedule") {
1090  auto pos = items.erase(items.begin());
1091  std::transform(tods_.begin(), tods_.end(), std::inserter<std::vector<config>>(items, pos), [](const tods_map::value_type& tod) -> config {
1092  return config {"label", tod.second.first};
1093  });
1094  }
1095 
1096  command_executor::show_menu(items, xloc, yloc, context_menu, disp);
1097 }
1098 
1100 {
1102  gui2::dialogs::preferences_dialog::display();
1103 
1104  gui_->queue_rerender();
1105 }
1106 
1108 {
1110  gui_->invalidate_all();
1111 }
1112 
1114 {
1115  map_location loc = gui_->mouseover_hex();
1116  const unit_map & units = get_current_map_context().units();
1117  const unit_map::const_unit_iterator un = units.find(loc);
1118  if(un != units.end()) {
1119  help::show_unit_help(un->type_id(), un->type().show_variations_in_help(), false);
1120  } else {
1121  help::show_help("..units");
1122  }
1123 }
1124 
1125 
1127 {
1128  if (!get_current_map_context().map().selection().empty()) {
1129  context_manager_->get_clipboard() = map_fragment(get_current_map_context().map(), get_current_map_context().map().selection());
1130  context_manager_->get_clipboard().center_by_mass();
1131  }
1132 }
1133 
1135 {
1136  map_location loc = gui_->mouseover_hex();
1137  unit_map& units = get_current_map_context().units();
1138  const unit_map::unit_iterator& un = units.find(loc);
1139 
1140  const std::string title(N_("Change Unit ID"));
1141  const std::string label(N_("ID:"));
1142 
1143  if(un != units.end()) {
1144  std::string id = un->id();
1145  if (gui2::dialogs::edit_text::execute(title, label, id)) {
1146  un->set_id(id);
1147  }
1148  }
1149 }
1150 
1152 {
1153  map_location loc = gui_->mouseover_hex();
1154  unit_map& units = get_current_map_context().units();
1155  const unit_map::unit_iterator& un = units.find(loc);
1156 
1157  const std::string title(N_("Rename Unit"));
1158  const std::string label(N_("Name:"));
1159 
1160  if(un != units.end()) {
1161  std::string name = un->name();
1162  if(gui2::dialogs::edit_text::execute(title, label, name)) {
1163  //TODO we may not want a translated name here.
1164  un->set_name(name);
1165  }
1166  }
1167 }
1168 
1170 {
1172 }
1173 
1175 {
1176  copy_selection();
1178 }
1179 
1181 {
1182  const std::set<map_location>& area = get_current_map_context().map().selection();
1184 }
1185 
1187 {
1188  const std::set<map_location>& area = get_current_map_context().map().selection();
1190 }
1191 
1193 {
1194  std::stringstream ssx, ssy;
1195  std::set<map_location>::const_iterator i = get_current_map_context().map().selection().begin();
1196  if (i != get_current_map_context().map().selection().end()) {
1197  ssx << "x = " << i->wml_x();
1198  ssy << "y = " << i->wml_y();
1199  ++i;
1200  while (i != get_current_map_context().map().selection().end()) {
1201  ssx << ", " << i->wml_x();
1202  ssy << ", " << i->wml_y();
1203  ++i;
1204  }
1205  ssx << "\n" << ssy.str() << "\n";
1206  desktop::clipboard::copy_to_clipboard(ssx.str(), false);
1207  }
1208 }
1209 
1210 void editor_controller::perform_delete(std::unique_ptr<editor_action> action)
1211 {
1212  if (action) {
1214  }
1215 }
1216 
1217 void editor_controller::perform_refresh_delete(std::unique_ptr<editor_action> action, bool drag_part /* =false */)
1218 {
1219  if (action) {
1220  context_manager_->perform_refresh(*action, drag_part);
1221  }
1222 }
1223 
1225 {
1227  context_manager_->refresh_all();
1228 }
1229 
1231 {
1232  set_button_state();
1233  toolkit_->adjust_size();
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 (get_current_map_context().map().on_board_with_border(drag_from_hex_) && is_dragging()) {
1255  std::unique_ptr<editor_action> a;
1256  bool partial = false;
1257  // last_undo is a non-owning pointer. Although it could have other uses, it seems to be
1258  // mainly (only?) used for printing debugging information.
1259  auto last_undo = get_current_map_context().last_undo_action();
1260  if (dragging_left_ && (sdl::get_mouse_button_mask() & SDL_BUTTON(1)) != 0) {
1261  if (!get_current_map_context().map().on_board_with_border(hex_clicked)) return;
1262  a = get_mouse_action().drag_left(*gui_, x, y, partial, last_undo);
1263  } else if (dragging_right_ && (sdl::get_mouse_button_mask() & SDL_BUTTON(3)) != 0) {
1264  if (!get_current_map_context().map().on_board_with_border(hex_clicked)) return;
1265  a = get_mouse_action().drag_right(*gui_, x, y, partial, last_undo);
1266  }
1267  //Partial means that the mouse action has modified the
1268  //last undo action and the controller shouldn't add
1269  //anything to the undo stack (hence a different perform_ call)
1270  if (a != nullptr) {
1271  if (partial) {
1273  } else {
1275  }
1276  context_manager_->refresh_after_action(true);
1277  }
1278  } else {
1279  get_mouse_action().move(*gui_, hex_clicked);
1280  }
1281  gui().highlight_hex(hex_clicked);
1282 }
1283 
1284 void editor_controller::touch_motion(int /* x */, int /* y */, const bool /* browse */, bool /* update */, map_location /* new_loc */)
1285 {
1286  // Not implemented at all. Sorry, it's a very low priority for iOS port.
1287 }
1288 
1290 {
1291  return get_current_map_context().map().on_board_with_border(gui().hex_clicked_on(x,y));
1292 }
1293 
1294 bool editor_controller::right_click_show_menu(int /*x*/, int /*y*/, const bool /*browse*/)
1295 {
1297 }
1298 
1299 bool editor_controller::left_click(int x, int y, const bool browse)
1300 {
1301  toolkit_->clear_mouseover_overlay();
1302  if (mouse_handler_base::left_click(x, y, browse))
1303  return true;
1304 
1305  LOG_ED << "Left click, after generic handling";
1306  map_location hex_clicked = gui().hex_clicked_on(x, y);
1307  if (!get_current_map_context().map().on_board_with_border(hex_clicked))
1308  return true;
1309 
1310  LOG_ED << "Left click action " << hex_clicked;
1311  auto a = get_mouse_action().click_left(*gui_, x, y);
1312  if(a) {
1313  perform_refresh_delete(std::move(a), true);
1314  set_button_state();
1315  }
1316 
1317  return false;
1318 }
1319 
1320 void editor_controller::left_drag_end(int x, int y, const bool /*browse*/)
1321 {
1322  auto a = get_mouse_action().drag_end_left(*gui_, x, y);
1323  perform_delete(std::move(a));
1324 }
1325 
1326 void editor_controller::left_mouse_up(int x, int y, const bool /*browse*/)
1327 {
1328  auto a = get_mouse_action().up_left(*gui_, x, y);
1329  if(a) {
1330  perform_delete(std::move(a));
1331  set_button_state();
1332  }
1333  toolkit_->set_mouseover_overlay();
1334  context_manager_->refresh_after_action();
1335 }
1336 
1337 bool editor_controller::right_click(int x, int y, const bool browse)
1338 {
1339  toolkit_->clear_mouseover_overlay();
1340  if (mouse_handler_base::right_click(x, y, browse)) return true;
1341  LOG_ED << "Right click, after generic handling";
1342  map_location hex_clicked = gui().hex_clicked_on(x, y);
1343  if (!get_current_map_context().map().on_board_with_border(hex_clicked)) return true;
1344  LOG_ED << "Right click action " << hex_clicked;
1345  auto a = get_mouse_action().click_right(*gui_, x, y);
1346  if(a) {
1347  perform_refresh_delete(std::move(a), true);
1348  set_button_state();
1349  }
1350  return false;
1351 }
1352 
1353 void editor_controller::right_drag_end(int x, int y, const bool /*browse*/)
1354 {
1355  auto a = get_mouse_action().drag_end_right(*gui_, x, y);
1356  perform_delete(std::move(a));
1357 }
1358 
1359 void editor_controller::right_mouse_up(int x, int y, const bool browse)
1360 {
1361  // Call base method to handle context menus.
1362  mouse_handler_base::right_mouse_up(x, y, browse);
1363 
1364  auto a = get_mouse_action().up_right(*gui_, x, y);
1365  if(a) {
1366  perform_delete(std::move(a));
1367  set_button_state();
1368  }
1369  toolkit_->set_mouseover_overlay();
1370  context_manager_->refresh_after_action();
1371 }
1372 
1374 {
1375  const map_location& loc = gui().mouseover_hex();
1376  if (get_current_map_context().map().on_board(loc) == false)
1377  return;
1378 
1381 }
1382 
1383 void editor_controller::process_keyup_event(const SDL_Event& event)
1384 {
1385  auto a = get_mouse_action().key_event(gui(), event);
1386  perform_refresh_delete(std::move(a));
1387  toolkit_->set_mouseover_overlay();
1388 }
1389 
1391  return this;
1392 }
1393 
1395 {
1397 }
1398 
1400 {
1402 }
1403 
1405 {
1407 }
1408 
1410 {
1412 }
1413 
1415 {
1416  return toolkit_->get_palette_manager()->active_palette().action_pressed();
1417 }
1418 
1419 } //end namespace editor
virtual bool in_context_menu(hotkey::HOTKEY_COMMAND command) const
const map_location & mouseover_hex() const
Definition: display.hpp:296
Randomize terrain in an area.
Definition: action.hpp:398
virtual std::unique_ptr< editor_action > drag_end_left(editor_display &disp, int x, int y)
The end of dragging.
void undo()
Un-does the last action, and puts it in the redo stack for a possible redo.
void set_grid(bool ison)
Definition: general.cpp:570
void set_scroll_up(bool on)
::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:162
void set_scroll_down(bool on)
unit_iterator end()
Definition: map.hpp:429
bool minimap_draw_units()
Definition: general.cpp:855
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
A map fragment – a collection of locations and information abut them.
void add_to_playlist(const sound::music_track &track)
const std::string & id() const
Select the entire map.
std::unique_ptr< font::floating_label_context > floating_label_manager_
void queue_rerender()
Marks everything for rendering including all tiles and sidebar.
Definition: display.cpp:2322
const t_translation::terrain_code & get_selected_bg_terrain()
bool dragging_right_
RMB drag init flag.
void set(CURSOR_TYPE type)
Use the default parameter to reset cursors.
Definition: cursor.cpp:176
void save_map() override
Save the map, open dialog if not named yet.
void init_tods(const game_config_view &game_config)
init the available time-of-day settings
void export_selection_coords()
Export the WML-compatible list of selected tiles to the system clipboard.
virtual std::unique_ptr< editor_action > click_right(editor_display &disp, int x, int y)=0
A click, possibly the beginning of a drag.
game_classification * classification
Definition: resources.cpp:35
void show_terrain_description(const terrain_type &t)
Definition: help.cpp:81
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 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.
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:581
bool quit_confirm()
Show a quit confirmation dialog and returns true if the user pressed &#39;yes&#39;.
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&#39;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
config_array_view child_range(config_key_type key) const
void toggle_debug_flag(DEBUG_FLAG flag)
Definition: display.hpp:990
bool minimap_movement_coding()
Definition: general.cpp:835
const std::string & get_filename() const
editor_display & gui() override
Reference to the used display objects.
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:344
void new_area(const std::set< map_location > &area)
void show_unit_list(display &gui)
Definition: unit_list.cpp:199
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)
int get_current_time(const map_location &loc=map_location::null_location()) const
map_labels & get_labels()
#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 std::vector< std::string > items
save_result save_image(const locator &i_locator, const std::string &filename)
Definition: picture.cpp:1092
const mouse_action & get_mouse_action() const
Get the current mouse action.
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) const
Definition: map.cpp:98
void add_area()
Add a new area to the current context, filled with the selection if any.
virtual 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.
HOTKEY_COMMAND command
The command associated with this hotkey.
#define SCOPE_ED
List of starting locations and location ids.
void play_music_once(const std::string &file)
Definition: sound.cpp:603
static std::string _(const char *str)
Definition: gettext.hpp:93
The editor_controller class contains the mouse and keyboard event handling routines for the editor...
bool draw_terrain_codes()
Definition: editor.cpp:37
virtual std::unique_ptr< editor_action > up_right(editor_display &disp, int x, int y)
void partial_undo()
Un-does a single step from a undo action chain.
Contains functions for cleanly handling SDL input.
virtual std::unique_ptr< editor_action > drag_end_right(editor_display &disp, int x, int y)
Keyboard shortcuts for game actions.
Unit and team statistics.
void remove_area(int index)
void flush_cache()
Purges all image caches.
Definition: picture.cpp:234
bool modified() const
void perform_delete(std::unique_ptr< editor_action > action)
Perform an action, then delete the action object.
#define b
#define WRN_ED
bool minimap_draw_villages()
Definition: general.cpp:865
void show() const
Shows the error in a dialog.
const std::unique_ptr< editor_display > gui_
The display object used and owned by the editor.
Overlays x,y coords on tiles.
Definition: display.hpp:962
void show_menu(const std::vector< config > &items_arg, int xloc, int yloc, bool context_menu, display &disp) override
controller_base override
bool do_execute_command(const hotkey::hotkey_command &command, int index=-1, bool press=true, bool release=false) override
command_executor override
map_context & get_current_map_context() const
void right_mouse_up(int x, int y, const bool browse) override
Called when the right mouse button is up.
void clear_help_string()
Removes the help string.
void right_drag_end(int x, int y, const bool browse) override
Called whenever the right mouse drag has "ended".
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:87
void set_local_starting_time(int time)
TODO.
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.
std::string label
What to show in the filter&#39;s drop-down list.
Definition: manager.cpp:217
const std::set< map_location > & selection() const
Return the selection set.
Definition: editor_map.hpp:149
surface screenshot(bool map_screenshot=false)
Capture a (map-)screenshot into a surface.
Definition: display.cpp:781
virtual bool has_context_menu() const
void remove_side()
removes the last side from the scenario
Definition: map_context.hpp:99
Implements a quit confirmation dialog.
filter_context * filter_con
Definition: resources.cpp:24
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.
bool valid() const
Definition: location.hpp:89
bool on_board_with_border(const map_location &loc) const
Definition: map.cpp:390
void undo() override
Undos an action in the current map context.
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)
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:185
void init_music(const game_config_view &game_config)
init background music for the editor
editor_action * last_undo_action()
bool is_pure_map() const
bool draw_hex_coordinates()
Definition: editor.cpp:45
void touch_motion(int x, int y, const bool browse, bool update=false, map_location new_loc=map_location::null_location()) override
void refresh_image_cache()
Reload images.
Manage the empty-palette in the editor.
Definition: action.cpp:30
void perform_action(const editor_action &action)
Performs an action (thus modifying the map).
const char * what() const noexcept
Definition: exceptions.hpp:36
void invalidate_all()
Function to invalidate all tiles.
Definition: display.cpp:3134
uint32_t get_mouse_button_mask()
Returns the current mouse button mask.
Definition: input.cpp:49
Paint the same terrain on a number of locations on the map.
Definition: action.hpp:265
bool dragging_left_
LMB drag init flag.
virtual bool supports_brushes() const
Whether we need the brush bar, is used to grey it out.
bool can_redo() const
static bool quit()
Shows the quit confirmation if needed.
std::vector< std::string > get_area_ids() const
Encapsulates the map of the game.
Definition: location.hpp:38
Helper class, don&#39;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...
unit_iterator find(std::size_t id)
Definition: map.cpp:301
void recalculate_labels()
Definition: label.cpp:245
void set_starting_position_labels(display &disp)
static void quit_to_desktop()
void init_gui()
init the display object and general set-up
void scroll_right(bool on) override
std::size_t i
Definition: function.cpp:968
bool everything_selected() const
Definition: editor_map.cpp:207
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:1542
Game configuration data as global variables.
Definition: build_info.cpp:60
static void update()
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
const tod_manager * get_time_manager() const
const std::vector< time_of_day > & times(const map_location &loc=map_location::null_location()) const
structure which will hide all current floating labels, and cause floating labels instantiated after i...
const std::string & selected_item() const
Return the currently selected item.
Internal representation of music tracks.
The help implementation caches data parsed from the game_config.
Definition: help.hpp:40
virtual std::vector< std::string > additional_actions_pressed() override
void set_scroll_right(bool on)
bool empty() const
Definition: map.hpp:446
CURSOR_TYPE get()
Definition: cursor.cpp:216
void cut_selection()
Cut the selection from the current map to the clipboard.
virtual bool do_execute_command(const hotkey_command &command, int index=-1, bool press=true, bool release=false)
void set_debug_flag(DEBUG_FLAG flag, bool value)
Definition: display.hpp:985
DIRECTION
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:40
void display_redraw_callback(display &)
Callback function passed to display to be called on queue_rerender.
std::vector< sound::music_track > music_tracks_
#define N_(String)
Definition: gettext.hpp:101
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
void do_screenshot(const std::string &screenshot_filename="map_screenshot.png")
Takes a screenshot.
void toggle_grid() override
Grid toggle.
virtual std::unique_ptr< editor_action > up_left(editor_display &disp, int x, int y)
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
bool can_undo() const
bool grid()
Definition: general.cpp:565
bool left_click(int x, int y, const bool browse) override
Overridden in derived classes, called on a left click (mousedown).
const std::string & file_path() const
virtual const unit_map & units() const override
Const units accessor.
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:34
Overlays number of bitmaps on tiles.
Definition: display.hpp:968
const game_config_view & game_config_
bool minimap_draw_terrain()
Definition: general.cpp:875
virtual const editor_map & map() const override
Const map accessor.
void set_draw_terrain_codes(bool value)
Definition: editor.cpp:41
int get_active_area() const
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
bool is_in_playlist(std::string track_id)
virtual std::unique_ptr< editor_action > click_left(editor_display &disp, int x, int y)=0
A click, possibly the beginning of a drag.
Overlays terrain codes on tiles.
Definition: display.hpp:965
void replace_local_schedule(const std::vector< time_of_day > &schedule)
Replace the [time]s of the currently active area.
virtual std::unique_ptr< editor_action > drag_left(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Drag operation.
Container associating units to locations.
Definition: map.hpp:98
const std::set< map_location > & get_area_by_index(int index) const
void set_draw_num_of_bitmaps(bool value)
Definition: editor.cpp:57
void show_error_message(const std::string &msg, bool message_use_markup)
Shows an error message to the user.
Definition: message.cpp:204
#define e
int get_current_area_time(int index) const
void set_draw_hex_coordinates(bool value)
Definition: editor.cpp:49
const std::string & title() const
editor_controller()
The constructor.
There are still moves and/or attacks possible, but the unit doesn&#39;t fit in the "unmoved" status...
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:60
mock_char c
void scroll_down(bool on) override
virtual std::unique_ptr< editor_action > drag_right(editor_display &disp, int x, int y, bool &partial, editor_action *last_undo)
Drag operation.
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).
virtual const std::vector< team > & teams() const override
Const teams accessor.
static std::vector< std::string > saved_windows_
std::string::const_iterator iterator
Definition: tokenizer.hpp:25
void redo() override
Redos an action in the current map context.
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
bool minimap_terrain_coding()
Definition: general.cpp:845