From ce599e4f9f94b4eb00c1b5edb85bce5431ab3df2 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: 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 --- blinken/src/Makefile.am | 23 ++ blinken/src/artsplayer.cpp | 147 +++++++ blinken/src/artsplayer.h | 66 ++++ blinken/src/blinken.cpp | 855 ++++++++++++++++++++++++++++++++++++++++ blinken/src/blinken.desktop | 113 ++++++ blinken/src/blinken.h | 92 +++++ blinken/src/blinken.kcfg | 18 + blinken/src/blinkengame.cpp | 181 +++++++++ blinken/src/blinkengame.h | 72 ++++ blinken/src/button.cpp | 119 ++++++ blinken/src/button.h | 43 ++ blinken/src/counter.cpp | 57 +++ blinken/src/counter.h | 23 ++ blinken/src/fontchecker.cpp | 27 ++ blinken/src/fontchecker.h | 21 + blinken/src/fontutils.cpp | 33 ++ blinken/src/fontutils.h | 18 + blinken/src/highscoredialog.cpp | 198 ++++++++++ blinken/src/highscoredialog.h | 33 ++ blinken/src/main.cpp | 41 ++ blinken/src/number.cpp | 196 +++++++++ blinken/src/number.h | 39 ++ blinken/src/settings.kcfgc | 4 + 23 files changed, 2419 insertions(+) create mode 100644 blinken/src/Makefile.am create mode 100644 blinken/src/artsplayer.cpp create mode 100644 blinken/src/artsplayer.h create mode 100644 blinken/src/blinken.cpp create mode 100644 blinken/src/blinken.desktop create mode 100644 blinken/src/blinken.h create mode 100644 blinken/src/blinken.kcfg create mode 100644 blinken/src/blinkengame.cpp create mode 100644 blinken/src/blinkengame.h create mode 100644 blinken/src/button.cpp create mode 100644 blinken/src/button.h create mode 100644 blinken/src/counter.cpp create mode 100644 blinken/src/counter.h create mode 100644 blinken/src/fontchecker.cpp create mode 100644 blinken/src/fontchecker.h create mode 100644 blinken/src/fontutils.cpp create mode 100644 blinken/src/fontutils.h create mode 100644 blinken/src/highscoredialog.cpp create mode 100644 blinken/src/highscoredialog.h create mode 100644 blinken/src/main.cpp create mode 100644 blinken/src/number.cpp create mode 100644 blinken/src/number.h create mode 100644 blinken/src/settings.kcfgc (limited to 'blinken/src') 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 * + * * + * 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 + +#include + +#ifdef WITHOUT_ARTS +#include +#include +#endif +#include + +#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 * + * * + * 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 + +#ifdef WITHOUT_ARTS +class KArtsDispatcher; +class KArtsServer; + +namespace KDE +{ + class PlayObjectFactory; + class PlayObject; +} +#else +#include +#include +#include +#include +#endif + +#include + +#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 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 * + * * + * 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 ¢er, 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 * + * * + * 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 + +#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 ¢er, 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 @@ + + + + + + + true + + + + true + + + + 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 * + * * + * 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 // for RAND_MAX + +#include + +#include + +#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 * + * * + * 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 +#include + +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 m_sequence; + QValueList::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 * + * * + * 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 +#include +#include +#include +#include + +#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 * + * * + * 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 + +#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 * + * * + * 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 +#include + +#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 * + * * + * 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 * + * * + * 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 +#include + +#include + +#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 * + * * + * 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 * + * * + * 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 + +#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 * + * * + * 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 * + * * + * 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 +#include +#include +#include + +#include +#include +#include + +#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 > &scores); + QSize calcSize(); + + protected: + void paintEvent(QPaintEvent *); + + private: + const QValueList< QPair > &m_scores; +}; + +scoresWidget::scoresWidget(QWidget *parent, const QValueList< QPair > &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 >::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 >::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 >::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 >::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(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 * + * * + * 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 +#include + +#include + +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 > 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 * + * * + * 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 +#include +#include +#include +#include + +#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 * + * * + * 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 +#include +#include + +#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 * + * * + * 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 -- cgit v1.2.1