File indexing completed on 2024-04-21 04:02:03

0001 /*
0002     KBlackBox - A simple game inspired by an emacs module
0003 
0004     SPDX-FileCopyrightText: 1999-2000 Robert Cimrman <cimrman3@students.zcu.cz>
0005     SPDX-FileCopyrightText: 2007 Nicolas Roffet <nicolas-kde@roffet.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 
0011 
0012 #ifndef KBBSCALABLEGRAPHICWIDGET_H
0013 #define KBBSCALABLEGRAPHICWIDGET_H
0014 
0015 
0016 class QAction;
0017 class QGraphicsScene;
0018 #include <QGraphicsView>
0019 class QLCDNumber;
0020 class QResizeEvent;
0021 
0022 
0023 class KGamePopupItem;
0024 class QPushButton;
0025 
0026 
0027 class KBBBallsOnBoard;
0028 class KBBGameDoc;
0029 class KBBGraphicsItem;
0030 class KBBGraphicsItemBallRepository;
0031 class KBBGraphicsItemBlackBox;
0032 class KBBGraphicsItemCursor;
0033 class KBBGraphicsItemRay;
0034 class KBBGraphicsItemSet;
0035 class KBBThemeManager;
0036 
0037 
0038 
0039 /**
0040  * @brief Scalable graphic central widget for KBlackBox
0041  */
0042 class KBBScalableGraphicWidget : public QGraphicsView
0043 {
0044     Q_OBJECT
0045 
0046     public:
0047         /**
0048          * @brief Distance between the black box and the widget border
0049          *
0050          * Note: The widget is scalable, so it's just an arbitrary default compared with other ranges.
0051          * It's the minimal distance as the width/height ratio is constant and the widget may have another width/height ratio.
0052          * @see RATIO
0053          */
0054         static int const BORDER_SIZE = 50;
0055 
0056         /**
0057          * @brief Width and height of a single square on the black box
0058          *
0059          * Note: The widget is scalable, so it's just an arbitrary default compared with other ranges.
0060          */
0061         static int const RATIO = 25;
0062 
0063         /**
0064          * @brief Every graphic items
0065          *
0066          * Values are used to define the relative heights between the displayed graphic items.
0067          * @see KBBThemeManager::zValue(const KBBScalableGraphicWidget::itemType itemType);
0068          */
0069         enum itemType {
0070             background=0,
0071             informationBackground=1,
0072             blackbox=2,
0073             blackboxGrid=3,
0074             tutorialMarker=4,
0075             markerNothing=5,
0076             solutionRay=6,
0077             playerRay=7,
0078             resultBackground=8,
0079             resultBackgroundHighlight=9,
0080             resultReflection=10,
0081             resultHit=11,
0082             resultText=12,
0083             solutionBall=13,
0084             playerBall=14,
0085             unsureBall=15,
0086             wrongPlayerBall=16,
0087             rightPlayerBall=17,
0088             interactionInfoDeflection=18,
0089             interactionInfoHit=19,
0090             interactionInfoNothing=20,
0091             interactionInfoReflection=21,
0092             interactionInfoReflectionSym=22,
0093             laser0=23,
0094             laser90=24,
0095             laser180=25,
0096             laser270=26,
0097             cursor=27
0098         };
0099         
0100         
0101         /**
0102          * @brief Constructor
0103          */
0104         explicit KBBScalableGraphicWidget(KBBGameDoc* gameDoc, KBBThemeManager* themeManager, QAction* done);
0105         ~KBBScalableGraphicWidget() override;
0106 
0107 
0108         void addBall(int boxPosition);
0109         void addBall(int boxPosition, int outsidePosition);
0110         void addBallUnsure(const int boxPosition);
0111         void addMarkerNothing(const int boxPosition);
0112         void drawRay(const int borderPosition);
0113         void mouseBorderClick(const int borderPosition);
0114         void mouseBoxClick(const Qt::MouseButton button, int boxPosition);
0115         int moveBall(const int boxPositionFrom, const int boxPositionTo);
0116         int moveMarkerNothing(const int boxPositionFrom, const int boxPositionTo);
0117         void newGame(int columns, int rows, int ballNumber);
0118 
0119         /**
0120          * @brief Message to display
0121          *
0122          * @param text Message. Attention: Message should not be too wide.
0123          * @param time Time (in ms) the message remains displayed. 0 = forever.
0124          */
0125         void popupText(const QString& text, int time = 5000);
0126 
0127         int positionAfterMovingBall(const int boxPositionFrom, const int boxPositionTo) const;
0128 
0129         void setPause(bool state);
0130         void removeAllBalls();
0131         void removeBall(const int boxPosition);
0132         void removeRay();
0133         void resizeEvent(QResizeEvent*) override;
0134         QGraphicsScene* scene();
0135         void setScore(int score);
0136 
0137         /**
0138          * @brief display the solution
0139          *
0140          * Used at the end of the game and for the sandbox mode.
0141          * @param continueGame Sould the game continue after displaying the solution? (Yes for sandbox mode, no for normal game end).
0142          */
0143         void solve(const bool continueGame);
0144 
0145         void toggleCursor();
0146 
0147     public Q_SLOTS:
0148             void cursorOff();
0149         void hoverMovePosition(int newPosition);
0150         void cursorAtNewPosition(int borderPosition);
0151         void keyboardEnter();
0152         void keyboardMoveDown();
0153         void keyboardMoveLeft();
0154         void keyboardMoveRight();
0155         void keyboardMoveUp();
0156         void keyboardSpace();
0157 
0158 
0159     protected:
0160         void drawBackground(QPainter* painter, const QRectF&) override;
0161 
0162 
0163     private:
0164         /**
0165          * @brief Minimum width and height
0166          *
0167          * Minimum width and minimum height of the widget. The widget needs a minimal site: it is ugly if it is too small.
0168          */
0169         static int const MINIMUM_SIZE = 250;
0170 
0171         static int const OFFSET_DONE_BUTTON = 12;
0172 
0173         void fillBallsOutside();
0174         void removeMarkerNothing(const int boxPosition);
0175         void setBallUnsure(const int boxPosition, const bool unsure);
0176         void setInputAccepted(bool inputAccepted);
0177         void switchBall();
0178         void switchMarker();
0179         void updateDoneButton();
0180         void useLaser(const int incomingPosition);
0181         
0182         
0183         // Graphics items
0184         KBBGraphicsItemBlackBox* m_blackbox;
0185         KBBGraphicsItemSet* m_balls;
0186         KBBGraphicsItemSet* m_ballsSolution;
0187         KBBGraphicsItemSet* m_ballsUnsure;
0188         KBBGraphicsItemCursor* m_cursor;
0189         KBBGraphicsItemBallRepository* m_ballRepository;
0190         KBBGraphicsItemSet* m_lasers;
0191         KBBGraphicsItemSet* m_markersNothing;
0192         KBBGraphicsItemSet* m_rayResults;
0193         KBBGraphicsItemRay* m_playerRay;
0194         KBBGraphicsItemRay* m_solutionRay;
0195         
0196         
0197         /**
0198          * @brief Position and size of the background in scene coordinates
0199          *
0200          * Used for drwing the background.
0201          * @see drawBackground(QPainter* painter, const QRectF&)
0202          */
0203         QRectF m_rectBackground;
0204         
0205         // Various member variables
0206         int m_ballNumber;
0207         KBBBallsOnBoard* m_boardBalls;
0208         KBBBallsOnBoard* m_boardBallsPlaced;
0209         int m_columns;
0210         QAction* m_doneAction;
0211         QPushButton* m_doneButton;
0212         KBBGameDoc* m_gameDoc;
0213         KGamePopupItem* m_infoScore;
0214         bool m_inputAccepted;
0215         bool m_pause;
0216         int m_rayNumber;
0217         
0218         int m_rows;
0219         QGraphicsScene* m_scene; //TODO: Remove it because scene() already gives it back.
0220         QLCDNumber* m_score;
0221         KBBThemeManager* m_themeManager;
0222         bool m_cursorFollowsMouse; //enable cursor following
0223 };
0224 
0225 #endif // KBBSCALABLEGRAPHICWIDGET_H