1 /////////////////////////////////////////////////////////////////////////////// 2 // Copyright (C) 2004-2010 by The Allacrost Project 3 // All Rights Reserved 4 // 5 // This code is licensed under the GNU GPL version 2. It is free software 6 // and you may modify it and/or redistribute it under the terms of this license. 7 // See http://www.gnu.org/copyleft/gpl.html for details. 8 /////////////////////////////////////////////////////////////////////////////// 9 10 /*!**************************************************************************** 11 * \file editor.h 12 * \author Philip Vorsilak, gorzuate@allacrost.org 13 * \brief Header file for editor's main window and user interface. 14 *****************************************************************************/ 15 16 #ifndef __EDITOR_HEADER__ 17 #define __EDITOR_HEADER__ 18 19 #include <map> 20 21 #include <QApplication> 22 #include <QCheckBox> 23 #include <QCloseEvent> 24 #include <QComboBox> 25 #include <QContextMenuEvent> 26 #include <QErrorMessage> 27 #include <QFileDialog> 28 #include <QLayout> 29 #include <QLineEdit> 30 #include <QMainWindow> 31 #include <QMenuBar> 32 #include <QMessageBox> 33 #include <QMouseEvent> 34 #include <QProgressDialog> 35 #include <Q3ScrollView> 36 #include <QSplitter> 37 #include <QSpinBox> 38 #include <QStatusBar> 39 #include <QTabWidget> 40 #include <QToolBar> 41 #include <QUndoCommand> 42 43 #include "dialog_boxes.h" 44 #include "grid.h" 45 #include "sprites.h" 46 #include "skill_editor.h" 47 #include "tileset_editor.h" 48 49 //! All calls to the editor are wrapped in this namespace. 50 namespace hoa_editor 51 { 52 53 //! Different tile editing modes follow. 54 enum TILE_MODE_TYPE 55 { 56 INVALID_TILE = -1, 57 PAINT_TILE = 0, 58 MOVE_TILE = 1, 59 DELETE_TILE = 2, 60 TOTAL_TILE = 3 61 }; 62 63 //! Different types of transition patterns for autotileable tiles follow. 64 enum TRANSITION_PATTERN_TYPE 65 { 66 INVALID_PATTERN = -1, 67 NW_BORDER_PATTERN = 0, 68 N_BORDER_PATTERN = 1, 69 NE_BORDER_PATTERN = 2, 70 E_BORDER_PATTERN = 3, 71 SE_BORDER_PATTERN = 4, 72 S_BORDER_PATTERN = 5, 73 SW_BORDER_PATTERN = 6, 74 W_BORDER_PATTERN = 7, 75 NW_CORNER_PATTERN = 8, 76 NE_CORNER_PATTERN = 9, 77 SE_CORNER_PATTERN = 10, 78 SW_CORNER_PATTERN = 11, 79 TOTAL_PATTERN = 12 80 }; 81 82 //! Maximum number of allowable map contexts. 83 const int MAX_CONTEXTS = 32; 84 85 86 class EditorScrollView; 87 88 89 class Editor: public QMainWindow 90 { 91 //! Macro needed to use Qt's slots and signals. 92 Q_OBJECT 93 94 public: 95 Editor(); // constructor 96 ~Editor(); // destructor 97 98 //! Needed for tile editing and accessing the map properties. 99 friend class EditorScrollView; 100 friend class MapPropertiesDialog; 101 friend class MusicDialog; 102 friend class ContextPropertiesDialog; 103 friend class LayerCommand; 104 105 106 protected: 107 //! Handles close and/or quit events. 108 //! \note Reimplemented from QMainWindow. 109 //! \param QCloseEvent* A pointer to a Qt close event. 110 void closeEvent(QCloseEvent*); 111 112 private slots: 113 //! \name Menu-Toolbar Setup Slots 114 //! \brief These slots are used to gray out items in the menus and toolbars. 115 //{@ 116 void _FileMenuSetup(); 117 void _ViewMenuSetup(); 118 void _TilesEnableActions(); 119 void _TilesetMenuSetup(); 120 void _MapMenuSetup(); 121 void _ScriptMenuSetup(); 122 //@} 123 124 //! \name File Menu Item Slots 125 //! \brief These slots process selection for their item in the File menu. 126 //{@ 127 void _FileNew(); 128 void _FileOpen(); 129 void _FileSaveAs(); 130 void _FileSave(); 131 void _FileClose(); 132 void _FileQuit(); 133 //@} 134 135 //! \name View Menu Item Slots 136 //! \brief These slots process selection for their item in the View menu. 137 //{@ 138 void _ViewToggleGrid(); 139 void _ViewToggleLL(); 140 void _ViewToggleML(); 141 void _ViewToggleUL(); 142 void _ViewToggleOL(); 143 void _ViewCoordTile(); 144 void _ViewCoordCollision(); 145 void _ViewTextures(); 146 //@} 147 148 //! \name Tiles Menu Item Slots 149 //! \brief These slots process selection for their item in the Tiles menu. 150 //{@LayerCommand 151 void _TileLayerFill(); 152 void _TileLayerClear(); 153 void _TileToggleSelect(); 154 void _TileModePaint(); 155 void _TileModeMove(); 156 void _TileModeDelete(); 157 void _TileEditLL(); 158 void _TileEditML(); 159 void _TileEditUL(); 160 void _TileEditOL(); 161 //@} 162 163 //! \name Tileset Menu Item Slots 164 //! \brief These slots process selection for their item in the Tileset menu. 165 //{@ 166 void _TilesetEdit(); 167 //@} 168 169 //! \name Map Menu Item Slots 170 //! \brief These slots process selection for their item in the Map menu. 171 //{@ 172 void _MapSelectMusic(); 173 void _MapProperties(); 174 void _MapAddContext(); 175 //@} 176 177 //! \name Script Menu Item Slots 178 //! \brief These slots handle the events for the Script menu 179 //{@ 180 void _ScriptEditSkills(); 181 //@} 182 183 //! \name Help Menu Item Slots 184 //! \brief These slots process selection for their item in the Help menu. 185 //{@ 186 void _HelpHelp(); 187 void _HelpAbout(); 188 void _HelpAboutQt(); 189 //@} 190 191 //! This slot switches the map context to the designated one for editing. 192 void _SwitchMapContext(int context); 193 private: 194 //! Helper function to the constructor, creates actions for use by menus 195 //! and toolbars. 196 void _CreateActions(); 197 //! Helper function to the constructor, creates the actual menus. 198 void _CreateMenus(); 199 //! Helper function to the constructor, creates the actual toolbars. 200 void _CreateToolbars(); 201 202 //! \brief Used to determine if it is safe to erase the current map. 203 //! Will prompt the user for action: to save or not to save. 204 //! \return True if user decided to save the map or intentionally erase it; 205 //! False if user canceled the operation. 206 bool _EraseOK(); 207 208 //! \name Application Menus 209 //! \brief These are used to represent various menus found in the menu bar. 210 //{@ 211 QMenu* _file_menu; 212 QMenu* _view_menu; 213 QMenu* _tiles_menu; 214 QMenu* _map_menu; 215 QMenu* _help_menu; 216 QMenu* _tileset_menu; 217 QMenu* _script_menu; 218 //@} 219 220 //! \name Application Toolbars 221 //! \brief These are used to represent various toolbars found in the main window. 222 //{@ 223 QToolBar* _tiles_toolbar; 224 //@} 225 226 //! \name Application Menu Actions 227 //! \brief These are Qt's way of associating the same back-end functionality to occur whether a user 228 //! invokes a menu through the menu bar, a keyboard shortcut, a toolbar button, or other means. 229 //{@ 230 QAction* _new_action; 231 QAction* _open_action; 232 QAction* _save_as_action; 233 QAction* _save_action; 234 QAction* _close_action; 235 QAction* _quit_action; 236 237 QAction* _toggle_grid_action; 238 QAction* _toggle_ll_action; 239 QAction* _toggle_ml_action; 240 QAction* _toggle_ul_action; 241 QAction* _toggle_ol_action; 242 QAction* _coord_tile_action; 243 QAction* _coord_collision_action; 244 QAction* _view_textures_action; 245 246 QAction* _undo_action; 247 QAction* _redo_action; 248 QAction* _layer_fill_action; 249 QAction* _layer_clear_action; 250 QAction* _toggle_select_action; 251 QAction* _mode_paint_action; 252 QAction* _mode_move_action; 253 QAction* _mode_delete_action; 254 QAction* _edit_ll_action; 255 QAction* _edit_ml_action; 256 QAction* _edit_ul_action; 257 QAction* _edit_ol_action; 258 QActionGroup* _mode_group; 259 QActionGroup* _edit_group; 260 261 QAction* _edit_tileset_action; 262 263 QAction* _context_properties_action; 264 QAction* _map_properties_action; 265 QAction* _select_music_action; 266 267 QAction* _edit_skill_action; 268 269 QAction* _help_action; 270 QAction* _about_action; 271 QAction* _about_qt_action; 272 //@} 273 274 //! Tabbed widget of tilesets. 275 QTabWidget* _ed_tabs; 276 //! Used to add scrollbars to the QGLWidget of the map. 277 EditorScrollView* _ed_scrollview; 278 //! The skills editor window 279 SkillEditor *_skill_editor; 280 //! Used as the main widget in the editor since it enables user-sizable sub-widgets. 281 QSplitter* _ed_splitter; 282 283 //! Grid toggle view switch. 284 bool _grid_on; 285 //! Selection rectangle toggle view switch. 286 bool _select_on; 287 //! Textures toggle view switch. 288 bool _textures_on; 289 //! Lower layer toggle view switch. 290 bool _ll_on; 291 //! Middle layer toggle view switch. 292 bool _ml_on; 293 //! Upper layer toggle view switch. 294 bool _ul_on; 295 //! Object layer toggle view switch. 296 bool _ol_on; 297 //! Coordinate display type (0 = tile, 1 = collision, 2 = classic) 298 int32 _coord_type; 299 300 //! The stack that contains the undo and redo operations. 301 QUndoStack* _undo_stack; 302 303 //! The combobox that allows the user to change the current map context 304 //! for editing. Contains a list of all existing contexts. 305 QComboBox* _context_cbox; 306 307 //! An error dialog for exceeding the maximum allowable number of contexts. 308 QErrorMessage* _error_max_contexts; 309 }; // class Editor 310 311 class EditorScrollView: public Q3ScrollView 312 { 313 //! Macro needed to use Qt's slots and signals. 314 Q_OBJECT 315 316 public: 317 EditorScrollView(QWidget* parent, const QString& name, int width, int height); 318 ~EditorScrollView(); 319 320 //! Resizes the map. 321 //! \param width Width of the map. 322 //! \param height Height of the map. 323 void Resize(int width, int height); 324 325 //! Gets currently edited layer 326 std::vector<int32>& GetCurrentLayer(); 327 328 //! Needed for changing the editing mode and painting, and accessing the map's properties. 329 friend class Editor; 330 friend class MapPropertiesDialog; 331 friend class MusicDialog; 332 friend class ContextPropertiesDialog; 333 friend class LayerCommand; 334 335 protected: 336 //! \name Mouse Processing Functions 337 //! \brief Functions to process mouse events on the map. 338 //! \note Reimplemented from QScrollView. 339 //! \param evt A pointer to the QMouseEvent generated by the mouse. 340 //{@ 341 void contentsMousePressEvent(QMouseEvent *evt); 342 void contentsMouseMoveEvent(QMouseEvent *evt); 343 void contentsMouseReleaseEvent(QMouseEvent *evt); 344 void contentsContextMenuEvent(QContextMenuEvent *evt); 345 void keyPressEvent(QKeyEvent *evt); 346 //@} 347 348 private slots: 349 //! \name Context Menu Slots 350 //! \brief These slots process selection for their item in the Context menu, 351 //! which pops up on right-clicks of the mouse on the map. 352 //{@ 353 void _ContextInsertRow(); 354 void _ContextInsertColumn(); 355 void _ContextDeleteRow(); 356 void _ContextDeleteColumn(); 357 //@} 358 359 private: 360 //! \name Tile Editing Functions 361 //! \brief These functions perform the gritty details of tile modification 362 //! such as painting, deleting, and moving. 363 //! \param index The index on the map/grid of the tile to modify. 364 //{@ 365 void _PaintTile(int32 index); 366 //void _MoveTile(int32 index); 367 void _DeleteTile(int32 index); 368 //@} 369 370 //! \name Autotiling Functions 371 //! \brief These functions perform all the nitty gritty details associated 372 //! with autotiling. _AutotileRandomize randomizes tiles being painted 373 //! on the map, and _AutotileTransitions calculates which tiles need 374 //! border transitions from one tile group to the next. 375 //! _CheckForTransitionPattern checks tiles surrounding the current tile 376 //! for patterns necessary to put in a transition tile. It's a helper to 377 //! _AutotileTransitions. 378 //! \param tileset_num The index of the specified tileset as loaded in the 379 //! QTabWidget. 380 //! \param tile_index The index of the selected tile in its tileset. 381 //! \param tile_group The autotileable group that the current tile belongs to. 382 //{@ 383 void _AutotileRandomize(int32& tileset_num, int32& tile_index); 384 void _AutotileTransitions(int32& tileset_num, int32& tile_index, const std::string tile_group); 385 TRANSITION_PATTERN_TYPE _CheckForTransitionPattern(const std::string current_group, 386 const std::vector<std::string>& surrounding_groups, std::string& border_group); 387 //@} 388 389 //! \name Context Menu Actions 390 //! \brief These are Qt's way of associating the same back-end functionality to occur whether a user 391 //! invokes a menu through the menu bar, a keyboard shortcut, a toolbar button, or other means. 392 //{@ 393 QAction* _insert_row_action; 394 QAction* _insert_column_action; 395 QAction* _delete_row_action; 396 QAction* _delete_column_action; 397 //@} 398 399 //! Current working map. 400 Grid* _map; 401 //! Current tile edit mode being used. 402 TILE_MODE_TYPE _tile_mode; 403 //! Current layer being edited. 404 LAYER_TYPE _layer_edit; 405 //! Mouse is at this tile index on the map. 406 int32 _tile_index; 407 //! Menu used on right-clicks of the mouse on the map. 408 QMenu* _context_menu; 409 410 //! Stores first index, i.e. beginning, of the selection rectangle. 411 int32 _first_corner_index; 412 //! Stores source index of the moved tile. 413 int32 _move_source_index; 414 //! Moving tiles has 2 phases to it when using the selection rectangle 415 //! and hence moving more than one tile at a time. This determines which phase 416 //! is in effect: false is the first phase, when the user creates the 417 //! selection rectangle; true is the second phase, when the user clicks on 418 //! the rectangle and moves it to another location. 419 bool _moving; 420 421 //! \name Tile Vectors 422 //! \brief The following three vectors are used to know how to perform undo and redo operations 423 //! for this command. They should be the same size and one-to-one. So, the j-th element 424 //! of each vector should correspond to the j-th element of the other vectors. 425 //{@ 426 std::vector<int32> _tile_indeces; //! A vector of tile indeces in the map that were modified by a command. 427 std::vector<int32> _previous_tiles;//! A vector of indeces into tilesets of the modified tiles before they were modified. 428 std::vector<int32> _modified_tiles;//! A vector of indeces into tilesets of the modified tiles after they were modified. 429 //@} 430 }; // class EditorScrollView 431 432 class LayerCommand: public QUndoCommand 433 { 434 public: 435 LayerCommand(std::vector<int32> indeces, std::vector<int32> previous, 436 std::vector<int32> modified, LAYER_TYPE layer, int context, Editor* editor, 437 const QString& text = "Layer Operation", QUndoCommand* parent = 0); 438 439 //! \name Undo Functions 440 //! \brief Reimplemented from the QUndoCommand class to provide specific undo/redo capability towards the map. 441 //{@ 442 void undo(); 443 void redo(); 444 //@} 445 446 //! Needed for accessing the current map's layers. 447 friend class Editor; 448 friend class EditorScrollView; 449 450 private: 451 //! \name Tile Vectors 452 //! \brief The following three vectors are used to know how to perform undo and redo operations 453 //! for this command. They should be the same size and one-to-one. So, the j-th element 454 //! of each vector should correspond to the j-th element of the other vectors. 455 //{@ 456 std::vector<int32> _tile_indeces; //! A vector of tile indeces in the map that were modified by this command. 457 std::vector<int32> _previous_tiles;//! A vector of indeces into tilesets of the modified tiles before they were modified. 458 std::vector<int32> _modified_tiles;//! A vector of indeces into tilesets of the modified tiles after they were modified. 459 //@} 460 461 //! Indicates which map layer this command was performed upon. 462 LAYER_TYPE _edited_layer; 463 //! A record of the active context when this command was performed. 464 int _context; 465 //! A reference to the main window so we can get the current map. 466 Editor* _editor; 467 }; // class LayerCommand 468 469 } // namespace hoa_editor 470 471 #endif 472 // __EDITOR_HEADER__ 473