editor.hpp

Go to the documentation of this file.
00001 /* $Id: editor.hpp 26688 2008-05-18 10:56:04Z mog $ */
00002 /*
00003   Copyright (C) 2003 - 2008 by David White <dave@whitevine.net>
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 version 2
00008   or at your option any later version.
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY.
00011 
00012   See the COPYING file for more details.
00013 */
00014 
00015 //! @file editor/editor.hpp
00016 //!
00017 
00018 #ifndef EDITOR_H_INCLUDED
00019 #define EDITOR_H_INCLUDED
00020 
00021 #include "global.hpp"
00022 
00023 #include "SDL.h"
00024 
00025 #include "editor_palettes.hpp"
00026 #include "editor_layout.hpp"
00027 #include "editor_undo.hpp"
00028 #include "map_manip.hpp"
00029 
00030 #include "../display.hpp"
00031 #include "../events.hpp"
00032 #include "../font.hpp"
00033 #include "../hotkeys.hpp"
00034 #include "../preferences_display.hpp"
00035 #include "../theme.hpp"
00036 #include "../tooltips.hpp"
00037 //#include "gui/key_listener.hpp"
00038 //#include "gui/mouse_listener.hpp"
00039 
00040 #include <map>
00041 #include <queue>
00042 #include <set>
00043 #include <vector>
00044 
00045 namespace map_editor {
00046 
00047 bool check_data(std::string &data, std::string &filename, bool &from_scenario, config &game_cfg);
00048 
00049 //! A map editor. Receives SDL events and can execute hotkey commands.
00050 class map_editor : public events::handler,
00051                    public hotkey::command_executor {
00052 public:
00053     map_editor(editor_display &gui, editormap &map, config &theme, config &game_config);
00054     virtual ~map_editor();
00055 
00056     //! Enter the main loop. The loop runs until set_abort() is called
00057     //! to set an abort mode which makes the loop exit.
00058     void main_loop();
00059 
00060     //! Set the filename that map should be saved as.
00061     void set_file_to_save_as(const std::string, bool from_scenario);
00062 
00063     //! How to abort the map editor.
00064     //! DONT_ABORT is set during normal operation.
00065     //! When ABORT_NORMALLY is set, the editor asks for confirmation and
00066     //! if save is desired before it exits.
00067     //! When ABORT_HARD is set, the editor exists without asking any
00068     //! questions or saving.
00069     enum ABORT_MODE {DONT_ABORT, ABORT_NORMALLY, ABORT_HARD};
00070 
00071     //! Set the abort flag, which indicates if the editor should exit in
00072     //! some way after the current iteration of the main loop.
00073     void set_abort(const ABORT_MODE abort=ABORT_NORMALLY);
00074 
00075     //! Save the current map. If filename is an empty string, use the
00076     //! filename that is set with set_file_to_save_as(). A message box
00077     //! that shows confirmation that the map was saved is shown if
00078     //! display_confirmation is true. Return false if the save failed.
00079     bool save_map(const std::string filename="",
00080                   const bool display_confirmation=true);
00081 
00082     //! Exception thrown when the loading of a map failed.
00083     struct load_map_exception {};
00084 
00085     virtual void handle_event(const SDL_Event &event);
00086 
00087     //! Handle a keyboard event. mousex and mousey is the current
00088     //! position of the mouse.
00089     void handle_keyboard_event(const SDL_KeyboardEvent &event,
00090                                const int mousex, const int mousey);
00091 
00092     //! Handle a mouse button event. mousex and mousey is the current
00093     //! position of the mouse.
00094     void handle_mouse_button_event(const SDL_MouseButtonEvent &event,
00095                                    const int mousex, const int mousey);
00096 
00097     //! Return true if the map has changed since the last time it was
00098     //! saved.
00099     bool changed_since_save() const;
00100 
00101     //! Recalculate layout and redraw everything.
00102     void redraw_everything();
00103 
00104     // Change the language in_game
00105     virtual void change_language();
00106 
00107     // Methods inherited from command_executor. Used to perform
00108     // operations on menu/hotkey commands.
00109     virtual void toggle_grid();
00110     virtual void undo();
00111     virtual void redo();
00112     virtual void preferences();
00113     virtual void edit_quit();
00114     virtual void edit_new_map();
00115     virtual void edit_load_map();
00116     virtual void edit_save_map();
00117     virtual void edit_save_as();
00118     //! Display a dialog asking for a player number and set the starting
00119     //! position of the given player to the currently selected hex.
00120     virtual void edit_set_start_pos();
00121     virtual void edit_flood_fill();
00122     virtual void edit_fill_selection();
00123     virtual void edit_rotate_selection();
00124     virtual void edit_cut();
00125     virtual void edit_copy();
00126     virtual void edit_paste();
00127     virtual void edit_revert();
00128     virtual void edit_resize();
00129     virtual void edit_flip();
00130     //! Either select or deselect all hexes on the map depending on if
00131     //! this operations has been invoked before or not.
00132     virtual void edit_select_all();
00133     virtual void edit_draw();
00134     virtual void edit_refresh();
00135     virtual void edit_update();
00136     virtual void edit_auto_update();
00137 
00138     void perform_flood_fill(const t_translation::t_terrain fill_with);
00139     void perform_paste();
00140     void perform_set_starting_pos();
00141 
00142     virtual bool can_execute_command(hotkey::HOTKEY_COMMAND command, int) const;
00143     //Does the action control a toggle switch? If so, return the state of the action (on or off)
00144     virtual hotkey::ACTION_STATE get_action_state(hotkey::HOTKEY_COMMAND command) const;
00145 
00146 
00147     //! Exception thrown when new map is to be loaded.
00148     struct new_map_exception {
00149         new_map_exception(const std::string &map, const std::string filename="", const bool scenario = false)
00150             : new_map(map), new_filename(filename), from_scenario(scenario) {}
00151         const std::string new_map;
00152         const std::string new_filename;
00153         const bool from_scenario;
00154     };
00155 
00156 private:
00157     //! What to perform while the left button is held down.
00158     enum LEFT_BUTTON_HELD_FUNC {DRAW_TERRAIN, DRAW_TERRAIN_LAYER, ADD_SELECTION, REMOVE_SELECTION,
00159                                 MOVE_SELECTION, NONE};
00160 
00161     //! What to perform on a left button click.
00162     enum LEFT_BUTTON_FUNC {DRAW, SELECT_HEXES, FLOOD_FILL,
00163                            SET_STARTING_POSITION, PASTE, NUM_L_BUTTON_FUNC};
00164 
00165     //! Called in every iteration when the left mouse button is held
00166     //! down. Note that this differs from a click.
00167     void left_button_down(const int mousex, const int mousey);
00168 
00169     //! Handle a left click on the location.
00170     void left_click(const gamemap::location loc);
00171 
00172     //! Called in every iteration when the right mouse button is held
00173     //! down. Note that this differs from a click.
00174     void right_button_down(const int mousex, const int mousey);
00175 
00176     //! Handle a right click on the location.
00177     void right_click(const gamemap::location loc);
00178 
00179     //! Called in every iteration when the middle mouse button is held
00180     //! down. Note that this differs from a click.
00181     void middle_button_down(const int mousex, const int mousey);
00182 
00183     //! Confirm that exiting is desired and ask for saving of the map.
00184     //! Return true if exit is confirmed and the save is successful or not
00185     //! wanted. Return false if exit is cancelled or the requested save
00186     //! failed.
00187     bool confirm_exit_and_save();
00188 
00189     //! Set the starting position for the given player to the location
00190     //! given.
00191     void set_starting_position(const int player, const gamemap::location loc);
00192 
00193     //! Check whether the filename contains illegal characters.
00194     bool verify_filename(const std::string& filename, bool show_error) const;
00195 
00196     //! Display a menu with given items and at the given location.
00197     void show_menu(const std::vector<std::string>& items_arg, const int xloc,
00198                    const int yloc, const bool context_menu=false);
00199 
00200     //! Pass the command onto the hotkey handling system. Quit requests
00201     //! are intercepted because the editor does not want the default
00202     //! behavior of those.
00203     void execute_command(const hotkey::HOTKEY_COMMAND command);
00204 
00205     //! Draw terrain at a location. The operation is saved in the undo
00206     //! stack. Update the map to reflect the change.
00207     void draw_terrain(const t_translation::t_terrain terrain,
00208                       const std::vector<gamemap::location> &hexes, const bool one_layer_only);
00209 
00210     //! Re-set the labels for the starting positions of the
00211     //! players. Should be called when the terrain has changed, which
00212     //! may have changed the starting positions.
00213     void recalculate_starting_pos_labels();
00214 
00215     //! Update the selection and highlightning of the hexes the mouse
00216     //! currently is over.
00217     void update_mouse_over_hexes(const gamemap::location mouse_over_hex);
00218 
00219     //! Insert the currently selected locations in the clipboard.
00220     void insert_selection_in_clipboard();
00221 
00222     //! Commit hexes filling.
00223     void perform_fill_hexes(std::set<gamemap::location> &fill_hexes,
00224         const t_translation::t_terrain terrain, map_undo_action &undo_action);
00225     
00226     //! Commit the movement of a selection.
00227     void perform_selection_move();
00228 
00229     //! Highlight the currently selected hexes. If clear_old is true the
00230     //! old highlighting is cleared, otherwise the current selection is
00231     //! only added, which may leave old selected terrain still
00232     //! highlighted.
00233     void highlight_selected_hexes(const bool clear_old=true);
00234 
00235     //! Clear the highlighted hexes in the gui and set a variable to
00236     //! indicate this so that the brush size highlighting may be
00237     //! refreshed.
00238     void clear_highlighted_hexes_in_gui();
00239 
00240     // Sets the special overlay with the selection of fore and background
00241     void set_mouseover_overlay();
00242     // Clears the special overlay
00243     void reset_mouseover_overlay() { gui_.clear_mouseover_hex_overlay(); }
00244 
00245     //! Terrain has changed at the specified hex through user drawing
00246     //! (not undo/redo or other special things).
00247     void terrain_changed(const gamemap::location &hex);
00248 //  void terrain_changed(const std::vector<gamemap::location> &hexes);
00249 //  void terrain_changed(const std::set<gamemap::location> &hexes);
00250 
00251     //! Save an action so that it may be undone. Add an operation to the
00252     //! number done since save.
00253     void save_undo_action(const map_undo_action &action);
00254 
00255     //! Call when the left mouse button function has changed. Updated
00256     //! the report indicating what will be performed. New_function is
00257     //! the hotkey-string describing the action.
00258     void left_button_func_changed(const LEFT_BUTTON_FUNC func);
00259 
00260     //! Draw black squares around the buttons that are used to select
00261     //! the left button function and draw a read square around the
00262     //! currently selected function.
00263     void update_l_button_palette();
00264 
00265     //! Return the hotkey-string representing the left button
00266     //! function. The "action_" is left out.
00267     std::string get_action_name(const LEFT_BUTTON_FUNC func) const;
00268 
00269     //! Return true if the menu is a button used for setting the left
00270     //! mouse button function.
00271     bool is_left_button_func_menu(const theme::menu &menu) const;
00272 
00273     //! Draw the terrain on the hexes the mouse is over, taking account
00274     //! for brush size.
00275     void draw_on_mouseover_hexes(const t_translation::t_terrain t, const bool one_layer_only = false);
00276 
00277     // Load the tooltips for each button
00278     void load_tooltips(void);
00279 
00280     //! An item in the buffer. Consists of the copied terrain and an
00281     //! offset. When pasting stuff, the offset is used to calculate
00282     //! where to put the pasted hex
00283     struct buffer_item {
00284         buffer_item(const gamemap::location &o, t_translation::t_terrain t, int start_side) :
00285             offset(o), terrain(t), starting_side(start_side) {}
00286         gamemap::location offset;
00287         t_translation::t_terrain terrain;
00288         int starting_side;
00289     };
00290 
00291     // map_buffer is used for clipboard and other map operations
00292     typedef std::vector<buffer_item> map_buffer;
00293 
00294     void copy_buffer(map_buffer& buffer, const std::set<gamemap::location> &locs,
00295              const gamemap::location &origin);
00296     void paste_buffer(const map_buffer& buffer, const gamemap::location &loc,
00297             map_undo_action &undo_action);
00298     void clear_buffer(map_buffer& buffer) {buffer.clear();};
00299 
00300     editor_display &gui_;
00301     editormap &map_;
00302     std::string filename_, original_filename_;
00303     bool from_scenario_;
00304     ABORT_MODE abort_;
00305     // Keep track of the number of operations performed since the last
00306     // save. If this is zero when the editor is exited there is no need
00307     // to ask the user to save.
00308     static int num_operations_since_save_;
00309     size_specs size_specs_;
00310     config &theme_;
00311     config &game_config_;
00312     CKey key_;
00313     gamemap::location selected_hex_;
00314     // When map_dirty_ is true, schedule redraw of the minimap and
00315     // perform some updates like recalculating labels of starting
00316     // positions. But only it the option auto_update is enabled
00317     bool map_dirty_;
00318     bool auto_update_;
00319     bool l_button_palette_dirty_;
00320     bool everything_dirty_;
00321     terrain_palette palette_;
00322     brush_bar brush_;
00323     std::vector<gamemap::location> starting_positions_;
00324     std::set<gamemap::location> mouse_over_hexes_;
00325     std::set<gamemap::location> selected_hexes_;
00326     map_buffer clipboard_;
00327     
00328     LEFT_BUTTON_HELD_FUNC l_button_held_func_;
00329     gamemap::location selection_move_start_;
00330 
00331     tooltips::manager tooltip_manager_;
00332     font::floating_label_context floating_label_manager_;
00333     // mouse_moved_ will be true if the mouse have moved between two
00334     // cycles.
00335     bool mouse_moved_;
00336     bool highlighted_locs_cleared_;
00337     const hotkey::manager hotkey_manager_;
00338     const preferences::display_manager prefs_disp_manager_;
00339     static config prefs_;
00340     static config hotkeys_;
00341     static bool first_time_created_;
00342     static LEFT_BUTTON_FUNC l_button_func_;
00343     static t_translation::t_terrain old_fg_terrain_, old_bg_terrain_;
00344     static int old_brush_size_;
00345     bool all_hexes_selected_;
00346 
00347 };
00348 
00349 }
00350 
00351 #endif // EDITOR_H_INCLUDED
00352 

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs