The Battle for Wesnoth  1.15.7+dev
editor_controller.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2018 by Tomasz Sniatowski <kailoran@gmail.com>
3  Part of the Battle for Wesnoth Project https://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/retval.hpp"
37 #include "wml_exception.hpp"
38 
39 #include "resources.hpp"
40 #include "reports.hpp"
41 
42 #include "cursor.hpp"
43 #include "desktop/clipboard.hpp"
44 #include "floating_label.hpp"
45 #include "game_board.hpp"
46 #include "preferences/game.hpp"
47 #include "gettext.hpp"
48 #include "picture.hpp"
49 #include "preferences/display.hpp"
50 #include "sound.hpp"
51 #include "units/unit.hpp"
53 #include "game_config_manager.hpp"
54 #include "quit_confirmation.hpp"
55 
56 #include "utils/functional.hpp"
57 
58 namespace {
59 static std::vector<std::string> saved_windows_;
60 }
61 
62 namespace editor {
63 
65  : controller_base()
66  , mouse_handler_base()
67  , quit_confirmation(std::bind(&editor_controller::quit_confirm, this))
68  , active_menu_(editor::MAP)
69  , reports_(new reports())
70  , gui_(new editor_display(*this, *reports_, controller_base::get_theme(game_config_, "editor")))
71  , tods_()
72  , context_manager_(new context_manager(*gui_.get(), game_config_))
73  , toolkit_(nullptr)
74  , tooltip_manager_()
75  , floating_label_manager_(nullptr)
76  , help_manager_(nullptr)
77  , do_quit_(false)
78  , quit_mode_(EXIT_ERROR)
79  , music_tracks_()
80 {
81  init_gui();
82  toolkit_.reset(new editor_toolkit(*gui_.get(), key_, game_config_, *context_manager_.get()));
83  help_manager_.reset(new help::help_manager(&game_config_));
84  context_manager_->locs_ = toolkit_->get_palette_manager()->location_palette_.get();
85  context_manager_->switch_context(0, true);
86  init_tods(game_config_);
87  init_music(game_config_);
90 
91  gui().create_buttons();
93 }
94 
96 {
97  gui_->change_display_context(&get_current_map_context());
99  gui_->add_redraw_observer(std::bind(&editor_controller::display_redraw_callback, this, _1));
104 // halo_manager_.reset(new halo::manager(*gui_));
105 // resources::halo = halo_manager_.get();
106 // ^ These lines no longer necessary, the gui owns its halo manager.
107 // TODO: Should the editor map contexts actually own the halo manager and swap them in and out from the gui?
108 // 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
109 // without deleting it.
110 }
111 
113 {
114  for (const config &schedule : game_config.child_range("editor_times")) {
115 
116  const std::string& schedule_id = schedule["id"];
117  const std::string& schedule_name = schedule["name"];
118  if (schedule_id.empty()) {
119  ERR_ED << "Missing ID attribute in a TOD Schedule." << std::endl;
120  continue;
121  }
122 
123  tods_map::iterator times = tods_.find(schedule_id);
124  if (times == tods_.end()) {
125  std::pair<tods_map::iterator, bool> new_times =
126  tods_.emplace(schedule_id, std::make_pair(schedule_name, std::vector<time_of_day>()));
127 
128  times = new_times.first;
129  } else {
130  ERR_ED << "Duplicate TOD Schedule identifiers." << std::endl;
131  continue;
132  }
133 
134  for (const config &time : schedule.child_range("time")) {
135  times->second.second.emplace_back(time);
136  }
137 
138  }
139 
140  if (tods_.empty()) {
141  ERR_ED << "No editor time-of-day defined" << std::endl;
142  }
143 }
144 
146 {
147  const std::string tag_name = "editor_music";
148  if (game_config.child_range(tag_name).size() == 0) {
149  ERR_ED << "No editor music defined" << std::endl;
150  }
151  else {
152  for (const config& editor_music : game_config.child_range(tag_name)) {
153  for (const config& music : editor_music.child_range("music")) {
154  sound::music_track track(music);
155  if (track.file_path().empty())
156  WRN_ED << "Music track " << track.id() << " not found." << std::endl;
157  else
158  music_tracks_.emplace_back(music);
159  }
160  }
161  }
162 }
163 
165 {
166  resources::tod_manager = nullptr;
167  resources::filter_con = nullptr;
168 
169  resources::classification = nullptr;
170 }
171 
173 {
174  try {
175  while (!do_quit_) {
176  play_slice();
177  }
178  } catch (const editor_exception& e) {
179  gui2::show_transient_message(_("Fatal error"), e.what());
180  return EXIT_ERROR;
181  } catch (const wml_exception& e) {
182  e.show();
183  }
184  return quit_mode_;
185 }
186 
188 }
189 
190 void editor_controller::do_screenshot(const std::string& screenshot_filename /* = "map_screenshot.bmp" */)
191 {
192  try {
193  surface screenshot = gui().screenshot(true);
194  if(!screenshot || image::save_image(screenshot, screenshot_filename) != image::save_result::success) {
195  ERR_ED << "Screenshot creation failed!\n";
196  }
197  } catch (const wml_exception& e) {
198  e.show();
199  }
200 }
201 
203 {
204  std::string modified;
205  std::size_t amount = context_manager_->modified_maps(modified);
206 
207  std::string message;
208  if (amount == 0) {
209  message = _("Do you really want to quit?");
210  } else if (amount == 1 && get_current_map_context().modified()) {
211  message = _("Do you really want to quit? Changes to this map since the last save will be lost.");
212  } else {
213  message = _("Do you really want to quit? The following maps were modified and all changes since the last save will be lost:");
214  message += "\n" + modified;
215  }
216  return quit_confirmation::show_prompt(message);
217 }
218 
220 {
221  if (tods_.empty()) {
222  gui2::show_error_message(_("No editor time-of-day found."));
223  return;
224  }
225 
227 
228  if(gui2::dialogs::custom_tod::execute(manager.times(), manager.get_current_time())) {
229  // TODO save the new tod here
230  }
231 
232  gui_->update_tod();
233 
234  context_manager_->refresh_all();
235 }
236 
238 {
239  using namespace hotkey; //reduce hotkey:: clutter
240  switch (cmd.id) {
241  case HOTKEY_NULL:
242  if (index >= 0) {
243  unsigned i = static_cast<unsigned>(index);
244 
245  switch (active_menu_) {
246  case editor::MAP:
247  if (i < context_manager_->open_maps()) {
248  return true;
249  }
250  return false;
251  case editor::LOAD_MRU:
252  case editor::PALETTE:
253  case editor::AREA:
254  case editor::SIDE:
255  case editor::TIME:
256  case editor::SCHEDULE:
258  case editor::MUSIC:
259  case editor::LOCAL_TIME:
260  case editor::UNIT_FACING:
261  return true;
262  }
263  }
264  return false;
266  return true;
268  return toolkit_->get_palette_manager()->can_scroll_up();
270  return toolkit_->get_palette_manager()->can_scroll_down();
271  case HOTKEY_ZOOM_IN:
272  return !gui_->zoom_at_max();
273  case HOTKEY_ZOOM_OUT:
274  return !gui_->zoom_at_min();
275  case HOTKEY_ZOOM_DEFAULT:
276  case HOTKEY_FULLSCREEN:
277  case HOTKEY_SCREENSHOT:
279  case HOTKEY_TOGGLE_GRID:
280  case HOTKEY_MOUSE_SCROLL:
281  case HOTKEY_ANIMATE_MAP:
282  case HOTKEY_MUTE:
283  case HOTKEY_PREFERENCES:
284  case HOTKEY_HELP:
285  case HOTKEY_QUIT_GAME:
286  case HOTKEY_SCROLL_UP:
287  case HOTKEY_SCROLL_DOWN:
288  case HOTKEY_SCROLL_LEFT:
289  case HOTKEY_SCROLL_RIGHT:
290  return true; //general hotkeys we can always do
291 
293  return !get_current_map_context().units().empty();
294 
295  case HOTKEY_STATUS_TABLE:
296  return !get_current_map_context().teams().empty();
297 
299  return gui().mouseover_hex().valid();
300 
301  // unit tool related
302  case HOTKEY_DELETE_UNIT:
303  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  {
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_->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<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.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::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, 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();
795  perform_delete(std::make_unique<editor_action_unit_delete>(loc));
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(!get_current_map_context().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  get_current_map_context().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
927  if(get_current_map_context().teams().size() >= 9) {
928  size_t new_side_num = get_current_map_context().teams().size() + 1;
929  toolkit_->get_palette_manager()->location_palette_->add_item(std::to_string(new_side_num));
930  }
932  gui_->init_flags();
933  return true;
935  gui_->set_team(0, true);
936  gui_->set_playing_team(0);
938  return true;
940  context_manager_->edit_side_dialog(gui_->viewing_team());
941  return true;
942 
943  // Transitions
945  context_manager_->set_update_transitions_mode(2);
946  return true;
948  context_manager_->set_update_transitions_mode(1);
949  return true;
951  context_manager_->set_update_transitions_mode(0);
952  return true;
954  if(context_manager_->toggle_update_transitions()) {
955  return true;
956  }
957  FALLTHROUGH;
959  context_manager_->refresh_all();
960  return true;
961  // Refresh
963  context_manager_->reload_map();
964  return true;
967  return true;
968 
970  gui().set_draw_coordinates(!gui().get_draw_coordinates());
971  preferences::editor::set_draw_hex_coordinates(gui().get_draw_coordinates());
972  gui().invalidate_all();
973  return true;
975  gui().set_draw_terrain_codes(!gui().get_draw_terrain_codes());
976  preferences::editor::set_draw_terrain_codes(gui().get_draw_terrain_codes());
977  gui().invalidate_all();
978  return true;
980  gui().set_draw_num_of_bitmaps(!gui().get_draw_num_of_bitmaps());
981  preferences::editor::set_draw_num_of_bitmaps(gui().get_draw_num_of_bitmaps());
982  gui().invalidate_all();
983  return true;
985  location_palette* lp = dynamic_cast<location_palette*>(&toolkit_->get_palette_manager()->active_palette());
986  if (lp) {
987  perform_delete(std::make_unique<editor_action_starting_position>(map_location(), lp->selected_item()));
988  // No idea if this is the right thing to call, but it ensures starting
989  // position labels get removed on delete.
990  context_manager_->refresh_after_action();
991  }
992  return true;
993  }
994  default:
995  return hotkey::command_executor::do_execute_command(cmd, index, press, release);
996  }
997 }
998 
1000 {
1001  help::show_help("..editor");
1002 }
1003 
1004 void editor_controller::show_menu(const std::vector<config>& items_arg, int xloc, int yloc, bool context_menu, display& disp)
1005 {
1006  if(context_menu) {
1007  if(!get_current_map_context().map().on_board_with_border(gui().hex_clicked_on(xloc, yloc))) {
1008  return;
1009  }
1010  }
1011 
1012  std::vector<config> items;
1013  for(const auto& c : items_arg) {
1014  const std::string& id = c["id"];
1016 
1017  if((can_execute_command(command) && (!context_menu || in_context_menu(command.id)))
1018  || command.id == hotkey::HOTKEY_NULL)
1019  {
1020  items.emplace_back("id", id);
1021  }
1022  }
1023 
1024  // No point in showing an empty menu.
1025  if(items.empty()) {
1026  return;
1027  }
1028 
1029  // Based on the ID of the first entry, we fill the menu contextually.
1030  const std::string& first_id = items.front()["id"];
1031 
1032  if(first_id == "EDITOR-LOAD-MRU-PLACEHOLDER") {
1034  context_manager_->expand_load_mru_menu(items, 0);
1035  }
1036 
1037  if(first_id == "editor-switch-map") {
1039  context_manager_->expand_open_maps_menu(items, 0);
1040  }
1041 
1042  if(first_id == "editor-palette-groups") {
1044  toolkit_->get_palette_manager()->active_palette().expand_palette_groups_menu(items, 0);
1045  }
1046 
1047  if(first_id == "editor-switch-side") {
1049  context_manager_->expand_sides_menu(items, 0);
1050  }
1051 
1052  if(first_id == "editor-switch-area") {
1054  context_manager_->expand_areas_menu(items, 0);
1055  }
1056 
1057  if(!items.empty() && items.front()["id"] == "editor-switch-time") {
1059  context_manager_->expand_time_menu(items, 0);
1060  }
1061 
1062  if(first_id == "editor-assign-local-time") {
1064  context_manager_->expand_local_time_menu(items, 0);
1065  }
1066 
1067  if(first_id == "menu-unit-facings") {
1069  auto pos = items.erase(items.begin());
1070  int dir = 0;
1071  std::generate_n(std::inserter<std::vector<config>>(items, pos), static_cast<int>(map_location::NDIRECTIONS), [&dir]() -> config {
1073  });
1074  }
1075 
1076  if(first_id == "editor-playlist") {
1078  auto pos = items.erase(items.begin());
1079  std::transform(music_tracks_.begin(), music_tracks_.end(), std::inserter<std::vector<config>>(items, pos), [](const sound::music_track& track) -> config {
1080  return config {"label", track.title().empty() ? track.id() : track.title()};
1081  });
1082  }
1083 
1084  if(first_id == "editor-assign-schedule") {
1086  auto pos = items.erase(items.begin());
1087  std::transform(tods_.begin(), tods_.end(), std::inserter<std::vector<config>>(items, pos), [](const tods_map::value_type& tod) -> config {
1088  return config {"label", tod.second.first};
1089  });
1090  }
1091 
1092  if(first_id == "editor-assign-local-schedule") {
1094  auto pos = items.erase(items.begin());
1095  std::transform(tods_.begin(), tods_.end(), std::inserter<std::vector<config>>(items, pos), [](const tods_map::value_type& tod) -> config {
1096  return config {"label", tod.second.first};
1097  });
1098  }
1099 
1100  command_executor::show_menu(items, xloc, yloc, context_menu, disp);
1101 }
1102 
1104 {
1105  gui_->video().clear_all_help_strings();
1107 
1108  gui_->redraw_everything();
1109 }
1110 
1112 {
1114  gui_->invalidate_all();
1115 }
1116 
1118 {
1119  map_location loc = gui_->mouseover_hex();
1120  const unit_map & units = get_current_map_context().units();
1121  const unit_map::const_unit_iterator un = units.find(loc);
1122  if(un != units.end()) {
1123  help::show_unit_help(un->type_id(), un->type().show_variations_in_help(), false);
1124  } else {
1125  help::show_help("..units");
1126  }
1127 }
1128 
1129 
1131 {
1132  if (!get_current_map_context().map().selection().empty()) {
1133  context_manager_->get_clipboard() = map_fragment(get_current_map_context().map(), get_current_map_context().map().selection());
1134  context_manager_->get_clipboard().center_by_mass();
1135  }
1136 }
1137 
1139 {
1140  map_location loc = gui_->mouseover_hex();
1141  unit_map& units = get_current_map_context().units();
1142  const unit_map::unit_iterator& un = units.find(loc);
1143 
1144  const std::string title(N_("Change Unit ID"));
1145  const std::string label(N_("ID:"));
1146 
1147  if(un != units.end()) {
1148  std::string id = un->id();
1149  if (gui2::dialogs::edit_text::execute(title, label, id)) {
1150  un->set_id(id);
1151  }
1152  }
1153 }
1154 
1156 {
1157  map_location loc = gui_->mouseover_hex();
1158  unit_map& units = get_current_map_context().units();
1159  const unit_map::unit_iterator& un = units.find(loc);
1160 
1161  const std::string title(N_("Rename Unit"));
1162  const std::string label(N_("Name:"));
1163 
1164  if(un != units.end()) {
1165  std::string name = un->name();
1166  if(gui2::dialogs::edit_text::execute(title, label, name)) {
1167  //TODO we may not want a translated name here.
1168  un->set_name(name);
1169  }
1170  }
1171 }
1172 
1174 {
1176 }
1177 
1179 {
1180  copy_selection();
1182 }
1183 
1185 {
1186  const std::set<map_location>& area = get_current_map_context().map().selection();
1188 }
1189 
1191 {
1192  const std::set<map_location>& area = get_current_map_context().map().selection();
1194 }
1195 
1197 {
1198  std::stringstream ssx, ssy;
1199  std::set<map_location>::const_iterator i = get_current_map_context().map().selection().begin();
1200  if (i != get_current_map_context().map().selection().end()) {
1201  ssx << "x = " << i->wml_x();
1202  ssy << "y = " << i->wml_y();
1203  ++i;
1204  while (i != get_current_map_context().map().selection().end()) {
1205  ssx << ", " << i->wml_x();
1206  ssy << ", " << i->wml_y();
1207  ++i;
1208  }
1209  ssx << "\n" << ssy.str() << "\n";
1210  desktop::clipboard::copy_to_clipboard(ssx.str(), false);
1211  }
1212 }
1213 
1214 void editor_controller::perform_delete(std::unique_ptr<editor_action> action)
1215 {
1216  if (action) {
1218  }
1219 }
1220 
1221 void editor_controller::perform_refresh_delete(std::unique_ptr<editor_action> action, bool drag_part /* =false */)
1222 {
1223  if (action) {
1224  context_manager_->perform_refresh(*action, drag_part);
1225  }
1226 }
1227 
1229 {
1231  context_manager_->refresh_all();
1232 }
1233 
1235 {
1236  set_button_state();
1237  toolkit_->adjust_size();
1238  toolkit_->get_palette_manager()->draw_contents();
1240 }
1241 
1243 {
1245  context_manager_->refresh_after_action();
1246 }
1247 
1249 {
1251  context_manager_->refresh_after_action();
1252 }
1253 
1254 void editor_controller::mouse_motion(int x, int y, const bool /*browse*/,
1255  bool update, map_location /*new_loc*/)
1256 {
1257  if (mouse_handler_base::mouse_motion_default(x, y, update)) return;
1258  map_location hex_clicked = gui().hex_clicked_on(x, y);
1259  if (get_current_map_context().map().on_board_with_border(drag_from_hex_) && is_dragging()) {
1260  std::unique_ptr<editor_action> a;
1261  bool partial = false;
1262  // last_undo is a non-owning pointer. Although it could have other uses, it seems to be
1263  // mainly (only?) used for printing debugging information.
1264  auto last_undo = get_current_map_context().last_undo_action();
1265  if (dragging_left_ && (SDL_GetMouseState(nullptr, nullptr) & SDL_BUTTON(1)) != 0) {
1266  if (!get_current_map_context().map().on_board_with_border(hex_clicked)) return;
1267  a = get_mouse_action().drag_left(*gui_, x, y, partial, last_undo);
1268  } else if (dragging_right_ && (SDL_GetMouseState(nullptr, nullptr) & SDL_BUTTON(3)) != 0) {
1269  if (!get_current_map_context().map().on_board_with_border(hex_clicked)) return;
1270  a = get_mouse_action().drag_right(*gui_, x, y, partial, last_undo);
1271  }
1272  //Partial means that the mouse action has modified the
1273  //last undo action and the controller shouldn't add
1274  //anything to the undo stack (hence a different perform_ call)
1275  if (a != nullptr) {
1276  if (partial) {
1278  } else {
1280  }
1281  context_manager_->refresh_after_action(true);
1282  }
1283  } else {
1284  get_mouse_action().move(*gui_, hex_clicked);
1285  }
1286  gui().highlight_hex(hex_clicked);
1287 }
1288 
1289 void editor_controller::touch_motion(int /* x */, int /* y */, const bool /* browse */, bool /* update */, map_location /* new_loc */)
1290 {
1291  // Not implemented at all. Sorry, it's a very low priority for iOS port.
1292 }
1293 
1295 {
1296  return get_current_map_context().map().on_board_with_border(gui().hex_clicked_on(x,y));
1297 }
1298 
1299 bool editor_controller::right_click_show_menu(int /*x*/, int /*y*/, const bool /*browse*/)
1300 {
1302 }
1303 
1304 bool editor_controller::left_click(int x, int y, const bool browse)
1305 {
1306  toolkit_->clear_mouseover_overlay();
1307  if (mouse_handler_base::left_click(x, y, browse))
1308  return true;
1309 
1310  LOG_ED << "Left click, after generic handling\n";
1311  map_location hex_clicked = gui().hex_clicked_on(x, y);
1312  if (!get_current_map_context().map().on_board_with_border(hex_clicked))
1313  return true;
1314 
1315  LOG_ED << "Left click action " << hex_clicked << "\n";
1316  auto a = get_mouse_action().click_left(*gui_, x, y);
1317  if(a) {
1318  perform_refresh_delete(std::move(a), true);
1319  set_button_state();
1320  }
1321 
1322  return false;
1323 }
1324 
1325 void editor_controller::left_drag_end(int x, int y, const bool /*browse*/)
1326 {
1327  auto a = get_mouse_action().drag_end_left(*gui_, x, y);
1328  perform_delete(std::move(a));
1329 }
1330 
1331 void editor_controller::left_mouse_up(int x, int y, const bool /*browse*/)
1332 {
1333  auto a = get_mouse_action().up_left(*gui_, x, y);
1334  if(a) {
1335  perform_delete(std::move(a));
1336  set_button_state();
1337  }
1338  toolkit_->set_mouseover_overlay();
1339  context_manager_->refresh_after_action();
1340 }
1341 
1342 bool editor_controller::right_click(int x, int y, const bool browse)
1343 {
1344  toolkit_->clear_mouseover_overlay();
1345  if (mouse_handler_base::right_click(x, y, browse)) return true;
1346  LOG_ED << "Right click, after generic handling\n";
1347  map_location hex_clicked = gui().hex_clicked_on(x, y);
1348  if (!get_current_map_context().map().on_board_with_border(hex_clicked)) return true;
1349  LOG_ED << "Right click action " << hex_clicked << "\n";
1350  auto a = get_mouse_action().click_right(*gui_, x, y);
1351  if(a) {
1352  perform_refresh_delete(std::move(a), true);
1353  set_button_state();
1354  }
1355  return false;
1356 }
1357 
1358 void editor_controller::right_drag_end(int x, int y, const bool /*browse*/)
1359 {
1360  auto a = get_mouse_action().drag_end_right(*gui_, x, y);
1361  perform_delete(std::move(a));
1362 }
1363 
1364 void editor_controller::right_mouse_up(int x, int y, const bool browse)
1365 {
1366  // Call base method to handle context menus.
1367  mouse_handler_base::right_mouse_up(x, y, browse);
1368 
1369  auto a = get_mouse_action().up_right(*gui_, x, y);
1370  if(a) {
1371  perform_delete(std::move(a));
1372  set_button_state();
1373  }
1374  toolkit_->set_mouseover_overlay();
1375  context_manager_->refresh_after_action();
1376 }
1377 
1379 {
1380  const map_location& loc = gui().mouseover_hex();
1381  if (get_current_map_context().map().on_board(loc) == false)
1382  return;
1383 
1386 }
1387 
1388 void editor_controller::process_keyup_event(const SDL_Event& event)
1389 {
1390  auto a = get_mouse_action().key_event(gui(), event);
1391  perform_refresh_delete(std::move(a));
1392  toolkit_->set_mouseover_overlay();
1393 }
1394 
1396  return this;
1397 }
1398 
1400 {
1402 }
1403 
1405 {
1407 }
1408 
1410 {
1412 }
1413 
1415 {
1417 }
1418 
1420 {
1421  return toolkit_->get_palette_manager()->active_palette().action_pressed();
1422 }
1423 
1424 } //end namespace editor
virtual bool in_context_menu(hotkey::HOTKEY_COMMAND command) const
const map_location & mouseover_hex() const
Definition: display.hpp:285
Randomize terrain in an area.
Definition: action.hpp:397
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: display.cpp:70
void set_scroll_up(bool on)
void set_preference_display_settings()
Definition: display.cpp:44
::tod_manager * tod_manager
Definition: resources.cpp:29
void copy_selection()
Copy the selection on the current map to the clipboard.
static std::string write_translated_direction(DIRECTION dir)
Definition: location.cpp:161
void set_draw_num_of_bitmaps(bool value)
Setter for the terrain code debug overlay on tiles.
Definition: display.hpp:365
void set_scroll_down(bool on)
unit_iterator end()
Definition: map.hpp:429
bool minimap_draw_units()
Definition: general.cpp:794
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:114
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_
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()
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:360
void set(CURSOR_TYPE type)
Use the default parameter to reset cursors.
Definition: cursor.cpp:175
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.
int dummy
Definition: lstrlib.cpp:1125
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:34
void show_terrain_description(const terrain_type &t)
Definition: help.cpp:62
void do_screenshot(const std::string &screenshot_filename="map_screenshot.bmp")
Takes a screenshot.
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:594
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:52
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
bool minimap_movement_coding()
Definition: general.cpp:774
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:362
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)
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.
int get_current_time(const map_location &loc=map_location::null_location()) const
void redraw_everything()
Invalidates entire screen, including all tiles and sidebar.
Definition: display.cpp:2414
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.
save_result save_image(const locator &i_locator, const std::string &filename)
Definition: picture.cpp:1101
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:97
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.
#define SCOPE_ED
const std::vector< std::string > items
void play_music_once(const std::string &file)
Definition: sound.cpp:602
The editor_controller class contains the mouse and keyboard event handling routines for the editor...
bool draw_terrain_codes()
Definition: editor.cpp:36
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.
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()
Definition: picture.cpp:225
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:804
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.
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.
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:100
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.
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.
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:785
virtual bool has_context_menu() const
bool on_board_with_border(const map_location &loc) const
Definition: map.cpp:382
void remove_side()
removes the last side from the scenario
Definition: map_context.hpp:98
Implements a quit confirmation dialog.
filter_context * filter_con
Definition: resources.cpp:23
bool valid() const
Definition: location.hpp:93
void set_draw_coordinates(bool value)
Setter for the x,y debug overlay on tiles.
Definition: display.hpp:355
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:182
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:44
void create_buttons()
Definition: display.cpp:874
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:29
void perform_action(const editor_action &action)
Performs an action (thus modifying the map).
const char * what() const noexcept
Definition: exceptions.hpp:37
void invalidate_all()
Function to invalidate all tiles.
Definition: display.cpp:3011
Paint the same terrain on a number of locations on the map.
Definition: action.hpp:264
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:42
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:311
void recalculate_labels()
Definition: label.cpp:244
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:933
bool everything_selected() const
Definition: editor_map.cpp:209
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:1620
u64 size
Definition: statement.cpp:80
Game configuration data as global variables.
Definition: build_info.cpp:55
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:124
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.
std::string name
Definition: sdl_ttf.cpp:70
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:215
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)
DIRECTION
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:44
void display_redraw_callback(display &)
Callback function passed to display to be called on each redraw_everything run.
std::vector< sound::music_track > music_tracks_
#define N_(String)
Definition: gettext.hpp:108
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:71
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:504
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:35
const game_config_view & game_config_
bool minimap_draw_terrain()
Definition: general.cpp:814
virtual const editor_map & map() const override
Const map accessor.
static void display(const game_config_view &game_cfg, const preferences::PREFERENCE_VIEW initial_view=preferences::VIEW_DEFAULT)
The display function – see modal_dialog for more information.
void set_draw_terrain_codes(bool value)
Definition: editor.cpp:40
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.
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:99
const std::set< map_location > & get_area_by_index(int index) const
void set_draw_num_of_bitmaps(bool value)
Definition: editor.cpp:56
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
int get_current_area_time(int index) const
void set_draw_hex_coordinates(bool value)
Definition: editor.cpp:48
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:68
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:24
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:784