1 /***************************************************************************
2 BoardTheme - graphics theme for BoardView
3 -------------------
4 begin : nie sie 21 2005
5 copyright : (C) 2005 Michal Rudolf <mrudolf@kdewebdev.org>
6 ***************************************************************************/
7
8 /***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17 #include "boardtheme.h"
18 #include "settings.h"
19 #include "messagedialog.h"
20
21 #include <QPixmap>
22
23 #if defined(_MSC_VER) && defined(_DEBUG)
24 #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
25 #define new DEBUG_NEW
26 #endif // _MSC_VER
27
BoardTheme()28 BoardTheme::BoardTheme()
29 {}
30
~BoardTheme()31 BoardTheme::~BoardTheme()
32 {}
33
piece(Piece p) const34 const QPixmap& BoardTheme::piece(Piece p) const
35 {
36 return m_piece[p];
37 }
38
square(bool dark) const39 const QPixmap& BoardTheme::square(bool dark) const
40 {
41 return m_square[dark ? 1 : 0];
42 }
43
originalPiece(Piece p) const44 const QPixmap& BoardTheme::originalPiece(Piece p) const
45 {
46 return m_originalPiece[p];
47 }
48
originalSquare(bool dark) const49 const QPixmap& BoardTheme::originalSquare(bool dark) const
50 {
51 return m_originalSquare[dark ? 1 : 0];
52 }
53
pieceThemeName() const54 QString BoardTheme::pieceThemeName() const
55 {
56 int start = m_pieceFilename.lastIndexOf('/') + 1;
57 return m_pieceFilename.mid(start + 1, m_pieceFilename.length() - start - 4);
58 }
59
boardThemeName() const60 QString BoardTheme::boardThemeName() const
61 {
62 int start = m_boardFilename.lastIndexOf('/') + 1;
63 return m_boardFilename.mid(start + 1, m_pieceFilename.length() - start - 4);
64 }
65
isValid() const66 bool BoardTheme::isValid() const
67 {
68 return !m_pieceFilename.isNull();
69 }
70
loadPieces(const QString & pieces,int effect)71 bool BoardTheme::loadPieces(const QString& pieces, int effect)
72 {
73 QString effectPath;
74 if(effect == Outline)
75 {
76 effectPath = "outline";
77 }
78 else if(effect == Shadow)
79 {
80 effectPath = "shadow";
81 }
82
83 QString themePath = AppSettings->getThemePath(effectPath, pieces);
84
85 QPixmap big;
86 if(!big.load(themePath) || big.width() < 160)
87 {
88 return false;
89 }
90
91 big.setDevicePixelRatio(2.0);
92
93 int realsize = big.height() / 2;
94 if(realsize == big.width() / 6)
95 {
96 /* Cut big theme bitmap into separate pieces */
97 m_originalPiece[WhiteRook] = big.copy(0 * realsize, 0, realsize, realsize);
98 m_originalPiece[WhiteKnight] = big.copy(1 * realsize, 0, realsize, realsize);
99 m_originalPiece[WhiteBishop] = big.copy(2 * realsize, 0, realsize, realsize);
100 m_originalPiece[WhiteQueen] = big.copy(3 * realsize, 0, realsize, realsize);
101 m_originalPiece[WhiteKing] = big.copy(4 * realsize, 0, realsize, realsize);
102 m_originalPiece[WhitePawn] = big.copy(5 * realsize, 0, realsize, realsize);
103 m_originalPiece[BlackRook] = big.copy(0 * realsize, realsize, realsize, realsize);
104 m_originalPiece[BlackKnight] = big.copy(1 * realsize, realsize, realsize, realsize);
105 m_originalPiece[BlackBishop] = big.copy(2 * realsize, realsize, realsize, realsize);
106 m_originalPiece[BlackQueen] = big.copy(3 * realsize, realsize, realsize, realsize);
107 m_originalPiece[BlackKing] = big.copy(4 * realsize, realsize, realsize, realsize);
108 m_originalPiece[BlackPawn] = big.copy(5 * realsize, realsize, realsize, realsize);
109 }
110 else
111 {
112 // Test SCID format
113 realsize = big.height();
114 if(realsize != big.width() / 12)
115 {
116 return false;
117 }
118 /* Cut big theme bitmap into separate pieces */
119 m_originalPiece[WhitePawn] = big.copy(0 * realsize, 0, realsize, realsize);
120 m_originalPiece[WhiteKnight] = big.copy(1 * realsize, 0, realsize, realsize);
121 m_originalPiece[WhiteBishop] = big.copy(2 * realsize, 0, realsize, realsize);
122 m_originalPiece[WhiteRook] = big.copy(3 * realsize, 0, realsize, realsize);
123 m_originalPiece[WhiteQueen] = big.copy(4 * realsize, 0, realsize, realsize);
124 m_originalPiece[WhiteKing] = big.copy(5 * realsize, 0, realsize, realsize);
125 m_originalPiece[BlackPawn] = big.copy(6 * realsize, 0, realsize, realsize);
126 m_originalPiece[BlackKnight] = big.copy(7 * realsize, 0, realsize, realsize);
127 m_originalPiece[BlackBishop] = big.copy(8 * realsize, 0, realsize, realsize);
128 m_originalPiece[BlackRook] = big.copy(9 * realsize, 0, realsize, realsize);
129 m_originalPiece[BlackQueen] = big.copy(10 * realsize, 0, realsize, realsize);
130 m_originalPiece[BlackKing] = big.copy(11 * realsize, 0, realsize, realsize);
131 }
132
133 m_pieceFilename = themePath;
134
135 if(size().isEmpty())
136 {
137 setSize(QSize(realsize, realsize));
138 }
139 else
140 {
141 setSize(size());
142 }
143 return true;
144 }
145
loadBoard(const QString & board)146 bool BoardTheme::loadBoard(const QString& board)
147 {
148 if(board.isEmpty())
149 {
150 m_boardFilename = board;
151 updateSquares();
152 return true;
153 }
154 QString themePath = AppSettings->getBoardPath(board);
155
156 QPixmap big;
157 if(!big.load(themePath))
158 {
159 return false;
160 }
161 int realsize = big.height() / 2;
162 if(realsize != big.width())
163 {
164 return false;
165 }
166
167 m_originalSquare[0] = big.copy(0, 0, realsize, realsize);
168 m_originalSquare[1] = big.copy(0, realsize, realsize, realsize);
169 m_boardFilename = themePath;
170
171 updateSquares();
172 return true;
173 }
174
configure()175 void BoardTheme::configure()
176 {
177 AppSettings->beginGroup("/Board/");
178 setColor(BoardTheme::LightSquare, AppSettings->getValue("lightColor").value<QColor>());
179 setColor(BoardTheme::DarkSquare, AppSettings->getValue("darkColor").value<QColor>());
180 setColor(BoardTheme::Highlight, AppSettings->getValue("highlightColor").value<QColor>());
181 setColor(BoardTheme::Frame, AppSettings->getValue("frameColor").value<QColor>());
182 setColor(BoardTheme::CurrentMove, AppSettings->getValue("currentMoveColor").value<QColor>());
183 setColor(BoardTheme::StoredMove, AppSettings->getValue("storedMoveColor").value<QColor>());
184 setColor(BoardTheme::VariationMove, AppSettings->getValue("variationMoveColor").value<QColor>());
185 setColor(BoardTheme::Threat, AppSettings->getValue("threatColor").value<QColor>());
186 setColor(BoardTheme::Target, AppSettings->getValue("targetColor").value<QColor>());
187 setColor(BoardTheme::Check, AppSettings->getValue("checkColor").value<QColor>());
188 setColor(BoardTheme::Wall, AppSettings->getValue("wallColor").value<QColor>());
189 setColor(BoardTheme::UnderProtected, AppSettings->getValue("underprotectedColor").value<QColor>());
190 setColor(BoardTheme::Engine, AppSettings->getValue("engineColor").value<QColor>());
191
192 QString pieceTheme = AppSettings->getValue("pieceTheme").toString();
193 int pieceEffect = AppSettings->getValue("pieceEffect").toInt();
194 QString boardTheme = AppSettings->getValue("boardTheme").toString();
195 AppSettings->endGroup();
196
197 if(!loadPieces(pieceTheme, pieceEffect))
198 {
199 static bool errorShown = false;
200 if (!errorShown)
201 {
202 errorShown = true;
203 MessageDialog::error(tr("Cannot find piece data.\nPlease check your installation."));
204 }
205 }
206 if (!loadBoard(boardTheme))
207 {
208 static bool errorShown = false;
209 if (!errorShown)
210 {
211 errorShown = true;
212 MessageDialog::error(tr("Cannot find board data.\nPlease check your installation."));
213 }
214 }
215 }
216
size() const217 QSize BoardTheme::size() const
218 {
219 return m_size;
220 }
221
pieceCenter() const222 QPoint BoardTheme::pieceCenter() const
223 {
224 return QPoint(m_size.width() / 2, m_size.height() / 2);
225 }
226
rect() const227 QRect BoardTheme::rect() const
228 {
229 return QRect(QPoint(0, 0), m_size);
230 }
231
setSize(const QSize & value)232 void BoardTheme::setSize(const QSize& value)
233 {
234 if(!isValid())
235 {
236 return;
237 }
238 m_size = value;
239 for(int i = 1; i < ConstPieceTypes; i++)
240 {
241 float r = m_originalPiece[i].devicePixelRatio();
242 m_piece[i] = m_originalPiece[i].scaled(m_size * r, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
243 m_piece[i].setDevicePixelRatio(r);
244 }
245 updateSquares();
246 }
247
updateSquares()248 void BoardTheme::updateSquares()
249 {
250 if(!isValid())
251 {
252 return;
253 }
254 bool scale = m_size.width() > m_originalPiece[WhiteRook].width()
255 || m_size.height() > m_originalPiece[WhiteRook].height()
256 || m_size.width() < 30 || m_size.height() < 30;
257 if (AppSettings->getValue("/Board/AlwaysScale").toBool())
258 {
259 scale = true;
260 }
261 if(isBoardPlain())
262 {
263 m_square[0] = QPixmap(m_size);
264 m_square[0].fill(color(LightSquare).rgb());
265 m_square[1] = QPixmap(m_size);
266 m_square[1].fill(color(DarkSquare).rgb());
267 }
268 else if(scale)
269 {
270 QSize sz = size();
271 m_square[0] = m_originalSquare[0].scaled(sz, Qt::IgnoreAspectRatio,
272 Qt::SmoothTransformation);
273 m_square[1] = m_originalSquare[1].scaled(sz, Qt::IgnoreAspectRatio,
274 Qt::SmoothTransformation);
275 }
276 else
277 {
278 m_square[0] = m_originalSquare[0].copy(rect());
279 m_square[1] = m_originalSquare[1].copy(rect());
280 }
281 }
282
isBoardPlain() const283 bool BoardTheme::isBoardPlain() const
284 {
285 return m_boardFilename.isEmpty();
286 }
287
setColor(ColorRole role,const QColor & value)288 void BoardTheme::setColor(ColorRole role, const QColor& value)
289 {
290 m_colors[role] = value;
291 if(role == LightSquare || role == DarkSquare)
292 {
293 updateSquares();
294 }
295 }
296
color(ColorRole role) const297 QColor BoardTheme::color(ColorRole role) const
298 {
299 return m_colors[role];
300 }
301
setEnabled(bool enabled)302 void BoardTheme::setEnabled(bool enabled)
303 {
304 if(enabled)
305 {
306 AppSettings->beginGroup("/Board/");
307 setColor(BoardTheme::LightSquare, AppSettings->getValue("lightColor").value<QColor>());
308 setColor(BoardTheme::DarkSquare, AppSettings->getValue("darkColor").value<QColor>());
309 QString boardTheme = AppSettings->getValue("boardTheme").toString();
310 AppSettings->endGroup();
311 loadBoard(boardTheme);
312 }
313 else
314 {
315 setColor(BoardTheme::LightSquare, QColor(Qt::lightGray));
316 setColor(BoardTheme::DarkSquare, QColor(Qt::darkGray));
317 loadBoard(QString());
318 }
319 }
320