00001 /* $Id: map_context.hpp 53522 2012-03-13 18:19:16Z fendrin $ */ 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 00016 #ifndef EDITOR_MAP_CONTEXT_HPP_INCLUDED 00017 #define EDITOR_MAP_CONTEXT_HPP_INCLUDED 00018 00019 #include "editor_map.hpp" 00020 #include "map_label.hpp" 00021 00022 #include <boost/utility.hpp> 00023 00024 namespace editor { 00025 00026 /** 00027 * This class wraps around a map to provide a concise interface for the editor to work with. 00028 * The actual map object can change rapidly (be assigned to), the map context persists 00029 * data (like the undo stacks) in this case. The functionality is here, not in editor_controller 00030 * as e.g. the undo stack is part of the map, not the editor as a whole. This might allow many 00031 * maps to be open at the same time. 00032 */ 00033 class map_context : private boost::noncopyable 00034 { 00035 public: 00036 /** 00037 * Create a map context from an existing map. The filename is set to be 00038 * empty, indicating a new map. 00039 * Marked "explicit" to avoid automatic conversions. 00040 */ 00041 explicit map_context(const editor_map& map); 00042 00043 /** 00044 * Create map_context from a map file. If the map cannot be loaded, an 00045 * exception will be thrown and the object will not be constructed. If the 00046 * map file is a scenario, the map specified in its map_data key will be 00047 * loaded, and the stored filename updated accordingly. Maps embedded 00048 * inside scenarios do not change the filename, but set the "embedded" flag 00049 * instead. 00050 */ 00051 map_context(const config& game_config, const std::string& filename, const display& disp); 00052 00053 /** 00054 * Map context destructor 00055 */ 00056 ~map_context(); 00057 00058 /** 00059 * Map accesor 00060 */ 00061 editor_map& get_map() { return map_; }; 00062 00063 /** 00064 * Map accesor - const version 00065 */ 00066 const editor_map& get_map() const { return map_; } 00067 00068 /** 00069 * Draw a terrain on a single location on the map. 00070 * Sets the refresh flags accordingly. 00071 */ 00072 void draw_terrain(t_translation::t_terrain terrain, const map_location& loc, 00073 bool one_layer_only = false); 00074 00075 /** 00076 * Actual drawing function used by both overloaded variants of draw_terrain. 00077 */ 00078 void draw_terrain_actual(t_translation::t_terrain terrain, const map_location& loc, 00079 bool one_layer_only = false); 00080 00081 /** 00082 * Draw a terrain on a set of locations on the map. 00083 * Sets the refresh flags accordingly. 00084 */ 00085 void draw_terrain(t_translation::t_terrain terrain, const std::set<map_location>& locs, 00086 bool one_layer_only = false); 00087 00088 /** 00089 * Getter for the reload flag. Reload is the highest level of required refreshing, 00090 * set when the map size has changed or the map was reassigned. 00091 */ 00092 bool needs_reload() const { return needs_reload_; } 00093 00094 /** 00095 * Setter for the reload flag 00096 */ 00097 void set_needs_reload(bool value=true) { needs_reload_ = value; } 00098 00099 /** 00100 * Getter for the terrain rebuild flag. Set whenever any terrain has changed. 00101 */ 00102 bool needs_terrain_rebuild() const { return needs_terrain_rebuild_; } 00103 00104 /** 00105 * Setter for the terrain rebuild flag 00106 */ 00107 void set_needs_terrain_rebuild(bool value=true) { needs_terrain_rebuild_ = value; } 00108 00109 /** 00110 * Getter fo the labels reset flag. Set when the labels need to be refreshed. 00111 */ 00112 bool needs_labels_reset() const { return needs_labels_reset_; } 00113 00114 /** 00115 * Setter for the labels reset flag 00116 */ 00117 void set_needs_labels_reset(bool value=true) { needs_labels_reset_ = value; } 00118 00119 const std::set<map_location> changed_locations() const { return changed_locations_; } 00120 void clear_changed_locations(); 00121 void add_changed_location(const map_location& loc); 00122 void add_changed_location(const std::set<map_location>& locs); 00123 void set_everything_changed(); 00124 bool everything_changed() const; 00125 00126 void set_labels(display& disp); 00127 00128 void clear_starting_position_labels(display& disp); 00129 00130 void set_starting_position_labels(display& disp); 00131 00132 void reset_starting_position_labels(display& disp); 00133 00134 const std::string& get_filename() const { return filename_; } 00135 00136 void set_filename(const std::string& fn) { filename_ = fn; } 00137 00138 const std::string& get_map_data_key() const { return map_data_key_; } 00139 00140 bool is_embedded() const { return embedded_; } 00141 00142 void set_embedded(bool v) { embedded_ = v; } 00143 00144 /** 00145 * Saves the map under the current filename. Filename must be valid. 00146 * May throw an exception on failure. 00147 */ 00148 bool save(); 00149 00150 void set_map(const editor_map& map); 00151 00152 /** 00153 * Performs an action (thus modyfying the map). An appropriate undo action is added to 00154 * the undo stack. The redo stack is cleared. Note that this may throw, use caution 00155 * when calling this with a dereferennced pointer that you own (i.e. use a smart pointer). 00156 */ 00157 void perform_action(const editor_action& action); 00158 00159 /** 00160 * Performs a partial action, assumes that the top undo action has been modified to 00161 * maintain coherent state of the undo stacks, and so a new undo action is not 00162 * created. 00163 */ 00164 void perform_partial_action(const editor_action& action); 00165 00166 /** @return whether the map was modified since the last save */ 00167 bool modified() const; 00168 00169 /** Clear the modified state */ 00170 void clear_modified(); 00171 00172 /** @return true when undo can be performed, false otherwise */ 00173 bool can_undo() const; 00174 00175 /** @return true when redo can be performed, false otherwise */ 00176 bool can_redo() const; 00177 00178 /** @return a pointer to the last undo action or NULL if the undo stack is empty */ 00179 editor_action* last_undo_action(); 00180 00181 /** @return a pointer to the last redo action or NULL if the undo stack is empty */ 00182 editor_action* last_redo_action(); 00183 00184 /** const version of last_undo_action */ 00185 const editor_action* last_undo_action() const; 00186 00187 /** const version of last_redo_action */ 00188 const editor_action* last_redo_action() const; 00189 00190 /** Un-does the last action, and puts it in the redo stack for a possible redo */ 00191 void undo(); 00192 00193 /** Re-does a previousle undid action, and puts it back in the undo stack. */ 00194 void redo(); 00195 00196 /** 00197 * Un-does a single step from a undo action chain. The action is separated 00198 * from the chain and it's undo (the redo) is added as a standalone action 00199 * to the redo stack. 00200 * Precodnition: the last undo action has to actually be an action chain. 00201 */ 00202 void partial_undo(); 00203 00204 /** 00205 * Clear the undo and redo stacks 00206 */ 00207 void clear_undo_redo(); 00208 00209 protected: 00210 /** 00211 * The actual filename of this map. An empty string indicates a new map. 00212 */ 00213 std::string filename_; 00214 00215 /** 00216 * When a scenario file is loaded, the referenced map is loaded instead. 00217 * The verbatim form of the reference is kept here. 00218 */ 00219 std::string map_data_key_; 00220 00221 /** 00222 * Whether the map context refers to a map embedded in a scenario file. 00223 * This distinction is important in order to avoid overwriting the scenario. 00224 */ 00225 bool embedded_; 00226 00227 /** 00228 * The map object of this map_context. 00229 */ 00230 editor_map map_; 00231 00232 00233 /** 00234 * Container type used to store actions in the undo and redo stacks 00235 */ 00236 typedef std::deque<editor_action*> action_stack; 00237 00238 /** 00239 * Checks if an action stack reached its capacity and removes the front element if so. 00240 */ 00241 void trim_stack(action_stack& stack); 00242 00243 /** 00244 * Clears an action stack and deletes all its contents. Helper function used when the undo 00245 * or redo stack needs to be cleared 00246 */ 00247 void clear_stack(action_stack& stack); 00248 00249 /** 00250 * Perform an action at the back of one stack, and then move it to the back of the other stack. 00251 * This is the implementation of both undo and redo which only differ in the direction. 00252 */ 00253 void perform_action_between_stacks(action_stack& from, action_stack& to); 00254 00255 /** 00256 * The undo stack. A double-ended queues due to the need to add items to one end, 00257 * and remove from both when performing the undo or when trimming the size. This container owns 00258 * all contents, i.e. no action in the stack shall be deleted, and unless otherwise noted the contents 00259 * could be deleted at an time during normal operation of the stack. To work on an action, either 00260 * remove it from the container or make a copy. Actions are inserted at the back of the container 00261 * and disappear from the front when the capacity is exceeded. 00262 * @todo Use boost's pointer-owning container? 00263 */ 00264 action_stack undo_stack_; 00265 00266 /** 00267 * The redo stack. @see undo_stack_ 00268 */ 00269 action_stack redo_stack_; 00270 00271 /** 00272 * Action stack (i.e. undo and redo) maximum size 00273 */ 00274 static const size_t max_action_stack_size_; 00275 00276 /** 00277 * Number of actions performed since the map was saved. Zero means the map was not modified. 00278 */ 00279 int actions_since_save_; 00280 00281 /** 00282 * Cache of set starting position labels. Necessary for removing them. 00283 */ 00284 std::set<map_location> starting_position_label_locs_; 00285 00286 /** 00287 * Refresh flag indicating the map in this context should be completely reloaded by the display 00288 */ 00289 bool needs_reload_; 00290 00291 /** 00292 * Refresh flag indicating the terrain in the map has changed and requires a rebuild 00293 */ 00294 bool needs_terrain_rebuild_; 00295 00296 /** 00297 * Refresh flag indicating the labels in the map have changed 00298 */ 00299 bool needs_labels_reset_; 00300 00301 std::set<map_location> changed_locations_; 00302 bool everything_changed_; 00303 }; 00304 00305 00306 } //end namespace editor 00307 00308 #endif
| Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:50 for The Battle for Wesnoth | Gna! | Forum | Wiki | CIA | devdocs |