summaryrefslogtreecommitdiffstats
path: root/blinken/src
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
commitce599e4f9f94b4eb00c1b5edb85bce5431ab3df2 (patch)
treed3bb9f5d25a2dc09ca81adecf39621d871534297 /blinken/src
downloadtdeedu-ce599e4f9f94b4eb00c1b5edb85bce5431ab3df2.tar.gz
tdeedu-ce599e4f9f94b4eb00c1b5edb85bce5431ab3df2.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/kdeedu@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'blinken/src')
-rw-r--r--blinken/src/Makefile.am23
-rw-r--r--blinken/src/artsplayer.cpp147
-rw-r--r--blinken/src/artsplayer.h66
-rw-r--r--blinken/src/blinken.cpp855
-rw-r--r--blinken/src/blinken.desktop113
-rw-r--r--blinken/src/blinken.h92
-rw-r--r--blinken/src/blinken.kcfg18
-rw-r--r--blinken/src/blinkengame.cpp181
-rw-r--r--blinken/src/blinkengame.h72
-rw-r--r--blinken/src/button.cpp119
-rw-r--r--blinken/src/button.h43
-rw-r--r--blinken/src/counter.cpp57
-rw-r--r--blinken/src/counter.h23
-rw-r--r--blinken/src/fontchecker.cpp27
-rw-r--r--blinken/src/fontchecker.h21
-rw-r--r--blinken/src/fontutils.cpp33
-rw-r--r--blinken/src/fontutils.h18
-rw-r--r--blinken/src/highscoredialog.cpp198
-rw-r--r--blinken/src/highscoredialog.h33
-rw-r--r--blinken/src/main.cpp41
-rw-r--r--blinken/src/number.cpp196
-rw-r--r--blinken/src/number.h39
-rw-r--r--blinken/src/settings.kcfgc4
23 files changed, 2419 insertions, 0 deletions
diff --git a/blinken/src/Makefile.am b/blinken/src/Makefile.am
new file mode 100644
index 00000000..a980ac81
--- /dev/null
+++ b/blinken/src/Makefile.am
@@ -0,0 +1,23 @@
+if include_ARTS
+artslib = -lartskde
+else
+artslib =
+endif
+
+bin_PROGRAMS = blinken
+
+INCLUDES = $(all_includes)
+
+blinken_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+blinken_LDADD = $(LIB_KDEUI) $(LIB_KIO) $(artslib)
+
+blinken_SOURCES = main.cpp blinken.cpp artsplayer.cpp blinkengame.cpp number.cpp highscoredialog.cpp counter.cpp fontutils.cpp fontchecker.cpp button.cpp settings.kcfgc
+
+METASOURCES = AUTO
+
+xdg_apps_DATA = blinken.desktop
+
+kde_kcfg_DATA = blinken.kcfg
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/blinken.pot
diff --git a/blinken/src/artsplayer.cpp b/blinken/src/artsplayer.cpp
new file mode 100644
index 00000000..b9632737
--- /dev/null
+++ b/blinken/src/artsplayer.cpp
@@ -0,0 +1,147 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include <qtimer.h>
+
+#include <config.h>
+
+#ifdef WITHOUT_ARTS
+#include <klocale.h>
+#include <kmessagebox.h>
+#endif
+#include <kstandarddirs.h>
+
+#include "artsplayer.h"
+#include "settings.h"
+
+artsPlayer::artsPlayer() : m_playobj(0)
+{
+ m_endChecker = new QTimer(this);
+ connect(m_endChecker, SIGNAL(timeout()), this, SLOT(checkEnded()));
+
+#ifndef WITHOUT_ARTS
+ m_dispatcher = new KArtsDispatcher;
+ m_server = new KArtsServer;
+ m_factory = new KDE::PlayObjectFactory(m_server->server());
+
+ m_allPath = locate("appdata","sounds/lose.wav");
+ m_greenPath = locate("appdata","sounds/1.wav");
+ m_redPath = locate("appdata","sounds/2.wav");
+ m_bluePath = locate("appdata","sounds/3.wav");
+ m_yellowPath = locate("appdata","sounds/4.wav");
+#else
+ KMessageBox::information(0, i18n("aRts was not found, therefore the sounds will be disabled."), i18n("Sounds Disabled"), "infoaboutartsnotfound");
+#endif
+}
+
+artsPlayer::~artsPlayer()
+{
+#ifndef WITHOUT_ARTS
+ delete m_playobj;
+ delete m_factory;
+ delete m_server;
+ delete m_dispatcher;
+#endif
+}
+
+void artsPlayer::play(blinkenGame::color c, bool stopCurrent)
+{
+ int check;
+#ifndef WITHOUT_ARTS
+ if (blinkenSettings::playSounds())
+ {
+ if (m_playobj && m_playobj -> state() == Arts::posPlaying)
+ {
+ if (stopCurrent)
+ {
+ m_nextSounds.clear();
+ m_nextSounds.append(c);
+ m_playobj -> halt();
+ play();
+ }
+ else m_nextSounds.append(c);
+ }
+ else
+ {
+ m_nextSounds.append(c);
+ play();
+ }
+ check = 50;
+ }
+ else check = 250;
+#else
+ //shut up gcc
+ (void)c;
+ (void)stopCurrent;
+ check = 250;
+#endif
+ if (!m_endChecker -> isActive()) m_endChecker -> start(check);
+}
+
+void artsPlayer::play()
+{
+#ifndef WITHOUT_ARTS
+ QString path;
+ blinkenGame::color c = m_nextSounds.first();
+ m_nextSounds.pop_front();
+ switch (c)
+ {
+ case blinkenGame::red:
+ path = m_redPath;
+ break;
+
+ case blinkenGame::green:
+ path = m_greenPath;
+ break;
+
+ case blinkenGame::blue:
+ path = m_bluePath;
+ break;
+
+ case blinkenGame::yellow:
+ path = m_yellowPath;
+ break;
+
+ case blinkenGame::all:
+ path = m_allPath;
+ break;
+
+ case blinkenGame::none:
+ break;
+ }
+ delete m_playobj;
+ m_playobj = m_factory -> createPlayObject(path, true);
+ m_playobj -> play();
+#endif
+}
+
+void artsPlayer::checkEnded()
+{
+#ifndef WITHOUT_ARTS
+ if (blinkenSettings::playSounds())
+ {
+ if (m_playobj -> state() != Arts::posPlaying)
+ {
+ m_endChecker -> stop();
+ emit ended();
+ if (m_nextSounds.size() > 0) play();
+ }
+ }
+ else
+ {
+ m_endChecker -> stop();
+ emit ended();
+ }
+#else
+ m_endChecker -> stop();
+ emit ended();
+#endif
+}
+
+#include "artsplayer.moc"
diff --git a/blinken/src/artsplayer.h b/blinken/src/artsplayer.h
new file mode 100644
index 00000000..d502ddbd
--- /dev/null
+++ b/blinken/src/artsplayer.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef ARTSPLAYER_H
+#define ARTSPLAYER_H
+
+#include <config.h>
+
+#ifdef WITHOUT_ARTS
+class KArtsDispatcher;
+class KArtsServer;
+
+namespace KDE
+{
+ class PlayObjectFactory;
+ class PlayObject;
+}
+#else
+#include <arts/kartsdispatcher.h>
+#include <arts/kartsserver.h>
+#include <arts/kplayobject.h>
+#include <arts/kplayobjectfactory.h>
+#endif
+
+#include <qvaluelist.h>
+
+#include "blinkengame.h"
+
+class QTimer;
+
+class artsPlayer : public QObject
+{
+Q_OBJECT
+ public:
+ artsPlayer();
+ ~artsPlayer();
+
+ void play(blinkenGame::color c, bool stopCurrent = false);
+
+ signals:
+ void ended();
+
+ private slots:
+ void play();
+ void checkEnded();
+
+ private:
+ QValueList<blinkenGame::color> m_nextSounds;
+
+ QString m_greenPath, m_redPath, m_bluePath, m_yellowPath, m_allPath;
+
+ QTimer *m_endChecker;
+
+ KArtsDispatcher *m_dispatcher;
+ KArtsServer *m_server;
+ KDE::PlayObjectFactory *m_factory;
+ KDE::PlayObject *m_playobj;
+};
+
+#endif
diff --git a/blinken/src/blinken.cpp b/blinken/src/blinken.cpp
new file mode 100644
index 00000000..997895fa
--- /dev/null
+++ b/blinken/src/blinken.cpp
@@ -0,0 +1,855 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include <qcursor.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qtimer.h>
+
+#include <kaction.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <khelpmenu.h>
+#include <kinputdialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kpopupmenu.h>
+#include <kstandarddirs.h>
+
+#include "blinken.h"
+#include "button.h"
+#include "counter.h"
+#include "fontutils.h"
+#include "number.h"
+#include "highscoredialog.h"
+#include "settings.h"
+
+blinken::blinken() : QWidget(0, 0, WStaticContents | WNoAutoErase), m_overHighscore(false), m_overQuit(false), m_overCentralText(false), m_overMenu(false), m_overAboutKDE(false), m_overAboutBlinken(false), m_overManual(false), m_overCentralLetters(false), m_overCounter(false), m_overFont(false), m_overSound(false), m_showPreferences(false), m_updateButtonHighlighting(false), m_highlighted(blinkenGame::none)
+{
+ m_back = new QPixmap(locate("appdata", "images/blinken.png"));
+
+ m_buttons[0] = new button(blinkenGame::blue);
+ m_buttons[1] = new button(blinkenGame::yellow);
+ m_buttons[2] = new button(blinkenGame::red);
+ m_buttons[3] = new button(blinkenGame::green);
+
+ m_highscore = new QPixmap(locate("appdata", "images/highscore.png"));
+ m_highscoreHover = new QPixmap(locate("appdata", "images/highscore_hover.png"));
+ m_quit = new QPixmap(locate("appdata", "images/quit.png"));
+ m_quitHover = new QPixmap(locate("appdata", "images/quit_hover.png"));
+ m_menu = new QPixmap(locate("appdata", "images/menu.png"));
+ m_menuHover = new QPixmap(locate("appdata", "images/menu_hover.png"));
+ m_mark = new QPixmap(locate("appdata", "images/mark.png"));
+ m_highscoreRect = QRect(10, 10, 72, 72);
+ m_quitRect = QRect(562, 10, 72, 73);
+ m_menuRect = QRect(562, 443, 72, 72);
+ m_aboutKDERect = QRect(452, 461, 54, 54);
+ m_aboutBlinkenRect = QRect(506, 461, 56, 54);
+ m_manualRect = QRect(578, 389, 54, 54);
+ m_centralLettersRect = QRect(192, 194, 254, 54);
+ m_counterRect = QRect(268, 110, 102, 52);
+
+ m_fillColor = QColor(40, 40, 40);
+ m_fontColor = QColor(126, 126, 126);
+ m_fontHighlightColor = QColor(230, 230, 230);
+ m_countDownColor = QColor(55, 55, 55);
+
+ setMouseTracking(true);
+ setFixedSize(644, 525);
+ show();
+
+ m_unhighlighter = new QTimer(this);
+ connect(m_unhighlighter, SIGNAL(timeout()), this, SLOT(unhighlight()));
+
+ connect(&m_game, SIGNAL(gameEnded()), this, SLOT(checkHS()));
+ connect(&m_game, SIGNAL(phaseChanged()), this, SLOT(update()));
+ connect(&m_game, SIGNAL(highlight(blinkenGame::color, bool)), this, SLOT(highlight(blinkenGame::color, bool)));
+
+ m_helpMenu = new KHelpMenu(this, kapp->aboutData());
+
+ for (int i = 0; i < 3; i++) m_overLevels[i] = false;
+
+ QString aux = i18n("If the Steve font that is used by bliken by default to show status messages does not support any of the characters of your language, please translate that message to 1 and KDE standard font will be used to show the texts, if not translate it to 0", "0");
+
+ m_alwaysUseNonCoolFont = aux == "1";
+}
+
+blinken::~blinken()
+{
+ delete m_back;
+ for (int i = 0; i < 4; i++) delete m_buttons[i];
+ delete m_highscore;
+ delete m_highscoreHover;
+ delete m_quit;
+ delete m_quitHover;
+ delete m_menu;
+ delete m_menuHover;
+ delete m_mark;
+ delete m_helpMenu;
+}
+
+void blinken::paintEvent(QPaintEvent *)
+{
+ QPixmap buf(width(), height());
+ QPainter p(&buf);
+
+ p.drawPixmap(0, 0, *m_back);
+
+ drawMenuQuit(p);
+ QFont f1, f = p.font();
+ f1 = f;
+ f.setBold(true);
+ p.setFont(f);
+ switch (m_game.phase())
+ {
+ case blinkenGame::starting:
+ drawText(p, i18n("Start"), QPoint(318, 316), true, 10, 5, &m_centralTextRect, m_overCentralText, false);
+ break;
+
+ case blinkenGame::choosingLevel:
+ drawLevel(p);
+ break;
+
+ case blinkenGame::waiting3:
+ case blinkenGame::waiting2:
+ case blinkenGame::waiting1:
+ case blinkenGame::learningTheSequence:
+ case blinkenGame::typingTheSequence:
+ drawText(p, i18n("Restart"), QPoint(318, 316), true, 10, 5, &m_centralTextRect, m_overCentralText, false);
+ break;
+ }
+ p.setFont(f1);
+
+ if (m_showPreferences)
+ {
+ // draw the current keys
+ drawText(p, m_buttons[0]->shortcut(), QPoint(115, 285), true, 20, 5, 0, m_buttons[0]->selected(), false);
+ drawText(p, m_buttons[1]->shortcut(), QPoint(115, 155), true, 20, 5, 0, m_buttons[1]->selected(), false);
+ drawText(p, m_buttons[2]->shortcut(), QPoint(520, 155), true, 20, 5, 0, m_buttons[2]->selected(), false);
+ drawText(p, m_buttons[3]->shortcut(), QPoint(520, 285), true, 20, 5, 0, m_buttons[3]->selected(), false);
+
+ const QPen &oPen = p.pen();
+ const QBrush &oBrush = p.brush();
+ const QFont &oFont = p.font();
+
+ // draw the internal square plus a bit of ellipse on the sides and the
+ // two delimiter lines
+ p.setPen(NoPen);
+ p.setBrush(m_fillColor);
+ p.drawPie(169, 192, 4, 58, 1440, 2880);
+ p.drawPie(465, 192, 4, 58, -1440, 2880);
+ p.setPen(QPen(Qt::black, 3));
+ p.fillRect(171, 192, 296, 58, m_fillColor);
+ p.drawLine(169, 192, 469, 192);
+ p.drawLine(169, 250, 469, 250);
+
+ // draw the two squares of the options
+ p.setPen(QPen(m_fontColor, 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
+
+ m_soundRect = QRect(181, 209, 25, 25);
+ m_fontRect = QRect(432, 209, 25, 25);
+#ifndef WITHOUT_ARTS
+ p.drawRect(m_soundRect);
+ if (blinkenSettings::playSounds())
+ {
+ p.drawLine(186, 214, 199, 227);
+ p.drawLine(186, 227, 199, 214);
+ }
+#endif
+ if (!m_alwaysUseNonCoolFont)
+ {
+ p.drawRect(m_fontRect);
+ if (blinkenSettings::customFont())
+ {
+ p.drawLine(437, 214, 450, 227);
+ p.drawLine(437, 227, 450, 214);
+ }
+ }
+
+ // draw the options' text
+ QFont f1 = QFont();
+ p.setFont(f1);
+ int size, sizeAux;
+ QRect area;
+ QString sounds = i18n("Sounds");
+ QString font = i18n("Font");
+ size = fontUtils::fontSize(p, sounds, 95, 20);
+ sizeAux = fontUtils::fontSize(p, font, 95, 20);
+ if (sizeAux > size) size = sizeAux;
+ f1.setPointSize(size);
+#ifndef WITHOUT_ARTS
+ area = p.boundingRect(QRect(), Qt::AlignAuto, sounds);
+ area.moveBy(212, 221 - (area.height() / 2));
+ p.drawText(area, Qt::AlignCenter, sounds);
+ m_soundRect = m_soundRect.unite(area);
+#endif
+ if (!m_alwaysUseNonCoolFont)
+ {
+ area = p.boundingRect(QRect(), Qt::AlignAuto, font);
+ area.moveBy(426 - area.width(), 221 - (area.height() / 2));
+ p.drawText(area, Qt::AlignCenter, font);
+ m_fontRect = m_fontRect.unite(area);
+ }
+
+ p.setFont(oFont);
+ p.setPen(oPen);
+ p.setBrush(oBrush);
+ }
+
+ drawScoreAndCounter(p);
+
+ if (m_highlighted & blinkenGame::blue) p.drawPixmap(14, 225, *m_buttons[0] -> pixmap());
+ if (m_highlighted & blinkenGame::yellow) p.drawPixmap(14, 16, *m_buttons[1] -> pixmap());
+ if (m_highlighted & blinkenGame::red) p.drawPixmap(322, 16, *m_buttons[2] -> pixmap());
+ if (m_highlighted & blinkenGame::green) p.drawPixmap(322, 225, *m_buttons[3] -> pixmap());
+
+ drawStatusText(p);
+
+ bitBlt(this, 0, 0, &buf);
+
+ if (m_updateButtonHighlighting) updateButtonHighlighting(mapFromGlobal(QCursor::pos()));
+}
+
+void blinken::keyPressEvent(QKeyEvent *e)
+{
+ if (e -> isAutoRepeat()) return;
+
+ if (m_showPreferences)
+ {
+ int i = 0;
+ while (i < 4 && !m_buttons[i] -> selected()) i++;
+
+ if (i < 4)
+ {
+ if (e -> key() == Qt::Key_Escape)
+ {
+ m_buttons[i] -> setSelected(false);
+ update();
+ }
+ else
+ {
+ KShortcut ks(e -> key());
+ if (!ks.toString().isEmpty())
+ {
+ bool different = true;
+ int j = 0;
+ while (different && j < 4)
+ {
+ different = (ks.toString() != m_buttons[j] -> shortcut());
+ j++;
+ }
+
+ if (different)
+ {
+ m_buttons[i] -> setShortcut(ks);
+ update();
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (e -> key() == m_buttons[0] -> key()) pressedBlue();
+ else if (e -> key() == m_buttons[1] -> key()) pressedYellow();
+ else if (e -> key() == m_buttons[2] -> key()) pressedRed();
+ else if (e -> key() == m_buttons[3] -> key()) pressedGreen();
+ }
+}
+
+void blinken::keyReleaseEvent(QKeyEvent *e)
+{
+ if (e -> isAutoRepeat()) return;
+
+ if (e -> state() == Qt::ControlButton && e -> stateAfter() != Qt::ControlButton && (m_game.phase() == blinkenGame::starting || m_game.phase() == blinkenGame::choosingLevel))
+ {
+ m_showPreferences = !m_showPreferences;
+ for (int i = 0; i < 4; i++) m_buttons[i] -> setSelected(false);
+ updateButtonHighlighting(mapFromGlobal(QCursor::pos()));
+ update();
+ }
+}
+
+void blinken::mouseMoveEvent(QMouseEvent *e)
+{
+ updateButtonHighlighting(e->pos());
+}
+
+void blinken::mousePressEvent(QMouseEvent *e)
+{
+ if (m_overHighscore || m_overCounter)
+ {
+ highScoreDialog *hsd = new highScoreDialog(this);
+ hsd->showLevel(1);
+ m_updateButtonHighlighting = true;
+ }
+ else if (m_showPreferences && m_fontRect.contains(e -> pos()) && !m_alwaysUseNonCoolFont)
+ {
+ blinkenSettings::setCustomFont(!blinkenSettings::customFont());
+ blinkenSettings::writeConfig();
+ update();
+ }
+ else if (m_showPreferences && m_soundRect.contains(e -> pos()))
+ {
+ blinkenSettings::setPlaySounds(!blinkenSettings::playSounds());
+ blinkenSettings::writeConfig();
+ update();
+ }
+ else if (m_overQuit) kapp->quit();
+ else if (m_overAboutBlinken || m_overCentralLetters) m_helpMenu -> aboutApplication();
+ else if (m_overAboutKDE) m_helpMenu -> aboutKDE();
+ else if (m_overManual) m_helpMenu -> appHelpActivated();
+ else if (m_game.phase() != blinkenGame::choosingLevel && m_overCentralText)
+ {
+ highlight(blinkenGame::none, true);
+ m_overCentralText = false;
+ for(int i = 0; i < 3; i++) m_overLevels[i] = false;
+ m_game.setPhase(blinkenGame::choosingLevel);
+ m_updateButtonHighlighting = true;
+ }
+ else if (m_game.phase() == blinkenGame::choosingLevel)
+ {
+ int level = 0;
+ if (m_levelsRect[1].contains(e -> pos())) level = 1;
+ else if (m_levelsRect[0].contains(e -> pos())) level = 2;
+ else if (m_levelsRect[2].contains(e -> pos())) level = 3;
+ if (level)
+ {
+ for(int i = 0; i < 3; i++) m_overLevels[i] = false;
+ m_game.start(level);
+ if (m_showPreferences) m_showPreferences = false;
+ m_updateButtonHighlighting = true;
+ }
+ }
+
+ QPoint p = e->pos();
+ p -= QPoint(319, 221);
+ if (insideGreen(p))
+ {
+ if (m_showPreferences) selectButton(3);
+ else pressedGreen();
+ }
+ else if (insideBlue(p))
+ {
+ if (m_showPreferences) selectButton(0);
+ else pressedBlue();
+ }
+ else if (insideYellow(p))
+ {
+ if (m_showPreferences) selectButton(1);
+ else pressedYellow();
+ }
+ else if (insideRed(p))
+ {
+ if (m_showPreferences) selectButton(2);
+ else pressedRed();
+ }
+}
+
+void blinken::checkHS()
+{
+ highScoreDialog *hsd = new highScoreDialog(this);
+ if (hsd->scoreGoodEnough(m_game.level(), m_game.score()))
+ {
+ bool ok;
+ QString name = KInputDialog::getText(i18n("Enter Your Name"), i18n("Name:"), m_lastName, &ok);
+ if (!name.isNull() && ok)
+ {
+ m_lastName = name;
+ hsd->addScore(m_game.level(), m_game.score(), name);
+ }
+ hsd->showLevel(m_game.level());
+ }
+}
+
+void blinken::highlight(blinkenGame::color c, bool unhighlight)
+{
+ m_highlighted = c;
+ update();
+ if (unhighlight) m_unhighlighter -> start(250);
+ else if (c == blinkenGame::none)
+ {
+ m_unhighlighter -> stop();
+ updateCursor(mapFromGlobal(QCursor::pos()));
+ }
+}
+
+void blinken::unhighlight()
+{
+ highlight(blinkenGame::none, false);
+}
+
+void blinken::pressedYellow()
+{
+ if (m_game.canType())
+ {
+ highlight(blinkenGame::yellow, true);
+ m_game.clicked(blinkenGame::yellow);
+ }
+}
+
+void blinken::pressedRed()
+{
+ if (m_game.canType())
+ {
+ highlight(blinkenGame::red, true);
+ m_game.clicked(blinkenGame::red);
+ }
+}
+
+void blinken::pressedGreen()
+{
+ if (m_game.canType())
+ {
+ highlight(blinkenGame::green, true);
+ m_game.clicked(blinkenGame::green);
+ }
+}
+
+void blinken::pressedBlue()
+{
+ if (m_game.canType())
+ {
+ highlight(blinkenGame::blue, true);
+ m_game.clicked(blinkenGame::blue);
+ }
+}
+
+void blinken::selectButton(int button)
+{
+ int i = 0;
+ bool selected = false;
+ while (i < 4 && !selected)
+ {
+ selected = m_buttons[i] -> selected();
+ if (!selected) i++;
+ }
+
+ if (selected)
+ {
+ if (i == button)
+ {
+ m_buttons[button] -> setSelected(false);
+ update();
+ }
+ }
+ else
+ {
+ m_buttons[button] -> setSelected(true);
+ update();
+ }
+}
+
+bool blinken::insideGreen(const QPoint &p) const
+{
+ return insideButtonsArea(p) && p.x() > 6 && p.y() > 6;
+}
+
+bool blinken::insideBlue(const QPoint &p) const
+{
+ return insideButtonsArea(p) && p.x() < -6 && p.y() > 6;
+}
+
+bool blinken::insideYellow(const QPoint &p) const
+{
+ return insideButtonsArea(p) && p.x() < -6 && p.y() < -6;
+}
+
+bool blinken::insideRed(const QPoint &p) const
+{
+ return insideButtonsArea(p) && p.x() > 6 && p.y() < -6;
+}
+
+bool blinken::insideButtonsArea(const QPoint &p) const
+{
+ double x, y, x2, y2;
+ x = (double)p.x();
+ y = (double)p.y();
+ x2 = x * x;
+ y2 = y * y;
+ if (x2 + y2 > 162.5 * 162.5)
+ {
+ // Outside the circle
+ double x3, y3;
+ x3 = x2 / (301 * 301);
+ y3 = y2 / (201 * 201);
+ if (x3 + y3 < 1) return true;
+ }
+ return false;
+}
+
+void blinken::drawMenuQuit(QPainter &p)
+{
+ if (!m_overHighscore) p.drawPixmap(10, 10, *m_highscore);
+ else p.drawPixmap(10, 10, *m_highscoreHover);
+
+ if (!m_overQuit) p.drawPixmap(562, 10, *m_quit);
+ else p.drawPixmap(562, 10, *m_quitHover);
+
+ if (!m_overMenu) p.drawPixmap(562, 443, *m_menu);
+ else p.drawPixmap(454, 389, *m_menuHover);
+
+ if (m_overAboutKDE) p.drawPixmap(462, 433, *m_mark);
+ else if (m_overAboutBlinken) p.drawPixmap(516, 433, *m_mark);
+ else if (m_overManual)
+ {
+ p.translate(550, 430);
+ p.rotate(-90.0);
+ p.drawPixmap(0, 0, *m_mark);
+ p.rotate(90.0);
+ p.translate(-550, -430);
+ }
+}
+
+void blinken::drawScoreAndCounter(QPainter &p)
+{
+ QColor c1, c2, c3;
+ p.translate(268, 110);
+
+ switch (m_game.phase())
+ {
+ case blinkenGame::waiting3:
+ c1 = red;
+ c2 = red;
+ c3 = red;
+ break;
+
+ case blinkenGame::waiting2:
+ c1 = m_countDownColor;
+ c2 = red;
+ c3 = red;
+ break;
+
+ case blinkenGame::waiting1:
+ c1 = m_countDownColor;
+ c2 = c1;
+ c3 = red;
+ break;
+
+ default:
+ c1 = m_countDownColor;
+ c2 = c1;
+ c3 = c1;
+ break;
+ }
+
+ counter::paint(p, m_game.phase() != blinkenGame::starting, m_game.score(), true, c1, c2, c3);
+
+ p.translate(-268, -110);
+}
+
+void blinken::drawStatusText(QPainter &p)
+{
+ p.translate(25, 505);
+ p.rotate(-3.29);
+ p.setPen(blue);
+
+ QString restartText = i18n("Restart the game");
+ QString text;
+ if (m_overQuit) text = i18n("Quit blinKen");
+ else if (m_overHighscore || m_overCounter) text = i18n("View Highscore Table");
+ else if (m_overAboutBlinken || m_overCentralLetters) text = m_helpMenu -> menu() -> text(KHelpMenu::menuAboutApp).remove("&");
+ else if (m_overAboutKDE) text = m_helpMenu -> menu() -> text(KHelpMenu::menuAboutKDE).remove("&");
+ else if (m_overManual) text = m_helpMenu -> menu() -> text(KHelpMenu::menuHelpContents).remove("&");
+ else if (m_overLevels[0]) text = i18n("2nd Level");
+ else if (m_overLevels[1]) text = i18n("1st Level");
+ else if (m_overLevels[2]) text = i18n("Random Level");
+ else if (m_buttons[0]->selected() || m_buttons[1]->selected() || m_buttons[2]->selected() || m_buttons[3]->selected()) text = i18n("Press the key for this button");
+ else if (m_showPreferences) text = i18n("Click any button to change its key");
+ else
+ {
+ switch (m_game.phase())
+ {
+ case blinkenGame::starting:
+ text = i18n("Press Start to begin!");
+ break;
+
+ case blinkenGame::choosingLevel:
+ text = i18n("Set the Difficulty Level...");
+ break;
+
+ case blinkenGame::waiting3:
+ if (m_overCentralText) text = restartText;
+ else text = i18n("Next sequence in 3...");
+ break;
+
+ case blinkenGame::waiting2:
+ if (m_overCentralText) text = restartText;
+ else if (m_game.level() == 1) text = i18n("Next sequence in 3, 2...");
+ else text = i18n("Next sequence in 2...");
+ break;
+
+ case blinkenGame::waiting1:
+ if (m_overCentralText) text = restartText;
+ else if (m_game.level() == 1) text = i18n("Next sequence in 3, 2, 1...");
+ else text = i18n("Next sequence in 2, 1...");
+ break;
+
+ case blinkenGame::learningTheSequence:
+ if (m_overCentralText) text = restartText;
+ else text = i18n("Remember this sequence...");
+ break;
+
+ case blinkenGame::typingTheSequence:
+ if (m_overCentralText) text = restartText;
+ else text = i18n("Repeat the sequence!");
+ break;
+ }
+ }
+
+ QFont f;
+ if (blinkenSettings::customFont() && !m_alwaysUseNonCoolFont) f = QFont("Steve");
+ p.setFont(f);
+ f.setPointSize(fontUtils::fontSize(p, text, 380, 30));
+ p.setFont(f);
+ p.drawText(0, 0, text);
+}
+
+void blinken::drawLevel(QPainter &p)
+{
+ QString n[3];
+ n[0] = i18n("2");
+ n[1] = i18n("1");
+ n[2] = i18n("?");
+
+ drawText(p, i18n("Level"), QPoint(322, 281), false, 0, 0, 0, false, true);
+
+ QPoint cp;
+ for (int i = 0; i < 3; i++)
+ {
+ if (i == 0) cp = QPoint(319, 315);
+ else if (i == 1) cp = QPoint(m_levelsRect[0].left() - m_levelsRect[0].width(), 315);
+ else if (i == 2) cp = QPoint(m_levelsRect[0].right() + m_levelsRect[0].width(), 315);
+ drawText(p, n[i], cp, true, 20, 5, &(m_levelsRect[i]), m_overLevels[i], true);
+ }
+}
+
+void blinken::drawText(QPainter &p, const QString &text, const QPoint &center, bool withMargin, int xMargin, int yMargin, QRect *rect, bool highlight, bool bold)
+{
+ QRect r;
+ QFont oldFont, f = p.font();
+ oldFont = f;
+ f.setPointSize(fontUtils::fontSize(p, text, 190, 30));
+ if (bold) f.setBold(true);
+ p.setFont(f);
+
+ r = p.boundingRect(QRect(), Qt::AlignAuto, text);
+ r = QRect(0, 0, r.width() + xMargin, r.height() + yMargin);
+ r.moveBy(center.x() - r.width() / 2, center.y() - r.height() / 2);
+
+ if (withMargin)
+ {
+ p.fillRect(r, m_fillColor);
+ p.setPen(QPen(black, 3));
+ p.drawRoundRect(r.left(), r.top(), r.width(), r.height(), 15, 15);
+ }
+
+ if (!highlight) p.setPen(m_fontColor);
+ else p.setPen(m_fontHighlightColor);
+ p.drawText(r, Qt::AlignCenter, text);
+
+ if (rect) *rect = r;
+ p.setFont(oldFont);
+}
+
+
+void blinken::updateButtonHighlighting(const QPoint &p)
+{
+ bool haveToUpdate;
+ m_updateButtonHighlighting = false;
+ haveToUpdate = false;
+
+ if (m_highscoreRect.contains(p))
+ {
+ if (!m_overHighscore)
+ {
+ m_overHighscore = true;
+ haveToUpdate = true;
+ }
+ }
+ else if (m_overHighscore)
+ {
+ m_overHighscore = false;
+ haveToUpdate = true;
+ }
+
+ if (m_menuRect.contains(p))
+ {
+ if (!m_overMenu)
+ {
+ m_overMenu = true;
+ m_overAboutKDE = false;
+ m_overAboutBlinken = false;
+ m_overManual = false;
+ haveToUpdate = true;
+ }
+ else if (m_overAboutKDE || m_overAboutBlinken || m_overManual)
+ {
+ m_overAboutKDE = false;
+ m_overAboutBlinken = false;
+ m_overManual = false;
+ haveToUpdate = true;
+ }
+ }
+ else if (m_overMenu)
+ {
+ if (m_aboutKDERect.contains(p))
+ {
+ if (!m_overAboutKDE)
+ {
+ m_overAboutKDE = true;
+ m_overAboutBlinken = false;
+ m_overManual = false;
+ haveToUpdate = true;
+ }
+ }
+ else if (m_aboutBlinkenRect.contains(p))
+ {
+ if (!m_overAboutBlinken)
+ {
+ m_overAboutKDE = false;
+ m_overAboutBlinken = true;
+ m_overManual = false;
+ haveToUpdate = true;
+ }
+ }
+ else if (m_manualRect.contains(p))
+ {
+ if (!m_overManual)
+ {
+ m_overAboutKDE = false;
+ m_overAboutBlinken = false;
+ m_overManual = true;
+ haveToUpdate = true;
+ }
+ }
+ else
+ {
+ m_overMenu = false;
+ m_overAboutKDE = false;
+ m_overAboutBlinken = false;
+ m_overManual = false;
+ haveToUpdate = true;
+ }
+ }
+
+ if (!m_showPreferences && m_centralLettersRect.contains(p))
+ {
+ m_overCentralLetters = true;
+ haveToUpdate = true;
+ }
+ else if (m_overCentralLetters)
+ {
+ m_overCentralLetters = false;
+ haveToUpdate = true;
+ }
+
+ if (m_showPreferences && m_soundRect.contains(p))
+ {
+ m_overSound = true;
+ haveToUpdate = true;
+ }
+ else if (m_overSound)
+ {
+ m_overSound = false;
+ haveToUpdate = true;
+ }
+
+ if (m_showPreferences && m_fontRect.contains(p) && !m_alwaysUseNonCoolFont)
+ {
+ m_overFont = true;
+ haveToUpdate = true;
+ }
+ else if (m_overFont)
+ {
+ m_overFont = false;
+ haveToUpdate = true;
+ }
+
+ if (m_counterRect.contains(p))
+ {
+ m_overCounter = true;
+ haveToUpdate = true;
+ }
+ else if (m_overCounter)
+ {
+ m_overCounter = false;
+ haveToUpdate = true;
+ }
+
+ if (m_quitRect.contains(p))
+ {
+ if (!m_overQuit)
+ {
+ m_overQuit = true;
+ haveToUpdate = true;
+ }
+ }
+ else if (m_overQuit)
+ {
+ m_overQuit = false;
+ haveToUpdate = true;
+ }
+
+ switch (m_game.phase())
+ {
+ case blinkenGame::starting:
+ case blinkenGame::waiting3:
+ case blinkenGame::waiting2:
+ case blinkenGame::waiting1:
+ case blinkenGame::learningTheSequence:
+ case blinkenGame::typingTheSequence:
+ if (m_centralTextRect.contains(p))
+ {
+ if (!m_overCentralText)
+ {
+ m_overCentralText = true;
+ haveToUpdate = true;
+ }
+ }
+ else if (m_overCentralText)
+ {
+ m_overCentralText = false;
+ haveToUpdate = true;
+ }
+ break;
+
+ case blinkenGame::choosingLevel:
+ for (int i = 0; i < 3; i++)
+ {
+ if (m_levelsRect[i].contains(p))
+ {
+ if (!m_overLevels[i])
+ {
+ m_overLevels[i] = true;
+ haveToUpdate = true;
+ }
+ }
+ else if (m_overLevels[i])
+ {
+ m_overLevels[i] = false;
+ haveToUpdate = true;
+ }
+ }
+ break;
+ }
+
+ updateCursor(p);
+ if (haveToUpdate) update();
+}
+
+void blinken::updateCursor(const QPoint &p)
+{
+ QPoint p2 = p - QPoint(319, 221);
+
+ if (m_overHighscore || m_overQuit || m_overCentralText || m_overMenu || m_overAboutKDE || m_overAboutBlinken || m_overManual || m_overLevels[0] || m_overLevels[1] || m_overLevels[2] || m_overCentralLetters || m_overCounter || (m_game.canType() && (insideGreen(p2) || insideRed(p2) || insideBlue(p2) || insideYellow(p2))) || m_overFont || m_overSound) setCursor(PointingHandCursor);
+ else setCursor(ArrowCursor);
+}
+
+#include "blinken.moc"
diff --git a/blinken/src/blinken.desktop b/blinken/src/blinken.desktop
new file mode 100644
index 00000000..47b5567d
--- /dev/null
+++ b/blinken/src/blinken.desktop
@@ -0,0 +1,113 @@
+[Desktop Entry]
+Name=blinKen
+Name[bn]=ব্লিনকেন
+Name[eo]=blinKeno
+Name[ne]=झिमझिम
+Name[pa]=ਬਲਿਨਕਿਨ
+Name[tr]=Blinken
+DocPath=blinken/index.html
+GenericName=Simon Says Game
+GenericName[be]=Гульня "Сайман кажа"
+GenericName[bg]=Игра за паметта
+GenericName[bn]=সায়মনের কথা খেলা
+GenericName[bs]=Simon Says igra
+GenericName[ca]=Joc del Simon Diu
+GenericName[cs]=Hra Kuba řekl
+GenericName[csb]=Gra jidzenié w szlach
+GenericName[cy]=Gêm Dewi yn Dweud
+GenericName[da]='Simon siger'-spil
+GenericName[de]="Simon sagt"-Spiel
+GenericName[el]=Παιχνίδι "Ο Σάιμον λέει"
+GenericName[eo]=Simona ludo
+GenericName[es]=Simón dice
+GenericName[et]='Simon Says' mäng
+GenericName[eu]="Simon-ek dio" jokoa
+GenericName[fa]=بازی سیمون می‌گوید
+GenericName[fi]=Simon Says -peli
+GenericName[fr]=Jeu de Simon
+GenericName[ga]=Cluiche "Simon Says"
+GenericName[gl]=O xogo de "Simón di..."
+GenericName[he]=משחק המלך אמר
+GenericName[hr]=Igra kako Simon kaže
+GenericName[hu]=Memóriajáték
+GenericName[is]=Hermi leikur
+GenericName[it]=Gioco Simon Says
+GenericName[ja]=ゲーム「サイモンさんが言いました」
+GenericName[ka]=თამაში "წერეთელმა დაგვიბარა"
+GenericName[km]=ល្បែង ស៊ីម៉ុន​និយាយ
+GenericName[lt]=Simon Says žaidimas
+GenericName[ms]=Permainan Simon Says
+GenericName[nb]=Hukommelsesleke
+GenericName[nds]=Behollspeel
+GenericName[ne]=सिमोन भनिने खेल
+GenericName[nl]='Simon zegt'-spel
+GenericName[nn]=Hugsespel
+GenericName[pa]=ਸੀਮੋਨ ਕਿਹਾ ਖੇਡ
+GenericName[pl]=Gra w naśladowanie
+GenericName[pt]=Jogo o Simão Diz
+GenericName[pt_BR]=Jogo Simon Diz
+GenericName[ru]=Игра «Саймон сказал»
+GenericName[sk]=Hra Simon Says
+GenericName[sl]=Igra ponavljanja
+GenericName[sr]=Игра Сима каже
+GenericName[sr@Latn]=Igra Sima kaže
+GenericName[sv]=Simon säger lek
+GenericName[tr]=Simon Süylüyor Oyunu
+GenericName[uk]=Гра "Саймон каже"
+GenericName[vi]=Trò chơi Phát âm Simon
+GenericName[zh_CN]=我说你做游戏
+GenericName[zh_TW]=老師說遊戲
+Exec=blinken
+Icon=blinken
+Type=Application
+Comment=A retro memory enhancement game
+Comment[be]=Класічная гульня для развіцця памяці
+Comment[bg]=Игра за упражнение на паметта
+Comment[bn]=পুরনো দিনের স্মৃতিবর্ধক খেলা
+Comment[bs]=Program za poboljšanje retro memorije
+Comment[ca]=Un joc per millorar la memòria amb aspecte retro
+Comment[cs]=Hra k procvičování paměti
+Comment[csb]=Znónô gra na cwiczënk pamiãcë ë pòstrzég
+Comment[cy]=Gêm oes-a-fu i wella eich cof
+Comment[da]=Et indlæringsprogram for hukommelsesforbedring
+Comment[de]=Ein Spiel zum Training Ihres Gedächtnisses
+Comment[el]=Ένα κλασικό παιχνίδι βελτίωσης της μνήμης
+Comment[eo]=Malnovaĉa memorpliboniga ludo
+Comment[es]=Un juego para mejorar la memoria
+Comment[et]=Vanaaegne mälu parandamise mäng
+Comment[eu]=Memoria hobetzeko joko zaharra
+Comment[fa]=بازی تقویت حافظه گذشته
+Comment[fi]=Vanha muistinparantamispeli
+Comment[fr]=Un ancien jeu de mémoire
+Comment[ga]=Cluiche feabhsaithe cuimhne den seandéanamh
+Comment[gl]=Un programa para mellorar a memoria
+Comment[he]=משחק ישן לשיפור הזיכרון
+Comment[hr]=Starinska igra memorije
+Comment[hu]=Egy klasszikus memóriajavító játék
+Comment[is]=Minnisþjálfunarleikur
+Comment[it]=Un programma per esercitare la memoria
+Comment[ja]=レトロな記憶力増強ゲーム
+Comment[ka]=მეხსიერების გასავარჯიშებელი თამაში
+Comment[km]=ល្បែង​ត្រឡប់​បន្កើន​សតិ
+Comment[lt]=Retro atminties padidinimo priemonė
+Comment[nb]=Et hukommelsesspill etter gammel stil
+Comment[nds]=En oolt Speel för't Verbetern vun't Behollen
+Comment[ne]=रेट्रो स्मृति बढाउने खेल
+Comment[nl]=Een geheugenoefenspel
+Comment[nn]=Eit gammaldags hugsespel
+Comment[pl]=Znana gra na ćwiczenie pamięci i spotrzegawczości
+Comment[pt]=Um jogo antigo para melhorar a memória
+Comment[pt_BR]=Um jogo para treinar a memória
+Comment[ru]=Игра для развития памяти
+Comment[sk]=Retro hra na zlepšenie pamäte
+Comment[sl]=Igra za izboljšanje spomina
+Comment[sr]=Стара игра за побољшавање меморије
+Comment[sr@Latn]=Stara igra za poboljšavanje memorije
+Comment[sv]=Ett gammalmodigt program för att förbättra minnet
+Comment[tr]=Bir hafıza geliştirme oyunu
+Comment[uk]=Гра для розвитку пам'яті
+Comment[vi]=Một trò chơi tăng cường trí nhớ quá khứ
+Comment[zh_CN]=一个记忆强化游戏
+Comment[zh_TW]=加強記憶力的遊戲
+Terminal=false
+Categories=Qt;KDE;Education;
diff --git a/blinken/src/blinken.h b/blinken/src/blinken.h
new file mode 100644
index 00000000..a6ea2199
--- /dev/null
+++ b/blinken/src/blinken.h
@@ -0,0 +1,92 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef BLINKEN_H
+#define BLINKEN_H
+
+#include <qwidget.h>
+
+#include "blinkengame.h"
+
+class QTimer;
+
+class KAction;
+class KHelpMenu;
+
+class button;
+class highScoreDialog;
+
+class blinken : public QWidget
+{
+Q_OBJECT
+ public:
+ blinken();
+ ~blinken();
+
+ protected:
+ void paintEvent(QPaintEvent *);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+ void keyReleaseEvent(QKeyEvent *e);
+
+ private slots:
+ void checkHS();
+ void highlight(blinkenGame::color c, bool unhighlight);
+ void unhighlight();
+
+ void pressedYellow();
+ void pressedRed();
+ void pressedGreen();
+ void pressedBlue();
+
+ private:
+ void selectButton(int button);
+ bool insideGreen(const QPoint &p) const;
+ bool insideYellow(const QPoint &p) const;
+ bool insideRed(const QPoint &p) const;
+ bool insideBlue(const QPoint &p) const;
+ bool insideButtonsArea(const QPoint &p) const;
+ void updateCursor(const QPoint &p);
+
+ void drawMenuQuit(QPainter &p);
+ void drawScoreAndCounter(QPainter &p);
+ void drawStatusText(QPainter &p);
+ void drawLevel(QPainter &p);
+ void drawText(QPainter &p, const QString &text, const QPoint &center, bool withMargin, int xMargin, int yMargin, QRect *rect, bool highlight, bool bold);
+ void updateButtonHighlighting(const QPoint &p);
+
+
+ button *m_buttons[4];
+ QPixmap *m_back, *m_highscore, *m_highscoreHover, *m_quit, *m_quitHover, *m_menu, *m_menuHover, *m_mark;
+ bool m_overHighscore, m_overQuit, m_overCentralText, m_overMenu, m_overAboutKDE, m_overAboutBlinken, m_overManual, m_overLevels[3], m_overCentralLetters, m_overCounter, m_overFont, m_overSound;
+ // i obviously suck but m_levelsRect[0] is 2, m_levelsRect[1] is 1 and m_levelsRect[3] is ?
+ QRect m_highscoreRect, m_quitRect, m_centralTextRect, m_menuRect, m_aboutKDERect, m_aboutBlinkenRect, m_manualRect, m_levelsRect[3], m_centralLettersRect, m_counterRect, m_soundRect, m_fontRect;
+ QColor m_fillColor, m_fontColor, m_fontHighlightColor, m_countDownColor;
+
+ // Preferences setting handling
+ bool m_showPreferences;
+
+ // if should update the highlighting after the next repaint
+ bool m_updateButtonHighlighting;
+
+ // use always the non-cool font?
+ bool m_alwaysUseNonCoolFont;
+
+ blinkenGame::color m_highlighted;
+ QTimer *m_unhighlighter;
+
+ QString m_lastName;
+
+ blinkenGame m_game;
+
+ KHelpMenu *m_helpMenu;
+};
+
+#endif
diff --git a/blinken/src/blinken.kcfg b/blinken/src/blinken.kcfg
new file mode 100644
index 00000000..362b9c52
--- /dev/null
+++ b/blinken/src/blinken.kcfg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <kcfgfile name="blinkenrc"/>
+ <group name="general">
+ <entry name="playSounds" type="Bool">
+ <label>Play sounds</label>
+ <default>true</default>
+ </entry>
+ <entry name="customFont" type="Bool">
+ <label>Use custom font for status text</label>
+ <default>true</default>
+ </entry>
+ </group>
+</kcfg>
+
diff --git a/blinken/src/blinkengame.cpp b/blinken/src/blinkengame.cpp
new file mode 100644
index 00000000..d1ec463b
--- /dev/null
+++ b/blinken/src/blinkengame.cpp
@@ -0,0 +1,181 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include <stdlib.h> // for RAND_MAX
+
+#include <qtimer.h>
+
+#include <kapplication.h>
+
+#include "artsplayer.h"
+#include "blinkengame.h"
+
+blinkenGame::blinkenGame() : m_phase(starting)
+{
+ m_artsPlayer = new artsPlayer;
+ m_waitTimer = new QTimer(this);
+ connect(m_waitTimer, SIGNAL(timeout()), this, SLOT(waiting()));
+}
+
+blinkenGame::~blinkenGame()
+{
+ delete m_artsPlayer;
+}
+
+int blinkenGame::level() const
+{
+ return m_level;
+}
+
+bool blinkenGame::canType() const
+{
+ return m_phase == typingTheSequence || m_phase == starting;
+}
+
+blinkenGame::gamePhase blinkenGame::phase() const
+{
+ return m_phase;
+}
+
+int blinkenGame::score() const
+{
+ if (m_phase == starting || m_phase == choosingLevel) return 0;
+ return m_sequenceLength - 1;
+}
+
+void blinkenGame::clicked(color c)
+{
+ if (m_phase == starting)
+ {
+ m_artsPlayer -> play(c);
+ return;
+ }
+ if (c == *m_nextColor)
+ {
+ ++m_nextColor;
+ m_artsPlayer -> play(c);
+
+ if (m_nextColor == m_sequence.end())
+ {
+ m_sequenceLength++;
+ nextRound();
+ }
+ }
+ else
+ {
+ m_artsPlayer -> play(all, true);
+ emit highlight(all, true);
+ emit gameEnded();
+ setPhase(choosingLevel);
+ }
+}
+
+void blinkenGame::setPhase(gamePhase p)
+{
+ if (p != waiting3 && p != waiting2 && p != waiting1) m_waitTimer -> stop();
+ m_phase = p;
+ emit phaseChanged();
+}
+
+void blinkenGame::start(int level)
+{
+ m_level = level;
+ m_sequenceLength = 1;
+
+ nextRound();
+
+ m_sequence.clear();
+}
+
+void blinkenGame::nextSound()
+{
+ if (m_nextColor != m_sequence.end())
+ {
+ color c;
+ c = *m_nextColor;
+ ++m_nextColor;
+ m_artsPlayer -> play(c);
+ emit highlight(c, false);
+ }
+ else
+ {
+ setPhase(typingTheSequence);
+ m_nextColor = m_sequence.begin();
+ emit highlight(none, false);
+ m_artsPlayer->disconnect();
+ }
+}
+
+void blinkenGame::soundEnded()
+{
+ QTimer::singleShot(100, this, SLOT(nextSound()));
+ QTimer::singleShot(50, this, SLOT(unhighlight()));
+}
+
+void blinkenGame::unhighlight()
+{
+ emit highlight(none, false);
+}
+
+void blinkenGame::waiting()
+{
+ if (m_phase == waiting1)
+ {
+ setPhase(blinkenGame::learningTheSequence);
+ if (m_level == 3)
+ {
+ m_sequence.clear();
+ for (int i = 0; i < m_sequenceLength; i++) m_sequence.append(generateColor());
+ }
+ else m_sequence.append(generateColor());
+
+ connect(m_artsPlayer, SIGNAL(ended()), this, SLOT(soundEnded()));
+ m_nextColor = m_sequence.begin();
+ soundEnded();
+ }
+ else if (m_phase == waiting3) setPhase(waiting2);
+ else /* m_phase == waiting2 */ setPhase(waiting1);
+}
+
+void blinkenGame::nextRound()
+{
+ if (m_level == 1) setPhase(waiting3);
+ else setPhase(waiting2);
+ m_waitTimer -> start(1000);
+}
+
+blinkenGame::color blinkenGame::generateColor()
+{
+ int r;
+ // make the compiler happy :-D
+ color c = none;
+
+ r = 1 + (int)(4.0 * kapp -> random() / (RAND_MAX + 1.0));
+ switch(r)
+ {
+ case 1:
+ c = red;
+ break;
+
+ case 2:
+ c = green;
+ break;
+
+ case 3:
+ c = blue;
+ break;
+
+ case 4:
+ c = yellow;
+ break;
+ }
+ return c;
+}
+
+#include "blinkengame.moc"
diff --git a/blinken/src/blinkengame.h b/blinken/src/blinkengame.h
new file mode 100644
index 00000000..7a0f2941
--- /dev/null
+++ b/blinken/src/blinkengame.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef BLINKENGAME_H
+#define BLINKENGAME_H
+
+#include <qobject.h>
+#include <qvaluelist.h>
+
+class QTimer;
+
+class artsPlayer;
+
+class blinkenGame : public QObject
+{
+Q_OBJECT
+ public:
+ blinkenGame();
+ ~blinkenGame();
+
+ enum gamePhase { starting, choosingLevel, waiting3, waiting2, waiting1, learningTheSequence, typingTheSequence };
+ enum color
+ {
+ none = 0,
+ red = 1,
+ green = 2,
+ blue = 4,
+ yellow = 8,
+ all = 15};
+
+ int level() const;
+ bool canType() const;
+ gamePhase phase() const;
+ int score() const;
+
+ void clicked(color c);
+ void setPhase(gamePhase p);
+ void start(int level);
+
+ signals:
+ void gameEnded();
+ void phaseChanged();
+ void highlight(blinkenGame::color c, bool unhighlight);
+
+ private slots:
+ void nextSound();
+ void soundEnded();
+ void unhighlight();
+ void waiting();
+
+ private:
+ void nextRound();
+ color generateColor();
+
+ gamePhase m_phase;
+ int m_level;
+ int m_sequenceLength;
+
+ QTimer *m_waitTimer;
+
+ artsPlayer *m_artsPlayer;
+ QValueList<color> m_sequence;
+ QValueList<color>::const_iterator m_nextColor;
+};
+
+#endif
diff --git a/blinken/src/button.cpp b/blinken/src/button.cpp
new file mode 100644
index 00000000..b359e953
--- /dev/null
+++ b/blinken/src/button.cpp
@@ -0,0 +1,119 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include <kaction.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+
+#include "button.h"
+
+button::button(blinkenGame::color c) : m_selected(false), m_color(c)
+{
+ KConfig *kc = kapp->config();
+ kc->setGroup("General");
+ QString cs = getColorString();
+ QString pixmap = QString("images/%1h.png").arg(cs);
+
+ switch (c)
+ {
+ case blinkenGame::blue:
+ m_key = kc->readNumEntry(cs, Qt::Key_3);
+ break;
+
+ case blinkenGame::yellow:
+ m_key = kc->readNumEntry(cs, Qt::Key_1);
+ break;
+
+ case blinkenGame::red:
+ m_key = kc->readNumEntry(cs, Qt::Key_2);
+ break;
+
+ case blinkenGame::green:
+ m_key = kc->readNumEntry(cs, Qt::Key_4);
+ break;
+
+ default:
+ // never happens
+ break;
+ }
+
+ m_highlighted = new QPixmap(locate("appdata", pixmap));
+}
+
+button::~button()
+{
+ delete m_highlighted;
+}
+
+void button::setShortcut(int key)
+{
+ m_key = key;
+ m_selected = false;
+
+ KConfig *kc = kapp->config();
+ kc->setGroup("General");
+ kc->writeEntry(getColorString(), key);
+ kc->sync();
+}
+
+QString button::shortcut() const
+{
+ return KShortcut(m_key).toString();
+}
+
+int button::key() const
+{
+ return m_key;
+}
+
+void button::setSelected(bool b)
+{
+ m_selected = b;
+}
+
+bool button::selected() const
+{
+ return m_selected;
+}
+
+QPixmap *button::pixmap() const
+{
+ return m_highlighted;
+}
+
+QString button::getColorString() const
+{
+ switch (m_color)
+ {
+ case blinkenGame::blue:
+ return "blue";
+ break;
+
+ case blinkenGame::yellow:
+ return "yellow";
+ break;
+
+ case blinkenGame::red:
+ return "red";
+ break;
+
+ case blinkenGame::green:
+ return "green";
+ break;
+
+ default:
+ // never happens
+ break;
+ }
+
+ // never happens
+ return QString::null;
+}
diff --git a/blinken/src/button.h b/blinken/src/button.h
new file mode 100644
index 00000000..80300c06
--- /dev/null
+++ b/blinken/src/button.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef BUTTON_H
+#define BUTTON_H
+
+#include <qobject.h>
+
+#include "blinkengame.h"
+
+class KAction;
+class KActionCollection;
+class KShortcut;
+
+class button
+{
+ public:
+ button(blinkenGame::color c);
+ ~button();
+
+ void setShortcut(int key);
+ QString shortcut() const;
+ int key() const;
+ void setSelected(bool b);
+ bool selected() const;
+ QPixmap *pixmap() const;
+
+ private:
+ QString getColorString() const;
+
+ QPixmap *m_highlighted;
+ bool m_selected;
+ int m_key;
+ blinkenGame::color m_color;
+};
+
+#endif
diff --git a/blinken/src/counter.cpp b/blinken/src/counter.cpp
new file mode 100644
index 00000000..6d5ec217
--- /dev/null
+++ b/blinken/src/counter.cpp
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include <qcolor.h>
+#include <qpainter.h>
+
+#include "counter.h"
+#include "number.h"
+
+void counter::paint(QPainter &p, bool drawScore, int score, bool drawTimer, const QColor &c1, const QColor &c2, const QColor &c3)
+{
+ p.save();
+ p.translate(45, 15);
+ p.setPen(QPen(Qt::black, 3));
+ p.setBrush(QColor(40, 40, 40));
+ if (drawTimer)
+ {
+ p.fillRect(-44, -13, 98, 48, p.brush());
+ p.drawRoundRect(-45, -15, 100, 50, 15, 15);
+ }
+ else
+ {
+ p.fillRect(-44, -13, 70, 48, p.brush());
+ p.drawRoundRect(-45, -15, 73, 50, 15, 15);
+ }
+
+ if (drawScore)
+ {
+ number n(score);
+ n.paint(p, 2);
+ }
+
+ if (drawTimer)
+ {
+ p.fillRect(35, -6, 11, 9, c1);
+ p.fillRect(35, 6, 11, 9, c2);
+ p.fillRect(35, 18, 11, 9, c3);
+ }
+ p.restore();
+}
+
+int counter::width(bool drawTimer)
+{
+ if (drawTimer) return 100;
+ else return 73;
+}
+
+int counter::height()
+{
+ return 50;
+}
diff --git a/blinken/src/counter.h b/blinken/src/counter.h
new file mode 100644
index 00000000..81e20ed3
--- /dev/null
+++ b/blinken/src/counter.h
@@ -0,0 +1,23 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef COUNTER_H
+#define COUNTER_H
+
+class QPainter;
+
+class counter
+{
+ public:
+ static void paint(QPainter &p, bool drawScore, int score, bool drawTimer, const QColor &c1, const QColor &c2, const QColor &c3);
+ static int width(bool drawTimer);
+ static int height();
+};
+
+#endif
diff --git a/blinken/src/fontchecker.cpp b/blinken/src/fontchecker.cpp
new file mode 100644
index 00000000..684afaaa
--- /dev/null
+++ b/blinken/src/fontchecker.cpp
@@ -0,0 +1,27 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include <qfont.h>
+#include <qfontinfo.h>
+
+#include <kio/netaccess.h>
+
+#include "fontchecker.h"
+
+bool fontChecker::checkInstalled(const QFont &font, const QString &fontPath)
+{
+ QFontInfo fi(font);
+ // Works with Steve may need some tweaking to work with other fonts
+ if (!fi.exactMatch())
+ {
+ bool success = KIO::NetAccess::copy(fontPath, "fonts:/Personal/", 0);
+ return !success;
+ }
+ return true;
+}
diff --git a/blinken/src/fontchecker.h b/blinken/src/fontchecker.h
new file mode 100644
index 00000000..b8b60b6f
--- /dev/null
+++ b/blinken/src/fontchecker.h
@@ -0,0 +1,21 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef FONTCHECKER_H
+#define FONTCHECKER_H
+
+class QFont;
+
+class fontChecker
+{
+ public:
+ static bool checkInstalled(const QFont &font, const QString &fontPath);
+};
+
+#endif
diff --git a/blinken/src/fontutils.cpp b/blinken/src/fontutils.cpp
new file mode 100644
index 00000000..eacbbd46
--- /dev/null
+++ b/blinken/src/fontutils.cpp
@@ -0,0 +1,33 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include <qpainter.h>
+
+#include "fontutils.h"
+
+int fontUtils::fontSize(QPainter &p, const QString &s1, int w, int h)
+{
+ int size;
+ QRect aux1;
+ bool done = false;
+
+ size = 28;
+
+ while (!done)
+ {
+ QFont f = p.font();
+ f.setPointSize(size);
+ p.setFont(f);
+ aux1 = p.boundingRect(QRect(), Qt::AlignAuto, s1);
+ if (aux1.width() > w || aux1.height() > h) size = QMIN(w * size / aux1.width(), h * size / aux1.height());
+ else done = true;
+ }
+
+ return size;
+}
diff --git a/blinken/src/fontutils.h b/blinken/src/fontutils.h
new file mode 100644
index 00000000..b6bc9c97
--- /dev/null
+++ b/blinken/src/fontutils.h
@@ -0,0 +1,18 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef FONTUTILS_H
+#define FONTUTILS_H
+
+namespace fontUtils
+{
+ int fontSize(QPainter &p, const QString &s1, int w, int h);
+}
+
+#endif
diff --git a/blinken/src/highscoredialog.cpp b/blinken/src/highscoredialog.cpp
new file mode 100644
index 00000000..a162ab33
--- /dev/null
+++ b/blinken/src/highscoredialog.cpp
@@ -0,0 +1,198 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qtabbar.h>
+#include <qtabwidget.h>
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <klocale.h>
+
+#include "highscoredialog.h"
+#include "counter.h"
+#include "fontutils.h"
+#include "settings.h"
+
+static const int margin = 15;
+static const int smallMargin = 5;
+static const int namesFontSize = 25;
+
+/* scoresWidget */
+
+class scoresWidget : public QWidget
+{
+ public:
+ scoresWidget(QWidget *parent, const QValueList< QPair<int, QString> > &scores);
+ QSize calcSize();
+
+ protected:
+ void paintEvent(QPaintEvent *);
+
+ private:
+ const QValueList< QPair<int, QString> > &m_scores;
+};
+
+scoresWidget::scoresWidget(QWidget *parent, const QValueList< QPair<int, QString> > &scores) : QWidget(parent, 0, WStaticContents | WNoAutoErase), m_scores(scores)
+{
+}
+
+void scoresWidget::paintEvent(QPaintEvent *)
+{
+ int w = width();
+ int h = height();
+ QFont f;
+ QPixmap buf(w, h);
+ QPainter p(&buf);
+ QRect r;
+ QColor bg = paletteBackgroundColor();
+
+ // bg color
+ p.fillRect(0, 0, w, h, bg);
+
+ p.setPen(black);
+
+ if (blinkenSettings::customFont()) f = QFont("Steve");
+ p.setFont(f);
+ f.setPointSize(fontUtils::fontSize(p, "A", 1000, namesFontSize));
+ p.setFont(f);
+
+ p.translate(margin, margin);
+
+ QValueList< QPair<int, QString> >::const_iterator it;
+ for (it = m_scores.begin(); it != m_scores.end(); ++it)
+ {
+ counter::paint(p, !(*it).second.isEmpty(), (*it).first, false, QColor(), QColor(), QColor());
+ p.setPen(black);
+ p.drawText(counter::width(false) + 2 * smallMargin, 30, (*it).second);
+ p.translate(0, counter::height() + smallMargin);
+ }
+
+ bitBlt(this, 0, 0, &buf);
+}
+
+QSize scoresWidget::calcSize()
+{
+ int mw, mh, lt;
+ QRect r;
+ QPainter p(this);
+ QFont f;
+
+ if (blinkenSettings::customFont()) f = QFont("Steve");
+ p.setFont(f);
+ f.setPointSize(fontUtils::fontSize(p, "A", 1000, namesFontSize));
+ p.setFont(f);
+ for (int i = 0; i < 3; i++)
+ {
+ lt = 0;
+ QValueList< QPair<int, QString> >::const_iterator it;
+ for (it = m_scores.begin(); it != m_scores.end(); ++it)
+ {
+ r = p.boundingRect(QRect(), Qt::AlignAuto, (*it).second);
+ lt = QMAX(lt, r.width());
+ }
+ }
+
+ mw = margin + counter::width(false) + 2 * smallMargin + lt + margin;
+ mh = margin * 2 + counter::height() * 5 + smallMargin * 4;
+
+ QSize size(mw, mh);
+ setMinimumSize(size);
+ resize(size);
+
+ return size;
+}
+
+/* myTabWidget */
+
+class myTabWidget : public QTabWidget
+{
+ public:
+ myTabWidget(QWidget *parent) : QTabWidget(parent) {}
+
+ QSize tabBarSizeHint() const
+ {
+ return tabBar() -> sizeHint();
+ }
+};
+
+/* highScoreDialog */
+
+highScoreDialog::highScoreDialog(QWidget *parent) : KDialogBase(parent, 0, true, i18n("Highscores"), KDialogBase::Close)
+{
+ m_tw = new myTabWidget(this);
+ setMainWidget(m_tw);
+
+ KConfig *cfg = kapp -> config();
+ for (int i = 1; i <= 3; i++)
+ {
+ cfg -> setGroup(QString("Level%1").arg(i));
+ for (int j = 1; j <= 5; j++)
+ {
+ m_scores[i-1].append(qMakePair(cfg->readNumEntry(QString("Score%1").arg(j)), cfg->readEntry(QString("Name%1").arg(j))));
+ }
+ }
+
+ m_tw -> addTab(new scoresWidget(m_tw, m_scores[0]), i18n("Level 1"));
+ m_tw -> addTab(new scoresWidget(m_tw, m_scores[1]), i18n("Level 2"));
+ m_tw -> addTab(new scoresWidget(m_tw, m_scores[2]), i18n("Level ?"));
+}
+
+bool highScoreDialog::scoreGoodEnough(int level, int score)
+{
+ level--;
+ QValueList< QPair<int, QString> >::iterator it, itEnd;
+ it = m_scores[level].begin();
+ itEnd = m_scores[level].end();
+ while (it != itEnd && (*it).first >= score) it++;
+
+ return (it != itEnd);
+}
+
+void highScoreDialog::addScore(int level, int score, const QString &name)
+{
+ level--;
+ QValueList< QPair<int, QString> >::iterator it, itEnd;
+ it = m_scores[level].begin();
+ itEnd = m_scores[level].end();
+ while (it != itEnd && (*it).first >= score) it++;
+
+ if (it != itEnd)
+ {
+ m_scores[level].insert(it, qMakePair(score, name));
+ m_scores[level].remove(--m_scores[level].end());
+
+ KConfig *cfg = kapp -> config();
+ cfg -> setGroup(QString("Level%1").arg(level + 1));
+ int j;
+ for (it = m_scores[level].begin(), j = 1; it != m_scores[level].end(); ++it, j++)
+ {
+ cfg->writeEntry(QString("Score%1").arg(j), (*it).first);
+ cfg->writeEntry(QString("Name%1").arg(j), (*it).second);
+ }
+ cfg -> sync();
+ }
+}
+
+void highScoreDialog::showLevel(int level)
+{
+ QSize max, aux;
+ m_tw -> setCurrentPage(level -1);
+
+ for (int i = 0; i < 3; i++)
+ {
+ aux = static_cast<scoresWidget*>(m_tw -> page(i)) -> calcSize();
+ max = max.expandedTo(aux);
+ }
+ if (max.width() < m_tw -> tabBarSizeHint().width() + 5) m_tw -> setMinimumSize(m_tw -> tabBarSizeHint().width() + 5, max.height() + m_tw -> tabBarSizeHint().height() + 5);
+
+ exec();
+ delete this;
+}
diff --git a/blinken/src/highscoredialog.h b/blinken/src/highscoredialog.h
new file mode 100644
index 00000000..d61edf48
--- /dev/null
+++ b/blinken/src/highscoredialog.h
@@ -0,0 +1,33 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef HIGHSCOREDIALOG_H
+#define HIGHSCOREDIALOG_H
+
+#include <qpair.h>
+#include <qvaluelist.h>
+
+#include <kdialogbase.h>
+
+class myTabWidget;
+
+class highScoreDialog : private KDialogBase
+{
+ public:
+ highScoreDialog(QWidget *parent);
+
+ bool scoreGoodEnough(int level, int score);
+ void addScore(int level, int score, const QString &name);
+ void showLevel(int level);
+
+ QValueList< QPair<int, QString> > m_scores[3];
+ myTabWidget *m_tw;
+};
+
+#endif
diff --git a/blinken/src/main.cpp b/blinken/src/main.cpp
new file mode 100644
index 00000000..4ad79157
--- /dev/null
+++ b/blinken/src/main.cpp
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kprocess.h>
+#include <kstandarddirs.h>
+
+#include "fontchecker.h"
+#include "blinken.h"
+
+int main(int argc, char *argv[])
+{
+ KAboutData about("blinken", I18N_NOOP("blinKen"), "0.1.1", I18N_NOOP("A memory enhancement game"), KAboutData::License_GPL, "© 2005 Albert Astals Cid\n© 2005 Danny Allen");
+ about.addAuthor("Albert Astals Cid", I18N_NOOP("Coding"), "tsdgeos@terra.es");
+ about.addAuthor("Danny Allen", I18N_NOOP("Design, Graphics and Sounds"), "danny@dannyallen.co.uk");
+ about.addCredit("Steve Jordi", I18N_NOOP("GPL'ed his 'Steve' font so that we could use it"), "steve@sjordi.com");
+ KCmdLineArgs::init(argc, argv, &about);
+ KApplication app;
+ app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
+
+ QFont f("Steve", 12, QFont::Normal, true);
+ if (!fontChecker::checkInstalled(f, locate("appdata", "fonts/steve.ttf")))
+ {
+ KProcess *proc = new KProcess;
+ for (int i = 0; i < argc; i++) *proc << argv[i];
+ proc->start();
+ }
+ else
+ {
+ app.setTopWidget(new blinken());
+ return app.exec();
+ }
+}
diff --git a/blinken/src/number.cpp b/blinken/src/number.cpp
new file mode 100644
index 00000000..230d23ce
--- /dev/null
+++ b/blinken/src/number.cpp
@@ -0,0 +1,196 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include <qbrush.h>
+#include <qcolor.h>
+#include <qpainter.h>
+
+#include "number.h"
+
+const int number::m_number0[20] = {1, 0, 0, 2,
+ 0, 5, 5, 0,
+ 0, 5, 5, 0,
+ 0, 5, 5, 0,
+ 4, 0, 0, 3};
+
+const int number::m_number1[20] = {5, 1, 0, 5,
+ 5, 5, 0, 5,
+ 5, 5, 0, 5,
+ 5, 5, 0, 5,
+ 5, 5, 0, 5};
+
+const int number::m_number2[20] = {0, 0, 0, 2,
+ 5, 5, 5, 0,
+ 1, 0, 0, 3,
+ 0, 5, 5, 5,
+ 0, 0, 0, 0};
+
+const int number::m_number3[20] = {0, 0, 0, 2,
+ 5, 5, 5, 0,
+ 5, 0, 0, 3,
+ 5, 5, 5, 2,
+ 0, 0, 0, 3};
+
+
+const int number::m_number4[20] = {0, 5, 5, 0,
+ 0, 5, 5, 0,
+ 0, 5, 5, 0,
+ 4, 0, 0, 0,
+ 5, 5, 5, 0};
+
+const int number::m_number5[20] = {0, 0, 0, 0,
+ 0, 5, 5, 5,
+ 4, 0, 0, 2,
+ 5, 5, 5, 0,
+ 0, 0, 0, 3};
+
+const int number::m_number6[20] = {1, 0, 0, 0,
+ 0, 5, 5, 5,
+ 0, 0, 0, 2,
+ 0, 5, 5, 0,
+ 4, 0, 0, 3};
+
+const int number::m_number7[20] = {0, 0, 0, 2,
+ 5, 5, 5, 0,
+ 5, 5, 5, 0,
+ 5, 5, 5, 0,
+ 5, 5, 5, 0};
+
+const int number::m_number8[20] = {1, 0, 0, 2,
+ 0, 5, 5, 0,
+ 4, 0, 0, 3,
+ 1, 5, 5, 2,
+ 4, 0, 0, 3};
+
+const int number::m_number9[20] = {1, 0, 0, 2,
+ 0, 5, 5, 0,
+ 4, 0, 0, 3,
+ 5, 5, 5, 0,
+ 0, 0, 0, 3};
+
+number::number(int n)
+{
+ m_number = n;
+}
+
+void number::paint(QPainter &p, int digits) const
+{
+ int nDigits, digit, number;
+ nDigits = 0;
+ number = m_number;
+
+ while(nDigits < digits || number != 0)
+ {
+ digit = number % 10;
+ number /= 10;
+ paintDigit(p, digit);
+ nDigits++;
+ p.translate(-30, 0);
+ }
+ p.translate(30 * nDigits, 0);
+}
+
+void number::paintDigit(QPainter &p, int number) const
+{
+ // make gcc happy
+ const int *n = m_number0;
+ int shape;
+
+ switch (number)
+ {
+ case 1:
+ n = m_number1;
+ break;
+
+ case 2:
+ n = m_number2;
+ break;
+
+ case 3:
+ n = m_number3;
+ break;
+
+ case 4:
+ n = m_number4;
+ break;
+
+ case 5:
+ n = m_number5;
+ break;
+
+ case 6:
+ n = m_number6;
+ break;
+
+ case 7:
+ n = m_number7;
+ break;
+
+ case 8:
+ n = m_number8;
+ break;
+
+ case 9:
+ n = m_number9;
+ break;
+ }
+
+ p.setBrush(Qt::red);
+ p.setPen(Qt::red);
+ for (int i = 0; i < 5; i++)
+ {
+ for (int j = 0; j < 4; j++)
+ {
+ shape = n[j + i * 4];
+ if (shape == 0)
+ {
+ p.fillRect(7 * (j-1), 7 * (i-1), 6, 6, Qt::red);
+ }
+ else if (shape != 5)
+ {
+ if (shape == 1) p.translate(7 * (j-1), 7 * (i-1));
+ else if (shape == 2)
+ {
+ p.translate(7 * j - 2, 7 * (i-1));
+ p.rotate(90);
+ }
+ else if (shape == 3)
+ {
+ p.translate(7 * j - 2, 7 * i - 2);
+ p.rotate(180);
+ }
+ else if (shape == 4)
+ {
+ p.translate(7 * (j-1), 7 * i - 2);
+ p.rotate(270);
+ }
+
+ p.drawPie(0, 0, 11, 11, 90 * 16, 16 * 90);
+
+ if (shape == 1) p.translate(-7 * (j-1), -7 * (i-1));
+ else if (shape == 2)
+ {
+ p.rotate(-90);
+ p.translate(-(7 * j - 2), -7 * (i-1));
+
+ }
+ else if (shape == 3)
+ {
+ p.rotate(-180);
+ p.translate(-(7 * j - 2), -(7 * i - 2));
+ }
+ else if (shape == 4)
+ {
+ p.rotate(-270);
+ p.translate(- (7 * (j-1)), -(7 * i - 2));
+ }
+ }
+ }
+ }
+}
diff --git a/blinken/src/number.h b/blinken/src/number.h
new file mode 100644
index 00000000..c4014024
--- /dev/null
+++ b/blinken/src/number.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Albert Astals Cid <tsdgeos@terra.es> *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef NUMBER_H
+#define NUMBER_H
+
+class QPainter;
+
+class number
+{
+ public:
+ number(int n);
+
+ void paint(QPainter &p, int digits) const;
+
+ private:
+ void paintDigit(QPainter &p, int n) const;
+
+ int m_number;
+
+ static const int m_number0[20];
+ static const int m_number1[20];
+ static const int m_number2[20];
+ static const int m_number3[20];
+ static const int m_number4[20];
+ static const int m_number5[20];
+ static const int m_number6[20];
+ static const int m_number7[20];
+ static const int m_number8[20];
+ static const int m_number9[20];
+};
+
+#endif
diff --git a/blinken/src/settings.kcfgc b/blinken/src/settings.kcfgc
new file mode 100644
index 00000000..2bd38496
--- /dev/null
+++ b/blinken/src/settings.kcfgc
@@ -0,0 +1,4 @@
+File=blinken.kcfg
+ClassName=blinkenSettings
+Singleton=true
+Mutators=true