summaryrefslogtreecommitdiffstats
path: root/fifteenapplet/fifteenapplet.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitae2a03c2941bf92573f89b88ef73f8aa842bea0a (patch)
tree3566563f3fb6ac3cb3496669d8f233062d3091bc /fifteenapplet/fifteenapplet.cpp
downloadtdetoys-ae2a03c2941bf92573f89b88ef73f8aa842bea0a.tar.gz
tdetoys-ae2a03c2941bf92573f89b88ef73f8aa842bea0a.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdetoys@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'fifteenapplet/fifteenapplet.cpp')
-rw-r--r--fifteenapplet/fifteenapplet.cpp321
1 files changed, 321 insertions, 0 deletions
diff --git a/fifteenapplet/fifteenapplet.cpp b/fifteenapplet/fifteenapplet.cpp
new file mode 100644
index 0000000..d55221a
--- /dev/null
+++ b/fifteenapplet/fifteenapplet.cpp
@@ -0,0 +1,321 @@
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <stdlib.h>
+#include <time.h>
+
+#include <qlayout.h>
+#include <qpainter.h>
+#include <qpopupmenu.h>
+
+#include <klocale.h>
+#include <kglobal.h>
+#include <kmessagebox.h>
+#include <kaboutapplication.h>
+
+#include "fifteenapplet.h"
+#include "fifteenapplet.moc"
+
+extern "C"
+{
+ KDE_EXPORT KPanelApplet* init(QWidget *parent, const QString& configFile)
+ {
+ KGlobal::locale()->insertCatalogue("kfifteenapplet");
+ return new FifteenApplet(configFile, KPanelApplet::Normal,
+ KPanelApplet::About, parent, "kfifteenapplet");
+ }
+}
+
+FifteenApplet::FifteenApplet(const QString& configFile, Type type, int actions,
+ QWidget *parent, const char *name)
+ : KPanelApplet(configFile, type, actions, parent, name), _aboutData(0)
+{
+ // setup table
+ _table = new PiecesTable(this);
+ setCustomMenu(_table->popup());
+
+ // setup layout
+ QHBoxLayout *_layout = new QHBoxLayout(this);
+ _layout->add(_table);
+
+ srand(time(0));
+}
+
+int FifteenApplet::widthForHeight(int h) const
+{
+ return h; // we want to be quadratic
+}
+
+int FifteenApplet::heightForWidth(int w) const
+{
+ return w; // we want to be quadratic
+}
+
+void FifteenApplet::about()
+{
+ if(!_aboutData) {
+ _aboutData = new KAboutData("kfifteenapplet", I18N_NOOP("KFifteenApplet"), "1.0",
+ I18N_NOOP("Fifteen pieces applet.\n\n"
+ "The goal is to put the sliding pieces into numerical order.\n"
+ "Select \"Randomize Pieces\" from the right mouse button menu\n"
+ "to start a game."),
+ KAboutData::License_BSD, "(c) 2001, Matthias Elter");
+ _aboutData->addAuthor("Matthias Elter", 0, "elter@kde.org");
+ }
+
+ KAboutApplication dialog(_aboutData);
+ dialog.exec();
+}
+
+PiecesTable::PiecesTable(QWidget* parent, const char* name )
+ : QtTableView(parent, name), _activeRow(-1), _activeCol(-1), _randomized(false)
+{
+ _menu = new QPopupMenu(this);
+ _menu->insertItem(i18n("R&andomize Pieces"), this, SLOT(randomizeMap()));
+ _menu->insertItem(i18n("&Reset Pieces"), this, SLOT(resetMap()));
+ _menu->adjustSize(); // setup table view
+
+ setFrameStyle(StyledPanel | Sunken);
+ setBackgroundMode(NoBackground);
+ setMouseTracking(true);
+
+ setNumRows(4);
+ setNumCols(4);
+
+ // init arrays
+ initMap();
+ initColors();
+}
+
+void PiecesTable::paintCell(QPainter *p, int row, int col)
+{
+ int w = cellWidth();
+ int h = cellHeight();
+ int x2 = w - 1;
+ int y2 = h - 1;
+
+ int number = _map[col + row * numCols()] + 1;
+
+ bool active = (row == _activeRow && col == _activeCol);
+
+ // draw cell background
+ if(number == 16)
+ p->setBrush(colorGroup().background());
+ else
+ p->setBrush(_colors[number-1]);
+ p->setPen(NoPen);
+ p->drawRect(0, 0, w, h);
+
+ // draw borders
+ if (height() > 40) {
+ p->setPen(colorGroup().text());
+ if(col < numCols()-1)
+ p->drawLine(x2, 0, x2, y2); // right border line
+
+ if(row < numRows()-1)
+ p->drawLine(0, y2, x2, y2); // bottom boder line
+ }
+
+ // draw number
+ if (number == 16) return;
+ if(active)
+ p->setPen(white);
+ else
+ p->setPen(black);
+ p->drawText(0, 0, x2, y2, AlignHCenter | AlignVCenter, QString::number(number));
+}
+
+void PiecesTable::resizeEvent(QResizeEvent *e)
+{
+ QtTableView::resizeEvent(e);
+
+ // set font
+ QFont f = font();
+ if (height() > 50)
+ f.setPixelSize(8);
+ else if (height() > 40)
+ f.setPixelSize(7);
+ else if (height() > 24)
+ f.setPixelSize(5);
+ else
+ f.setPixelSize(3);
+
+ setFont(f);
+
+ setCellWidth(contentsRect().width()/ numRows());
+ setCellHeight(contentsRect().height() / numCols());
+}
+
+void PiecesTable::initColors()
+{
+ _colors.resize(numRows() * numCols());
+ for (int r = 0; r < numRows(); r++)
+ for (int c = 0; c < numCols(); c++)
+ _colors[c + r *numCols()] = QColor(255 - 70 * c,255 - 70 * r, 150);
+}
+
+void PiecesTable::initMap()
+{
+ _map.resize(16);
+ for (unsigned int i = 0; i < 16; i++)
+ _map[i] = i;
+
+ _randomized = false;
+}
+
+void PiecesTable::randomizeMap()
+{
+ QMemArray<int> positions;
+ positions.fill(0, 16);
+
+ for (unsigned int i = 0; i < 16; i++) {
+ while(1) {
+ int r = (int) (((double)rand() / RAND_MAX) * 16);
+ if(positions[r] == 0) {
+ _map[i] = r;
+ positions[r] = 1;
+ break;
+ }
+ }
+ }
+ repaint();
+ _randomized = true;
+}
+
+void PiecesTable::resetMap()
+{
+ initMap();
+ repaint();
+}
+
+void PiecesTable::checkwin()
+{
+ if(!_randomized) return;
+
+ int i;
+ for (i = 0; i < 16; i++)
+ if(i != _map[i])
+ break;
+
+ if (i == 16)
+ KMessageBox::information(this, i18n("Congratulations!\nYou win the game!"), i18n("Fifteen Pieces"));
+}
+
+void PiecesTable::mousePressEvent(QMouseEvent* e)
+{
+ QtTableView::mousePressEvent(e);
+
+ if (e->button() == RightButton) {
+ // execute RMB popup and check result
+ _menu->exec(mapToGlobal(e->pos()));
+ e->accept();
+ return;
+ }
+ else {
+ // GAME LOGIC
+
+ // find the free position
+ int pos = _map.find(15);
+ if(pos < 0) return;
+
+ int frow = pos / numCols();
+ int fcol = pos - frow * numCols();
+
+ // find click position
+ int row = findRow(e->y());
+ int col = findCol(e->x());
+
+ // sanity check
+ if (row < 0 || row >= numRows()) return;
+ if (col < 0 || col >= numCols()) return;
+
+ // valid move?
+ if(row != frow && col != fcol) return;
+
+ // rows match -> shift pieces
+ if(row == frow) {
+
+ if (col < fcol) {
+ for(int c = fcol; c > col; c--) {
+ _map[c + row * numCols()] = _map[ c-1 + row *numCols()];
+ updateCell(row, c, false);
+ }
+ }
+ else if (col > fcol) {
+ for(int c = fcol; c < col; c++) {
+ _map[c + row * numCols()] = _map[ c+1 + row *numCols()];
+ updateCell(row, c, false);
+ }
+ }
+ }
+ // cols match -> shift pieces
+ else if (col == fcol) {
+
+ if (row < frow) {
+ for(int r = frow; r > row; r--) {
+ _map[col + r * numCols()] = _map[ col + (r-1) *numCols()];
+ updateCell(r, col, false);
+ }
+ }
+ else if (row > frow) {
+ for(int r = frow; r < row; r++) {
+ _map[col + r * numCols()] = _map[ col + (r+1) *numCols()];
+ updateCell(r, col, false);
+ }
+ }
+ }
+ // move free cell to click position
+ _map[col + row * numCols()] = 15;
+ updateCell(row, col, false);
+
+ // check if the player wins with this move
+ checkwin();
+ }
+}
+
+void PiecesTable::mouseMoveEvent(QMouseEvent* e)
+{
+ QtTableView::mouseMoveEvent(e);
+
+ // highlight on mouse over
+ int row = findRow(e->y());
+ int col = findCol(e->x());
+
+ int oldrow = _activeRow;
+ int oldcol = _activeCol;
+
+ if(row >= numRows()
+ || col >= numCols()
+ || row < 0
+ || col < 0) {
+ _activeRow = -1;
+ _activeCol = -1;
+ }
+ else {
+ _activeRow = row;
+ _activeCol = col;
+ }
+
+ updateCell(oldrow, oldcol, false);
+ updateCell(row, col, false);
+}