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 "colorpeg.h"
22 
23 using namespace std;
24 
25 const QFont ColorPeg::mFont = ColorPeg::GetLetterFont();
26 const QBrush ColorPeg::mShadowBrush = ColorPeg::GetShadowBrush();
27 const QBrush ColorPeg::mOutlineBrush = ColorPeg::GetOutlineBrush();
28 const QBrush ColorPeg::mGlossyBrush = ColorPeg::GetGlossyBrush();
29 const QBrush ColorPeg::mNeutralBrush = ColorPeg::GetNeutralBrush();
30 
GetLetterFont()31 QFont ColorPeg::GetLetterFont()
32 {
33     QFont lf("Arial", 12, QFont::Bold, false);
34     lf.setStyleHint(QFont::SansSerif);
35     lf.setPixelSize(16);
36 
37     return lf;
38 }
39 
GetNeutralBrush()40 QBrush ColorPeg::GetNeutralBrush()
41 {
42     QRadialGradient rgrad(20, 20, 40, 5, 5);
43     rgrad.setColorAt(0.0, QColor(0xff, 0xff, 0xff, 0xff));
44     rgrad.setColorAt(1.0, QColor(0x80, 0x80, 0x80, 0xff));
45 
46     return QBrush(rgrad);
47 }
48 
GetShadowBrush()49 QBrush ColorPeg::GetShadowBrush()
50 {
51     QRadialGradient rgrad(22, 22, 22, 22, 22);
52     rgrad.setColorAt(0.3, QColor(0, 0, 0, 0xff));
53     rgrad.setColorAt(1.0, QColor(0, 0, 0, 0));
54 
55     return QBrush(rgrad);
56 }
57 
GetOutlineBrush()58 QBrush ColorPeg::GetOutlineBrush()
59 {
60     QLinearGradient lgrad(0, 0, 38, 38);
61     lgrad.setColorAt(0.0, QColor(0, 0, 0, 0xa0));
62     lgrad.setColorAt(1.0, QColor(0xff, 0xff, 0xff, 0xa0));
63     return QBrush(lgrad);
64 }
65 
GetGlossyBrush()66 QBrush ColorPeg::GetGlossyBrush()
67 {
68     QLinearGradient lgrad(20, 4, 20, 20);
69     lgrad.setColorAt(0.0, QColor(0xff, 0xff, 0xff, 0x80));
70     lgrad.setColorAt(1.0, QColor(0xff, 0xff, 0xff, 0x00));
71     return QBrush(lgrad);
72 }
73 
74 
ColorPeg(QObject *)75 ColorPeg::ColorPeg(QObject*)
76 {
77     setFlags(QGraphicsItem::GraphicsItemFlags(0));
78 
79     mPegType = NULL;
80     mPegRow = NULL;
81     SetBtn(true);
82     mIsDragged = false;
83     mShowIndicator = false;
84     mHideColor = false;
85     mSort = 0;
86     mId = -1;
87 }
88 
~ColorPeg()89 ColorPeg::~ColorPeg()
90 {
91 }
92 
SetPegType(PegType * pt)93 void ColorPeg::SetPegType(PegType *pt)
94 {
95     mPegType = pt;
96     setFlags(ItemIsMovable | ItemIsSelectable);
97 }
98 
SetPegRow(PegRow * pr)99 void ColorPeg::SetPegRow(PegRow *pr)
100 {
101     mPegRow = pr;
102 }
103 
GetPegType()104 PegType* ColorPeg::GetPegType()
105 {
106     return mPegType;
107 }
108 
SetId(int id)109 void ColorPeg::SetId(int id)
110 {
111     mId = id;
112 }
113 
IsBtn() const114 bool ColorPeg::IsBtn() const
115 {
116     return mIsBtn;
117 }
118 
GetSort() const119 int ColorPeg::GetSort() const
120 {
121     return mSort;
122 }
123 
SetBtn(bool b)124 void ColorPeg::SetBtn(bool b)
125 {
126     mIsBtn = b;
127     SetCursorShape();
128 }
129 
GetType() const130 int ColorPeg::GetType() const
131 {
132     return mType;
133 }
134 
SetType(const int t)135 void ColorPeg::SetType(const int t)
136 {
137     mType = t;
138 }
139 
Reset()140 void ColorPeg::Reset()
141 {
142     SetIsDragged(false);
143     setSelected(false);
144     if (mPegRow != NULL)
145     {
146         mPegRow->RemovePeg(this);
147         mPegRow = NULL;
148     }
149 }
150 
GetIsDragged() const151 bool ColorPeg::GetIsDragged() const
152 {
153     return mIsDragged;
154 }
155 
SetIsDragged(bool b)156 void ColorPeg::SetIsDragged(bool b)
157 {
158     if (false == b)
159     {
160         update(boundingRect());
161     }
162     mIsDragged = b;
163 }
164 
SetEnabled(const bool b)165 void ColorPeg::SetEnabled(const bool b)
166 {
167     setEnabled(b);
168     SetCursorShape();
169 }
170 
SetPaused(const bool b)171 void ColorPeg::SetPaused(const bool b)
172 {
173     bool enable;
174     if (b)
175     {
176         mEnabledBuff = isEnabled();
177         enable = false;
178     }
179     else
180     {
181         enable = mEnabledBuff;
182     }
183     SetEnabled(enable);
184 }
185 
SetIndicator(const bool b,const int t,const bool c)186 void ColorPeg::SetIndicator(const bool b, const int t, const bool c)
187 {
188     if (mShowIndicator != b || mIndicatorType != t || mHideColor != c)
189     {
190         mShowIndicator = b;
191         mIndicatorType = t;
192         mHideColor = c;
193         update(boundingRect());
194     }
195 }
196 
SetCursorShape(Qt::CursorShape shape,const bool force)197 void ColorPeg::SetCursorShape(Qt::CursorShape shape, const bool force)
198 {
199     if (!force)
200     {
201         if (mIsDragged && isEnabled())
202         {
203             if (mSort == 0)
204             {
205                 shape = Qt::ClosedHandCursor;
206             }
207             else if (mSort == 1)
208             {
209                 shape = Qt::SizeVerCursor;
210             }
211             else
212             {
213                 shape = Qt::SplitVCursor;
214             }
215         }
216         else if (isEnabled())
217         {
218             shape = Qt::OpenHandCursor;
219         }
220     }
221 
222     if (cursor().shape() != shape)
223     {
224         setCursor(QCursor(shape));
225     }
226 }
227 
itemChange(GraphicsItemChange change,const QVariant & value)228 QVariant ColorPeg::itemChange(GraphicsItemChange change, const QVariant &value)
229 {
230     if (change == ItemSelectedHasChanged)
231     {
232         scene()->update(scene()->sceneRect());
233     }
234     return QGraphicsItem::itemChange(change, value);
235 }
236 
ForceRelease()237 void ColorPeg::ForceRelease()
238 {
239     QGraphicsSceneMouseEvent re(QEvent::GraphicsSceneMouseRelease);
240     re.setButton(Qt::LeftButton);
241     mouseReleaseEvent(&re);
242 }
243 
mousePressEvent(QGraphicsSceneMouseEvent * e)244 void ColorPeg::mousePressEvent(QGraphicsSceneMouseEvent *e)
245 {
246     QGraphicsItem::mousePressEvent(e);
247     if (mPegType != NULL)
248     {
249         if (e->button() == Qt::LeftButton)
250         {
251             Reset();
252             SetIsDragged(true);
253             if (IsBtn() && (e->modifiers() & Qt::ControlModifier) != 0)
254             {
255                 if ((e->modifiers() & Qt::ShiftModifier) == 0)
256                 {
257                     mSort = 1;
258                 }
259                 else
260                 {
261                     mSort = 2;
262                 }
263             }
264             else
265             {
266                 mSort = 0;
267 
268             }
269             emit PegPressSignal(this);
270             SetCursorShape();
271         }
272     }
273 }
274 
mouseReleaseEvent(QGraphicsSceneMouseEvent * e)275 void ColorPeg::mouseReleaseEvent (QGraphicsSceneMouseEvent *e)
276 {
277     QGraphicsItem::mouseReleaseEvent(e);
278     if (mPegType != NULL)
279     {
280         if (e->button() == Qt::LeftButton)
281         {
282             SetIsDragged(false);
283             emit PegReleasedSignal(this);
284             SetCursorShape();
285         }
286     }
287 }
288 
shape() const289 QPainterPath ColorPeg::shape() const
290 {
291     QPainterPath path;
292     path.addEllipse(boundingRect());
293     return path;
294 }
295 
boundingRect() const296 QRectF ColorPeg::boundingRect() const
297 {
298     int margin;
299     if (mIsDragged)
300     {
301         margin = 8;
302     }
303     else
304     {
305         margin = 1;
306     }
307     return outlineRect().adjusted(-margin, -margin, +margin, +margin);
308 }
309 
outlineRect() const310 QRectF ColorPeg::outlineRect() const
311 {
312     QRectF rect(0.0, 0.0, 36.0, 36.0);
313     return rect;
314 }
315 
GetColorRect() const316 QRectF ColorPeg::GetColorRect() const
317 {
318     QRectF rect(1.0, 1.0, 34.0, 34.0);
319     return rect;
320 }
321 
paint(QPainter * painter,const QStyleOptionGraphicsItem *,QWidget *)322 void ColorPeg::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
323 {
324     painter->setPen(Qt::NoPen);
325 
326     if (!mIsDragged)
327     {
328         painter->setBrush(ColorPeg::mOutlineBrush);
329         painter->drawEllipse(outlineRect());
330     }
331     else
332     {
333         painter->translate(QPointF(-2, -2));
334         painter->setBrush(ColorPeg::mShadowBrush);
335         painter->drawEllipse(QRectF(0, 0, 44, 44));
336         painter->translate(QPointF(2, 2));
337     }
338 
339     if (!mHideColor)
340     {
341         painter->setBrush(QBrush(*mPegType->grad));
342         painter->drawEllipse(GetColorRect());
343     }
344     else
345     {
346         painter->setBrush(mNeutralBrush);
347         painter->drawEllipse(GetColorRect());
348     }
349 
350     painter->setBrush(mGlossyBrush);
351     painter->drawEllipse(QRectF(5, 3, 24, 20));
352 
353     if (mShowIndicator)
354     {
355         painter->setPen(QPen(QColor("#303133")));
356         painter->setRenderHint(QPainter::TextAntialiasing, true);
357         painter->setFont(mFont);
358         QString ind;
359         if (mIndicatorType == Settings::INDICATOR_LETTER)
360         {
361             ind = QString(mPegType->let);
362         }
363         else
364         {
365             ind.setNum((mPegType->ix + 1));
366         }
367         painter->drawText(QRectF(1.5, 2.0, 32.0, 32.0), Qt::AlignCenter, ind);
368     }
369 }
370