1 | /* |
2 | Copyright 2006-2007 Dmitry Suzdalev <dimsuz@gmail.com> |
3 | Copyright 2010 Brian Croom <brian.s.croom@gmail.com> |
4 | Copyright 2013 Denis Kuplyakov <dener.kup@gmail.com> |
5 | |
6 | This program is free software: you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation, either version 2 of the License, or |
9 | (at your option) any later version. |
10 | |
11 | This program is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | GNU General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 | */ |
19 | |
20 | #include <kreversiview.h> |
21 | |
22 | #include <KLocalizedString> |
23 | #include <KStandardDirs> |
24 | |
25 | #include <colorscheme.h> |
26 | |
27 | KReversiView::KReversiView(KReversiGame* game, QWidget *parent, KgThemeProvider *provider) : |
28 | KgDeclarativeView(parent), m_delay(ANIMATION_SPEED_NORMAL), m_game(0), |
29 | m_showLastMove(false), m_showLegalMoves(false), |
30 | m_showLabels(false), m_provider(provider) |
31 | { |
32 | m_provider->setDeclarativeEngine("themeProvider" , engine()); |
33 | |
34 | qmlRegisterType<ColorScheme>("ColorScheme" , 1, 0, "ColorScheme" ); |
35 | |
36 | QString path = |
37 | KStandardDirs::locate("appdata" , QLatin1String("qml/Table.qml" )); |
38 | setSource(QUrl::fromLocalFile(path)); |
39 | |
40 | m_qml_root = (QObject*) rootObject(); |
41 | rootContext()->setContextProperty("container" , this); |
42 | |
43 | connect(m_qml_root, SIGNAL(cellClicked(int,int)), |
44 | this, SLOT(onPlayerMove(int,int))); |
45 | setGame(game); |
46 | } |
47 | |
48 | void KReversiView::setGame(KReversiGame *game) |
49 | { |
50 | // disconnect signals from previous game if they exist, |
51 | // we are not interested in them anymore |
52 | if (m_game) { |
53 | disconnect(m_game, SIGNAL(boardChanged()), this, SLOT(updateBoard())); |
54 | disconnect(m_game, SIGNAL(moveFinished()), this, SLOT(gameMoveFinished())); |
55 | disconnect(m_game, SIGNAL(gameOver()), this, SLOT(gameOver())); |
56 | disconnect(m_game, SIGNAL(whitePlayerCantMove()), this, SLOT(whitePlayerCantMove())); |
57 | disconnect(m_game, SIGNAL(blackPlayerCantMove()), this, SLOT(blackPlayerCantMove())); |
58 | delete m_game; |
59 | } |
60 | |
61 | m_game = game; |
62 | |
63 | if (m_game) { |
64 | connect(m_game, SIGNAL(boardChanged()), this, SLOT(updateBoard())); |
65 | connect(m_game, SIGNAL(moveFinished()), this, SLOT(gameMoveFinished())); |
66 | connect(m_game, SIGNAL(gameOver()), this, SLOT(gameOver())); |
67 | connect(m_game, SIGNAL(whitePlayerCantMove()), this, SLOT(whitePlayerCantMove())); |
68 | connect(m_game, SIGNAL(blackPlayerCantMove()), this, SLOT(blackPlayerCantMove())); |
69 | |
70 | m_game->setDelay(m_delay); |
71 | } |
72 | |
73 | m_hint = KReversiMove(); |
74 | |
75 | updateBoard(); |
76 | } |
77 | |
78 | void KReversiView::setChipsPrefix(ChipsPrefix chipsPrefix) |
79 | { |
80 | m_qml_root->setProperty("chipsImagePrefix" , |
81 | Utils::chipPrefixToString(chipsPrefix)); |
82 | } |
83 | |
84 | void KReversiView::setShowBoardLabels(bool show) |
85 | { |
86 | m_showLabels = show; |
87 | updateBoard(); |
88 | } |
89 | |
90 | void KReversiView::setAnimationSpeed(int speed) |
91 | { |
92 | int value = ANIMATION_SPEED_NORMAL; |
93 | switch (speed) { |
94 | case 0: |
95 | value = ANIMATION_SPEED_SLOW; |
96 | break; |
97 | default: |
98 | case 1: |
99 | value = ANIMATION_SPEED_NORMAL; |
100 | break; |
101 | case 2: |
102 | value = ANIMATION_SPEED_FAST; |
103 | break; |
104 | } |
105 | |
106 | m_delay = value; |
107 | |
108 | if (m_game) |
109 | m_game->setDelay(value); |
110 | |
111 | m_qml_root->setProperty("chipsAnimationTime" , value); |
112 | } |
113 | |
114 | KReversiView::~KReversiView() |
115 | { |
116 | setGame(0); |
117 | } |
118 | |
119 | void KReversiView::updateBoard() |
120 | { |
121 | for (int i = 0; i < 8; i++) { |
122 | for (int j = 0; j < 8; j++) { |
123 | QMetaObject::invokeMethod(m_qml_root, "setPreAnimationTime" , |
124 | Q_ARG(QVariant, i), |
125 | Q_ARG(QVariant, j), |
126 | Q_ARG(QVariant, m_game ? m_game->getPreAnimationDelay(KReversiPos(i, j)) : 0)); |
127 | } |
128 | } |
129 | |
130 | for (int i = 0; i < 8; i++) |
131 | for (int j = 0; j < 8; j++) { |
132 | QString new_state = "" ; |
133 | if (m_game) // showing empty board if has no game |
134 | switch (m_game->chipColorAt(KReversiMove(NoColor, i, j))) { |
135 | case Black: |
136 | new_state = "Black" ; |
137 | break; |
138 | case White: |
139 | new_state = "White" ; |
140 | break; |
141 | case NoColor: |
142 | new_state = "" ; |
143 | break; |
144 | } |
145 | |
146 | QMetaObject::invokeMethod(m_qml_root, "setChipState" , |
147 | Q_ARG(QVariant, i), |
148 | Q_ARG(QVariant, j), |
149 | Q_ARG(QVariant, new_state)); |
150 | |
151 | // clearing legal markers, hints and lastmove |
152 | QMetaObject::invokeMethod(m_qml_root, "setLegal" , |
153 | Q_ARG(QVariant, i), |
154 | Q_ARG(QVariant, j), |
155 | Q_ARG(QVariant, false)); |
156 | QMetaObject::invokeMethod(m_qml_root, "setHint" , |
157 | Q_ARG(QVariant, i), |
158 | Q_ARG(QVariant, j), |
159 | Q_ARG(QVariant, false)); |
160 | QMetaObject::invokeMethod(m_qml_root, "setLastMove" , |
161 | Q_ARG(QVariant, i), |
162 | Q_ARG(QVariant, j), |
163 | Q_ARG(QVariant, false)); |
164 | } |
165 | |
166 | if (m_game && m_showLegalMoves) { |
167 | MoveList possible_moves = m_game->possibleMoves(); |
168 | for (int i = 0; i < possible_moves.size(); i++) { |
169 | QMetaObject::invokeMethod(m_qml_root, "setLegal" , |
170 | Q_ARG(QVariant, possible_moves.at(i).row), |
171 | Q_ARG(QVariant, possible_moves.at(i).col), |
172 | Q_ARG(QVariant, true)); |
173 | } |
174 | } |
175 | |
176 | m_qml_root->setProperty("isBoardShowingLabels" , m_showLabels); |
177 | |
178 | if (m_hint.isValid()) { |
179 | QMetaObject::invokeMethod(m_qml_root, "setChipState" , |
180 | Q_ARG(QVariant, m_hint.row), |
181 | Q_ARG(QVariant, m_hint.col), |
182 | Q_ARG(QVariant, "Black" )); |
183 | QMetaObject::invokeMethod(m_qml_root, "setHint" , |
184 | Q_ARG(QVariant, m_hint.row), |
185 | Q_ARG(QVariant, m_hint.col), |
186 | Q_ARG(QVariant, true)); |
187 | } |
188 | |
189 | if (m_game && m_showLastMove) { |
190 | KReversiMove lastmove = m_game->getLastMove(); |
191 | if (lastmove.isValid()) |
192 | QMetaObject::invokeMethod(m_qml_root, "setLastMove" , |
193 | Q_ARG(QVariant, lastmove.row), |
194 | Q_ARG(QVariant, lastmove.col), |
195 | Q_ARG(QVariant, true)); |
196 | } |
197 | } |
198 | |
199 | void KReversiView::setShowLastMove(bool show) |
200 | { |
201 | m_showLastMove = show; |
202 | updateBoard(); |
203 | } |
204 | |
205 | void KReversiView::setShowLegalMoves(bool show) |
206 | { |
207 | m_showLegalMoves = show; |
208 | updateBoard(); |
209 | } |
210 | |
211 | void KReversiView::slotHint() |
212 | { |
213 | if (!m_game) { |
214 | m_hint = KReversiMove(); |
215 | return; |
216 | } |
217 | |
218 | m_hint = m_game->getHint(); |
219 | updateBoard(); |
220 | } |
221 | |
222 | void KReversiView::onPlayerMove(int row, int col) |
223 | { |
224 | if (!m_game) |
225 | return; |
226 | |
227 | emit userMove(KReversiPos(row, col)); |
228 | } |
229 | |
230 | |
231 | void KReversiView::gameMoveFinished() |
232 | { |
233 | m_hint = KReversiMove(); |
234 | updateBoard(); |
235 | } |
236 | |
237 | void KReversiView::gameOver() |
238 | { |
239 | } |
240 | |
241 | void KReversiView::whitePlayerCantMove() |
242 | { |
243 | // TODO: use Computer, You and Opponent instead in message |
244 | QMetaObject::invokeMethod(m_qml_root, "showPopup" , |
245 | Q_ARG(QVariant, |
246 | i18n("White can not perform any move. It is black turn again." ))); |
247 | updateBoard(); |
248 | } |
249 | |
250 | void KReversiView::blackPlayerCantMove() |
251 | { |
252 | // TODO: use Computer, You and Opponent instead in message |
253 | QMetaObject::invokeMethod(m_qml_root, "showPopup" , |
254 | Q_ARG(QVariant, |
255 | i18n("Black can not perform any move. It is white turn again." ))); |
256 | updateBoard(); |
257 | } |
258 | |