editor/editor_controller.cpp

Go to the documentation of this file.
00001 /* $Id: editor_controller.cpp 53848 2012-04-08 07:37:17Z mordante $ */
00002 /*
00003    Copyright (C) 2008 - 2012 by Tomasz Sniatowski <kailoran@gmail.com>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 #define GETTEXT_DOMAIN "wesnoth-editor"
00016 
00017 #include "editor/map/context_manager.hpp"
00018 
00019 #include "asserts.hpp"
00020 #include "editor/action/action.hpp"
00021 #include "editor_controller.hpp"
00022 
00023 #include "editor/palette/terrain_palettes.hpp"
00024 
00025 #include "editor/action/mouse/mouse_action.hpp"
00026 
00027 #include "editor_preferences.hpp"
00028 
00029 #include "gui/dialogs/editor_settings.hpp"
00030 #include "gui/dialogs/message.hpp"
00031 #include "gui/dialogs/transient_message.hpp"
00032 #include "gui/widgets/window.hpp"
00033 
00034 #include "../clipboard.hpp"
00035 #include "../foreach.hpp"
00036 #include "../game_preferences.hpp"
00037 #include "../gettext.hpp"
00038 #include "../preferences_display.hpp"
00039 #include "../rng.hpp"
00040 #include "../sound.hpp"
00041 
00042 #include "halo.hpp"
00043 
00044 #include <boost/bind.hpp>
00045 
00046 namespace {
00047 static std::vector<std::string> saved_windows_;
00048 }
00049 
00050 namespace editor {
00051 
00052 
00053 editor_controller::editor_controller(const config &game_config, CVideo& video)
00054     : controller_base(SDL_GetTicks(), game_config, video)
00055     , mouse_handler_base()
00056     , active_menu_(editor::MAP)
00057     , rng_(NULL)
00058     , rng_setter_(NULL)
00059     , units_()
00060     , gui_(new editor_display(NULL, video, NULL, NULL, get_theme(game_config, "editor"), config()))
00061     , teams_()
00062     , tods_()
00063     , context_manager_(new context_manager(*gui_.get(), game_config_))
00064     , toolkit_()
00065     , prefs_disp_manager_(NULL)
00066     , tooltip_manager_(video)
00067     , floating_label_manager_(NULL)
00068     , halo_manager_(NULL)
00069     , do_quit_(false)
00070     , quit_mode_(EXIT_ERROR)
00071 {
00072     init_gui();
00073     toolkit_.reset(new editor_toolkit(*gui_.get(), key_, game_config_));
00074     init_tods(game_config);
00075     init_music(game_config);
00076     rng_.reset(new rand_rng::rng());
00077     rng_setter_.reset(new rand_rng::set_random_generator(rng_.get()));
00078     hotkey::get_hotkey(hotkey::HOTKEY_QUIT_GAME).set_description(_("Quit Editor"));
00079     context_manager_->get_map_context().set_starting_position_labels(gui());
00080     cursor::set(cursor::NORMAL);
00081     image::set_color_adjustment(preferences::editor::tod_r(), preferences::editor::tod_g(), preferences::editor::tod_b());
00082 //  TODO enable if you can say what the purpose of the code is. I think it is old stuff and deserves to be removed.
00083 /*  theme& theme = gui().get_theme();
00084     const theme::menu* default_tool_menu = NULL;
00085     foreach (const theme::menu& m, theme.menus()) {
00086         if (m.get_id() == "draw_button_editor") {
00087             default_tool_menu = &m;
00088             break;
00089         }
00090     }*/
00091 
00092     gui().redraw_everything();
00093     events::raise_draw_event();
00094 /*  TODO enable if you can say what the purpose of the code is.
00095     if (default_tool_menu != NULL) {
00096         const SDL_Rect& menu_loc = default_tool_menu->location(get_display().screen_area());
00097         show_menu(default_tool_menu->items(),menu_loc.x+1,menu_loc.y + menu_loc.h + 1,false);
00098         return;
00099     }
00100 */
00101 }
00102 
00103 void editor_controller::init_gui()
00104 {
00105     gui_->change_map(&context_manager_->get_map());
00106     gui_->change_units(&context_manager_->get_map().get_units());
00107     gui_->change_teams(&context_manager_->get_map().get_teams());
00108     gui_->set_grid(preferences::grid());
00109     prefs_disp_manager_.reset(new preferences::display_manager(&gui()));
00110     gui_->add_redraw_observer(boost::bind(&editor_controller::display_redraw_callback, this, _1));
00111     floating_label_manager_.reset(new font::floating_label_context());
00112     gui().set_draw_coordinates(preferences::editor::draw_hex_coordinates());
00113     gui().set_draw_terrain_codes(preferences::editor::draw_terrain_codes());
00114     halo_manager_.reset(new halo::manager(*gui_));
00115 }
00116 
00117 void editor_controller::init_tods(const config& game_config)
00118 {
00119     const config &cfg = game_config.child("editor_times");
00120     if (!cfg) {
00121         ERR_ED << "No editor time-of-day defined\n";
00122         return;
00123     }
00124     foreach (const config &i, cfg.child_range("time")) {
00125         tods_.push_back(time_of_day(i));
00126     }
00127 }
00128 
00129 void editor_controller::init_music(const config& game_config)
00130 {
00131     const config &cfg = game_config.child("editor_music");
00132     if (!cfg) {
00133         ERR_ED << "No editor music defined\n";
00134         return;
00135     }
00136     foreach (const config &i, cfg.child_range("music")) {
00137         sound::play_music_config(i);
00138     }
00139     sound::commit_music_changes();
00140 }
00141 
00142 editor_controller::~editor_controller()
00143 {
00144     //TODO is not working like expected
00145 //  delete toolkit_.get();
00146 //  delete context_manager_.get();
00147 }
00148 
00149 EXIT_STATUS editor_controller::main_loop()
00150 {
00151     try {
00152         while (!do_quit_) {
00153             play_slice();
00154         }
00155     } catch (editor_exception& e) {
00156         gui2::show_transient_message(gui().video(), _("Fatal error"), e.what());
00157         return EXIT_ERROR;
00158     } catch (twml_exception& e) {
00159         e.show(gui());
00160     }
00161     return quit_mode_;
00162 }
00163 
00164 void editor_controller::do_screenshot(const std::string& screenshot_filename /* = "map_screenshot.bmp" */)
00165 {
00166     try {
00167         gui().screenshot(screenshot_filename,true);
00168     } catch (twml_exception& e) {
00169         e.show(gui());
00170     }
00171 }
00172 
00173 void editor_controller::quit_confirm(EXIT_STATUS mode)
00174 {
00175     std::string modified;
00176     size_t amount = context_manager_->modified_maps(modified);
00177 
00178     std::string message;
00179     if (amount == 0) {
00180         message = _("Do you really want to quit?");
00181     } else if (amount == 1) {
00182         message = _("Do you really want to quit? Changes in the map since the last save will be lost.");
00183     } else {
00184         message = _("Do you really want to quit? The following maps were modified and all changes since the last save will be lost:");
00185         message += modified;
00186     }
00187     const int res = gui2::show_message(gui().video(), _("Quit"), message, gui2::tmessage::yes_no_buttons);
00188     if(res != gui2::twindow::CANCEL) {
00189         do_quit_ = true;
00190         quit_mode_ = mode;
00191     }
00192 }
00193 
00194 void editor_controller::editor_settings_dialog()
00195 {
00196     if (tods_.empty()) {
00197         gui2::show_error_message(gui().video(),
00198                 _("No editor time-of-day found."));
00199         return;
00200     }
00201 
00202     image::color_adjustment_resetter adjust_resetter;
00203     if(!gui2::teditor_settings::execute(&(gui()), tods_, gui().video())) {
00204         adjust_resetter.reset();
00205     }
00206     context_manager_->refresh_all();
00207 }
00208 
00209 void editor_controller::editor_settings_dialog_redraw_callback(int r, int g, int b)
00210 {
00211     SCOPE_ED;
00212     image::set_color_adjustment(r, g, b);
00213     gui().redraw_everything();
00214 }
00215 
00216 bool editor_controller::can_execute_command(hotkey::HOTKEY_COMMAND command, int index) const
00217 {
00218     using namespace hotkey; //reduce hotkey:: clutter
00219     switch (command) {
00220         case HOTKEY_NULL:
00221             if (index >= 0) {
00222                 unsigned i = static_cast<unsigned>(index);
00223 
00224                 switch (active_menu_) {
00225                     case editor::MAP:
00226                         if (i < context_manager_->open_maps()) {
00227                             return true;
00228                         }
00229                         return false;
00230                     case editor::PALETTE:
00231                     case editor::AREA:
00232                     case editor::SIDE:
00233                         return true;
00234                 }
00235             }
00236             return false;
00237         case HOTKEY_EDITOR_PALETTE_GROUPS:
00238         case HOTKEY_EDITOR_PALETTE_UPSCROLL:
00239         case HOTKEY_EDITOR_PALETTE_DOWNSCROLL:
00240             return true;
00241         case HOTKEY_ZOOM_IN:
00242         case HOTKEY_ZOOM_OUT:
00243         case HOTKEY_ZOOM_DEFAULT:
00244         case HOTKEY_FULLSCREEN:
00245         case HOTKEY_SCREENSHOT:
00246         case HOTKEY_MAP_SCREENSHOT:
00247         case HOTKEY_TOGGLE_GRID:
00248         case HOTKEY_MOUSE_SCROLL:
00249         case HOTKEY_ANIMATE_MAP:
00250         case HOTKEY_MUTE:
00251         case HOTKEY_PREFERENCES:
00252         case HOTKEY_HELP:
00253         case HOTKEY_QUIT_GAME:
00254             return true; //general hotkeys we can always do
00255         case HOTKEY_UNDO:
00256             return true;
00257         case HOTKEY_REDO:
00258             return true;
00259         case HOTKEY_EDITOR_PARTIAL_UNDO:
00260             return true;
00261         case TITLE_SCREEN__RELOAD_WML:
00262         case HOTKEY_EDITOR_QUIT_TO_DESKTOP:
00263         case HOTKEY_EDITOR_SETTINGS:
00264         case HOTKEY_EDITOR_MAP_NEW:
00265         case HOTKEY_EDITOR_MAP_LOAD:
00266         case HOTKEY_EDITOR_MAP_SAVE_AS:
00267         case HOTKEY_EDITOR_BRUSH_NEXT:
00268         case HOTKEY_EDITOR_TOOL_NEXT:
00269         case HOTKEY_EDITOR_PALETTE_ITEM_SWAP:
00270             return true; //editor hotkeys we can always do
00271         case HOTKEY_EDITOR_MAP_SAVE:
00272         case HOTKEY_EDITOR_MAP_SAVE_ALL:
00273         case HOTKEY_EDITOR_SWITCH_MAP:
00274         case HOTKEY_EDITOR_CLOSE_MAP:
00275             return true;
00276         case HOTKEY_EDITOR_MAP_REVERT:
00277             return !context_manager_->get_map_context().get_filename().empty();
00278         case HOTKEY_EDITOR_TOOL_PAINT:
00279         case HOTKEY_EDITOR_TOOL_FILL:
00280         case HOTKEY_EDITOR_TOOL_SELECT:
00281         case HOTKEY_EDITOR_TOOL_STARTING_POSITION:
00282         case HOTKEY_EDITOR_TOOL_LABEL:
00283             return true;
00284         case HOTKEY_EDITOR_TOOL_UNIT:
00285             return !context_manager_->get_map().get_teams().empty();
00286         case HOTKEY_EDITOR_CUT:
00287         case HOTKEY_EDITOR_COPY:
00288         case HOTKEY_EDITOR_EXPORT_SELECTION_COORDS:
00289         case HOTKEY_EDITOR_SELECTION_FILL:
00290         case HOTKEY_EDITOR_SELECTION_RANDOMIZE:
00291             return !context_manager_->get_map().selection().empty();
00292         case HOTKEY_EDITOR_SELECTION_ROTATE:
00293         case HOTKEY_EDITOR_SELECTION_FLIP:
00294         case HOTKEY_EDITOR_SELECTION_GENERATE:
00295             return false; //not implemented
00296         case HOTKEY_EDITOR_PASTE:
00297             return !context_manager_->clipboard_empty();
00298         case HOTKEY_EDITOR_CLIPBOARD_ROTATE_CW:
00299         case HOTKEY_EDITOR_CLIPBOARD_ROTATE_CCW:
00300         case HOTKEY_EDITOR_CLIPBOARD_FLIP_HORIZONTAL:
00301         case HOTKEY_EDITOR_CLIPBOARD_FLIP_VERTICAL:
00302             return !context_manager_->clipboard_empty();
00303         case HOTKEY_EDITOR_SELECT_ALL:
00304         case HOTKEY_EDITOR_SELECT_INVERSE:
00305         case HOTKEY_EDITOR_SELECT_NONE:
00306         case HOTKEY_EDITOR_MAP_RESIZE:
00307         case HOTKEY_EDITOR_MAP_GENERATE:
00308         case HOTKEY_EDITOR_MAP_APPLY_MASK:
00309         case HOTKEY_EDITOR_MAP_CREATE_MASK_TO:
00310         case HOTKEY_EDITOR_REFRESH:
00311         case HOTKEY_EDITOR_UPDATE_TRANSITIONS:
00312         case HOTKEY_EDITOR_AUTO_UPDATE_TRANSITIONS:
00313         case HOTKEY_EDITOR_REFRESH_IMAGE_CACHE:
00314             return true;
00315         case HOTKEY_EDITOR_MAP_ROTATE:
00316             return false; //not implemented
00317         case HOTKEY_EDITOR_DRAW_COORDINATES:
00318         case HOTKEY_EDITOR_DRAW_TERRAIN_CODES:
00319             return true;
00320         default:
00321             return false;
00322     }
00323 }
00324 
00325 hotkey::ACTION_STATE editor_controller::get_action_state(hotkey::HOTKEY_COMMAND command, int index) const {
00326     using namespace hotkey;
00327     switch (command) {
00328         case HOTKEY_EDITOR_TOOL_FILL:
00329         case HOTKEY_EDITOR_TOOL_LABEL:
00330         case HOTKEY_EDITOR_TOOL_PAINT:
00331         case HOTKEY_EDITOR_TOOL_SELECT:
00332         case HOTKEY_EDITOR_TOOL_STARTING_POSITION:
00333         case HOTKEY_EDITOR_TOOL_UNIT:
00334             return toolkit_->is_mouse_action_set(command) ? ACTION_ON : ACTION_OFF;
00335         case HOTKEY_EDITOR_DRAW_COORDINATES:
00336             return gui_->get_draw_coordinates() ? ACTION_ON : ACTION_OFF;
00337         case HOTKEY_EDITOR_DRAW_TERRAIN_CODES:
00338             return gui_->get_draw_terrain_codes() ? ACTION_ON : ACTION_OFF;
00339         case HOTKEY_NULL:
00340             switch (active_menu_) {
00341                 case editor::MAP:
00342                     return index == context_manager_->current_context_index() ? ACTION_ON : ACTION_OFF;
00343                 case editor::PALETTE:
00344                     return ACTION_STATELESS;
00345                 case editor::AREA:
00346                 case editor::SIDE:
00347                     return ACTION_ON;
00348             }
00349             return ACTION_ON;
00350         default:
00351             return command_executor::get_action_state(command, index);
00352     }
00353 }
00354 
00355 bool editor_controller::execute_command(hotkey::HOTKEY_COMMAND command, int index)
00356 {
00357     SCOPE_ED;
00358     using namespace hotkey;
00359     switch (command) {
00360         case HOTKEY_NULL:
00361             switch (active_menu_) {
00362             case MAP:
00363                 if (index >= 0) {
00364                     unsigned i = static_cast<unsigned>(index);
00365                     if (i < context_manager_->size()) {
00366                         context_manager_->switch_context(index);
00367                         return true;
00368                     }
00369                 }
00370                 return false;
00371             case PALETTE:
00372                 toolkit_->get_palette_manager()->set_group(index);
00373                 return true;
00374             case SIDE:
00375                 //TODO
00376             case AREA:
00377                 //TODO
00378                 return true;
00379             }
00380             return true;
00381         case HOTKEY_EDITOR_PALETTE_GROUPS:
00382             return true;
00383         case HOTKEY_EDITOR_PALETTE_UPSCROLL:
00384             toolkit_->get_palette_manager()->scroll_up();
00385             return true;
00386         case HOTKEY_EDITOR_PALETTE_DOWNSCROLL:
00387             toolkit_->get_palette_manager()->scroll_down();
00388             return true;
00389         case HOTKEY_QUIT_GAME:
00390             quit_confirm(EXIT_NORMAL);
00391             return true;
00392         case HOTKEY_EDITOR_QUIT_TO_DESKTOP:
00393             quit_confirm(EXIT_QUIT_TO_DESKTOP);
00394             return true;
00395         case TITLE_SCREEN__RELOAD_WML:
00396             context_manager_->save_all_maps(true);
00397             do_quit_ = true;
00398             quit_mode_ = EXIT_RELOAD_DATA;
00399             return true;
00400         case HOTKEY_EDITOR_SETTINGS:
00401             editor_settings_dialog();
00402             return true;
00403         case HOTKEY_EDITOR_PALETTE_ITEM_SWAP:
00404             toolkit_->get_palette_manager()->active_palette().swap();
00405             toolkit_->set_mouseover_overlay();
00406             return true;
00407         case HOTKEY_EDITOR_PARTIAL_UNDO:
00408             if (dynamic_cast<const editor_action_chain*>(context_manager_->get_map_context().last_undo_action()) != NULL) {
00409                 context_manager_->get_map_context().partial_undo();
00410                 context_manager_->refresh_after_action();
00411             } else {
00412                 undo();
00413             }
00414             return true;
00415         case HOTKEY_EDITOR_TOOL_PAINT:
00416         case HOTKEY_EDITOR_TOOL_FILL:
00417         case HOTKEY_EDITOR_TOOL_SELECT:
00418         case HOTKEY_EDITOR_TOOL_STARTING_POSITION:
00419         case HOTKEY_EDITOR_TOOL_LABEL:
00420         case HOTKEY_EDITOR_TOOL_UNIT:
00421             toolkit_->hotkey_set_mouse_action(command);
00422             return true;
00423         case HOTKEY_EDITOR_PASTE: //paste is somewhat different as it might be "one action then revert to previous mode"
00424             toolkit_->hotkey_set_mouse_action(command);
00425             return true;
00426         case HOTKEY_EDITOR_CLIPBOARD_ROTATE_CW:
00427             context_manager_->get_clipboard().rotate_60_cw();
00428             toolkit_->update_mouse_action_highlights();
00429             return true;
00430         case HOTKEY_EDITOR_CLIPBOARD_ROTATE_CCW:
00431             context_manager_->get_clipboard().rotate_60_ccw();
00432             toolkit_->update_mouse_action_highlights();
00433             return true;
00434         case HOTKEY_EDITOR_CLIPBOARD_FLIP_HORIZONTAL:
00435             context_manager_->get_clipboard().flip_horizontal();
00436             toolkit_->update_mouse_action_highlights();
00437             return true;
00438         case HOTKEY_EDITOR_CLIPBOARD_FLIP_VERTICAL:
00439             context_manager_->get_clipboard().flip_vertical();
00440             toolkit_->update_mouse_action_highlights();
00441             return true;
00442         case HOTKEY_EDITOR_BRUSH_NEXT:
00443             toolkit_->cycle_brush();
00444             return true;
00445         case HOTKEY_EDITOR_COPY:
00446             copy_selection();
00447             return true;
00448         case HOTKEY_EDITOR_CUT:
00449             cut_selection();
00450             return true;
00451         case HOTKEY_EDITOR_EXPORT_SELECTION_COORDS:
00452             export_selection_coords();
00453             return true;
00454         case HOTKEY_EDITOR_SELECT_ALL:
00455             if (!context_manager_->get_map().everything_selected()) {
00456                 context_manager_->perform_refresh(editor_action_select_all());
00457                 return true;
00458             } //else intentionally fall through
00459         case HOTKEY_EDITOR_SELECT_INVERSE:
00460             context_manager_->perform_refresh(editor_action_select_inverse());
00461             return true;
00462         case HOTKEY_EDITOR_SELECT_NONE:
00463             context_manager_->perform_refresh(editor_action_select_none());
00464             return true;
00465         case HOTKEY_EDITOR_SELECTION_FILL:
00466             //TODO
00467             context_manager_->fill_selection();
00468             return true;
00469         case HOTKEY_EDITOR_SELECTION_RANDOMIZE:
00470             context_manager_->perform_refresh(editor_action_shuffle_area(
00471                     context_manager_->get_map().selection()));
00472             return true;
00473         case HOTKEY_EDITOR_CLOSE_MAP:
00474             context_manager_->close_current_context();
00475             return true;
00476         case HOTKEY_EDITOR_MAP_LOAD:
00477             context_manager_->load_map_dialog();
00478             return true;
00479         case HOTKEY_EDITOR_MAP_REVERT:
00480             context_manager_->revert_map();
00481             return true;
00482         case HOTKEY_EDITOR_MAP_NEW:
00483             context_manager_->new_map_dialog();
00484             return true;
00485         case HOTKEY_EDITOR_MAP_SAVE:
00486             save_map();
00487             return true;
00488         case HOTKEY_EDITOR_MAP_SAVE_ALL:
00489             context_manager_->save_all_maps();
00490             return true;
00491         case HOTKEY_EDITOR_MAP_SAVE_AS:
00492             context_manager_->save_map_as_dialog();
00493             return true;
00494         case HOTKEY_EDITOR_MAP_GENERATE:
00495             context_manager_->generate_map_dialog();
00496             return true;
00497         case HOTKEY_EDITOR_MAP_APPLY_MASK:
00498             context_manager_->apply_mask_dialog();
00499             return true;
00500         case HOTKEY_EDITOR_MAP_CREATE_MASK_TO:
00501             context_manager_->create_mask_to_dialog();
00502             return true;
00503         case HOTKEY_EDITOR_MAP_RESIZE:
00504             context_manager_->resize_map_dialog();
00505             return true;
00506         case HOTKEY_EDITOR_AUTO_UPDATE_TRANSITIONS:
00507             if (context_manager_->toggle_update_transitions())
00508                 return true;
00509             // else intentionally fall through
00510         case HOTKEY_EDITOR_UPDATE_TRANSITIONS:
00511             context_manager_->refresh_all();
00512             return true;
00513         case HOTKEY_EDITOR_REFRESH:
00514             context_manager_->reload_map();
00515             return true;
00516         case HOTKEY_EDITOR_REFRESH_IMAGE_CACHE:
00517             refresh_image_cache();
00518             return true;
00519         case HOTKEY_EDITOR_DRAW_COORDINATES:
00520             gui().set_draw_coordinates(!gui().get_draw_coordinates());
00521             preferences::editor::set_draw_hex_coordinates(gui().get_draw_coordinates());
00522             gui().invalidate_all();
00523             return true;
00524         case HOTKEY_EDITOR_DRAW_TERRAIN_CODES:
00525             gui().set_draw_terrain_codes(!gui().get_draw_terrain_codes());
00526             preferences::editor::set_draw_terrain_codes(gui().get_draw_terrain_codes());
00527             gui().invalidate_all();
00528             return true;
00529         default:
00530             return controller_base::execute_command(command, index);
00531     }
00532 }
00533 
00534 
00535 
00536 void editor_controller::show_menu(const std::vector<std::string>& items_arg, int xloc, int yloc, bool context_menu)
00537 {
00538     if (context_menu) {
00539         if (!context_manager_->get_map().on_board_with_border(gui().hex_clicked_on(xloc, yloc))) {
00540             return;
00541         }
00542     }
00543 
00544     std::vector<std::string> items = items_arg;
00545     hotkey::HOTKEY_COMMAND command;
00546     std::vector<std::string>::iterator i = items.begin();
00547     while(i != items.end()) {
00548         command = hotkey::get_hotkey(*i).get_id();
00549         if (command == hotkey::HOTKEY_UNDO) {
00550             if (context_manager_->get_map_context().can_undo()) {
00551                 hotkey::get_hotkey(*i).set_description(_("Undo"));
00552             } else {
00553                 hotkey::get_hotkey(*i).set_description(_("Can’t Undo"));
00554             }
00555         } else if (command == hotkey::HOTKEY_REDO) {
00556             if (context_manager_->get_map_context().can_redo()) {
00557                 hotkey::get_hotkey(*i).set_description(_("Redo"));
00558             } else {
00559                 hotkey::get_hotkey(*i).set_description(_("Can’t Redo"));
00560             }
00561         } else if (command == hotkey::HOTKEY_EDITOR_AUTO_UPDATE_TRANSITIONS) {
00562             context_manager_->set_update_transitions_hotkey(command);
00563         } else if(!can_execute_command(command)
00564         || (context_menu && !in_context_menu(command))) {
00565             i = items.erase(i);
00566             continue;
00567         }
00568         ++i;
00569     }
00570     if (!items.empty() && items.front() == "editor-switch-map") {
00571         active_menu_ = editor::MAP;
00572         context_manager_->expand_open_maps_menu(items);
00573         context_menu = true; //FIXME hack to display a one-item menu
00574     }
00575     if (!items.empty() && items.front() == "editor-palette-groups") {
00576         active_menu_ = editor::PALETTE;
00577         toolkit_->get_palette_manager()->active_palette().expand_palette_groups_menu(items);
00578         context_menu = true; //FIXME hack to display a one-item menu
00579     }
00580     command_executor::show_menu(items, xloc, yloc, context_menu, gui());
00581 }
00582 
00583 void editor_controller::preferences()
00584 {
00585     preferences::show_preferences_dialog(*gui_, game_config_);
00586     gui_->redraw_everything();
00587 }
00588 
00589 void editor_controller::toggle_grid()
00590 {
00591     preferences::set_grid(!preferences::grid());
00592     gui_->invalidate_all();
00593 }
00594 
00595 void editor_controller::copy_selection()
00596 {
00597     if (!context_manager_->get_map().selection().empty()) {
00598         context_manager_->get_clipboard() = map_fragment(context_manager_->get_map(), context_manager_->get_map().selection());
00599         context_manager_->get_clipboard().center_by_mass();
00600     }
00601 }
00602 
00603 void editor_controller::cut_selection()
00604 {
00605     copy_selection();
00606     context_manager_->perform_refresh(editor_action_paint_area(context_manager_->get_map().selection(), get_selected_bg_terrain()));
00607 }
00608 
00609 void editor_controller::export_selection_coords()
00610 {
00611     std::stringstream ssx, ssy;
00612     std::set<map_location>::const_iterator i = context_manager_->get_map().selection().begin();
00613     if (i != context_manager_->get_map().selection().end()) {
00614         ssx << "x = " << i->x + 1;
00615         ssy << "y = " << i->y + 1;
00616         ++i;
00617         while (i != context_manager_->get_map().selection().end()) {
00618             ssx << ", " << i->x + 1;
00619             ssy << ", " << i->y + 1;
00620             ++i;
00621         }
00622         ssx << "\n" << ssy.str() << "\n";
00623         copy_to_clipboard(ssx.str(), false);
00624     }
00625 }
00626 
00627 void editor_controller::perform_delete(editor_action* action)
00628 {
00629     if (action) {
00630         boost::scoped_ptr<editor_action> action_auto(action);
00631         context_manager_->get_map_context().perform_action(*action);
00632     }
00633 }
00634 
00635 void editor_controller::perform_refresh_delete(editor_action* action, bool drag_part /* =false */)
00636 {
00637     if (action) {
00638         boost::scoped_ptr<editor_action> action_auto(action);
00639         context_manager_->perform_refresh(*action, drag_part);
00640     }
00641 }
00642 
00643 void editor_controller::refresh_image_cache()
00644 {
00645     image::flush_cache();
00646     context_manager_->refresh_all();
00647 }
00648 
00649 void editor_controller::display_redraw_callback(display&)
00650 {
00651     toolkit_->adjust_size();
00652     //TODO seems not to be needed and slows down the drawing?
00653     //gui().invalidate_all();
00654 }
00655 
00656 void editor_controller::undo()
00657 {
00658     context_manager_->get_map_context().undo();
00659     context_manager_->refresh_after_action();
00660 }
00661 
00662 void editor_controller::redo()
00663 {
00664     context_manager_->get_map_context().redo();
00665     context_manager_->refresh_after_action();
00666 }
00667 
00668 void editor_controller::mouse_motion(int x, int y, const bool /*browse*/,
00669         bool update, map_location /*new_loc*/)
00670 {
00671     if (mouse_handler_base::mouse_motion_default(x, y, update)) return;
00672     map_location hex_clicked = gui().hex_clicked_on(x, y);
00673     if (context_manager_->get_map().on_board_with_border(drag_from_hex_) && is_dragging()) {
00674         editor_action* a = NULL;
00675         bool partial = false;
00676         editor_action* last_undo = context_manager_->get_map_context().last_undo_action();
00677         if (dragging_left_ && (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(1)) != 0) {
00678             if (!context_manager_->get_map().on_board_with_border(hex_clicked)) return;
00679             a = toolkit_->get_mouse_action()->drag_left(*gui_, x, y, partial, last_undo);
00680         } else if (dragging_right_ && (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(3)) != 0) {
00681             if (!context_manager_->get_map().on_board_with_border(hex_clicked)) return;
00682             a = toolkit_->get_mouse_action()->drag_right(*gui_, x, y, partial, last_undo);
00683         }
00684         //Partial means that the mouse action has modified the
00685         //last undo action and the controller shouldn't add
00686         //anything to the undo stack (hence a different perform_ call)
00687         if (a != NULL) {
00688             boost::scoped_ptr<editor_action> aa(a);
00689             if (partial) {
00690                 context_manager_->get_map_context().perform_partial_action(*a);
00691             } else {
00692                 context_manager_->get_map_context().perform_action(*a);
00693             }
00694             context_manager_->refresh_after_action(true);
00695         }
00696     } else {
00697         toolkit_->get_mouse_action()->move(*gui_, hex_clicked);
00698     }
00699     gui().highlight_hex(hex_clicked);
00700 }
00701 
00702 bool editor_controller::allow_mouse_wheel_scroll(int x, int y)
00703 {
00704     return context_manager_->get_map().on_board_with_border(gui().hex_clicked_on(x,y));
00705 }
00706 
00707 bool editor_controller::right_click_show_menu(int /*x*/, int /*y*/, const bool /*browse*/)
00708 {
00709     return toolkit_->get_mouse_action()->has_context_menu();
00710 }
00711 
00712 bool editor_controller::left_click(int x, int y, const bool browse)
00713 {
00714     toolkit_->clear_mouseover_overlay();
00715     if (mouse_handler_base::left_click(x, y, browse)) return true;
00716     LOG_ED << "Left click, after generic handling\n";
00717     map_location hex_clicked = gui().hex_clicked_on(x, y);
00718     if (!context_manager_->get_map().on_board_with_border(hex_clicked)) return true;
00719     LOG_ED << "Left click action " << hex_clicked.x << " " << hex_clicked.y << "\n";
00720     editor_action* a = toolkit_->get_mouse_action()->click_left(*gui_, x, y);
00721     perform_refresh_delete(a, true);
00722     toolkit_->get_mouse_action()->get_palette().draw(true);
00723     return false;
00724 }
00725 
00726 void editor_controller::left_drag_end(int x, int y, const bool /*browse*/)
00727 {
00728     editor_action* a = toolkit_->get_mouse_action()->drag_end(*gui_, x, y);
00729     perform_delete(a);
00730 }
00731 
00732 void editor_controller::left_mouse_up(int x, int y, const bool /*browse*/)
00733 {
00734     editor_action* a = toolkit_->get_mouse_action()->up_left(*gui_, x, y);
00735     perform_delete(a);
00736     context_manager_->refresh_after_action();
00737     toolkit_->set_mouseover_overlay();
00738 }
00739 
00740 bool editor_controller::right_click(int x, int y, const bool browse)
00741 {
00742     toolkit_->clear_mouseover_overlay();
00743     if (mouse_handler_base::right_click(x, y, browse)) return true;
00744     LOG_ED << "Right click, after generic handling\n";
00745     map_location hex_clicked = gui().hex_clicked_on(x, y);
00746     if (!context_manager_->get_map().on_board_with_border(hex_clicked)) return true;
00747     LOG_ED << "Right click action " << hex_clicked.x << " " << hex_clicked.y << "\n";
00748     editor_action* a = toolkit_->get_mouse_action()->click_right(*gui_, x, y);
00749     perform_refresh_delete(a, true);
00750     toolkit_->get_mouse_action()->get_palette().draw(true);
00751     return false;
00752 }
00753 
00754 void editor_controller::right_drag_end(int x, int y, const bool /*browse*/)
00755 {
00756     editor_action* a = toolkit_->get_mouse_action()->drag_end(*gui_, x, y);
00757     perform_delete(a);
00758 }
00759 
00760 void editor_controller::right_mouse_up(int x, int y, const bool /*browse*/)
00761 {
00762     editor_action* a = toolkit_->get_mouse_action()->up_right(*gui_, x, y);
00763     perform_delete(a);
00764     context_manager_->refresh_after_action();
00765     toolkit_->set_mouseover_overlay();
00766 }
00767 
00768 void editor_controller::process_keyup_event(const SDL_Event& event)
00769 {
00770     editor_action* a = toolkit_->get_mouse_action()->key_event(gui(), event);
00771     perform_refresh_delete(a);
00772     toolkit_->set_mouseover_overlay();
00773 }
00774 
00775 
00776 } //end namespace editor
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Thu May 24 2012 01:02:34 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs