File indexing completed on 2024-12-08 06:45:59
0001 /* 0002 SPDX-FileCopyrightText: 2009 Ian Wadham <iandw.au@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KGREDITOR_H 0008 #define KGREDITOR_H 0009 0010 #include "kgrglobals.h" 0011 0012 #include <QObject> 0013 0014 class KGrView; 0015 class KGrScene; 0016 class KGrGameIO; 0017 class QTimer; 0018 0019 /** 0020 * This class is the game-editor for KGoldrunner. It loads KGrGameData and 0021 * KGrLevelData objects from files, operates directly on the data in those 0022 * objects and saves them back to files. In particular, the layout of a level 0023 * is edited by selecting objects such as bricks, ladders, etc. from a toolbar 0024 * and using mouse-clicks and drags to show where those objects are required. 0025 * As this happens, the corresponding character-codes are stored directly in 0026 * the QByteArray of layout-data and the corresponding visual objects (tiles) 0027 * are displayed on the screen by the KGrScene and KGrView objects. 0028 * 0029 * @short Game-editor class 0030 */ 0031 class KGrEditor : public QObject 0032 { 0033 Q_OBJECT 0034 public: 0035 /** 0036 * The constructor of KGrEditor. 0037 * 0038 * @param theView The canvas on which the editor paints the layout. 0039 * Also the object that owns the editor and will destroy 0040 * it if the KGoldrunner application is terminated. 0041 * @param theSystemDir The directory-path where the games and levels 0042 * released with KGoldrunner are stored. This data is 0043 * read-only, but can be copied, edited and saved in 0044 * the user's area. 0045 * @param theUserDir The directory-path where the user's composed or 0046 * edited games and levels are stored. 0047 * @param pGameList The current list of system and user game-data. The 0048 * user can add a game to the list and add levels to 0049 * that game or any other game in the user's area. 0050 */ 0051 KGrEditor (KGrView * theView, const QString &theSystemDir, 0052 const QString &theUserDir, 0053 QList<KGrGameData *> & pGameList); 0054 ~KGrEditor() override; 0055 0056 /** 0057 * Check if there are any unsaved edits and, if so, ask the user what to 0058 * do. It will call saveLevelFile() if the user wants to save. 0059 * 0060 * @return If true, the level was successfully saved or there 0061 * was nothing to save or the user decided not to save, 0062 * so it is OK to do something new or close KGoldrunner. 0063 * If false, the user decided to continue editing or the 0064 * file I/O failed. 0065 */ 0066 bool saveOK(); 0067 0068 /** 0069 * Set up a blank level-layout, ready for editing. 0070 * 0071 * @param pGameIndex The list-index of the game which will contain the new 0072 * level: assumed for now, but can change at save time. 0073 * 0074 * @return If false, the action failed or was cancelled. 0075 */ 0076 bool createLevel (int pGameIndex); 0077 0078 /** 0079 * Load and display an existing level, ready for editing. This can be a 0080 * released level, but the changes must be saved in the user's area. 0081 * 0082 * @param pGameIndex The list-index of the game that contains the level 0083 * to be edited: verified by a dialog and may change. 0084 * @param pLevel The number of the level to be edited: verified by a 0085 * dialog and may change. 0086 * 0087 * @return If false, the action failed or was cancelled. 0088 */ 0089 bool updateLevel (int pGameIndex, int pLevel); 0090 0091 /** 0092 * Save an edited level in a text file (*.grl) in the user's area. The 0093 * required game and level number are obtained from a dialog. These are the 0094 * same as the original game and level number by default, but can be altered 0095 * so as to get a Save As effect. For example, a system level can be loaded 0096 * and edited, then saved in one of the user's own games. 0097 * 0098 * @return If true, the level was successfully saved. If false, 0099 * the user cancelled the save or the file I/O failed. 0100 */ 0101 bool saveLevelFile(); // Save the edited level in a text file (.grl). 0102 0103 /** 0104 * Move a level to another game or level number. Can be used to arrange 0105 * levels in order of difficulty within a game. 0106 * 0107 * @param pGameIndex The list-index of the game that contains the level 0108 * to be moved: a dialog selects the game to move to. 0109 * @param pLevel The number of the level to be moved: a dialog selects 0110 * the number to move to. Other numbers may be changed, 0111 * to preserve the sequential numbering of levels. 0112 * 0113 * @return If false, the action failed or was cancelled. 0114 */ 0115 bool moveLevelFile (int pGameIndex, int pLevel); 0116 0117 /** 0118 * Delete a level from a game. 0119 * 0120 * @param pGameIndex The list-index of the game that contains the level 0121 * to be deleted: verified by a dialog and may change. 0122 * @param pLevel The number of the level to be deleted: verified by a 0123 * dialog and may change. 0124 * 0125 * @return If false, the action failed or was cancelled. 0126 */ 0127 bool deleteLevelFile (int pGameIndex, int pLevel); 0128 0129 /** 0130 * Create a new game (a collection point for levels) or load the details 0131 * of an existing game, ready for editing. 0132 * 0133 * @param pGameIndex The list-index of the game to be created or edited: 0134 * 0 = create, >0 = edit (verified by a dialog and may 0135 * change). 0136 * 0137 * @return If false, the action failed or was cancelled. 0138 */ 0139 bool editGame (int pGameIndex); 0140 0141 public Q_SLOTS: 0142 /** 0143 * Run a dialog in which the name and hint of a level can be edited. 0144 */ 0145 void editNameAndHint(); 0146 0147 public: 0148 /** 0149 * Set the next object for the editor to paint, e.g. brick, enemy, ladder. 0150 * 0151 * @param newEditObj A character-code for the type of object. 0152 */ 0153 void setEditObj (char newEditObj); 0154 0155 inline void getGameAndLevel (int & game, int & lev) { 0156 game = gameIndex; lev = editLevel; } 0157 0158 Q_SIGNALS: 0159 /** 0160 * Get the next grid-position at which to paint an object in the layout. 0161 * 0162 * @param i The row-number of the cell (return by reference). 0163 * @param j The column-number of the cell (return by reference). 0164 */ 0165 void getMousePos (int & i, int & j); 0166 0167 private: 0168 KGrView * view; // The canvas on which the editor paints. 0169 KGrScene * scene; 0170 KGrGameIO * io; // I/O object for reading level-data. 0171 QString systemDataDir; 0172 QString userDataDir; 0173 0174 // Will REFERENCE the main list in KGrGame, allowing KGrEditor to add games. 0175 QList<KGrGameData *> & gameList; 0176 0177 bool mouseMode; // Flag to set up keyboard OR mouse control. 0178 bool editMode; // Flag to change keyboard and mouse functions. 0179 char editObj; // Type of object to be painted by the mouse. 0180 bool paintEditObj; // Sets painting on/off (toggled by clicking). 0181 bool paintAltObj; // Sets painting for the alternate object on/off 0182 int oldI, oldJ; // Last mouse position painted. 0183 int editLevel; // Level to be edited (= 0 for new level). 0184 int heroCount; // Can enter at most one hero. 0185 bool shouldSave; // True if name or hint was edited. 0186 0187 // The list-index of the game (collection of levels) being composed/edited. 0188 int gameIndex; 0189 0190 // The data, including the layout, for the level being composed or edited. 0191 KGrLevelData levelData; 0192 KGrLevelData savedLevelData; 0193 QString levelName; // Level name during editing (optional). 0194 QString levelHint; // Level hint during editing (optional). 0195 0196 /** 0197 * Run a dialog to select a game and level to be edited or saved. 0198 * 0199 * @param action A code for the type of editing: affects validation 0200 * and labeling in the dialog. 0201 * @param requestedLevel The current level, used as a default, but can be 0202 * changed by the user. 0203 * @param requestedGame The current game, used as a default, but can be 0204 * changed by the user (return by reference). 0205 * 0206 * @return The level the user chose, or zero if the user 0207 * cancelled the dialog. The level chosen could be 0208 * different from the requestedLevel parameter. 0209 */ 0210 int selectLevel (int action, int requestedLevel, int & requestedGame); 0211 0212 void loadEditLevel (int); // Load and display an existing level for edit. 0213 void initEdit(); 0214 void insertEditObj (int, int, char object); 0215 char editableCell (int i, int j); 0216 void setEditableCell (int, int, char); 0217 bool reNumberLevels (int, int, int, int); 0218 bool ownerOK (Owner o); 0219 bool saveGameData (Owner o); 0220 0221 QString getTitle(); 0222 QString getLevelFilePath (KGrGameData * gameData, int lev); 0223 0224 QTimer * timer; // The time-signal for the game-editor. 0225 0226 bool mouseDisabled; 0227 0228 private Q_SLOTS: 0229 /** 0230 * Start painting or erasing cells on the layout. Triggered by pressing 0231 * a mouse-button. 0232 * 0233 * @param button The button being pressed: left for paint, right for erase. 0234 */ 0235 void doEdit (int button); 0236 0237 /** 0238 * If the mouse has moved to a new cell and a button is down, continue 0239 * painting or erasing cells on the layout. Triggered by a timer signal. 0240 */ 0241 void tick (); 0242 0243 /** 0244 * Stop painting or erasing cells on the layout. Triggered by releasing 0245 * a mouse-button. 0246 * 0247 * @param button The button being released: left for paint, right for erase. 0248 */ 0249 void endEdit (int button); 0250 }; 0251 0252 #endif // KGREDITOR_H