gamevariants.cpp 11.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/***************************************************************************
 *   Copyright 2007      Johannes Bergmeier <johannes.bergmeier@gmx.net>   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
Johannes Bergmeier's avatar
Johannes Bergmeier committed
17
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
18
19
 ***************************************************************************/

20
21
#include "gamevariants.h"
#include "ksudokugame.h"
22
#include "serializer.h"
23
24

#include <QtDebug>
Johannes Bergmeier's avatar
Johannes Bergmeier committed
25
#include <KMessageBox>
Johannes Bergmeier's avatar
Johannes Bergmeier committed
26
#include <KLocale>
27
28
29
#include <QPainter>
#include <KIconLoader>
#include <QEvent>
30
31
32
33
34

#include "gamevariants.moc"

#include "puzzle.h"

35

36
37
38
39
40
41
42
43
44
45
46
47
48
namespace ksudoku {

///////////////////////////////////////////////////////////////////////////////
// class GameVariant
///////////////////////////////////////////////////////////////////////////////

GameVariant::GameVariant(const QString& name, GameVariantCollection* collection)
	: m_name(name)
{
	if(collection)
		collection->addVariant(this);
}

49
50
51
52
void GameVariant::setDescription(const QString& descr) {
	m_description = descr;
}

53
54
55
56
void GameVariant::setIcon(const QString& icon) {
	m_icon = icon;
}

57
58
59
60
61
///////////////////////////////////////////////////////////////////////////////
// class GameVariantCollection
///////////////////////////////////////////////////////////////////////////////

GameVariantCollection::GameVariantCollection(QObject* parent, bool autoDel)
62
	: QAbstractListModel(parent), m_autoDelete(autoDel)
63
64
65
66
67
68
69
70
71
72
{
}

GameVariantCollection::~GameVariantCollection() {
	if(m_autoDelete)
		qDeleteAll(m_variants);
	m_variants.clear();
}

void GameVariantCollection::addVariant(GameVariant* variant) {
73
74
	int count = m_variants.count();
	beginInsertRows(QModelIndex(), count, count);
75
	m_variants.append(variant);
76
	endInsertRows();
77
78
79
	emit newVariant(variant);
}

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
int GameVariantCollection::rowCount(const QModelIndex& parent) const {
	Q_UNUSED(parent);
	return m_variants.count();
}

QModelIndex GameVariantCollection::index(int row, int column, const QModelIndex &parent) const {
	Q_UNUSED(parent);
	if ((row < 0) || (row >= m_variants.count()))
		return QModelIndex();
	return createIndex(row, column, m_variants[row]);
}

QVariant GameVariantCollection::data(const QModelIndex &index, int role) const {
	if (!index.isValid() || index.row() >= m_variants.count())
		return QVariant();

	if (!index.internalPointer())
		return QVariant();
98

99
100
101
102
103
104
	GameVariant* gameVariant = static_cast<GameVariant*>(index.internalPointer());

	switch(role) {
		case Qt::DisplayRole:
			return gameVariant->name();
		case Qt::DecorationRole:
105
			return gameVariant->icon();
106
107
		case GameVariantDelegate::Description:
			return gameVariant->description();
108
	}
109

110
111
112
113
114
115
116
	return QVariant();
}

GameVariant* GameVariantCollection::variant(const QModelIndex& index) const {
	return static_cast<GameVariant*>(index.internalPointer());
}

117
118
119
120
121
122
123
124
125
126
127
128
///////////////////////////////////////////////////////////////////////////////
// class GameVariantDelegate
////////////77/////////////////////////////////////////////////////////////////

GameVariantDelegate::GameVariantDelegate(QObject* parent)
	: QItemDelegate(parent)
{
}

QSize GameVariantDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const {
	Q_UNUSED(option);
	Q_UNUSED(index);
129
	QSize size(m_leftMargin+m_iconWidth+m_rightMargin+m_separatorPixels*2, 0);
130

131
132
	if( m_iconHeight < option.fontMetrics.height()*3 )
		size.setHeight( option.fontMetrics.height()*3 + m_separatorPixels*3);
133
	else
134
		size.setHeight( m_iconHeight+m_separatorPixels*2);
135
136

	return size;
137
138
139
}

void GameVariantDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
140

141
	// show background
142
	QColor bkgColor;
143
	if (option.state & QStyle::State_Selected) {
144
145
		bkgColor = option.palette.color(QPalette::Highlight);
		painter->fillRect(option.rect, bkgColor);
146
	} else if(index.row() % 2) {
147
148
		bkgColor = option.palette.color(QPalette::AlternateBase);
		painter->fillRect(option.rect, bkgColor);
149
	} else {
150
151
		bkgColor = option.palette.color(QPalette::Base);
		painter->fillRect(option.rect, bkgColor);
152
	}
153
154
155

	QRect contentRect = option.rect.adjusted(m_leftMargin, m_separatorPixels, -m_rightMargin, -m_separatorPixels);

156
	// Show icon
157
158

	QPixmap iconPixmap = KIcon(icon(index), KIconLoader::global()).pixmap(m_iconWidth, m_iconHeight);
159
	painter->drawPixmap(contentRect.left(), (contentRect.height() - iconPixmap.height()) / 2 + contentRect.top(), iconPixmap);
160
161
	contentRect.adjust(iconPixmap.width() + m_separatorPixels*2, 0, 0, 0);

162
163
164
165
166
167
// 	// Show configuration icon
// 	if(configurable(index)) {
// 		QPixmap configPixmap = KIcon("configure", KIconLoader::global()).pixmap(32, 32);
// 		painter->drawPixmap(contentRect.right() - configPixmap.width(), (contentRect.height() - configPixmap.height()) / 2 + contentRect.top(), configPixmap);
// 		contentRect.adjust(0, 0, -(configPixmap.width() + separatorPixels), 0);
// 	}
168

169
170
171
172
	// Show Title
	QFont titleFont(painter->font());
	titleFont.setPointSize(titleFont.pointSize() + 2);
	titleFont.setWeight(QFont::Bold);
173

174
175
176
177
178
179
180
181
182
183
	QPen previousPen(painter->pen());
	// TODO: don't we have a function for 'color1 similar color2'
	if(previousPen.color() == bkgColor) {
		QPen p(previousPen);
		int color = bkgColor.rgb();
		color = ~color | 0xff000000;
		p.setColor(color);
		painter->setPen(p);
	}

184
185
186
187
	QFont previousFont(painter->font());
	painter->setFont(titleFont);
	QString titleStr = painter->fontMetrics().elidedText(title(index), Qt::ElideRight, contentRect.width());
	painter->drawText(contentRect, titleStr);
188
	contentRect.adjust(0, m_separatorPixels + painter->fontMetrics().height(), 0, 0);
189
	painter->setFont(previousFont);
190

191
192
193
	// Show Description
	QString descrStr = painter->fontMetrics().elidedText(description(index), Qt::ElideRight, contentRect.width());
	painter->drawText(contentRect, descrStr);
194
195

	painter->setPen(previousPen);
196
197
198
199
200
201
202
203
204
205
}

QString GameVariantDelegate::title(const QModelIndex& index) const {
	return index.model()->data(index, Qt::DisplayRole).toString();
}

QString GameVariantDelegate::description(const QModelIndex& index) const {
	return index.model()->data(index, Description).toString();
}

206
207
208
209
QString GameVariantDelegate::icon(const QModelIndex& index) const {
	return index.model()->data(index, Qt::DecorationRole).toString();
}

210
211
212
bool GameVariantDelegate::configurable(const QModelIndex& index) const {
	const GameVariantCollection* collection = dynamic_cast<const GameVariantCollection*>(index.model());
	if(!collection) return false;
213

214
215
216
217
218
219
220
	return collection->variant(index)->canConfigure();
}

bool GameVariantDelegate::eventFilter(QObject* watched, QEvent* event) {
	if(event->type() == QEvent::MouseButtonPress) {
		return true;
	}
221

222
	// TODO insert code for handling clicks on buttons in items.
223

224
225
	return QItemDelegate::eventFilter(watched, event);
}
226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
///////////////////////////////////////////////////////////////////////////////
// class SudokuGame
///////////////////////////////////////////////////////////////////////////////

SudokuGame::SudokuGame(const QString& name, uint order, GameVariantCollection* collection)
	: GameVariant(name, collection), m_order(order), m_solver(0)
{
	// TODO load from settings
	m_symmetry = 0;
}

bool SudokuGame::canConfigure() const {
	return true;
}

bool SudokuGame::configure() {
243
	KMessageBox::information(0, i18n("Configuration not yet implemented"), "");
244
245
246
	return false;
}

247
248
249
250
251
252
253
254
255
bool SudokuGame::canStartEmpty() const {
	return true;
}

Game SudokuGame::startEmpty() const {
	if(!m_solver) {
		m_solver = new SKSolver(m_order, false);
		m_solver->init();
	}
256

257
258
	Puzzle* puzzle = new Puzzle(m_solver, false);
	puzzle->init();
259

260
261
262
	return Game(puzzle);
}

263
264
265
266
267
Game SudokuGame::createGame(int difficulty) const {
	if(!m_solver) {
		m_solver = new SKSolver(m_order, false);
		m_solver->init();
	}
268

269
270
	Puzzle* puzzle = new Puzzle(m_solver, true);
	puzzle->init(difficulty, m_symmetry);
271

272
273
274
	return Game(puzzle);
}

275
KsView* SudokuGame::createView(const Game& /*game*/) const {
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
	qDebug() << "KsView* ksudoku::SudokuGame::createView()";
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// class RoxdokuGame
///////////////////////////////////////////////////////////////////////////////

RoxdokuGame::RoxdokuGame(const QString& name, uint order, GameVariantCollection* collection)
	: GameVariant(name, collection), m_order(order), m_solver(0)
{
	// TODO load from settings
	m_symmetry = 0;
}

bool RoxdokuGame::canConfigure() const {
	return true;
}

bool RoxdokuGame::configure() {
296
	KMessageBox::information(0, i18n("Configuration not yet implemented"), "");
297
298
299
	return false;
}

300
301
302
303
304
305
306
307
308
bool RoxdokuGame::canStartEmpty() const {
	return true;
}

Game RoxdokuGame::startEmpty() const {
	if(!m_solver) {
		m_solver = new SKSolver(m_order, true);
		m_solver->init();
	}
309

310
311
	Puzzle* puzzle = new Puzzle(m_solver, false);
	puzzle->init();
312

313
314
315
	return Game(puzzle);
}

316
317
318
319
320
Game RoxdokuGame::createGame(int difficulty) const {
	if(!m_solver) {
		m_solver = new SKSolver(m_order, true);
		m_solver->init();
	}
321

322
323
	Puzzle* puzzle = new Puzzle(m_solver, true);
	puzzle->init(difficulty, m_symmetry);
324

325
326
327
	return Game(puzzle);
}

328
KsView* RoxdokuGame::createView(const Game& /*game*/) const {
329
330
331
332
	qDebug() << "KsView* ksudoku::RoxdokuGame::createView()";
	return 0;
}

333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
///////////////////////////////////////////////////////////////////////////////
// class CustomGame
///////////////////////////////////////////////////////////////////////////////

CustomGame::CustomGame(const QString& name, const KUrl& url,
                       GameVariantCollection* collection)
	: GameVariant(name, collection), m_url(url), m_solver(0)
{ }

bool CustomGame::canConfigure() const {
	return false;
}

bool CustomGame::configure() {
	return false;
}

350
351
352
353
354
355
356
bool CustomGame::canStartEmpty() const {
	return true;
}

Game CustomGame::startEmpty() const {
	if(!m_solver) {
		m_solver = ksudoku::Serializer::loadCustomShape(m_url, 0, 0);
357

358
359
		if(!m_solver) return Game();
	}
360

361
362
	Puzzle* puzzle = new Puzzle(m_solver, false);
	puzzle->init();
363

364
365
366
	return Game(puzzle);
}

367
368
369
Game CustomGame::createGame(int difficulty) const {
	if(!m_solver) {
		m_solver = ksudoku::Serializer::loadCustomShape(m_url, 0, 0);
370

371
372
		if(!m_solver) return Game();
	}
373

374
375
	Puzzle* puzzle = new Puzzle(m_solver, true);
	puzzle->init(difficulty, 1);
376

377
378
379
380
381
382
383
384
	return Game(puzzle);
}

KsView* CustomGame::createView(const Game& /*game*/) const {
	qDebug() << "KsView* ksudoku::CustomGame::createView()";
	return 0;
}

385
}