The Battle for Wesnoth  1.17.0-dev
editor_controller.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2021
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 
58 #include <functional>
59 
60 namespace {
61 static std::vector<std::string> saved_windows_;
62 }
63 
64 namespace editor {
65 
67  : controller_base()
68  , mouse_handler_base()
69  , quit_confirmation(std::bind(&editor_controller::quit_confirm, this))
70  , active_menu_(editor::MAP)
71  , reports_(new reports())
72  , gui_(new editor_display(*this, *reports_, controller_base::get_theme(game_config_, "editor")))
73  , tods_()
74  , context_manager_(new context_manager(*gui_.get(), game_config_))
75  , toolkit_(nullptr)
76  , tooltip_manager_()
77  , floating_label_manager_(nullptr)
78  , help_manager_(nullptr)
79  , do_quit_(false)
80  , quit_mode_(EXIT_ERROR)
81  , music_tracks_()
82 {
83  init_gui();
84  toolkit_.reset(new editor_toolkit(*gui_.get(), key_, game_config_, *context_manager_.get()));
85  help_manager_.reset(new help::help_manager(&game_config_));
86  context_manager_->locs_ = toolkit_->get_palette_manager()->location_palette_.get();
87  context_manager_->switch_context(0, true);
88  init_tods(game_config_);
89  init_music(game_config_);
92 
93  gui().create_buttons();
95 }
96 
98 {
99  gui_->change_display_context(&get_current_map_context());
101  gui_->add_redraw_observer(std::bind(&editor_controller::display_redraw_callback, this, std::placeholders::_1));
106 // halo_manager_.reset(new halo::manager(*gui_));
107 // resources::halo = halo_manager_.get();
108 // ^ These lines no longer necessary, the gui owns its halo manager.
109 // TODO: Should the editor map contexts actually own the halo manager and swap them in and out from the gui?
110 // 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
111 // without deleting it.
112 }
113 
115 {
116  for (const config &schedule : game_config.child_range("editor_times")) {
117 
118  const std::string& schedule_id = schedule["id"];
119  const std::string& schedule_name = schedule["name"];
120  if (schedule_id.empty()) {
121  ERR_ED << "Missing ID attribute in a TOD Schedule." << std::endl;
122  continue;
123  }
124 
125  tods_map::iterator times = tods_.find(schedule_id);
126  if (times == tods_.end()) {
127  std::pair<tods_map::iterator, bool> new_times =
128  tods_.emplace(schedule_id, std::pair(schedule_name, std::vector<time_of_day>()));
129 
130  times = new_times.first;
131  } else {
132  ERR_ED << "Duplicate TOD Schedule identifiers." << std::endl;
133  continue;
134  }
135 
136  for (const config &time : schedule.child_range("time")) {
137  times->second.second.emplace_back(time);
138  }
139 
140  }
141 
142  if (tods_.empty()) {
143  ERR_ED << "No editor time-of-day defined" << std::endl;
144  }
145 }
146 
148 {
149  const std::string tag_name = "editor_music";
150  if (game_config.child_range(tag_name).size() == 0) {
151  ERR_ED << "No editor music defined" << std::endl;
152  }
153  else {
154  for (const config& editor_music : game_config.child_range(tag_name)) {
155  for (const config& music : editor_music.child_range("music")) {
156  sound::music_track track(music);
157  if (track.file_path().empty())
158  WRN_ED << "Music track " << track.id() << " not found." << std::endl;
159  else
160  music_tracks_.emplace_back(music);
161  }
162  }
163  }
164 }
165 
167 {
168  resources::tod_manager = nullptr;
169  resources::filter_con = nullptr;
170 
171  resources::classification = nullptr;
172 }
173 
175 {
176  try {
177  while (!do_quit_) {
178  play_slice();
179  }
180  } catch (const editor_exception& e) {
181  gui2::show_transient_message(_("Fatal error"), e.what());
182  return EXIT_ERROR;
183  } catch (const wml_exception& e) {
184  e.show();
185  }
186  return quit_mode_;
187 }
188 
190 }
191 
192 void editor_controller::do_screenshot(const std::string& screenshot_filename /* = "map_screenshot.png" */)
193 {
194  try {
195  surface screenshot = gui().screenshot(true);
196  if(!screenshot || image::save_image(screenshot, screenshot_filename) != image::save_result::success) {
197  ERR_ED << "Screenshot creation failed!\n";
198  }
199  } catch (const wml_exception& e) {
200  e.show();
201  }
202 }
203 
205 {
206  std::string modified;
207  std::size_t amount = context_manager_->modified_maps(modified);
208 
209  std::string message;
210  if (amount == 0) {
211  message = _("Do you really want to quit?");
212  } else if (amount == 1 && get_current_map_context().modified()) {
213  message = _("Do you really want to quit? Changes to this map since the last save will be lost.");
214  } else {
215  message = _("Do you really want to quit? The following maps were modified and all changes since the last save will be lost:");
216  message += "\n" + modified;
217  }
218  return quit_confirmation::show_prompt(message);
219 }
220 
222 {
223  if (tods_.empty()) {
224  gui2::show_error_message(_("No editor time-of-day found."));
225  return;
226  }
227 
229 
230  if(gui2::dialogs::custom_tod::execute(manager.times(), manager.get_current_time())) {
231  // TODO save the new tod here
232  }
233 
234  gui_->update_tod();
235 
236  context_manager_->refresh_all();
237 }
238 
240 {
241  using namespace hotkey; //reduce hotkey:: clutter
242  switch (cmd.id) {
243  case HOTKEY_NULL:
244  if (index >= 0) {
245  unsigned i = static_cast<unsigned>(index);
246 
247  switch (active_menu_) {
248  case editor::MAP:
249  if (i < context_manager_->open_maps()) {
250  return true;
251  }
252  return false;
253  case editor::LOAD_MRU:
254  case editor::PALETTE:
255  case editor::AREA:
256  case editor::SIDE:
257  case editor::TIME:
258  case editor::SCHEDULE:
260  case editor::MUSIC:
261  case editor::LOCAL_TIME:
262  case editor::UNIT_FACING:
263  return true;
264  }
265  }
266  return false;
268  return true;
270  return toolkit_->get_palette_manager()->can_scroll_up();
272  return toolkit_->get_palette_manager()->can_scroll_down();
273  case HOTKEY_ZOOM_IN:
274  return !gui_->zoom_at_max();
275  case HOTKEY_ZOOM_OUT:
276  return !gui_->zoom_at_min();
277  case HOTKEY_ZOOM_DEFAULT:
278  case HOTKEY_FULLSCREEN:
279  case HOTKEY_SCREENSHOT:
281  case HOTKEY_TOGGLE_GRID:
282  case HOTKEY_MOUSE_SCROLL:
283  case HOTKEY_ANIMATE_MAP:
284  case HOTKEY_MUTE:
285  case HOTKEY_PREFERENCES:
286  case HOTKEY_HELP:
287  case HOTKEY_QUIT_GAME:
288  case HOTKEY_SCROLL_UP:
289  case HOTKEY_SCROLL_DOWN:
290  case HOTKEY_SCROLL_LEFT:
291  case HOTKEY_SCROLL_RIGHT:
292  return true; //general hotkeys we can always do
293 
295  return !get_current_map_context().units().empty();
296 
297  case HOTKEY_STATUS_TABLE:
298  return !get_current_map_context().teams().empty();
299 
301  return gui().mouseover_hex().valid();
302 
303  // unit tool related
304  case HOTKEY_DELETE_UNIT:
305  case HOTKEY_RENAME_UNIT:
312  {
313  map_location loc = gui_->mouseover_hex();
314  const unit_map& units = get_current_map_context().units();
315  return (toolkit_->is_mouse_action_set(HOTKEY_EDITOR_TOOL_UNIT) &&
316  units.find(loc) != units.end());
317  }
318  case HOTKEY_UNDO:
320  case HOTKEY_REDO:
332  return true;
333 
337 
340  return !get_current_map_context().teams().empty();
341 
342  // brushes
350 
352  return true;
354  return toolkit_->get_palette_manager()->active_palette().supports_swap();
358  {
359  std::string dummy;
360  return context_manager_->modified_maps(dummy) > 1;
361  }
367  return true;
369  return !get_current_map_context().get_filename().empty()
371 
372  // Tools
373  // Pure map editing tools this can be used all the time.
378  return true;
379  // WWL dependent tools which don't rely on defined sides.
386  return !get_current_map_context().teams().empty();
387 
391  return !get_current_map_context().is_pure_map() &&
393 
395  return !get_current_map_context().is_pure_map() &&
397  && !get_current_map_context().map().selection().empty();
398 
403  return !get_current_map_context().map().selection().empty()
404  && !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
406  return (get_current_map_context().map().selection().size() > 1
407  && !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE));
411  return !context_manager_->clipboard_empty();
416  return !context_manager_->clipboard_empty()
417  && toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
420  return !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
422  return !get_current_map_context().map().selection().empty()
424  && !toolkit_->is_mouse_action_set(HOTKEY_EDITOR_CLIPBOARD_PASTE);
441  return true;
445  return true;
446  default:
447  return false;
448  }
449 }
450 
452  using namespace hotkey;
453  switch (command) {
454 
456  {
458  get_current_map_context().units().find(gui_->mouseover_hex());
459  return un->loyal() ? ACTION_ON : ACTION_OFF;
460 
461  }
463  {
465  get_current_map_context().units().find(gui_->mouseover_hex());
466  return un->can_recruit() ? ACTION_ON : ACTION_OFF;
467  }
469  {
471  get_current_map_context().units().find(gui_->mouseover_hex());
472  return (!un->unrenamable()) ? ACTION_ON : ACTION_OFF;
473  }
474  //TODO remove hardcoded hotkey names
476  return context_manager_->is_active_transitions_hotkey("editor-auto-update-transitions")
479  return context_manager_->is_active_transitions_hotkey("editor-partial-update-transitions")
482  return context_manager_->is_active_transitions_hotkey("editor-no-update-transitions")
485  return toolkit_->is_active_brush("brush-1") ? ACTION_ON : ACTION_OFF;
487  return toolkit_->is_active_brush("brush-2") ? ACTION_ON : ACTION_OFF;
489  return toolkit_->is_active_brush("brush-3") ? ACTION_ON : ACTION_OFF;
491  return toolkit_->is_active_brush("brush-nw-se") ? ACTION_ON : ACTION_OFF;
493  return toolkit_->is_active_brush("brush-sw-ne") ? ACTION_ON : ACTION_OFF;
494 
495  case HOTKEY_TOGGLE_GRID:
501  return get_current_map_context().map().selection().empty() ?
512  return toolkit_->is_mouse_action_set(command) ? ACTION_ON : ACTION_OFF;
514  return gui_->get_draw_coordinates() ? ACTION_ON : ACTION_OFF;
516  return gui_->get_draw_terrain_codes() ? ACTION_ON : ACTION_OFF;
518  return gui_->get_draw_num_of_bitmaps() ? ACTION_ON : ACTION_OFF;
519 
530  case HOTKEY_ZOOM_DEFAULT:
531  return (gui_->get_zoom_factor() == 1.0) ? hotkey::ACTION_ON : hotkey::ACTION_OFF;
532 
533  case HOTKEY_NULL:
534  switch (active_menu_) {
535  case editor::MAP:
536  return index == context_manager_->current_context_index()
538  case editor::LOAD_MRU:
539  return ACTION_STATELESS;
540  case editor::PALETTE:
541  return ACTION_STATELESS;
542  case editor::AREA:
543  return index == get_current_map_context().get_active_area()
545  case editor::SIDE:
546  return static_cast<std::size_t>(index) == gui_->playing_team()
548  case editor::TIME:
551  case editor::LOCAL_TIME:
553  get_current_map_context().get_active_area())
555  case editor::MUSIC:
557  ? ACTION_ON : ACTION_OFF;
558  case editor::SCHEDULE:
559  {
560  tods_map::const_iterator it = tods_.begin();
561  std::advance(it, index);
562  const std::vector<time_of_day>& times1 = it->second.second;
563  const std::vector<time_of_day>& times2 = get_current_map_context().get_time_manager()->times();
564  return (times1 == times2) ? ACTION_SELECTED : ACTION_DESELECTED;
565  }
567  {
568  tods_map::const_iterator it = tods_.begin();
569  std::advance(it, index);
570  const std::vector<time_of_day>& times1 = it->second.second;
571  int active_area = get_current_map_context().get_active_area();
572  const std::vector<time_of_day>& times2 = get_current_map_context().get_time_manager()->times(active_area);
573  return (times1 == times2) ? ACTION_SELECTED : ACTION_DESELECTED;
574  }
575  case editor::UNIT_FACING:
576  {
578  assert(un != get_current_map_context().units().end());
579  return un->facing() == index ? ACTION_SELECTED : ACTION_DESELECTED;
580  }
581  }
582  return ACTION_ON;
583  default:
584  return command_executor::get_action_state(command, index);
585  }
586 }
587 
588 bool editor_controller::do_execute_command(const hotkey::hotkey_command& cmd, int index, bool press, bool release)
589 {
590  hotkey::HOTKEY_COMMAND command = cmd.id;
591  SCOPE_ED;
592  using namespace hotkey;
593 
594  // nothing here handles release; fall through to base implementation
595  if (!press) {
596  return hotkey::command_executor::do_execute_command(cmd, index, press, release);
597  }
598 
599  switch (command) {
600  case HOTKEY_NULL:
601  switch (active_menu_) {
602  case MAP:
603  if (index >= 0) {
604  unsigned i = static_cast<unsigned>(index);
605  if (i < context_manager_->size()) {
606  context_manager_->switch_context(index);
607  toolkit_->hotkey_set_mouse_action(HOTKEY_EDITOR_TOOL_PAINT);
608  return true;
609  }
610  }
611  return false;
612  case LOAD_MRU:
613  if (index >= 0) {
614  context_manager_->load_mru_item(static_cast<unsigned>(index));
615  }
616  return true;
617  case PALETTE:
618  toolkit_->get_palette_manager()->set_group(index);
619  return true;
620  case SIDE:
621  gui_->set_team(index, true);
622  gui_->set_playing_team(index);
623  toolkit_->get_palette_manager()->draw_contents();
624  return true;
625  case AREA:
626  {
628  const std::set<map_location>& area =
630  std::vector<map_location> locs(area.begin(), area.end());
632  gui_->scroll_to_tiles(locs.begin(), locs.end());
633  return true;
634  }
635  case TIME:
636  {
638  gui_->update_tod();
639  return true;
640  }
641  case LOCAL_TIME:
642  {
644  return true;
645  }
646  case MUSIC:
647  {
648  //TODO mark the map as changed
651  std::vector<config> items;
652  items.emplace_back("id", "editor-playlist");
653  std::shared_ptr<gui::button> b = gui_->find_menu_button("menu-playlist");
654  show_menu(items, b->location().x +1, b->location().y + b->height() +1, false, *gui_);
655  return true;
656  }
657  case SCHEDULE:
658  {
659  tods_map::iterator iter = tods_.begin();
660  std::advance(iter, index);
661  get_current_map_context().replace_schedule(iter->second.second);
662  // TODO: test again after the assign-schedule menu is fixed. Should work, though.
663  gui_->update_tod();
664  return true;
665  }
666  case LOCAL_SCHEDULE:
667  {
668  tods_map::iterator iter = tods_.begin();
669  std::advance(iter, index);
670  get_current_map_context().replace_local_schedule(iter->second.second);
671  return true;
672  }
673  case UNIT_FACING:
674  {
676  assert(un != get_current_map_context().units().end());
677  un->set_facing(map_location::DIRECTION(index));
678  un->anim_comp().set_standing();
679  return true;
680  }
681  }
682  return true;
683 
684  //Zoom
685  case HOTKEY_ZOOM_IN:
686  gui_->set_zoom(true);
688  toolkit_->set_mouseover_overlay(*gui_);
689  return true;
690  case HOTKEY_ZOOM_OUT:
691  gui_->set_zoom(false);
693  toolkit_->set_mouseover_overlay(*gui_);
694  return true;
695  case HOTKEY_ZOOM_DEFAULT:
696  gui_->toggle_default_zoom();
698  toolkit_->set_mouseover_overlay(*gui_);
699  return true;
700 
701  //Palette
703  {
704  //TODO this code waits for the gui2 dialog to get ready
705 // std::vector< std::pair< std::string, std::string >> blah_items;
706 // toolkit_->get_palette_manager()->active_palette().expand_palette_groups_menu(blah_items);
707 // int selected = 1; //toolkit_->get_palette_manager()->active_palette().get_selected;
708 // gui2::teditor_select_palette_group::execute(selected, blah_items, gui_->video());
709  }
710  return true;
712  toolkit_->get_palette_manager()->scroll_up();
713  return true;
715  toolkit_->get_palette_manager()->scroll_down();
716  return true;
717 
718  case HOTKEY_QUIT_GAME:
720  do_quit_ = true;
722  }
723  return true;
726  return true;
728  context_manager_->save_all_maps(true);
729  do_quit_ = true;
731  return true;
734  return true;
736  toolkit_->get_palette_manager()->active_palette().swap();
737  return true;
739  if (dynamic_cast<const editor_action_chain*>(get_current_map_context().last_undo_action()) != nullptr) {
741  context_manager_->refresh_after_action();
742  } else {
743  undo();
744  }
745  return true;
746 
747  //Tool Selection
756  toolkit_->hotkey_set_mouse_action(command);
757  return true;
758 
760  add_area();
761  return true;
762 
764  change_unit_id();
765  return true;
766 
767  return true;
769  {
770  map_location loc = gui_->mouseover_hex();
772  bool unrenamable = un->unrenamable();
773  un->set_unrenamable(!unrenamable);
774  }
775  return true;
777  {
778  map_location loc = gui_->mouseover_hex();
780  bool canrecruit = un->can_recruit();
781  un->set_can_recruit(!canrecruit);
782  un->anim_comp().set_standing();
783  }
784  return true;
785  case HOTKEY_DELETE_UNIT:
786  {
787  map_location loc = gui_->mouseover_hex();
788  perform_delete(std::make_unique<editor_action_unit_delete>(loc));
789  }
790  return true;
791  case HOTKEY_EDITOR_CLIPBOARD_PASTE: //paste is somewhat different as it might be "one action then revert to previous mode"
792  toolkit_->hotkey_set_mouse_action(command);
793  return true;
794 
795  //Clipboard
797  context_manager_->get_clipboard().rotate_60_cw();
798  toolkit_->update_mouse_action_highlights();
799  return true;
801  context_manager_->get_clipboard().rotate_60_ccw();
802  toolkit_->update_mouse_action_highlights();
803  return true;
805  context_manager_->get_clipboard().flip_horizontal();
806  toolkit_->update_mouse_action_highlights();
807  return true;
809  context_manager_->get_clipboard().flip_vertical();
810  toolkit_->update_mouse_action_highlights();
811  return true;
812 
813  //Brushes
815  toolkit_->cycle_brush();
816  return true;
818  toolkit_->set_brush("brush-1");
819  return true;
821  toolkit_->set_brush("brush-2");
822  return true;
824  toolkit_->set_brush("brush-3");
825  return true;
827  toolkit_->set_brush("brush-nw-se");
828  return true;
830  toolkit_->set_brush("brush-sw-ne");
831  return true;
832 
834  copy_selection();
835  return true;
837  cut_selection();
838  return true;
840  context_manager_->rename_area_dialog();
841  return true;
843  save_area();
844  return true;
847  return true;
849  if(!get_current_map_context().map().everything_selected()) {
850  context_manager_->perform_refresh(editor_action_select_all());
851  return true;
852  }
853  [[fallthrough]];
856  return true;
858  context_manager_->perform_refresh(editor_action_select_none());
859  return true;
861  context_manager_->fill_selection();
862  return true;
865  get_current_map_context().map().selection()));
866  return true;
867 
869  context_manager_->edit_scenario_dialog();
870  return true;
871 
874  get_current_map_context().get_active_area());
875  return true;
876 
877  // map specific
879  context_manager_->close_current_context();
880  // Copy behaviour from when switching windows to always reset the active tool to the Paint Tool
881  // This avoids the situation of having a scenario-specific tool active in a map context which can cause a crash if used
882  // Not elegant but at least avoids a potential crash and is consistent with existing behaviour
883  toolkit_->hotkey_set_mouse_action(HOTKEY_EDITOR_TOOL_PAINT);
884  return true;
886  context_manager_->load_map_dialog();
887  return true;
889  context_manager_->revert_map();
890  return true;
892  context_manager_->new_map_dialog();
893  return true;
895  context_manager_->new_scenario_dialog();
896  return true;
898  save_map();
899  return true;
901  context_manager_->save_all_maps();
902  return true;
904  context_manager_->save_map_as_dialog();
905  return true;
907  context_manager_->save_scenario_as_dialog();
908  return true;
910  context_manager_->generate_map_dialog();
911  return true;
913  context_manager_->apply_mask_dialog();
914  return true;
916  context_manager_->create_mask_to_dialog();
917  return true;
919  context_manager_->resize_map_dialog();
920  return true;
921 
922  // Side specific ones
924  if(get_current_map_context().teams().size() >= 9) {
925  size_t new_side_num = get_current_map_context().teams().size() + 1;
926  toolkit_->get_palette_manager()->location_palette_->add_item(std::to_string(new_side_num));
927  }
929  gui_->init_flags();
930  return true;
932  gui_->set_team(0, true);
933  gui_->set_playing_team(0);
935  return true;
937  context_manager_->edit_side_dialog(gui_->viewing_team());
938  return true;
939 
940  // Transitions
942  context_manager_->set_update_transitions_mode(2);
943  return true;
945  context_manager_->set_update_transitions_mode(1);
946  return true;
948  context_manager_->set_update_transitions_mode(0);
949  return true;
951  if(context_manager_->toggle_update_transitions()) {
952  return true;
953  }
954  [[fallthrough]];
956  context_manager_->refresh_all();
957  return true;
958  // Refresh
960  context_manager_->reload_map();
961  return true;
964  return true;
965 
967  gui().set_draw_coordinates(!gui().get_draw_coordinates());
968  preferences::editor::set_draw_hex_coordinates(gui().get_draw_coordinates());
969  gui().invalidate_all();
970  return true;
972  gui().set_draw_terrain_codes(!gui().get_draw_terrain_codes());
973  preferences::editor::set_draw_terrain_codes(gui().get_draw_terrain_codes());
974  gui().invalidate_all();
975  return true;
977  gui().set_draw_num_of_bitmaps(!gui().get_draw_num_of_bitmaps());
978  preferences::editor::set_draw_num_of_bitmaps(gui().get_draw_num_of_bitmaps());
979  gui().invalidate_all();
980  return true;
982  location_palette* lp = dynamic_cast<location_palette*>(&toolkit_->get_palette_manager()->active_palette());
983  if (lp) {
984  perform_delete(std::make_unique<editor_action_starting_position>(map_location(), lp->selected_item()));
985  // No idea if this is the right thing to call, but it ensures starting
986  // position labels get removed on delete.
987  context_manager_->refresh_after_action();
988  }
989  return true;
990  }
991  default:
992  return hotkey::command_executor::do_execute_command(cmd, index, press, release);
993  }
994 }
995 
997 {
998  help::show_help("..editor");
999 }
1000 
1001 void editor_controller::show_menu(const std::vector<config>& items_arg, int xloc, int yloc, bool context_menu, display& disp)
1002 {
1003  if(context_menu) {
1004  if(!get_current_map_context().map().on_board_with_border(gui().hex_clicked_on(xloc, yloc))) {
1005  return;
1006  }
1007  }
1008 
1009  std::vector<config> items;
1010  for(const auto& c : items_arg) {
1011  const std::string& id = c["id"];
1013 
1014  if((can_execute_command(command) && (!context_menu || in_context_menu(command.id)))
1015  || command.id == hotkey::HOTKEY_NULL)
1016  {
1017  items.emplace_back("id", id);
1018  }
1019  }
1020 
1021  // No point in showing an empty menu.
1022  if(items.empty()) {
1023  return;
1024  }
1025 
1026  // Based on the ID of the first entry, we fill the menu contextually.
1027  const std::string& first_id = items.front()["id"];
1028 
1029  if(first_id == "EDITOR-LOAD-MRU-PLACEHOLDER") {
1031  context_manager_->expand_load_mru_menu(items, 0);
1032  }
1033 
1034  if(first_id == "editor-switch-map") {
1036  context_manager_->expand_open_maps_menu(items, 0);
1037  }
1038 
1039  if(first_id == "editor-palette-groups") {
1041  toolkit_->get_palette_manager()->active_palette().expand_palette_groups_menu(items, 0);
1042  }
1043 
1044  if(first_id == "editor-switch-side") {
1046  context_manager_->expand_sides_menu(items, 0);
1047  }
1048 
1049  if(first_id == "editor-switch-area") {
1051  context_manager_->expand_areas_menu(items, 0);
1052  }
1053 
1054  if(!items.empty() && items.front()["id"] == "editor-switch-time") {
1056  context_manager_->expand_time_menu(items, 0);
1057  }
1058 
1059  if(first_id == "editor-assign-local-time") {
1061  context_manager_->expand_local_time_menu(items, 0);
1062  }
1063 
1064  if(first_id == "menu-unit-facings") {
1066  auto pos = items.erase(items.begin());
1067  int dir = 0;
1068  std::generate_n(std::inserter<std::vector<config>>(items, pos), static_cast<int>(map_location::NDIRECTIONS), [&dir]() -> config {
1070  });
1071  }
1072 
1073  if(first_id == "editor-playlist") {
1075  auto pos = items.erase(items.begin());
1076  std::transform(music_tracks_.begin(), music_tracks_.end(), std::inserter<std::vector<config>>(items, pos), [](const sound::music_track& track) -> config {
1077  return config {"label", track.title().empty() ? track.id() : track.title()};
1078  });
1079  }
1080 
1081  if(first_id == "editor-assign-schedule") {
1083  auto pos = items.erase(items.begin());
1084  std::transform(tods_.begin(), tods_.end(), std::inserter<std::vector<config>>(items, pos), [](const tods_map::value_type& tod) -> config {
1085  return config {"label", tod.second.first};
1086  });
1087  }
1088 
1089  if(first_id == "editor-assign-local-schedule") {
1091  auto pos = items.erase(items.begin());
1092  std::transform(tods_.begin(), tods_.end(), std::inserter<std::vector<config>>(items, pos), [](const tods_map::value_type& tod) -> config {
1093  return config {"label", tod.second.first};
1094  });
1095  }
1096 
1097  command_executor::show_menu(items, xloc, yloc, context_menu, disp);
1098 }
1099 
1101 {
1102  gui_->video().clear_all_help_strings();
1103  gui2::dialogs::preferences_dialog::display();
1104 
1105  gui_->redraw_everything();
1106 }
1107 
1109 {
1111  gui_->invalidate_all();
1112 }
1113 
1115 {
1116  map_location loc = gui_->mouseover_hex();
1117  const unit_map & units = get_current_map_context().units();
1118  const unit_map::const_unit_iterator un = units.find(loc);
1119  if(un != units.end()) {
1120  help::show_unit_help(un->type_id(), un->type().show_variations_in_help(), false);
1121  } else {
1122  help::show_help("..units");
1123  }
1124 }
1125 
1126 
1128 {
1129  if (!get_current_map_context().map().selection().empty()) {
1130  context_manager_->get_clipboard() = map_fragment(get_current_map_context().map(), get_current_map_context().map().selection());
1131  context_manager_->get_clipboard().center_by_mass();
1132  }
1133 }
1134 
1136 {
1137  map_location loc = gui_->mouseover_hex();
1138  unit_map& units = get_current_map_context().units();
1139  const unit_map::unit_iterator& un = units.find(loc);
1140 
1141  const std::string title(N_("Change Unit ID"));
1142  const std::string label(N_("ID:"));
1143 
1144  if(un != units.end()) {
1145  std::string id = un->id();
1146  if (gui2::dialogs::edit_text::execute(title, label, id)) {
1147  un->set_id(id);
1148  }
1149  }
1150 }
1151 
1153 {
1154  map_location loc = gui_->mouseover_hex();
1155  unit_map& units = get_current_map_context().units();
1156  const unit_map::unit_iterator& un = units.find(loc);
1157 
1158  const std::string title(N_("Rename Unit"));
1159  const std::string label(N_("Name:"));
1160 
1161  if(un != units.end()) {
1162  std::string name = un->name();
1163  if(gui2::dialogs::edit_text::execute(title, label, name)) {
1164  //TODO we may not want a translated name here.
1165  un->set_name(name);
1166  }
1167  }
1168 }
1169 
1171 {
1173 }
1174 
1176 {
1177  copy_selection();
1179 }
1180 
1182 {
1183  const std::set<map_location>& area = get_current_map_context().map().selection();
1185 }
1186 
1188 {
1189  const std::set<map_location>& area = get_current_map_context().map().selection();
1191 }
1192 
1194 {
1195  std::stringstream ssx, ssy;
1196  std::set<map_location>::const_iterator i = get_current_map_context().map().selection().begin();
1197  if (i != get_current_map_context().map().selection().end()) {
1198  ssx << "x = " << i->wml_x();
1199  ssy << "y = " << i->wml_y();
1200  ++i;
1201  while (i != get_current_map_context().map().selection().end()) {
1202  ssx << ", " << i->wml_x();
1203  ssy << ", " << i->wml_y();
1204  ++i;
1205  }
1206  ssx << "\n" << ssy.str() << "\n";
1207  desktop::clipboard::copy_to_clipboard(ssx.str(), false);
1208  }
1209 }
1210 
1211 void editor_controller::perform_delete(std::unique_ptr<editor_action> action)
1212 {
1213  if (action) {
1215  }
1216 }
1217 
1218 void editor_controller::perform_refresh_delete(std::unique_ptr<editor_action> action, bool drag_part /* =false */)
1219 {
1220  if (action) {
1221  context_manager_->perform_refresh(*action, drag_part);
1222  }
1223 }
1224 
1226 {
1228  context_manager_->refresh_all();
1229 }
1230 
1232 {
1233  set_button_state();
1234  toolkit_->adjust_size();
1235  toolkit_->get_palette_manager()->draw_contents();
1237 }
1238 
1240 {
1242  context_manager_->refresh_after_action();
1243 }
1244 
1246 {
1248  context_manager_->refresh_after_action();
1249 }
1250 
1251 void editor_controller::mouse_motion(int x, int y, const bool /*browse*/,
1252  bool update, map_location /*new_loc*/)
1253 {
1254  if (mouse_handler_base::mouse_motion_default(x, y, update)) return;
1255  map_location hex_clicked = gui().hex_clicked_on(x, y);
1256  if (get_current_map_context().map().on_board_with_border(drag_from_hex_) && is_dragging()) {
1257  std::unique_ptr<editor_action> a;
1258  bool partial = false;
1259  // last_undo is a non-owning pointer. Although it could have other uses, it seems to be
1260  // mainly (only?) used for printing debugging information.
1261  auto last_undo = get_current_map_context().last_undo_action();
1262  if (dragging_left_ && (SDL_GetMouseState(nullptr, nullptr) & SDL_BUTTON(1)) != 0) {
1263  if (!get_current_map_context().map().on_board_with_border(hex_clicked)) return;
1264  a = get_mouse_action().drag_left(*gui_, x, y, partial, last_undo);
1265  } else if (dragging_right_ && (SDL_GetMouseState(nullptr, nullptr) & SDL_BUTTON(3)) != 0) {
1266  if (!get_current_map_context().map().on_board_with_border(hex_clicked)) return;
1267  a = get_mouse_action().drag_right(*gui_, x, y, partial, last_undo);
1268  }
1269  //Partial means that the mouse action has modified the
1270  //last undo action and the controller shouldn't add
1271  //anything to the undo stack (hence a different perform_ call)
1272  if (a != nullptr) {
1273  if (partial) {
1275  } else {
1277  }
1278  context_manager_->refresh_after_action(true);
1279  }
1280  } else {
1281  get_mouse_action().move(*gui_, hex_clicked);
1282  }
1283  gui().highlight_hex(hex_clicked);
1284 }
1285 
1286 void editor_controller::touch_motion(int /* x */, int /* y */, const bool /* browse */, bool /* update */, map_location /* new_loc */)
1287 {
1288  // Not implemented at all. Sorry, it's a very low priority for iOS port.
1289 }
1290 
1292 {
1293  return get_current_map_context().map().on_board_with_border(gui().hex_clicked_on(x,y));
1294 }
1295 
1296 bool editor_controller::right_click_show_menu(int /*x*/, int /*y*/, const bool /*browse*/)
1297 {
1299 }
1300 
1301 bool editor_controller::left_click(int x, int y, const bool browse)
1302 {
1303  toolkit_->clear_mouseover_overlay();
1304  if (mouse_handler_base::left_click(x, y, browse))
1305  return true;
1306 
1307  LOG_ED << "Left click, after generic handling\n";
1308  map_location hex_clicked = gui().hex_clicked_on(x, y);
1309  if (!get_current_map_context().map().on_board_with_border(hex_clicked))
1310  return true;
1311 
1312  LOG_ED << "Left click action " << hex_clicked << "\n";
1313  auto a = get_mouse_action().click_left(*gui_, x, y);
1314  if(a) {
1315  perform_refresh_delete(std::move(a), true);
1316  set_button_state();
1317  }
1318 
1319  return false;
1320 }
1321 
1322 void editor_controller::left_drag_end(int x, int y, const bool /*browse*/)
1323 {
1324  auto a = get_mouse_action().drag_end_left(*gui_, x, y);
1325  perform_delete(std::move(a));
1326 }
1327 
1328 void editor_controller::left_mouse_up(int x, int y, const bool /*browse*/)
1329 {
1330  auto a = get_mouse_action().up_left(*gui_, x, y);
1331  if(a) {
1332  perform_delete(std::move(a));
1333  set_button_state();
1334  }
1335  toolkit_->set_mouseover_overlay();
1336  context_manager_->refresh_after_action();
1337 }
1338 
1339 bool editor_controller::right_click(int x, int y, const bool browse)
1340 {
1341  toolkit_->clear_mouseover_overlay();
1342  if (mouse_handler_base::right_click(x, y, browse)) return true;
1343  LOG_ED << "Right click, after generic handling\n";
1344  map_location hex_clicked = gui().hex_clicked_on(x, y);
1345  if (!get_current_map_context().map().on_board_with_border(hex_clicked)) return true;
1346  LOG_ED << "Right click action " << hex_clicked << "\n";
1347  auto a = get_mouse_action().click_right(*gui_, x, y);
1348  if(a) {
1349  perform_refresh_delete(std::move(a), true);
1350  set_button_state();
1351  }
1352  return false;
1353 }
1354 
1355 void editor_controller::right_drag_end(int x, int y, const bool /*browse*/)
1356 {
1357  auto a = get_mouse_action().drag_end_right(*gui_, x, y);
1358  perform_delete(std::move(a));
1359 }
1360 
1361 void editor_controller::right_mouse_up(int x, int y, const bool browse)
1362 {
1363  // Call base method to handle context menus.
1364  mouse_handler_base::right_mouse_up(x, y, browse);
1365 
1366  auto a = get_mouse_action().up_right(*gui_, x, y);
1367  if(a) {
1368  perform_delete(std::move(a));
1369  set_button_state();
1370  }
1371  toolkit_->set_mouseover_overlay();
1372  context_manager_->refresh_after_action();
1373 }
1374 
1376 {
1377  const map_location& loc = gui().mouseover_hex();
1378  if (get_current_map_context().map().on_board(loc) == false)
1379  return;
1380 
1383 }
1384 
1385 void editor_controller::process_keyup_event(const SDL_Event& event)
1386 {
1387  auto a = get_mouse_action().key_event(gui(), event);
1388  perform_refresh_delete(std::move(a));
1389  toolkit_->set_mouseover_overlay();
1390 }
1391 
1393  return this;
1394 }
1395 
1397 {
1399 }
1400 
1402 {
1404 }
1405 
1407 {
1409 }
1410 
1412 {
1414 }
1415 
1417 {
1418  return toolkit_->get_palette_manager()->active_palette().action_pressed();
1419 }
1420 
1421 } //end namespace editor
virtual bool in_context_menu(hotkey::HOTKEY_COMMAND command) const
const map_location & mouseover_hex() const
Definition: display.hpp:290
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: display.cpp:71
void set_scroll_up(bool on)
void set_preference_display_settings()
Definition: display.cpp:45
::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_draw_num_of_bitmaps(bool value)
Setter for the terrain code debug overlay on tiles.
Definition: display.hpp:370
void set_scroll_down(bool on)
unit_iterator end()
Definition: map.hpp:429
bool minimap_draw_units()
Definition: general.cpp:825
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_
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:365
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.
int dummy
Definition: lstrlib.cpp:1347
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:599
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
bool minimap_movement_coding()
Definition: general.cpp:805
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:198
bool right_click_show_menu(int x, int y, const bool browse) override
Called in the default right_click when the context menu is about to be shown, can be used for preproc...
void set_active_area(int index)
void show_transient_message(const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup, const bool restore_background)
Shows a transient message to the user.
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:2419
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:1081
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.
#define SCOPE_ED
const std::vector< std::string > items
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.
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:222
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:835
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.
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:790
virtual bool has_context_menu() const
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:24
bool valid() const
Definition: location.hpp:89
bool on_board_with_border(const map_location &loc) const
Definition: map.cpp:390
void set_draw_coordinates(bool value)
Setter for the x,y debug overlay on tiles.
Definition: display.hpp:360
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 create_buttons()
Definition: display.cpp:879
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:3019
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:310
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:967
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:1628
Game configuration data as global variables.
Definition: build_info.cpp:59
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:41
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)
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 each redraw_everything run.
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:535
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
const game_config_view & game_config_
bool minimap_draw_terrain()
Definition: general.cpp:845
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.
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:206
#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:61
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:815