1 /*
2     KBlackBox - A simple game inspired by an emacs module
3 
4     SPDX-FileCopyrightText: 1999-2000 Robert Cimrman <cimrman3@students.zcu.cz>
5     SPDX-FileCopyrightText: 2007 Nicolas Roffet <nicolas-kde@roffet.com>
6 
7     SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 
10 
11 
12 #ifndef KBBSCALABLEGRAPHICWIDGET_H
13 #define KBBSCALABLEGRAPHICWIDGET_H
14 
15 
16 class QAction;
17 class QGraphicsScene;
18 #include <QGraphicsView>
19 class QLCDNumber;
20 class QResizeEvent;
21 
22 
23 class KGamePopupItem;
24 class QPushButton;
25 
26 
27 class KBBBallsOnBoard;
28 class KBBGameDoc;
29 class KBBGraphicsItem;
30 class KBBGraphicsItemBallRepository;
31 class KBBGraphicsItemBlackBox;
32 class KBBGraphicsItemCursor;
33 class KBBGraphicsItemRay;
34 class KBBGraphicsItemSet;
35 class KBBThemeManager;
36 
37 
38 
39 /**
40  * @brief Scalable graphic central widget for KBlackBox
41  */
42 class KBBScalableGraphicWidget : public QGraphicsView
43 {
44 	Q_OBJECT
45 
46 	public:
47 		/**
48 		 * @brief Distance between the black box and the widget border
49 		 *
50 		 * Note: The widget is scalable, so it's just an arbitrary default compared with other ranges.
51 		 * It's the minimal distance as the width/height ratio is constant and the widget may have another width/height ratio.
52 		 * @see RATIO
53 		 */
54 		static int const BORDER_SIZE = 50;
55 
56 		/**
57 		 * @brief Width and height of a single square on the black box
58 		 *
59 		 * Note: The widget is scalable, so it's just an arbitrary default compared with other ranges.
60 		 */
61 		static int const RATIO = 25;
62 
63 		/**
64 		 * @brief Every graphic items
65 		 *
66 		 * Values are used to define the relative heights between the displayed graphic items.
67 		 * @see KBBThemeManager::zValue(const KBBScalableGraphicWidget::itemType itemType);
68 		 */
69 		enum itemType {
70 			background=0,
71 			informationBackground=1,
72 			blackbox=2,
73 			blackboxGrid=3,
74 			tutorialMarker=4,
75 			markerNothing=5,
76 			solutionRay=6,
77 			playerRay=7,
78 			resultBackground=8,
79 			resultBackgroundHighlight=9,
80 			resultReflection=10,
81 			resultHit=11,
82 			resultText=12,
83 			solutionBall=13,
84 			playerBall=14,
85 			unsureBall=15,
86 			wrongPlayerBall=16,
87 			rightPlayerBall=17,
88 			interactionInfoDeflection=18,
89 			interactionInfoHit=19,
90 			interactionInfoNothing=20,
91 			interactionInfoReflection=21,
92 			interactionInfoReflectionSym=22,
93 			laser0=23,
94 			laser90=24,
95 			laser180=25,
96 			laser270=26,
97 			cursor=27
98 		};
99 
100 
101 		/**
102 		 * @brief Constructor
103 		 */
104 		explicit KBBScalableGraphicWidget(KBBGameDoc* gameDoc, KBBThemeManager* themeManager, QAction* done);
105 		~KBBScalableGraphicWidget() override;
106 
107 
108 		void addBall(int boxPosition);
109 		void addBall(int boxPosition, int outsidePosition);
110 		void addBallUnsure(const int boxPosition);
111 		void addMarkerNothing(const int boxPosition);
112 		void drawRay(const int borderPosition);
113 		void mouseBorderClick(const int borderPosition);
114 		void mouseBoxClick(const Qt::MouseButton button, int boxPosition);
115 		int moveBall(const int boxPositionFrom, const int boxPositionTo);
116 		int moveMarkerNothing(const int boxPositionFrom, const int boxPositionTo);
117 		void newGame(int columns, int rows, int ballNumber);
118 
119 		/**
120 		 * @brief Message to display
121 		 *
122 		 * @param text Message. Attention: Message should not be too wide.
123 		 * @param time Time (in ms) the message remains displayed. 0 = forever.
124 		 */
125 		void popupText(const QString& text, int time = 5000);
126 
127 		int positionAfterMovingBall(const int boxPositionFrom, const int boxPositionTo) const;
128 
129 		void setPause(bool state);
130 		void removeAllBalls();
131 		void removeBall(const int boxPosition);
132 		void removeRay();
133 		void resizeEvent(QResizeEvent*) override;
134 		QGraphicsScene* scene();
135 		void setScore(int score);
136 
137 		/**
138 		 * @brief display the solution
139 		 *
140 		 * Used at the end of the game and for the sandbox mode.
141 		 * @param continueGame Sould the game continue after displaying the solution? (Yes for sandbox mode, no for normal game end).
142 		 */
143 		void solve(const bool continueGame);
144 
145 		void toggleCursor();
146 
147 	public Q_SLOTS:
148 	        void cursorOff();
149 		void hoverMovePosition(int newPosition);
150 		void cursorAtNewPosition(int borderPosition);
151 		void keyboardEnter();
152 		void keyboardMoveDown();
153 		void keyboardMoveLeft();
154 		void keyboardMoveRight();
155 		void keyboardMoveUp();
156 		void keyboardSpace();
157 
158 
159 	protected:
160 		void drawBackground(QPainter* painter, const QRectF&) override;
161 
162 
163 	private:
164 		/**
165 		 * @brief Minimum width and height
166 		 *
167 		 * Minimum width and minimum height of the widget. The widget needs a minimal site: it is ugly if it is too small.
168 		 */
169 		static int const MINIMUM_SIZE = 250;
170 
171 		static int const OFFSET_DONE_BUTTON = 12;
172 
173 		void fillBallsOutside();
174 		void removeMarkerNothing(const int boxPosition);
175 		void setBallUnsure(const int boxPosition, const bool unsure);
176 		void setInputAccepted(bool inputAccepted);
177 		void switchBall();
178 		void switchMarker();
179 		void updateDoneButton();
180 		void useLaser(const int incomingPosition);
181 
182 
183 		// Graphics items
184 		KBBGraphicsItemBlackBox* m_blackbox;
185 		KBBGraphicsItemSet* m_balls;
186 		KBBGraphicsItemSet* m_ballsSolution;
187 		KBBGraphicsItemSet* m_ballsUnsure;
188 		KBBGraphicsItemCursor* m_cursor;
189 		KBBGraphicsItemBallRepository* m_ballRepository;
190 		KBBGraphicsItemSet* m_lasers;
191 		KBBGraphicsItemSet* m_markersNothing;
192 		KBBGraphicsItemSet* m_rayResults;
193 		KBBGraphicsItemRay* m_playerRay;
194 		KBBGraphicsItemRay* m_solutionRay;
195 
196 
197 		/**
198 		 * @brief Position and size of the background in scene coordinates
199 		 *
200 		 * Used for drwing the background.
201 		 * @see drawBackground(QPainter* painter, const QRectF&)
202 		 */
203 		QRectF m_rectBackground;
204 
205 		// Various member variables
206 		int m_ballNumber;
207 		KBBBallsOnBoard* m_boardBalls;
208 		KBBBallsOnBoard* m_boardBallsPlaced;
209 		int m_columns;
210 		QAction* m_doneAction;
211 		QPushButton* m_doneButton;
212 		KBBGameDoc* m_gameDoc;
213 		KGamePopupItem* m_infoScore;
214 		bool m_inputAccepted;
215 		bool m_pause;
216 		int m_rayNumber;
217 
218 		int m_rows;
219 		QGraphicsScene* m_scene; //TODO: Remove it because scene() already gives it back.
220 		QLCDNumber* m_score;
221 		KBBThemeManager* m_themeManager;
222 		bool m_cursorFollowsMouse; //enable cursor following
223 };
224 
225 #endif // KBBSCALABLEGRAPHICWIDGET_H
226