File indexing completed on 2024-04-14 03:59:51

0001 /*
0002     SPDX-FileCopyrightText: 2012 Christian Krippendorf <Coding@Christian-Krippendorf.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef GAMEVIEW_H
0008 #define GAMEVIEW_H
0009 
0010 // Qt
0011 #include <QGraphicsView>
0012 
0013 // KMahjongg
0014 #include "kmtypes.h"
0015 
0016 constexpr int ANIMATION_SPEED = 200;
0017 
0018 // Forward declaration...
0019 class GameScene;
0020 class GameData;
0021 class GameItem;
0022 class GameBackground;
0023 class GameRemovedTiles;
0024 class SelectionAnimation;
0025 class MoveListAnimation;
0026 class DemoAnimation;
0027 class KMahjonggTileset;
0028 class KMahjonggBackground;
0029 class QMouseEvent;
0030 
0031 /**
0032  * The Mahjongg board where the tiles (GameItems) will be painted.
0033  *
0034  * @author Christian Krippendorf */
0035 class GameView : public QGraphicsView
0036 {
0037     Q_OBJECT
0038 
0039 public:
0040     /**
0041      * Constructor
0042      *
0043      * @param gameScene The related GameScene object.
0044      * @param gameData The related GameData object.
0045      * @param parent The parent widget.
0046      */
0047     GameView(GameScene * gameScene, GameData * gameData, QWidget * parent = nullptr);
0048     ~GameView() override;
0049 
0050     /**
0051      * Items where added to the scene and should now be layouted.
0052      *
0053      * @param gameItems The items of which the positions should be updated. */
0054     void updateItemsPosition(const QList<GameItem *> &gameItems);
0055 
0056     /**
0057      * Overloaded function of scene game item positioning.
0058      */
0059     void updateItemsPosition();
0060 
0061     /**
0062      * Updates the whole widget.
0063      *
0064      * @param showTiles True if the tiles should be displayed, else false. */
0065     void updateWidget(bool showTiles);
0066 
0067     /**
0068      * Override from QGraphcisView. */
0069     virtual QList<GameItem *> getGameItems() const;
0070 
0071     /**
0072      * Set whether removed tiles should be shown.
0073      * @param show True if removed tiles should be shown.
0074      */
0075     void showRemovedTiles(bool show);
0076 
0077     /**
0078      * Override from QGraphicsView. */
0079     GameScene * scene() const;
0080 
0081     /**
0082      * Set the GameData object.
0083      *
0084      * @param gameData The game data object. */
0085     void setGameData(GameData * gameData);
0086 
0087     /**
0088      * Get the GameData object that is actually set.
0089      *
0090      * @return The actual GameData object. */
0091     GameData * getGameData() const;
0092 
0093     /**
0094      * Set the angle of the view.
0095      *
0096      * @param angle The angle of to set up. */
0097     void setAngle(TileViewAngle angle);
0098 
0099     /**
0100      * Get the angle of the view.
0101      *
0102      * @return The angle of the view. */
0103     TileViewAngle getAngle() const;
0104 
0105     /**
0106      * Test for active help animation and maybe close.
0107      *
0108      * @param stop Stop the help animation if running.
0109      * @return Return true if the help animation was running else false. */
0110     bool checkHelpAnimationActive(bool stop = false);
0111 
0112     /**
0113      * Test for active demo animation and maybe close.
0114      *
0115      * @param stop Stop the demo animation if running.
0116      * @return Return true if the demo animation was running else false. */
0117     bool checkDemoAnimationActive(bool stop = false);
0118 
0119     /**
0120      * Test for active move list animation and maybe close.
0121      *
0122      * @param stop Stop the move list animation if running.
0123      * @return Return true if the move list animation was running else false. */
0124     bool checkMoveListAnimationActive(bool stop = false);
0125 
0126     /**
0127      * Set the match variable. If set to true, the matching items to the selected will be animated.
0128      *
0129      * @param match The match value to set up. */
0130     void setMatch(bool match);
0131 
0132     /**
0133      * Get the match value.
0134      *
0135      * @return True when matching items of the selected one will be displayed, else false. */
0136     bool getMatch() const;
0137 
0138     /**
0139      * Gets the tilesetpath that is actually set.
0140      *
0141      * @return The tilesetpath as a string. */
0142     QString getTilesetPath() const;
0143 
0144     /**
0145      * Gets the background path that is actually set.
0146      *
0147      * @return The background path as a string. */
0148     QString getBackgroundPath() const;
0149 
0150     /**
0151      * Sets the tileset path and tries to load it.
0152      *
0153      * @param tilesetPath The path to the tileset.
0154      * @return True if setting and therefore loading success, else false. */
0155     bool setTilesetPath(QString const & tilesetPath);
0156 
0157     /**
0158      * Sets the background path and tries to load it.
0159      *
0160      * @param backgroundPath The path to the background.
0161      * @return True if setting and therefore loading success, else false. */
0162     bool setBackgroundPath(QString const & backgroundPath);
0163 
0164     /**
0165      * Undo the last move.
0166      *
0167      * @return True if successful, else false. */
0168     bool undo();
0169 
0170     /**
0171      * Redo the last undo.
0172      *
0173      * @return True if successful, else false. */
0174     bool redo();
0175 
0176     /**
0177      * Test if undo is allowed.
0178      *
0179      * @return True if allowed, else false. */
0180     bool checkUndoAllowed();
0181 
0182     /**
0183      * Test if redo is allowed.
0184      *
0185      * @return True if allowed, else false. */
0186     bool checkRedoAllowed();
0187 
0188     /**
0189      * Get the game number.
0190      *
0191      * @return The game number or -1 if no game number set. */
0192     long getGameNumber() const;
0193 
0194     /**
0195      * Set the game number.
0196      *
0197      * @param gameNumber Game number. */
0198     void setGameNumber(long gameNumber);
0199 
0200     /**
0201      * Search for a valid move silently or with an information text.
0202      *
0203      * @param silent False if a message should appears when no legal moves exist, else true.
0204      *        Default ist false!
0205      * @return True if a legal move exist, else false. */
0206     bool validMovesAvailable(bool silent = false);
0207 
0208     /**
0209      * Hide/show tiles when game is paused/unpaused. */
0210     void pause(bool isPaused);
0211 
0212     /**
0213      * Get whether a game was generated.
0214      *
0215      * @return True if game was generated, or false. */
0216     bool gameGenerated();
0217 
0218 public Q_SLOTS:
0219     /**
0220      * Add a new item with the given position and update images, position and order. */
0221     void addItemAndUpdate(POSITION & stItemPos);
0222 
0223     /**
0224      * Remove the given item.
0225      *
0226      * @param stItemPos The item position. */
0227     void removeItem(POSITION & stItemPos);
0228 
0229     /**
0230      * Starts the demo animation. */
0231     void startDemo();
0232 
0233     /**
0234      * Switch the view angle to the next right around. */
0235     void angleSwitchCCW();
0236 
0237     /**
0238      * Switch the view angle to the next left around. */
0239     void angleSwitchCW();
0240 
0241     /**
0242      * Create a new game.
0243      *
0244      * @param gameNumber The game number to create or -1 for a random number. */
0245     void createNewGame(long gameNumber = -1);
0246 
0247     /**
0248      * Shuffle the position of items. */
0249     void shuffle();
0250 
0251     /**
0252      * Give a hint for a valid move. */
0253     void helpMove();
0254 
0255     /**
0256      * Give a hint to the matching tiles.
0257      *
0258      * @param gameItem The item we search matching tiles for. */
0259     void helpMatch(const GameItem * const gameItem);
0260 
0261     /**
0262      * Start the move list animation. */
0263     void startMoveListAnimation();
0264 
0265     /**
0266      * Clear the selection. */
0267     void clearSelectedTile();
0268 
0269 protected:
0270     /**
0271      * Override from QGraphicsView. */
0272     void resizeEvent(QResizeEvent * event) override;
0273 
0274     /**
0275      * Override from QGraphicsView. */
0276     void mousePressEvent(QMouseEvent * mouseEvent) override;
0277 
0278 Q_SIGNALS:
0279     /**
0280      * Emits when a new game was calculated. */
0281     void newGameCalculated();
0282 
0283     /**
0284      * Emits when the status text changed.
0285      *
0286      * @param text The new status text.
0287      * @param gameNumber The actual game number. */
0288     void statusTextChanged(const QString & text, long gameNumber);
0289 
0290     /**
0291      * Emits when the number of the items changed or could change.
0292      *
0293      * @param maxItemNum The max tile number.
0294      * @param itemNum The item number that are still there.
0295      * @param moveCount Number of moves. */
0296     void itemNumberChanged(int maxItemNum, int itemNum, int moveCount);
0297 
0298     /**
0299      * Emits when the game is over.
0300      *
0301      * @param removedItems The number of the removed items.
0302      * @param cheatsUsed The number of the cheats that are used. */
0303     void gameOver(unsigned short removedItems, unsigned short cheatsUsed);
0304 
0305     /**
0306      * Emits when demo is played out and lost or stopped by a mouse click, or
0307      * the MoveListAnimation is stopped by a mouse click.
0308      *
0309      * @param demoGameLost True if demo game is played out and lost. */
0310     void demoOrMoveListAnimationOver(bool demoGameLost);
0311 
0312     /**
0313      * Emits when no more moves are available. */
0314     void noMovesAvailable();
0315 
0316 private Q_SLOTS:
0317     /**
0318      * Add a new item with the given position.
0319      *
0320      * @param stItemPos The position for the new item.
0321      * @param updateImage True for updating the images else false.
0322      * @param updateOrder True for updating the order else false.
0323      * @param updatePosition True for updating the position else false. */
0324     void addItem(POSITION & stItemPos, bool updateImage = false, bool updateOrder = false,
0325                  bool updatePosition = false);
0326 
0327     /**
0328      * Add a new item.
0329      *
0330      * @param gameItem The new game item object.
0331      * @param updateImage True for updating the images else false.
0332      * @param updateOrder True for updating the order else false.
0333      * @param updatePosition True for updating the position else false. */
0334     void addItem(GameItem * gameItem, bool updateImage = false, bool updateOrder = false,
0335                  bool updatePosition = false);
0336 
0337     /**
0338      * When the game is over by the demo mode.
0339      *
0340      * @param won True if the computer won in demo mode, else false. */
0341     void demoGameOver(bool won);
0342 
0343     /**
0344      * Change the selected state of the given item.
0345      *
0346      * @param stItemPos The position of the item.
0347      * @param selected The selection state to set. */
0348     void changeItemSelectedState(POSITION & stItemPos, bool selected);
0349 
0350     /**
0351      * Gets called when a pair was selected. */
0352     void selectionChanged();
0353 
0354 private:
0355     /**
0356      * Updates the images of the items.
0357      *
0358      * @param gameItem The items of which the images should be updated. */
0359     void updateItemsImages(const QList<GameItem *> &gameItems);
0360 
0361     /**
0362      * Updates the order of the items. */
0363     void updateItemsOrder();
0364 
0365     /**
0366      * Populates the number of the items, by emit a signal: itemNumberChanged(...). */
0367     void populateItemNumber();
0368 
0369     /**
0370      * Sets the status text.
0371      *
0372      * @param text The new status text. */
0373     void setStatusText(const QString & text);
0374 
0375     /**
0376      * Resize the tileset to the given size.
0377      *
0378      * @param size The new size of the tileset. */
0379     void resizeTileset(const QSize & size);
0380 
0381     /**
0382      * Updates the background by creating a new QPalette object. */
0383     void updateBackground();
0384 
0385     /**
0386      * Add all the items from the board layout to the scene object. */
0387     void addItemsFromBoardLayout();
0388 
0389     /**
0390      * Order the line starting by the item.
0391      *
0392      * @param startItem The item where the line starts.
0393      * @param xStart The x position of the item.
0394      * @param y The y position of the item.
0395      * @param z The z position of the item.
0396      * @param zCount The z count variable for the order. */
0397     void orderLine(GameItem * startItem, int xStart, int xEnd, int xCounter, int y,
0398                    int yCounter, int z, int & zCount);
0399 
0400     unsigned short m_cheatsUsed;
0401     quint32 m_gameNumber;
0402     bool m_gamePaused;
0403     bool m_match;
0404     bool m_gameGenerated;
0405     bool m_showRemovedTiles;
0406 
0407     qreal m_remTilesWidthFactor;
0408 
0409     GameData * m_gameData;
0410     GameItem * m_selectedItem;
0411     GameBackground * m_gameBackground;
0412     GameRemovedTiles * m_gameRemovedTiles;
0413 
0414     QString * m_tilesetPath;
0415     QString * m_backgroundPath;
0416 
0417     SelectionAnimation * m_helpAnimation;
0418     MoveListAnimation * m_moveListAnimation;
0419     DemoAnimation * m_demoAnimation;
0420 
0421     KMahjonggTileset * m_tiles;
0422     KMahjonggBackground * m_background;
0423 
0424     TileViewAngle m_angle;
0425 
0426     // Needed for disconnecting connection
0427     QMetaObject::Connection m_selectionChangedConnect;
0428 };
0429 
0430 #endif // GAMEVIEW_H