1 /* ColorCode, a free MasterMind clone with built in solver
2 * Copyright (C) 2009 Dirk Laebisch
3 * http://www.laebisch.com/
4 *
5 * ColorCode is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * ColorCode is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with ColorCode. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <QtWidgets>
20
21 #include "rowhint.h"
22
23 using namespace std;
24
25 const int RowHint::mPegPos[4][5][3] = {
26 {
27 { 6, 14, 12 },
28 { 22, 14, 12 },
29 { 0, 0, 0 },
30 { 0, 0, 0 },
31 { 0, 0, 0 },
32 },
33 {
34 { 6, 7, 12 },
35 { 22, 7, 12 },
36 { 14, 21, 12 },
37 { 0, 0, 0 },
38 { 0, 0, 0 },
39 },
40 {
41 { 6, 6, 12 },
42 { 22, 6, 12 },
43 { 6, 22, 12 },
44 { 22, 22, 12 },
45 { 0, 0, 0 },
46 },
47 {
48 { 4, 4, 12 },
49 { 24, 4, 12 },
50 { 14, 14, 12 },
51 { 4, 24, 12 },
52 { 24, 24, 12 }
53 }
54 };
55
RowHint(QObject *)56 RowHint::RowHint(QObject*)
57 {
58 mIx = -1;
59 mPegCnt = 0;
60
61 mPen = QPen(QColor("#808080"));
62 mPen.setWidth(2);
63
64 QRadialGradient grad(QPointF(10, 10), 100);
65 grad.setColorAt(0, QColor("#d8d8d8"));
66 grad.setColorAt(1, QColor("#ffffff"));
67 mBrush1 = QBrush(grad);
68 grad.setColorAt(0, QColor(216, 216, 216, 51));
69 grad.setColorAt(1, QColor(255, 255, 255, 51));
70 mBrush0 = QBrush(grad);
71
72 Reset(0, 0);
73 }
74
~RowHint()75 RowHint::~RowHint()
76 {
77 scene()->removeItem(this);
78 }
79
Reset(const int pegcnt,const int gamemode)80 void RowHint::Reset(const int pegcnt, const int gamemode)
81 {
82 mActive = true;
83 mSolved = false;
84 SetPegCnt(pegcnt);
85 mHints.clear();
86 mHints.assign(mPegCnt, 0);
87 SetGameMode(gamemode);
88 SetActive(false);
89 }
90
GetIx() const91 int RowHint::GetIx() const
92 {
93 return mIx;
94 }
95
SetIx(const int ix)96 void RowHint::SetIx(const int ix)
97 {
98 mIx = ix;
99 }
100
SetPegCnt(const int pegcnt)101 void RowHint::SetPegCnt(const int pegcnt)
102 {
103 mPegCnt = pegcnt;
104 }
105
SetGameMode(const int gamemode)106 void RowHint::SetGameMode(const int gamemode)
107 {
108 mGameMode = gamemode;
109 }
110
IsActive() const111 bool RowHint::IsActive() const
112 {
113 return mActive;
114 }
115
SetActive(bool b)116 void RowHint::SetActive(bool b)
117 {
118 if (b == mActive)
119 {
120 return;
121 }
122
123 mActive = b;
124 setAcceptHoverEvents(b);
125 setEnabled(b);
126 if (b)
127 {
128 if (mGameMode == ColorCode::MODE_HVM)
129 {
130 setCursor(Qt::PointingHandCursor);
131 setToolTip(tr("Commit Your solution"));
132 }
133 else if (mGameMode == ColorCode::MODE_MVH)
134 {
135 mSolved = true;
136 mHints.assign(mPegCnt, 0);
137 setCursor(Qt::ArrowCursor);
138 setToolTip(tr("Click the circles to rate my guess.\nHit Ctrl+H or the corresponding toolbar button to let an impartial part of me do this for you ;-)"));
139 }
140 }
141 else
142 {
143 setCursor(Qt::ArrowCursor);
144 setToolTip(QString(""));
145 }
146
147 update(boundingRect());
148 }
149
SetPaused(const bool b)150 void RowHint::SetPaused(const bool b)
151 {
152 if (b)
153 {
154 setCursor(Qt::ArrowCursor);
155 setToolTip(QString(""));
156 }
157 else if (mActive)
158 {
159 setCursor(Qt::PointingHandCursor);
160 setToolTip(tr("Commit Your solution"));
161 }
162 update(boundingRect());
163 }
164
GetHints()165 std::vector<int> RowHint::GetHints()
166 {
167 return mHints;
168 }
169
DrawHints(std::vector<int> res)170 void RowHint::DrawHints(std::vector<int> res)
171 {
172 mHints.clear();
173 mHints.assign(mPegCnt, 0);
174 for (unsigned i = 0; i < res.size(); ++i)
175 {
176 mHints.at(i) = res.at(i);
177 }
178 mSolved = true;
179 update(boundingRect());
180 }
181
mousePressEvent(QGraphicsSceneMouseEvent * e)182 void RowHint::mousePressEvent(QGraphicsSceneMouseEvent* e)
183 {
184 if (ColorCode::INSTANCE->GetGameState() == ColorCode::STATE_PAUSED)
185 {
186 return;
187 }
188
189 if (e->button() != Qt::LeftButton)
190 {
191 return;
192 }
193
194 if (mGameMode == ColorCode::MODE_HVM)
195 {
196 bool disabled = false;
197 if (mActive && !mSolved)
198 {
199 if (e->button() == Qt::LeftButton)
200 {
201 SetActive(false);
202 emit HintPressedSignal(mIx);
203 disabled = true;
204 }
205 }
206
207 if (!disabled)
208 {
209 QGraphicsItem::mousePressEvent(e);
210 }
211 }
212 else if (mGameMode == ColorCode::MODE_MVH)
213 {
214 qreal xm = e->pos().x();
215 qreal ym = e->pos().y();
216
217 int posix = mPegCnt - 2;
218 for (int i = 0; i < mPegCnt; i++)
219 {
220 if ( xm >= mPegPos[posix][i][0] && xm <= mPegPos[posix][i][0] + mPegPos[posix][i][2]
221 && ym >= mPegPos[posix][i][1] && ym <= mPegPos[posix][i][1] + mPegPos[posix][i][2])
222 {
223 ++mHints.at(i);
224 if (mHints.at(i) > 2)
225 {
226 mHints.at(i) = 0;
227 }
228 }
229 }
230 update(boundingRect());
231 }
232 }
233
shape() const234 QPainterPath RowHint::shape() const
235 {
236 QPainterPath path;
237 path.addRect(boundingRect());
238 return path;
239 }
240
boundingRect() const241 QRectF RowHint::boundingRect() const
242 {
243 const int margin = 1;
244 return outlineRect().adjusted(-margin, -margin, 2 * margin, 2 * margin);
245 }
246
outlineRect() const247 QRectF RowHint::outlineRect() const
248 {
249 return QRectF(0.0, 0.0, 40.0, 40.0);
250 }
251
paint(QPainter * painter,const QStyleOptionGraphicsItem *,QWidget *)252 void RowHint::paint(QPainter* painter, const QStyleOptionGraphicsItem* , QWidget* )
253 {
254 if (mPegCnt == 0)
255 {
256 return;
257 }
258
259 int i;
260
261 QColor pend = QColor("#646568");
262 QColor penl = QColor("#ecedef");
263 QColor grad0 = QColor("#cccdcf");
264 QColor grad1 = QColor("#fcfdff");
265 if (mActive)
266 {
267 pend.setAlpha(0xff);
268 penl.setAlpha(0xff);
269 grad0.setAlpha(0xff);
270 grad1.setAlpha(0xff);
271 }
272 else if (mSolved)
273 {
274 pend.setAlpha(0xa0);
275 penl.setAlpha(0xa0);
276 grad0.setAlpha(0xa0);
277 grad1.setAlpha(0xa0);
278 }
279 else
280 {
281 pend.setAlpha(0x32);
282 penl.setAlpha(0x50);
283 grad0.setAlpha(0x32);
284 grad1.setAlpha(0x32);
285 }
286 painter->setPen(Qt::NoPen);
287
288 painter->setBrush(QBrush(penl));
289 painter->drawRect(QRectF(0.0, 0.0, 39, 1));
290 painter->drawRect(QRectF(0.0, 0.0, 1, 39));
291 painter->setBrush(QBrush(pend));
292 painter->drawRect(QRectF(0.0, 39.0, 40, 1));
293 painter->drawRect(QRectF(39, 0.0, 1, 40));
294
295 QRadialGradient grad(QPointF(10, 10), 100);
296 grad.setColorAt(0, grad0);
297 grad.setColorAt(1, grad1);
298 painter->setBrush(QBrush(grad));
299 painter->drawRect(QRectF(1, 1.0, 38.0, 38.0));
300
301 painter->setBrush(Qt::NoBrush);
302
303 int posix = mPegCnt - 2;
304 QPointF x0;
305 for (i = 0; i < mPegCnt; i++)
306 {
307 x0 = QPointF(mPegPos[posix][i][0], mPegPos[posix][i][1]);
308 QLinearGradient lgrad(x0, QPointF(x0.x() + 10, x0.y() + 10));
309 lgrad.setColorAt(0.0, QColor(0, 0, 0, 0xa0));
310 lgrad.setColorAt(1.0, QColor(0xff, 0xff, 0xff, 0xa0));
311 painter->setPen(QPen(QBrush(lgrad), 0.5));
312 painter->drawEllipse(QRectF(mPegPos[posix][i][0], mPegPos[posix][i][1], mPegPos[posix][i][2], mPegPos[posix][i][2]));
313 }
314
315 if (mSolved && ColorCode::INSTANCE->GetGameState() != ColorCode::STATE_PAUSED)
316 {
317 painter->setPen(Qt::NoPen);
318 for (unsigned i = 0; i < mHints.size(); i++)
319 {
320 if (mHints.at(i) == 0)
321 {
322 continue;
323 }
324
325 if (mHints.at(i) == 2)
326 {
327 painter->setBrush(QBrush(Qt::black));
328 }
329 else
330 {
331 painter->setBrush(QBrush(Qt::white));
332 }
333 painter->drawEllipse(QRectF(mPegPos[posix][i][0], mPegPos[posix][i][1], mPegPos[posix][i][2], mPegPos[posix][i][2]));
334 }
335 }
336 }
337