1/*
2 Copyright 2007 Dmitry Suzdalev <dimsuz@gmail.com>
3 Copyright 2010 Brian Croom <brian.s.croom@gmail.com>
4
5 This program 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 2 of the License, or
8 (at your option) any later version.
9
10 This program 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 this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20#include "cellitem.h"
21
22#include "settings.h"
23
24#include <kdebug.h>
25
26QHash<int, QString> CellItem::s_digitNames;
27QHash<KMinesState::CellState, QList<QString> > CellItem::s_stateNames;
28
29CellItem::CellItem(KGameRenderer* renderer, QGraphicsItem* parent)
30 : KGameRenderedItem(renderer, QLatin1String( "" ), parent)
31{
32 if(s_digitNames.isEmpty())
33 fillNameHashes();
34 setShapeMode(BoundingRectShape);
35 reset();
36}
37
38void CellItem::reset()
39{
40 m_state = KMinesState::Released;
41 m_hasMine = false;
42 m_exploded = false;
43 m_digit = 0;
44 updatePixmap();
45}
46
47void CellItem::updatePixmap()
48{
49 QList<QGraphicsItem*> children = childItems();
50 qDeleteAll(children);
51
52 QList<QString> spriteKeys = s_stateNames[m_state];
53 setSpriteKey(spriteKeys[0]);
54 for(int i=1; i<spriteKeys.count(); i++)
55 addOverlay(spriteKeys[i]);
56 if(m_state == KMinesState::Revealed)
57 {
58 if(m_digit != 0)
59 addOverlay(s_digitNames[m_digit]);
60 else if(m_hasMine)
61 {
62 if(m_exploded)
63 addOverlay(QLatin1String( "explosion" ));
64 addOverlay(QLatin1String( "mine" ));
65 }
66 }
67}
68
69void CellItem::setRenderSize(const QSize &renderSize)
70{
71 KGameRenderedItem::setRenderSize(renderSize);
72 QList<QGraphicsItem*> children = childItems();
73 foreach( QGraphicsItem* item, children)
74 {
75 ((KGameRenderedItem*)item)->setRenderSize(renderSize);
76 }
77}
78
79void CellItem::press()
80{
81 if(m_state == KMinesState::Released)
82 {
83 m_state = KMinesState::Pressed;
84 updatePixmap();
85 }
86}
87
88void CellItem::release(bool force)
89{
90 // special case for mid-button magic
91 if(force && (m_state == KMinesState::Flagged || m_state == KMinesState::Questioned))
92 return;
93
94 if(m_state == KMinesState::Pressed || force)
95 {
96 // if we hold mine, let's explode
97 m_exploded = m_hasMine;
98 reveal();
99 }
100}
101
102void CellItem::mark()
103{
104 // this will provide cycling through
105 // Released -> "?"-mark -> "RedFlag"-mark -> Released
106
107 bool useQuestion = Settings::useQuestionMarks();
108
109 switch(m_state)
110 {
111 case KMinesState::Released:
112 m_state = KMinesState::Flagged;
113 break;
114 case KMinesState::Flagged:
115 m_state = useQuestion ? KMinesState::Questioned : KMinesState::Released;
116 break;
117 case KMinesState::Questioned:
118 m_state = KMinesState::Released;
119 break;
120 default:
121 // shouldn't be here
122 break;
123 } // end switch
124 updatePixmap();
125}
126
127void CellItem::reveal()
128{
129 if(isRevealed())
130 return; // already revealed
131
132 if(m_state == KMinesState::Flagged && m_hasMine == false)
133 m_state = KMinesState::Error;
134 else
135 m_state = KMinesState::Revealed;
136 updatePixmap();
137}
138
139void CellItem::undoPress()
140{
141 if(m_state == KMinesState::Pressed)
142 {
143 m_state = KMinesState::Released;
144 updatePixmap();
145 }
146}
147
148void CellItem::fillNameHashes()
149{
150 s_digitNames[1] = QLatin1String( "arabicOne" );
151 s_digitNames[2] = QLatin1String( "arabicTwo" );
152 s_digitNames[3] = QLatin1String( "arabicThree" );
153 s_digitNames[4] = QLatin1String( "arabicFour" );
154 s_digitNames[5] = QLatin1String( "arabicFive" );
155 s_digitNames[6] = QLatin1String( "arabicSix" );
156 s_digitNames[7] = QLatin1String( "arabicSeven" );
157 s_digitNames[8] = QLatin1String( "arabicEight" );
158
159 s_stateNames[KMinesState::Released].append(QLatin1String( "cell_up" ));
160 s_stateNames[KMinesState::Pressed].append(QLatin1String( "cell_down" ));
161 s_stateNames[KMinesState::Revealed].append(QLatin1String( "cell_down" ));
162 s_stateNames[KMinesState::Questioned].append(QLatin1String( "cell_up" ));
163 s_stateNames[KMinesState::Questioned].append(QLatin1String( "question" ));
164 s_stateNames[KMinesState::Flagged].append(QLatin1String( "cell_up" ));
165 s_stateNames[KMinesState::Flagged].append(QLatin1String( "flag" ));
166 s_stateNames[KMinesState::Error].append(QLatin1String( "cell_down" ));
167 s_stateNames[KMinesState::Error].append(QLatin1String( "mine" ));
168 s_stateNames[KMinesState::Error].append(QLatin1String( "error" ));
169 s_stateNames[KMinesState::Hint].append(QLatin1String( "cell_up" ));
170 s_stateNames[KMinesState::Hint].append(QLatin1String( "hint" ));
171}
172
173void CellItem::addOverlay(const QString& spriteKey)
174{
175 KGameRenderedItem* overlay = new KGameRenderedItem(renderer(), spriteKey, this);
176 overlay->setRenderSize(renderSize());
177}
178