diff -Nru kdiamond-kde4-0.1/CMakeLists.txt kdiamond-kde4-0.2/CMakeLists.txt --- kdiamond-kde4-0.1/CMakeLists.txt 2008-02-08 04:08:25.000000000 -0500 +++ kdiamond-kde4-0.2/CMakeLists.txt 2008-02-15 10:35:05.000000000 -0500 @@ -3,6 +3,7 @@ find_package(LibKDEGames REQUIRED) include(KDE4Defaults) +include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES}) add_subdirectory(src) -add_subdirectory(pics) +add_subdirectory(themes) diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/debian/changelog /tmp/bioChyMyGn/kdiamond-kde4-0.2/debian/changelog --- kdiamond-kde4-0.1/debian/changelog 2008-02-17 23:04:54.000000000 -0500 +++ kdiamond-kde4-0.2/debian/changelog 2008-02-17 23:04:54.000000000 -0500 @@ -1,3 +1,15 @@ +kdiamond-kde4 (0.2-0ubuntu1) hardy; urgency=low + + * New upstream release (LP: #192296) + - port to Qt's Graphics View framework + - new default theme with remove animation + - greeter removed; replaced by popup items on the board + - timer can show minutes separately + - sound events; configuration dialog to change the sounds + * Added libqt4-dev build-dep + + -- Steve Stalcup Fri, 15 Feb 2008 22:38:08 -0500 + kdiamond-kde4 (0.1-0ubuntu1) hardy; urgency=low * Initial release (LP: #191286) diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/debian/control /tmp/bioChyMyGn/kdiamond-kde4-0.2/debian/control --- kdiamond-kde4-0.1/debian/control 2008-02-17 23:04:54.000000000 -0500 +++ kdiamond-kde4-0.2/debian/control 2008-02-17 23:04:54.000000000 -0500 @@ -4,7 +4,7 @@ Maintainer: Ubuntu MOTU Developers XSBC-Original-Maintainer: Steve Stalcup Build-Depends: cdbs, debhelper (>= 5), cmake, quilt, kdelibs5-dev (>= 4:4.0.1), - libkdegames-dev-kde4, libxss-dev, libphonon-dev + libkdegames-dev-kde4, libxss-dev, libphonon-dev, libqt4-dev Standards-Version: 3.7.3 Homepage: http://kdiamond.ages-skripte.org/ diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/DESIGN /tmp/bioChyMyGn/kdiamond-kde4-0.2/DESIGN --- kdiamond-kde4-0.1/DESIGN 2008-02-07 10:58:46.000000000 -0500 +++ kdiamond-kde4-0.2/DESIGN 1969-12-31 19:00:00.000000000 -0500 @@ -1,27 +0,0 @@ -Class hierarchy ---------------- - -MainWindow The main window of the application. Handles all access to libkdegames. - Greeter The greeter screen. - Game Represents the game. It carries the information about difficulty, left time, - Board Represents the board. Is the main widget which is displayed in the center of the main window. - Diamond Represents one diamond on the board, and the widget that draws the diamond. -Renderer Draws the SVG graphics on the Diamond widgets. - -The Game stores a two-dimensional array of pointers to Diamond instances to represent the board. This very primitive structure (Diamond ***) allows for quick access to and very simple movement of diamonds. - -Internal event processing -------------------------- - -When diamonds move on the board, or disappear from the board, the Diamond instances manage these animations itself. The needed updates are done by their animation slots. If an animation is in progress, the corresponding slot is connected to the Game::diamondsUpdate signal. - -When the user interacts with the board or the board structure needs an update (e.g. because of deleting completed rows), internal operations are scheduled in the Game instance. To process this operation queue, the event loop triggers the Game::update function every few milliseconds: -* If there are no recievers of the Game::diamondsUpdate signal (i.e. no diamond animations are in progress), the first operation on the queue is executed (basically FIFO principle, but some operations are allowed to be prioritized). -* If there are recievers for the Game::diamondsUpdate signal, the signal is triggered. This is because diamond animations are designed to block further operations for better visibility of the actions performed on and by the board. - -TODO: Use KPixmapCache in the renderer. -TODO: Add "What's this?" text once the UI is complete. -FIXME: Strange behavior of UI settings. -FIXME: Diamond pairs marked during a cascade won't swap. (Problem: m_selected** is not freed up. Move to using m_swapping** variables.) -TODO: Balancing. (Is "Very hard" always solveable?) -TODO: There is a memory leak which has been measured with 14 KB per game. \ No newline at end of file diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/kdiamond.spec /tmp/bioChyMyGn/kdiamond-kde4-0.2/kdiamond.spec --- kdiamond-kde4-0.1/kdiamond.spec 2008-02-08 04:14:48.000000000 -0500 +++ kdiamond-kde4-0.2/kdiamond.spec 1969-12-31 19:00:00.000000000 -0500 @@ -1,49 +0,0 @@ -### atrc spec file -Summary: KDiamond, a three-in-a-row game. -Name: kdiamond -Version: 0.1 -Release: 0 -License: GPL -Group: Games/Puzzles -Source: kdiamond-0.1.tar.bz2 -URL: http://kdiamond.ages-skripte.org/ -Packager: Stefan Majewsky - -%description -KDiamond is a three-in-a-row game for the KDE4 desktop. - -%prep -%setup - -%build -mkdir build -cd build -cmake -DCMAKE_INSTALL_PREFIX=/usr .. -make - -%install -cd build -make install - -%files -/usr/bin/kdiamond -/usr/share/kde4/config.kcfg/kdiamond.kcfg -/usr/share/kde4/apps/kdiamond/kdiamondui.rc -/usr/share/applications/kde4/kdiamond.desktop -/usr/share/kde4/apps/kdiamond/kdiamond-background.svg -/usr/share/kde4/apps/kdiamond/kdiamond-black.svg -/usr/share/kde4/apps/kdiamond/kdiamond-blue.svg -/usr/share/kde4/apps/kdiamond/kdiamond-green.svg -/usr/share/kde4/apps/kdiamond/kdiamond-orange.svg -/usr/share/kde4/apps/kdiamond/kdiamond-red.svg -/usr/share/kde4/apps/kdiamond/kdiamond-selected.svg -/usr/share/kde4/apps/kdiamond/kdiamond-white.svg -/usr/share/kde4/apps/kdiamond/kdiamond-yellow.svg -/usr/share/icons/hicolor/64x64/apps/kdiamond.png -/usr/share/icons/hicolor/22x22/apps/kdiamond.png -/usr/share/icons/hicolor/48x48/apps/kdiamond.png -/usr/share/icons/hicolor/32x32/apps/kdiamond.png -/usr/share/icons/hicolor/128x128/apps/kdiamond.png -/usr/share/icons/hicolor/16x16/apps/kdiamond.png -/usr/share/icons/hicolor/scalable/apps/kdiamond.svgz -%doc COPYING DESIGN diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/CMakeLists.txt /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/CMakeLists.txt --- kdiamond-kde4-0.1/pics/CMakeLists.txt 2008-02-07 09:58:37.000000000 -0500 +++ kdiamond-kde4-0.2/pics/CMakeLists.txt 1969-12-31 19:00:00.000000000 -0500 @@ -1,13 +0,0 @@ -set(kdiamond_IMGS - kdiamond-background.svg - kdiamond-black.svg - kdiamond-blue.svg - kdiamond-green.svg - kdiamond-orange.svg - kdiamond-red.svg - kdiamond-selected.svg - kdiamond-white.svg - kdiamond-yellow.svg -) -install(FILES ${kdiamond_IMGS} DESTINATION ${DATA_INSTALL_DIR}/kdiamond) -kde4_install_icons(${ICON_INSTALL_DIR}) Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/hi128-app-kdiamond.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/hi128-app-kdiamond.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/hi16-app-kdiamond.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/hi16-app-kdiamond.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/hi22-app-kdiamond.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/hi22-app-kdiamond.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/hi32-app-kdiamond.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/hi32-app-kdiamond.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/hi48-app-kdiamond.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/hi48-app-kdiamond.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/hi64-app-kdiamond.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/hi64-app-kdiamond.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/hisc-app-kdiamond.svgz and /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/hisc-app-kdiamond.svgz differ diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/kdiamond-background.svg /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/kdiamond-background.svg --- kdiamond-kde4-0.1/pics/kdiamond-background.svg 2008-02-07 10:43:54.000000000 -0500 +++ kdiamond-kde4-0.2/pics/kdiamond-background.svg 1969-12-31 19:00:00.000000000 -0500 @@ -1,1150 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/kdiamond-black.svg /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/kdiamond-black.svg --- kdiamond-kde4-0.1/pics/kdiamond-black.svg 2008-02-05 08:43:08.000000000 -0500 +++ kdiamond-kde4-0.2/pics/kdiamond-black.svg 1969-12-31 19:00:00.000000000 -0500 @@ -1,361 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/kdiamond-blue.svg /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/kdiamond-blue.svg --- kdiamond-kde4-0.1/pics/kdiamond-blue.svg 2008-02-05 09:18:11.000000000 -0500 +++ kdiamond-kde4-0.2/pics/kdiamond-blue.svg 1969-12-31 19:00:00.000000000 -0500 @@ -1,421 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/kdiamond-green.svg /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/kdiamond-green.svg --- kdiamond-kde4-0.1/pics/kdiamond-green.svg 2008-02-05 09:24:35.000000000 -0500 +++ kdiamond-kde4-0.2/pics/kdiamond-green.svg 1969-12-31 19:00:00.000000000 -0500 @@ -1,423 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/kdiamond-orange.svg /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/kdiamond-orange.svg --- kdiamond-kde4-0.1/pics/kdiamond-orange.svg 2008-02-05 09:27:01.000000000 -0500 +++ kdiamond-kde4-0.2/pics/kdiamond-orange.svg 1969-12-31 19:00:00.000000000 -0500 @@ -1,421 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/kdiamond-red.svg /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/kdiamond-red.svg --- kdiamond-kde4-0.1/pics/kdiamond-red.svg 2008-02-05 09:29:41.000000000 -0500 +++ kdiamond-kde4-0.2/pics/kdiamond-red.svg 1969-12-31 19:00:00.000000000 -0500 @@ -1,421 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/kdiamond-selected.svg /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/kdiamond-selected.svg --- kdiamond-kde4-0.1/pics/kdiamond-selected.svg 2008-02-05 10:00:28.000000000 -0500 +++ kdiamond-kde4-0.2/pics/kdiamond-selected.svg 1969-12-31 19:00:00.000000000 -0500 @@ -1,350 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/kdiamond-white.svg /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/kdiamond-white.svg --- kdiamond-kde4-0.1/pics/kdiamond-white.svg 2008-02-05 09:36:28.000000000 -0500 +++ kdiamond-kde4-0.2/pics/kdiamond-white.svg 1969-12-31 19:00:00.000000000 -0500 @@ -1,428 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/pics/kdiamond-yellow.svg /tmp/bioChyMyGn/kdiamond-kde4-0.2/pics/kdiamond-yellow.svg --- kdiamond-kde4-0.1/pics/kdiamond-yellow.svg 2008-02-05 09:43:27.000000000 -0500 +++ kdiamond-kde4-0.2/pics/kdiamond-yellow.svg 1969-12-31 19:00:00.000000000 -0500 @@ -1,421 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/board.cpp /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/board.cpp --- kdiamond-kde4-0.1/src/board.cpp 2008-02-08 03:36:01.000000000 -0500 +++ kdiamond-kde4-0.2/src/board.cpp 2008-02-15 10:32:26.000000000 -0500 @@ -21,10 +21,11 @@ #include "game.h" #include "renderer.h" -#include +#include +#include -Board::Board(KGameDifficulty::standardLevel difficulty, Game *game, QWidget *parent) - : QWidget(parent) +Board::Board(KGameDifficulty::standardLevel difficulty) + : QGraphicsScene() { switch (difficulty) { @@ -50,46 +51,62 @@ m_colorCount = KDiamond::VeryHardColors; break; } - //fill diamond field + //init scene (with some default scene size that makes board coordinates equal scene coordinates) + setSceneRect(0.0, 0.0, m_size, m_size); + m_diamondEdgeLength = 1.0; + m_topOffset = m_leftOffset = 0.0; + //fill diamond field and scene m_diamonds = new Diamond**[m_size]; - for (int i = 0; i < m_size; ++i) + for (int x = 0; x < m_size; ++x) { - m_diamonds[i] = new Diamond*[m_size]; - for (int j = 0; j < m_size; ++j) + m_diamonds[x] = new Diamond*[m_size]; + for (int y = 0; y < m_size; ++y) { //roll the dice to get a color, but ensure that there are not three of a color in a row from the start int color, otherColor1, otherColor2; while (true) { - color = qrand() % m_colorCount + 1; + color = qrand() % m_colorCount + 1; // +1 because numbering of enum KDiamond::Color starts at 1 //condition: no triplet in y axis (attention: only the diamonds above us are defined already) - if (j >= 2) //no triplet possible for i = 0, 1 + if (y >= 2) //no triplet possible for i = 0, 1 { - otherColor1 = m_diamonds[i][j - 1]->color(); - otherColor2 = m_diamonds[i][j - 2]->color(); + otherColor1 = m_diamonds[x][y - 1]->color(); + otherColor2 = m_diamonds[x][y - 2]->color(); if (otherColor1 == color && otherColor2 == color) continue; //roll the dice again } //same condition on x axis - if (i >= 2) + if (x >= 2) { - otherColor1 = m_diamonds[i - 1][j]->color(); - otherColor2 = m_diamonds[i - 2][j]->color(); + otherColor1 = m_diamonds[x - 1][y]->color(); + otherColor2 = m_diamonds[x - 2][y]->color(); if (otherColor1 == color && otherColor2 == color) continue; } break; } //set diamond - m_diamonds[i][j] = new Diamond(i, j, color, this); - m_diamonds[i][j]->show(); + m_diamonds[x][y] = new Diamond(x, y, x, y, KDiamond::colorFromNumber(color), this); } } + //init selection markers + m_selection1 = new Diamond(0, 0, 0, 0, KDiamond::Selection, this); + m_selection1->hide(); + m_selection2 = new Diamond(0, 0, 0, 0, KDiamond::Selection, this); + m_selection2->hide(); + //init background + m_background = new QGraphicsPixmapItem(0, this); + m_background->setZValue(1); + m_background->setAcceptedMouseButtons(0); + //init messengers + m_messenger = new KGamePopupItem; + m_messenger->setMessageOpacity(0.8); + addItem(m_messenger); + QRectF messengerRect = m_messenger->sceneBoundingRect(); + //init GUI and internal values (any metrical values are calc'ed in the first resizeEvent()) m_selected1x = m_selected1y = m_selected2x = m_selected2y = -1; m_swapping1x = m_swapping1y = m_swapping2x = m_swapping2y = -1; - //init GUI - m_game = game; - show(); + m_paused = false; } Board::~Board() @@ -103,79 +120,252 @@ delete[] m_diamonds[i]; } delete[] m_diamonds; + delete m_selection1; + delete m_selection2; + delete m_background; + delete m_messenger; +} + +int Board::diamondCountOnEdge() const +{ + return m_size; +} + +//Converts board coordinates (i.e. (0,0) is the top left point of the board, 1 unit = 1 diamond) to scene coordinates. +QPointF Board::boardToScene(const QPointF &boardCoords) const +{ + return QPointF( + boardCoords.x() * m_diamondEdgeLength + m_leftOffset, + boardCoords.y() * m_diamondEdgeLength + m_topOffset + ); +} + +QPointF Board::sceneToBoard(const QPointF &sceneCoords) const +{ + return QPointF( + (sceneCoords.x() - m_leftOffset) / m_diamondEdgeLength, + (sceneCoords.y() - m_topOffset) / m_diamondEdgeLength + ); +} + +qreal Board::diamondEdgeLength() const +{ + return m_diamondEdgeLength; } -void Board::makeUpdate(int milliseconds) +//Adapt scene coordinates to size of view. (This congruence is required by KGamePopupItem.) +void Board::resizeScene(qreal newWidth, qreal newHeight, bool force) { - static int ix = 0; - ix++; - if (receivers(SIGNAL(update(int))) > 0) + //do not resize if nothing would change + if (!force && width() == newWidth && height() == newHeight) + return; + setSceneRect(0.0, 0.0, newWidth, newHeight); + //calculate new metrics - A board margin of half a diamond's size is hard-coded. + m_diamondEdgeLength = qMin(newWidth, newHeight) / (m_size + 1); + qreal boardSize = m_size * m_diamondEdgeLength; + m_leftOffset = (newWidth - boardSize) / 2.0; + m_topOffset = (newHeight - boardSize) / 2.0; + //renderer + Renderer::boardResized(newWidth, newHeight, m_leftOffset, m_topOffset, m_diamondEdgeLength, m_size); + //diamonds + emit boardResized(); //give diamonds the chance to change their metrics + //background + m_background->setPixmap(Renderer::background()); + QRectF bgRect = m_background->sceneBoundingRect(); + //The 10.0 and -5.0 are part of a nasty hack to avoid white borders around the background. + m_background->scale((newWidth + 10.0) / bgRect.width(), (newHeight + 10.0) / bgRect.height()); + m_background->setPos(-5.0, -5.0); + m_background->setVisible(true); +} + +void Board::mouseOnDiamond(int xIndex, int yIndex) +{ + if (m_selected1x == xIndex && m_selected1y == yIndex) + { + //clicked again on first selected diamond - remove selection + //Attention: This code is re-used in Board::update for the RemoveRowsJob. If you modify it here, please do also apply your changes over there. + m_selected1x = m_selected2x; + m_selected1y = m_selected2y; + if (m_selected1x == -1 || m_selected1y == -1) + m_selection1->hide(); + else + { + m_selection1->setPosInBoardCoords(QPointF(m_selected1x, m_selected1y)); + m_selection1->show(); + } + m_selected2x = -1; + m_selected2y = -1; + m_selection2->hide(); + } + else if (m_selected2x == xIndex && m_selected2y == yIndex) { - emit update(milliseconds); + //clicked again on second selected diamond - remove selection + m_selected2x = -1; + m_selected2y = -1; + m_selection2->hide(); + } + else if (m_selected1x == -1 || m_selected1y == -1) + { + //nothing selected - this is the first selected diamond + m_selected1x = xIndex; + m_selected1y = yIndex; + m_selection1->setPosInBoardCoords(QPointF(xIndex, yIndex)); + m_selection1->show(); } - else if (m_jobQueue.count() != 0) + else if (m_selected2x == -1 || m_selected2y == -1) { - KDiamond::Job job = m_jobQueue.takeFirst(); - Diamond *temp; - QSet removeTheseDiamonds; - switch (job) + //this could be the second selected diamond - ensure that the second one is a neighbor of the other one + int dx = qAbs(m_selected1x - xIndex), dy = qAbs(m_selected1y - yIndex); + if (dx + dy == 1) + { + m_selected2x = xIndex; + m_selected2y = yIndex; + m_selection2->setPosInBoardCoords(QPointF(xIndex, yIndex)); + m_selection2->show(); + m_jobQueue << KDiamond::SwapDiamondsJob; + } + else { - case KDiamond::SwapDiamondsJob: - m_cascade = 0; //starting a new cascade - //copy selection info into another storage (to allow the user to select the next two diamonds while the cascade runs) - m_swapping1x = m_selected1x; - m_swapping1y = m_selected1y; - m_swapping2x = m_selected2x; - m_swapping2y = m_selected2y; + //selected a diamond that it is not a neighbor - move the first selection to this diamond + m_selected1x = xIndex; + m_selected1y = yIndex; + m_selection1->setPosInBoardCoords(QPointF(xIndex, yIndex)); + m_selection1->show(); + } + } +} + +void Board::pause(bool paused) +{ + m_paused = paused; + for (int x = 0; x < m_size; ++x) + { + for (int y = 0; y < m_size; ++y) + m_diamonds[x][y]->setVisible(!paused); + } + if (paused) + { + m_selection1->hide(); + m_selection2->hide(); + } + else + { + m_selection1->setVisible(m_selected1x != -1 && m_selected1y != -1); + m_selection2->setVisible(m_selected2x != -1 && m_selected2y != -1); + } +} + +void Board::update(int /*milliseconds*/) +{ + //see Diamond::move(const QPointF &) for explanation + if (m_paused || Diamond::animationsInProgress() > 0 || m_jobQueue.count() == 0) //nothing to do in this update + return; + //execute first job in queue + KDiamond::Job job = m_jobQueue.takeFirst(); + int dx, dy; + Diamond *temp; + switch (job) + { + case KDiamond::SwapDiamondsJob: + if (m_selected1x == -1 || m_selected1y == -1 || m_selected2x == -1 || m_selected2y == -1) + break; //this can be the case if, during a cascade, two diamonds are selected (inserts SwapDiamondsJob) and then deselected + //ensure that the selected diamonds are neighbors (this is not necessarily the case as diamonds can move to fill gaps) + dx = qAbs(m_selected1x - m_selected2x); + dy = qAbs(m_selected1y - m_selected2y); + if (dx + dy != 1) + { m_selected1x = m_selected1y = m_selected2x = m_selected2y = -1; - m_jobQueue << KDiamond::RemoveRowsJob; //We already insert this here to avoid another conditional statement. - case KDiamond::RevokeSwapDiamondsJob: //It is not an error that there is no break statement before this case: The swapping code is essentially the same, but the swap job has to do the above variable initializations. - //swap diamonds - temp = m_diamonds[m_swapping1x][m_swapping1y]; - m_diamonds[m_swapping1x][m_swapping1y] = m_diamonds[m_swapping2x][m_swapping2y]; - m_diamonds[m_swapping2x][m_swapping2y] = temp; - m_diamonds[m_swapping1x][m_swapping1y]->setX(m_swapping1x); - m_diamonds[m_swapping1x][m_swapping1y]->setY(m_swapping1y); - m_diamonds[m_swapping2x][m_swapping2y]->setX(m_swapping2x); - m_diamonds[m_swapping2x][m_swapping2y]->setY(m_swapping2y); - //invoke movement and unselect - m_diamonds[m_swapping1x][m_swapping1y]->setMoveTarget(m_swapping1x, m_swapping1y); - m_diamonds[m_swapping2x][m_swapping2y]->setMoveTarget(m_swapping2x, m_swapping2y); - m_diamonds[m_swapping1x][m_swapping1y]->setSelected(false); - m_diamonds[m_swapping2x][m_swapping2y]->setSelected(false); + m_selection1->hide(); + m_selection2->hide(); break; - case KDiamond::RemoveRowsJob: - m_cascade++; - //find diamond rows and delete these diamonds - removeTheseDiamonds = findCompletedRows(); - if (removeTheseDiamonds.count() == 0) - { - //no diamond rows were formed by the last move -> revoke movement (unless we are in a cascade) - if (m_swapping1x != -1 && m_swapping1y != -1 && m_swapping2x != -1 && m_swapping2y != -1) - m_jobQueue << KDiamond::RevokeSwapDiamondsJob; - break; - } - else - { - //report to Game - m_game->diamondsWereRemoved(removeTheseDiamonds.count(), m_cascade); - } - //delete diamonds - foreach (QPoint *diamondPos, removeTheseDiamonds) - { - delete m_diamonds[diamondPos->x()][diamondPos->y()]; - m_diamonds[diamondPos->x()][diamondPos->y()] = 0; - } - //cleanup pointers - foreach (QPoint *toDelete, removeTheseDiamonds) - delete toDelete; - //fill gaps - fillGaps(); + } + //start a new cascade + m_cascade = 0; + //copy selection info into another storage (to allow the user to select the next two diamonds while the cascade runs) + m_swapping1x = m_selected1x; + m_swapping1y = m_selected1y; + m_swapping2x = m_selected2x; + m_swapping2y = m_selected2y; + m_selected1x = m_selected1y = m_selected2x = m_selected2y = -1; + m_selection1->hide(); + m_selection2->hide(); + m_jobQueue << KDiamond::RemoveRowsJob; //We already insert this here to avoid another conditional statement. + case KDiamond::RevokeSwapDiamondsJob: //It is not an error that there is no break statement before this case: The swapping code is essentially the same, but the swap job has to do the above variable initializations etc. + //swap diamonds + temp = m_diamonds[m_swapping1x][m_swapping1y]; + m_diamonds[m_swapping1x][m_swapping1y] = m_diamonds[m_swapping2x][m_swapping2y]; + m_diamonds[m_swapping2x][m_swapping2y] = temp; + m_diamonds[m_swapping1x][m_swapping1y]->setXIndex(m_swapping1x); + m_diamonds[m_swapping1x][m_swapping1y]->setYIndex(m_swapping1y); + m_diamonds[m_swapping2x][m_swapping2y]->setXIndex(m_swapping2x); + m_diamonds[m_swapping2x][m_swapping2y]->setYIndex(m_swapping2y); + //invoke movement and unselect + KNotification::event("move"); + m_diamonds[m_swapping1x][m_swapping1y]->move(QPointF(m_swapping1x, m_swapping1y)); + m_diamonds[m_swapping2x][m_swapping2y]->move(QPointF(m_swapping2x, m_swapping2y)); + break; + case KDiamond::RemoveRowsJob: + m_cascade++; + //find diamond rows and delete these diamonds + m_diamondsToRemove = findCompletedRows(); + if (m_diamondsToRemove.count() == 0) + { + //no diamond rows were formed by the last move -> revoke movement (unless we are in a cascade) + if (m_swapping1x != -1 && m_swapping1y != -1 && m_swapping2x != -1 && m_swapping2y != -1) + m_jobQueue << KDiamond::RevokeSwapDiamondsJob; + } + else + { //it is now safe to delete the position of the swapping diamonds m_swapping1x = m_swapping1y = m_swapping2x = m_swapping2y = -1; - m_jobQueue.prepend(KDiamond::RemoveRowsJob); //allow cascades (i.e. clear rows that have been formed by falling diamonds); prepend this job as it has to be executed immediately after the animations (before handling any further user input) - break; - } + //report to Game + emit diamondsRemoved(m_diamondsToRemove.count(), m_cascade); + //prepare to fill gaps + m_jobQueue.prepend(KDiamond::FillGapsJob); //prepend this job as it has to be executed immediately after the animations (before handling any further user input) + //invoke remove animation + KNotification::event("remove"); + foreach (QPoint *diamondPos, m_diamondsToRemove) + { + m_diamonds[diamondPos->x()][diamondPos->y()]->remove(); + //remove selection if necessary + if (m_selected1x == diamondPos->x() && m_selected1y == diamondPos->y()) + { + m_selected1x = m_selected2x; + m_selected1y = m_selected2y; + if (m_selected1x == -1 || m_selected1y == -1) + m_selection1->hide(); + else + { + m_selection1->setPosInBoardCoords(QPointF(m_selected1x, m_selected1y)); + m_selection1->show(); + } + m_selected2x = -1; + m_selected2y = -1; + m_selection2->hide(); + } + else if (m_selected2x == diamondPos->x() && m_selected2y == diamondPos->y()) + { + m_selected2x = -1; + m_selected2y = -1; + m_selection2->hide(); + } + } + } + break; + case KDiamond::FillGapsJob: + //delete diamonds after their remove animation has played + foreach (QPoint *diamondPos, m_diamondsToRemove) + { + delete m_diamonds[diamondPos->x()][diamondPos->y()]; + m_diamonds[diamondPos->x()][diamondPos->y()] = 0; + //cleanup pointer + delete diamondPos; + } + m_diamondsToRemove.clear(); + //fill gaps + fillGaps(); + m_jobQueue.prepend(KDiamond::RemoveRowsJob); //allow cascades (i.e. clear rows that have been formed by falling diamonds) + break; } } @@ -267,11 +457,21 @@ if (m_diamonds[x][yt + 1] != 0) break; //xt now holds the lowest possible position } - //continue; m_diamonds[x][yt] = m_diamonds[x][y]; m_diamonds[x][y] = 0; - m_diamonds[x][yt]->setY(yt); - m_diamonds[x][yt]->setMoveTarget(x, yt); + m_diamonds[x][yt]->setYIndex(yt); + m_diamonds[x][yt]->move(QPointF(x, yt)); + //if this element is selected, move the selection, too + if (m_selected1x == x && m_selected1y == y) + { + m_selected1y = yt; + m_selection1->move(QPointF(x, yt)); + } + if (m_selected2x == x && m_selected2y == y) + { + m_selected2y = yt; + m_selection2->move(QPointF(x, yt)); + } } } //fill top rows with new elements @@ -283,105 +483,29 @@ if (m_diamonds[x][y] != 0) continue; //inside of diamond stack - no gaps to fill --yt; - m_diamonds[x][y] = new Diamond(x, y, qrand() % m_colorCount + 1, this, x, yt); - updateDiamondPosition(x, y); - m_diamonds[x][y]->setMoveTarget(x, y); - m_diamonds[x][y]->show(); - } - } -} - -void Board::updateDiamondPosition(int x, int y) -{ - m_diamonds[x][y]->setGeometry( - m_leftOffset + m_diamonds[x][y]->xPos() * m_diamondEdgeLength, - m_topOffset + m_diamonds[x][y]->yPos() * m_diamondEdgeLength, - m_diamondEdgeLength, m_diamondEdgeLength - ); -} - -bool Board::selectDiamond(int x, int y) -{ - if (m_selected1x == -1 || m_selected1y == -1) - { - m_selected1x = x; - m_selected1y = y; - return true; - } - if (m_selected2x == -1 || m_selected2y == -1) - { - //ensure that the second one is a neighbor of the other one - int dx = qAbs(m_selected1x - x), dy = qAbs(m_selected1y - y); - if ((dx == 1 && dy == 0) || (dx == 0 && dy == 1)) - { - m_selected2x = x; - m_selected2y = y; - m_jobQueue << KDiamond::SwapDiamondsJob; - return true; - } - else - { - //selected a diamond that it is not a neighbor - move the selection to this diamond - m_diamonds[m_selected1x][m_selected1y]->setSelected(false); - m_selected1x = x; - m_selected1y = y; - return true; + m_diamonds[x][y] = new Diamond(x, y, x, yt, KDiamond::colorFromNumber(qrand() % m_colorCount + 1), this); + m_diamonds[x][y]->setPosInBoardCoords(QPointF(x, yt)); + m_diamonds[x][y]->updateGeometry(); + m_diamonds[x][y]->move(QPointF(x, y)); } } - return false; } -bool Board::unselectDiamond(int x, int y) +void Board::gameFinished() { - if (m_selected1x == x && m_selected1y == y) - { - m_selected1x = m_selected2x; - m_selected1y = m_selected2y; - m_selected2x = -1; - m_selected2y = -1; - return true; - } - if (m_selected2x == x && m_selected2y == y) - { - m_selected2x = -1; - m_selected2y = -1; - return true; - } - return false; + m_selection1->hide(); + m_selection2->hide(); } -void Board::resizeEvent(QResizeEvent *) +void Board::showMessage(const QString &message, int timeout) { - //calculate new field position - qreal fieldWidth = width(); - qreal fieldHeight = height(); - qreal quadraticFieldSize = qMin(fieldHeight, fieldWidth); - m_leftOffset = (fieldWidth - quadraticFieldSize) / 2.0; - m_topOffset = (fieldHeight - quadraticFieldSize) / 2.0; - m_diamondEdgeLength = quadraticFieldSize / (qreal) m_size; - //adjust geometry of diamonds - for (int i = 0; i < m_size; ++i) - { - for (int j = 0; j < m_size; ++j) - { - m_diamonds[i][j]->setGeometry( - m_leftOffset + m_diamonds[i][j]->xPos() * m_diamondEdgeLength, - m_topOffset + m_diamonds[i][j]->yPos() * m_diamondEdgeLength, - m_diamondEdgeLength, m_diamondEdgeLength - ); - } - } + m_messenger->setMessageTimeout(timeout); + m_messenger->showMessage(message, KGamePopupItem::TopLeft); } -void Board::paintEvent(QPaintEvent *) +void Board::hideMessage() { - //draw background tiles - QPainter painter(this); - for (int x = 0; x < width(); x += KDiamond::BackgroundTileSize) - { - for (int y = 0; y < height(); y += KDiamond::BackgroundTileSize) - Renderer::drawBackground(&painter, QRectF(x, y, KDiamond::BackgroundTileSize, KDiamond::BackgroundTileSize)); - } + m_messenger->forceHide(); } #include "board.moc" diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/board.h /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/board.h --- kdiamond-kde4-0.1/src/board.h 2008-02-07 11:01:24.000000000 -0500 +++ kdiamond-kde4-0.2/src/board.h 2008-02-15 10:32:26.000000000 -0500 @@ -19,54 +19,92 @@ #ifndef KDIAMOND_BOARD_H #define KDIAMOND_BOARD_H -#include "consts.h" #ifndef KDIAMOND_DIAMOND_H class Diamond; + class QGraphicsPixmapItem; #endif #ifndef KDIAMOND_GAME_H class Game; #endif +#include #include #include -#include #include +class KGamePopupItem; -class Board : public QWidget +namespace KDiamond +{ + const qreal BorderPadding = 0.25; //border of the board has a padding of 0.25 diamond edge lengths (= 0.25 board units) + //specification of the difficulties + enum Size + { + VeryEasySize = 12, + EasySize = 10, + MediumSize = 8, + HardSize = 8, + VeryHardSize = 8 + }; + enum ColorCount + { + VeryEasyColors = 5, + EasyColors = 5, + MediumColors = 5, + HardColors = 6, + VeryHardColors = 7 + }; + //jobs to be done during the board update + enum Job { + SwapDiamondsJob = 1, //swap selected diamonds + RemoveRowsJob, //remove complete rows of diamonds and add points + RevokeSwapDiamondsJob, //revoke swapping of diamonds (will be requested by the RemoveRowsJob if no rows have been formed) + FillGapsJob + }; +} + +class Board : public QGraphicsScene { Q_OBJECT public: - Board(KGameDifficulty::standardLevel difficulty, Game *game, QWidget *parent = 0); + Board(KGameDifficulty::standardLevel difficulty); ~Board(); + int diamondCountOnEdge() const; - //interface to diamonds - bool selectDiamond(int x, int y); - bool unselectDiamond(int x, int y); - void updateDiamondPosition(int x, int y); + QPointF boardToScene(const QPointF &boardCoord) const; + QPointF sceneToBoard(const QPointF &sceneCoord) const; + void resizeScene(qreal width, qreal height, bool force = false); + qreal diamondEdgeLength() const; + + void mouseOnDiamond(int xIndex, int yIndex); public slots: - void makeUpdate(int milliseconds); - signals: + void gameFinished(); + void hideMessage(); + void pause(bool paused); + void showMessage(const QString &message, int timeout = 0); void update(int milliseconds); - protected: - virtual void paintEvent(QPaintEvent *event); - virtual void resizeEvent(QResizeEvent *event); - - //internal processing functions + signals: + void boardResized(); + void diamondsRemoved(int count, int cascade); + void updateScheduled(int milliseconds); + private: QSet findCompletedRows(); void fillGaps(); private: - qreal m_topOffset, m_leftOffset, m_diamondEdgeLength; - + KDiamond::Size m_size; + KDiamond::ColorCount m_colorCount; QList m_jobQueue; - int m_selected1x, m_selected1y, m_selected2x, m_selected2y; - int m_swapping1x, m_swapping1y, m_swapping2x, m_swapping2y; - int m_cascade; //holds the number of cascades + QSet m_diamondsToRemove; Diamond ***m_diamonds; - Game *m_game; - - KDiamond::Size m_size; - KDiamond::ColorCount m_colorCount; + Diamond *m_selection1, *m_selection2; + QGraphicsPixmapItem *m_background; + KGamePopupItem *m_messenger; + + qreal m_leftOffset, m_topOffset, m_diamondEdgeLength; //necessary for conversion between board coordinates (i.e. (0,0) for the top left point, 1 unit = 1 diamond) and scene coordinates (as defined by Qt) + int m_selected1x, m_selected1y, m_selected2x, m_selected2y; //coordinates of the selected items (or -1 if they are not selected) + int m_swapping1x, m_swapping1y, m_swapping2x, m_swapping2y; //coordinates of the swapping/swapped items (stored to revoke the swapping if necessary) + bool m_paused; + int m_cascade; //cascade count (necessary for score calculation in Game) }; -#endif // KDIAMOND_BOARD_H +#endif //KDIAMOND_BOARD_H diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/CMakeLists.txt /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/CMakeLists.txt --- kdiamond-kde4-0.1/src/CMakeLists.txt 2008-02-08 04:08:23.000000000 -0500 +++ kdiamond-kde4-0.2/src/CMakeLists.txt 2008-02-15 10:32:26.000000000 -0500 @@ -1,23 +1,21 @@ -add_definitions(${QT_DEFINITIONS} ${KDE_DEFINITIONS}) -include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES} ${KDEGAMES_INCLUDE_DIR}) +add_subdirectory(pics) +include_directories(${KDEGAMES_INCLUDE_DIR}) set(kdiamond_SRCS board.cpp + container.cpp diamond.cpp game.cpp - greeter.cpp main.cpp - mainwidget.cpp mainwindow.cpp renderer.cpp ) kde4_add_kcfg_files(kdiamond_SRCS settings.kcfgc) -kde4_add_executable(kdiamond ${kdiamond_SRCS}) -target_link_libraries(kdiamond ${KDE4_KDEUI_LIBS} ${KDEGAMES_LIBRARY}) +kde4_add_executable(kdiamond ${kdiamond_SRCS}) +target_link_libraries(kdiamond ${KDE4_KDEUI_LIBS} kdegames ${KDE4_KNOTIFYCONFIG_LIBS}) -install(TARGETS kdiamond DESTINATION ${BIN_INSTALL_DIR}) -install(FILES kdiamond.kcfg DESTINATION ${KCFG_INSTALL_DIR}) -install(FILES kdiamondui.rc DESTINATION ${DATA_INSTALL_DIR}/kdiamond) -install(FILES kdiamond.desktop DESTINATION ${XDG_APPS_INSTALL_DIR}) +install(TARGETS kdiamond DESTINATION ${BIN_INSTALL_DIR}) +install(FILES kdiamond.kcfg kdiamond.notifyrc kdiamondui.rc DESTINATION ${DATA_INSTALL_DIR}/kdiamond) +install(FILES kdiamond.desktop DESTINATION ${XDG_APPS_INSTALL_DIR}) diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/consts.h /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/consts.h --- kdiamond-kde4-0.1/src/consts.h 2008-02-08 04:28:29.000000000 -0500 +++ kdiamond-kde4-0.2/src/consts.h 1969-12-31 19:00:00.000000000 -0500 @@ -1,67 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 Stefan Majewsky - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - ***************************************************************************/ - -#ifndef KDIAMOND_CONSTS_H -#define KDIAMOND_CONSTS_H - -#include - -namespace KDiamond -{ - //constants - const int BackgroundTileSize = 200; //the width and height in pixels after which the background of the board is repeated - const int GameDuration = 120; //base duration of a game in seconds - const qreal MoveDuration = 200.0; //duration of a move animation in milliseconds - const int UpdateInterval = 10; //maximum update interval in milliseconds - //diamond colors - enum Color - { - RedDiamond = 1, - GreenDiamond, - BlueDiamond, - YellowDiamond, - WhiteDiamond, - BlackDiamond, - OrangeDiamond - }; - //specification of the difficulty levels - enum Size - { - VeryEasySize = 12, - EasySize = 10, - MediumSize = 8, - HardSize = 8, - VeryHardSize = 8 - }; - enum ColorCount - { - VeryEasyColors = 5, - EasyColors = 5, - MediumColors = 5, - HardColors = 6, - VeryHardColors = 7 - }; - //jobs to be done during the board update - enum Job { - SwapDiamondsJob = 1, //swap selected diamonds - RemoveRowsJob, //remove complete rows of diamonds and add points - RevokeSwapDiamondsJob //revoke swapping of diamonds (will be requested by the RemoveRowsJob if no rows have been formed) - }; -}; - -#endif //KDIAMOND_CONSTS_H diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/container.cpp /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/container.cpp --- kdiamond-kde4-0.1/src/container.cpp 1969-12-31 19:00:00.000000000 -0500 +++ kdiamond-kde4-0.2/src/container.cpp 2008-02-15 10:32:26.000000000 -0500 @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2008 Stefan Majewsky + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "container.h" + +Container::Container(QWidget *parent) + : QWidget(parent) +{ +} + +void Container::setWidget(QWidget *widget) +{ + m_widget = widget; + m_widget->setParent(this); + m_widget->setGeometry(0, 0, width(), height()); + m_widget->show(); +} + +void Container::resizeEvent(QResizeEvent *) +{ + m_widget->setGeometry(0, 0, width(), height()); +} + +#include "container.moc" diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/container.h /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/container.h --- kdiamond-kde4-0.1/src/container.h 1969-12-31 19:00:00.000000000 -0500 +++ kdiamond-kde4-0.2/src/container.h 2008-02-15 10:32:26.000000000 -0500 @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2008 Stefan Majewsky + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KDIAMOND_CONTAINER_H +#define KDIAMOND_CONTAINER_H + +#include + +class Container : public QWidget +{ + public: + Container(QWidget *parent = 0); + void setWidget(QWidget *widget); + protected: + virtual void resizeEvent(QResizeEvent *); + private: + QWidget *m_widget; +}; + +#endif //KDIAMOND_CONTAINER_H diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/diamond.cpp /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/diamond.cpp --- kdiamond-kde4-0.1/src/diamond.cpp 2008-02-08 03:23:05.000000000 -0500 +++ kdiamond-kde4-0.2/src/diamond.cpp 2008-02-15 10:32:26.000000000 -0500 @@ -16,103 +16,198 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ***************************************************************************/ -#include "board.h" -#include "consts.h" #include "diamond.h" +#include "board.h" #include "renderer.h" -#include +#include +#include -Diamond::Diamond(int x, int y, KDiamond::Color color, Board *game, int xPos, int yPos) - : QWidget(game) +int g_animationsInProgress = 0; //This counter can be used by the board to determine whether there are animations in progress. The board's job queue is not processed during animations to make the movements on the screen clearer for the user. + +KDiamond::Color KDiamond::colorFromNumber(int number) { - m_x = x; - m_xPos = (xPos == INT_MAX) ? x : xPos; - m_y = y; - m_yPos = (yPos == INT_MAX) ? y : yPos; - m_moving = false; - m_board = game; - m_color = color; - m_selected = false; + switch (number) + { + case 1: return KDiamond::RedDiamond; + case 2: return KDiamond::GreenDiamond; + case 3: return KDiamond::BlueDiamond; + case 4: return KDiamond::YellowDiamond; + case 5: return KDiamond::WhiteDiamond; + case 6: return KDiamond::BlackDiamond; + case 7: return KDiamond::OrangeDiamond; + default: return KDiamond::Selection; + } } -Diamond::Diamond(int x, int y, int color, Board *game, int xPos, int yPos) - : QWidget(game) +Diamond::Diamond(int xIndex, int yIndex, qreal xPos, qreal yPos, KDiamond::Color color, Board *board) + : QGraphicsPixmapItem(0, board) { - m_x = x; - m_xPos = (xPos == INT_MAX) ? x : xPos; - m_y = y; - m_yPos = (yPos == INT_MAX) ? y : yPos; - m_moving = false; - m_board = game; - switch (color) + //init internal values + m_xIndex = xIndex; + m_yIndex = yIndex; + m_color = color; + m_board = board; + m_pos = QPointF(xPos, yPos); + m_animation = 0; + m_timer = new QTimeLine; + m_timer->setCurveShape(QTimeLine::EaseInCurve); + m_currentRemoveFrame = -1; + //connect to board + connect(board, SIGNAL(boardResized()), this, SLOT(updateGeometry())); + //init QGraphicsPixmapItem (pixmap and geometry is initialized after the first resize event has occured) + setVisible(true); + //selection markers do not react to mouse events; they should also appear behind diamonds + if (color == KDiamond::Selection) { - case 1: m_color = KDiamond::RedDiamond; break; - case 2: m_color = KDiamond::GreenDiamond; break; - case 3: m_color = KDiamond::BlueDiamond; break; - case 4: m_color = KDiamond::YellowDiamond; break; - case 5: m_color = KDiamond::WhiteDiamond; break; - case 6: m_color = KDiamond::BlackDiamond; break; - case 7: m_color = KDiamond::OrangeDiamond; break; + setAcceptedMouseButtons(0); + setZValue(3); + } + else + { + setAcceptedMouseButtons(Qt::LeftButton); + setZValue(4); } - m_selected = false; } -void Diamond::setMoveTarget(int targetX, int targetY) +Diamond::~Diamond() { - //set starting point and target of move - m_xTarget = targetX; - m_yTarget = targetY; - connect(m_board, SIGNAL(update(int)), this, SLOT(moveAnimation(int))); + if (m_animation != 0) + moveComplete(); //cleanup the current move animation + delete m_timer; } -void Diamond::moveAnimation(int milliseconds) +KDiamond::Color Diamond::color() const { - //move each coordinate towards the target position - qreal dx = m_xTarget - m_xPos; - qreal dy = m_yTarget - m_yPos; - if (dx == 0.0 && dy == 0.0) - //advertise end of animation to m_board by disconnecting from update signal - m_board->disconnect(SIGNAL(update(int)), this, SLOT(moveAnimation(int))); - else - { - //maximum absolute value is maxStep - qreal maxStep = ((qreal) milliseconds) / KDiamond::MoveDuration; - if (qAbs(dx) > maxStep) - dx = maxStep * dx / qAbs(dx); // = maxStep * sign of dx - if (qAbs(dy) > maxStep) - dy = maxStep * dy / qAbs(dy); - //apply position change - m_xPos += dx; - m_yPos += dy; - m_board->updateDiamondPosition(m_x, m_y); - } + return m_color; } -void Diamond::paintEvent(QPaintEvent *) +int Diamond::xIndex() const { - QPainter p(this); - QRectF bounds(0.0, 0.0, width(), height()); - if (m_selected) - Renderer::drawShadow(&p, bounds); - Renderer::drawDiamond(&p, bounds, m_color); + return m_xIndex; } -void Diamond::mouseReleaseEvent(QMouseEvent *) +int Diamond::yIndex() const { - if (m_selected) + return m_yIndex; +} + +int Diamond::animationsInProgress() +{ + return g_animationsInProgress; +} + +void Diamond::setXIndex(int xIndex) +{ + m_xIndex = xIndex; +} + +void Diamond::setYIndex(int yIndex) +{ + m_yIndex = yIndex; +} + +void Diamond::move(const QPointF &target) +{ + //store target for resize events + m_target = target; + //position differences + qreal dx = qAbs(m_pos.x() - target.x()); + qreal dy = qAbs(m_pos.y() - target.y()); + //timeline + int duration = KDiamond::MoveDuration * qMax(dx, dy); //MoveDuration is the duration per board unit + m_timer->setDuration(duration); + m_timer->setUpdateInterval(KDiamond::MoveInterval); + connect(m_timer, SIGNAL(finished()), this, SLOT(moveComplete()), Qt::DirectConnection); + //animation + m_animation = new QGraphicsItemAnimation; + m_animation->setItem(this); + m_animation->setTimeLine(m_timer); + m_animation->setPosAt(0.0, m_board->boardToScene(m_pos).toPoint()); + m_animation->setPosAt(1.0, m_board->boardToScene(m_target).toPoint()); + m_timer->start(); + ++g_animationsInProgress; +} + +void Diamond::moveComplete() +{ + --g_animationsInProgress; + delete m_animation; + m_animation = 0; + delete m_timer; + m_timer = new QTimeLine; + m_pos = m_target; //the target has now been reached - use this as position for further resize events +} + +void Diamond::remove() +{ + //timeline + m_timer->setDuration(KDiamond::RemoveDuration); + m_timer->setFrameRange(0, Renderer::removeAnimFrameCount() - 1); + connect(m_timer, SIGNAL(frameChanged(int)), this, SLOT(setRemoveAnimFrame(int))); + connect(m_timer, SIGNAL(finished()), this, SLOT(removeComplete())); + m_timer->start(); + //see Diamond::move for details on the following connection + ++g_animationsInProgress; +} + +void Diamond::setRemoveAnimFrame(int frame) +{ + m_currentRemoveFrame = frame; + setPixmap(Renderer::removeFrame(m_color, frame)); +} + +void Diamond::removeComplete() +{ + --g_animationsInProgress; +} + +void Diamond::updateGeometry() +{ + prepareGeometryChange(); + //update pixmap + if (m_currentRemoveFrame == -1) + setPixmap(Renderer::diamond(m_color)); + else + setPixmap(Renderer::removeFrame(m_color, m_currentRemoveFrame)); + //resize + QRectF bounds = sceneBoundingRect(); + qreal diamondEdgeLength = m_board->diamondEdgeLength(); + scale(diamondEdgeLength / bounds.width(), diamondEdgeLength / bounds.height()); + //change position + if (m_animation == 0) + { + //no animation in progress - just change current position + setPos(m_board->boardToScene(m_pos)); + } + else { - if (m_board->unselectDiamond(m_x, m_y)) - { - m_selected = false; - update(); - } + //animation in progress - change fix points of animation + m_animation->setPosAt(0.0, m_board->boardToScene(m_pos).toPoint()); + m_animation->setPosAt(1.0, m_board->boardToScene(m_target).toPoint()); } - else if (m_board->selectDiamond(m_x, m_y)) +} + +void Diamond::setPosInBoardCoords(const QPointF &pos) +{ + if (m_animation == 0) { - m_selected = true; - update(); + m_pos = pos; + setPos(m_board->boardToScene(m_pos).toPoint()); } + else + { + //make the animation head towards this new position + m_target = pos; + m_animation->setPosAt(1.0, m_board->boardToScene(m_target).toPoint()); + } +} + +void Diamond::mouseReleaseEvent(QGraphicsSceneMouseEvent *) +{ + //propagate the mouse click to the board (to change the selection); clicking is blocked during movement + if (m_animation == 0) + m_board->mouseOnDiamond(m_xIndex, m_yIndex); } #include "diamond.moc" diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/diamond.h /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/diamond.h --- kdiamond-kde4-0.1/src/diamond.h 2008-02-06 11:05:12.000000000 -0500 +++ kdiamond-kde4-0.2/src/diamond.h 2008-02-15 10:32:26.000000000 -0500 @@ -19,42 +19,73 @@ #ifndef KDIAMOND_DIAMOND_H #define KDIAMOND_DIAMOND_H -#include "consts.h" #ifndef KDIAMOND_BOARD_H class Board; #endif -#include +class QGraphicsItemAnimation; +#include +class QTimeLine; -class Diamond : public QWidget +namespace KDiamond +{ + //duration of a move animation (per coordinate unit) in milliseconds + const int MoveDuration = 250; + //update interval during a move animation (KDiamond::MoveDuration should be divideable by KDiamond::MoveInterval) + const int MoveInterval = 25; + //duration of a move animation (frame count is determined by the theme) + const int RemoveDuration = 200; + //registered colors of diamonds + enum Color + { + Selection = 0, //that is actually no diamond type, but gives the chance to reuse the Diamond class' code for the selection marker + RedDiamond = 1, + GreenDiamond, + BlueDiamond, + YellowDiamond, + WhiteDiamond, + BlackDiamond, + OrangeDiamond + }; + //convert int into the KDiamond::Color that is represented by this int + KDiamond::Color colorFromNumber(int number); +} + +class Diamond : public QObject, public QGraphicsPixmapItem { Q_OBJECT public: - Diamond(int x, int y, KDiamond::Color color, Board *parent = 0, int xPos = INT_MAX, int yPos = INT_MAX); - Diamond(int x, int y, int color, Board *parent = 0, int xPos = INT_MAX, int yPos = INT_MAX); + Diamond(int xIndex, int yIndex, qreal xPos, qreal yPos, KDiamond::Color color, Board *board); + ~Diamond(); - inline KDiamond::Color color() const { return m_color; } - inline int x() const { return m_x; } - inline int y() const { return m_y; } - inline qreal xPos() const { return m_xPos; } - inline qreal yPos() const { return m_yPos; } - void setX(int x) { m_x = x; } - void setY(int y) { m_y = y; } - void setMoveTarget(int targetX, int targetY); - void setSelected(bool selected) { m_selected = selected; update(); } + KDiamond::Color color() const; + int xIndex() const; + int yIndex() const; + static int animationsInProgress(); + + void setXIndex(int xIndex); + void setYIndex(int yIndex); + void setPosInBoardCoords(const QPointF &pos); + public slots: + void updateGeometry(); + void move(const QPointF &target); + void remove(); protected: - virtual void paintEvent(QPaintEvent *event); - virtual void mouseReleaseEvent(QMouseEvent *event); - private slots: - void moveAnimation(int milliseconds); //performs the next iteration in a move animation (no update since the given time) + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *); + protected slots: + void moveComplete(); + void setRemoveAnimFrame(int frame); + void removeComplete(); private: Board *m_board; - int m_x, m_y; //index of element in the game's diamond array (this information needs to be sent with mouse events) - KDiamond::Color m_color; //color of the diamond + QGraphicsItemAnimation *m_animation; //pointer to the animation currently in progress + QTimeLine *m_timer; + + KDiamond::Color m_color; + int m_xIndex, m_yIndex; //the index of the diamond in the Board's internal array (used for communication with Board) + QPointF m_pos, m_target; //current position of diamond in board coordinates (see Board::boardToScene for details) - qreal m_xPos, m_yPos; //position of element in board coordinates, i.e. (0,0) is the top left corner of the board - qreal m_xTarget, m_yTarget; //target of a movement animation - bool m_moving, m_selected; + int m_currentRemoveFrame; //current frame in the remove animation (needed when updating the pixmap because of resize events); -1 means that there is no remove animation at the moment }; #endif //KDIAMOND_DIAMOND_H diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/game.cpp /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/game.cpp --- kdiamond-kde4-0.1/src/game.cpp 2008-02-08 03:51:57.000000000 -0500 +++ kdiamond-kde4-0.2/src/game.cpp 2008-02-15 10:32:26.000000000 -0500 @@ -20,55 +20,120 @@ #include "board.h" #include "mainwindow.h" +#include #include +#include +#include +#include -Game::Game(KGameDifficulty::standardLevel difficulty, MainWindow *mainWindow) +Game::Game(KGameDifficulty::standardLevel difficulty, MainWindow *mainWindow = 0) + : QGraphicsView(mainWindow) { + m_mainWindow = mainWindow; //init timers m_gameTime = new QTime; m_gameTime->start(); + m_pauseTime = new QTime; + m_pauseTime->start(); //now we can always call restart() + connect(m_mainWindow, SIGNAL(updateScheduled(int)), this, SLOT(update(int)), Qt::DirectConnection); //init board - m_board = new Board(difficulty, this, mainWindow); - connect(mainWindow, SIGNAL(update(int)), this, SLOT(makeUpdate()), Qt::DirectConnection); - connect(mainWindow, SIGNAL(update(int)), m_board, SLOT(makeUpdate(int)), Qt::DirectConnection); - //init main window connection - connect(this, SIGNAL(gameFinished(int)), mainWindow, SLOT(finishGame(int))); - connect(this, SIGNAL(pointsChanged(int)), mainWindow, SLOT(updatePoints(int))); - connect(this, SIGNAL(timeLeftChanged(int)), mainWindow, SLOT(updateTimeLeft(int))); - //init points and seconds and feed the main window with proper values + m_board = new Board(difficulty); + connect(m_mainWindow, SIGNAL(updateScheduled(int)), m_board, SLOT(update(int)), Qt::DirectConnection); + connect(m_board, SIGNAL(diamondsRemoved(int, int)), this, SLOT(diamondsRemoved(int, int))); + //init view + setScene(m_board); + setFrameStyle(QFrame::NoFrame); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + //internal values m_points = 0; - m_secondsEarned = 0; - m_secondsLeft = 0; - emit pointsChanged(0); - makeUpdate(); + m_secondsEarned = m_millisecondsPaused = m_secondsRemaining = 0; + m_paused = false; + m_finished = false; + //"What's this?" context help + setWhatsThis(i18n("

Rules of Game

Your goal is to assemble lines of at least three similar diamonds. Click on two adjacent diamonds to swap them.

Earn extra points by building cascades, and extra seconds by assembling big lines or multiple lines at one time.

")); } Game::~Game() { delete m_board; delete m_gameTime; + delete m_pauseTime; } -void Game::makeUpdate() +Board *Game::board() { - //calculate time left in this game and emit signal if necessary - int secondsLeft = KDiamond::GameDuration + m_secondsEarned - (m_gameTime->elapsed() / 1000); - if (secondsLeft == 0) - emit gameFinished(m_points); - else if (m_secondsLeft != secondsLeft) + return m_board; +} + +void Game::pause(bool paused) +{ + if (!m_paused && paused) + m_pauseTime->restart(); + else if (m_paused && !paused) + m_millisecondsPaused += m_pauseTime->elapsed(); //add pause time to calculate time correctly + m_paused = paused; + if (paused) + m_board->showMessage(i18n("Click the pause button again to resume the game."), 0); + else + m_board->hideMessage(); +} + +void Game::update(int /*milliseconds*/) +{ + if (m_paused) + return; + //calculate new time + int secondsRemaining = KDiamond::GameDuration + m_secondsEarned + (m_millisecondsPaused - m_gameTime->elapsed()) / 1000; + if (secondsRemaining <= 0) { - emit timeLeftChanged(secondsLeft); - m_secondsLeft = secondsLeft; + m_finished = true; + disconnect(m_mainWindow, SIGNAL(updateScheduled(int)), this, SLOT(update(int))); + disconnect(m_mainWindow, SIGNAL(updateScheduled(int)), m_board, SLOT(update(int))); + m_board->gameFinished(); + m_board->showMessage(i18nc("Not meant like 'You have lost', more like 'Time is up'.", "Game over."), 0); + KNotification::event("gamefinished"); + emit gameFinished(m_points); } + else if (m_secondsRemaining != secondsRemaining) + emit remainingTimeChanged(secondsRemaining); + m_secondsRemaining = secondsRemaining; } -void Game::diamondsWereRemoved(int count, int cascade) +void Game::diamondsRemoved(int count, int cascade) { m_points += cascade; emit pointsChanged(m_points); - //If more than three diamonds were removed, give extra seconds. - m_secondsEarned += qMax(0, count - 3); - makeUpdate(); + //If more than three diamonds were removed, give an extra second. + if (count > 3) + ++m_secondsEarned; + update(0); //calculate new remaining time +} + +void Game::mouseReleaseEvent(QMouseEvent *event) +{ + if (m_finished) + event->ignore(); //block input after the end of the game + else + QGraphicsView::mouseReleaseEvent(event); +} + +void Game::resizeEvent(QResizeEvent *) +{ + qreal newWidth = width(), newHeight = height(); + m_board->resizeScene(newWidth, newHeight); + fitInView(QRectF(0.0, 0.0, newWidth, newHeight)); +} + +void Game::updateTheme() +{ + //this makes the board reload all pixmaps + m_board->resizeScene(width(), height(), true); +} + +void Game::wheelEvent(QWheelEvent *event) +{ + event->ignore(); //prevent user-triggered scrolling } #include "game.moc" diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/game.h /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/game.h --- kdiamond-kde4-0.1/src/game.h 2008-02-08 03:51:43.000000000 -0500 +++ kdiamond-kde4-0.2/src/game.h 2008-02-15 10:32:26.000000000 -0500 @@ -26,33 +26,46 @@ class MainWindow; #endif -#include +#include class QTime; #include -class Game : public QObject +namespace KDiamond +{ + //base duration of a game in seconds + const int GameDuration = 200; +} + +class Game : public QGraphicsView { Q_OBJECT public: Game(KGameDifficulty::standardLevel difficulty, MainWindow *mainWindow); ~Game(); - inline Board *board() { return m_board; } - void diamondsWereRemoved(int count, int cascade); + Board *board(); + public slots: + void pause(bool paused); + void update(int milliseconds); + void updateTheme(); signals: void pointsChanged(int points); - void timeLeftChanged(int timeLeft); - void gameFinished(int finalPoints); + void remainingTimeChanged(int remainingTime); + void gameFinished(int points); + protected: + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void resizeEvent(QResizeEvent *); + virtual void wheelEvent(QWheelEvent *event); protected slots: - void makeUpdate(); + void diamondsRemoved(int count, int cascade); private: Board *m_board; - - QTime *m_gameTime; + MainWindow *m_mainWindow; + QTime *m_gameTime, *m_pauseTime; int m_points; - int m_secondsEarned; - int m_secondsLeft; + int m_secondsEarned, m_millisecondsPaused, m_secondsRemaining; + bool m_paused, m_finished; }; #endif //KDIAMOND_GAME_H diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/greeter.cpp /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/greeter.cpp --- kdiamond-kde4-0.1/src/greeter.cpp 2008-02-08 03:23:37.000000000 -0500 +++ kdiamond-kde4-0.2/src/greeter.cpp 1969-12-31 19:00:00.000000000 -0500 @@ -1,48 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 Stefan Majewsky - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - ***************************************************************************/ - -#include "greeter.h" - -#include -#include -#include -#include - -Greeter::Greeter(QWidget *parent) - : QWidget(parent) -{ - m_button = new KPushButton(KIcon("document-new"), i18n("Start new game"), this); - connect(m_button, SIGNAL(pressed()), this, SIGNAL(startNewGame())); - m_label = new QLabel(i18n("You can choose a difficulty level from the box at the right bottom of the window."), this); - m_label->setAlignment(Qt::AlignCenter); - m_label->setWordWrap(true); - //layout - m_layout = new QGridLayout; - m_layout->addWidget(m_button, 1, 1); - m_layout->addWidget(m_label, 2, 0, 1, 3); - m_layout->setRowStretch(0, 10); - m_layout->setRowStretch(3, 10); - setLayout(m_layout); -} - -Greeter::~Greeter() -{ - delete m_layout; - delete m_button; - delete m_label; -} diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/greeter.h /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/greeter.h --- kdiamond-kde4-0.1/src/greeter.h 2008-02-08 02:24:39.000000000 -0500 +++ kdiamond-kde4-0.2/src/greeter.h 1969-12-31 19:00:00.000000000 -0500 @@ -1,41 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 Stefan Majewsky - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - ***************************************************************************/ - -#ifndef KDIAMOND_GREETER_H -#define KDIAMOND_GREETER_H - -class QGridLayout; -class QLabel; -#include -class KPushButton; - -class Greeter : public QWidget -{ - Q_OBJECT - public: - Greeter(QWidget *parent = 0); - ~Greeter(); - signals: - void startNewGame(); - private: - KPushButton *m_button; - QLabel *m_label; - QGridLayout *m_layout; -}; - -#endif //KDIAMOND_GREETER_H diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/kdiamond.kcfg /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/kdiamond.kcfg --- kdiamond-kde4-0.1/src/kdiamond.kcfg 2008-02-07 02:13:39.000000000 -0500 +++ kdiamond-kde4-0.2/src/kdiamond.kcfg 2008-02-15 10:32:26.000000000 -0500 @@ -5,12 +5,13 @@ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" > - + + themes/default.desktop - + Easy @@ -21,5 +22,9 @@ + + + false + diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/kdiamond.notifyrc /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/kdiamond.notifyrc --- kdiamond-kde4-0.1/src/kdiamond.notifyrc 1969-12-31 19:00:00.000000000 -0500 +++ kdiamond-kde4-0.2/src/kdiamond.notifyrc 2008-02-15 10:32:26.000000000 -0500 @@ -0,0 +1,28 @@ +[Global] +IconName=kdiamond +Comment=kdiamond + +[Context/game] +Name=Game +Comment=Sounds that appear during a game + +[Event/remove] +Name=Diamonds removed +Comment=Diamonds were removed. +Contexts=game +Sound=KDE-Window-Shade-Down.ogg +Action=Sound + +[Event/move] +Name=Diamonds moving +Comment=Diamonds are moving. +Contexts=game +Sound= +Action=None + +[Event/gamefinished] +Name=Game over +Comment=Time is up. +Contexts=game +Sound=KDE-Im-User-Auth.ogg +Action=Sound diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/kdiamondui.rc /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/kdiamondui.rc --- kdiamond-kde4-0.1/src/kdiamondui.rc 2008-02-07 03:05:54.000000000 -0500 +++ kdiamond-kde4-0.2/src/kdiamondui.rc 2008-02-15 10:32:26.000000000 -0500 @@ -1,10 +1,15 @@ - + + + + + Main Toolbar + diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/main.cpp /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/main.cpp --- kdiamond-kde4-0.1/src/main.cpp 2008-02-08 03:55:12.000000000 -0500 +++ kdiamond-kde4-0.2/src/main.cpp 2008-02-15 10:36:05.000000000 -0500 @@ -27,19 +27,20 @@ #include "renderer.h" static const char description[] = I18N_NOOP("KDiamond, a three-in-a-row game."); -static const char version[] = "0.1"; +static const char version[] = "0.2"; int main(int argc, char ** argv) { - KAboutData about("kdiamond", 0, ki18n("KDiamond"), version, ki18n(description), + KAboutData about("kdiamond", 0, ki18nc("The application's name", "KDiamond"), version, ki18n(description), KAboutData::License_GPL, ki18n("(C) 2008 Stefan Majewsky")); - about.addAuthor(ki18n("Stefan Majewsky"), ki18n("Original author and current maintainer"), "majewsky.stefan@ages-skripte.org"); - about.addCredit(ki18n("Felix Lemke"), ki18n("First theme"), "lemke.felix@ages-skripte.org"); + about.addAuthor(ki18n("Stefan Majewsky"), ki18n("Original author and current maintainer"), "majewsky@gmx.net"); + about.addCredit(ki18n("Eugene Trounev"), ki18n("Default theme"), "eugene.trounev@gmail.com"); + about.addCredit(ki18n("Felix Lemke"), ki18n("Classic theme"), "lemke.felix@ages-skripte.org"); about.addCredit(ki18n("Jeffrey Kelling"), ki18n("Technical consultant"), "kelling.jeffrey@ages-skripte.org"); KCmdLineArgs::init(argc, argv, &about); KCmdLineOptions options; - options.add("VeryEasy", ki18n("Start with VeryEasy difficulty level")); + options.add("VeryEasy", ki18n("Start with Very Easy difficulty level")); options.add("Easy", ki18n("Start with Easy difficulty level")); options.add("Medium", ki18n("Start with Medium difficulty level")); options.add("Hard", ki18n("Start with Hard difficulty level")); diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/mainwidget.cpp /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/mainwidget.cpp --- kdiamond-kde4-0.1/src/mainwidget.cpp 2008-02-08 03:23:45.000000000 -0500 +++ kdiamond-kde4-0.2/src/mainwidget.cpp 1969-12-31 19:00:00.000000000 -0500 @@ -1,39 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 Stefan Majewsky - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - ***************************************************************************/ - -#include "mainwidget.h" - -MainWidget::MainWidget(QWidget *parent) - : QWidget(parent) -{ -} - -void MainWidget::setContainedWidget(QWidget *widget) -{ - m_widget = widget; - m_widget->setParent(this); - m_widget->setGeometry(0, 0, width(), height()); - m_widget->show(); -} - -void MainWidget::resizeEvent(QResizeEvent *) -{ - m_widget->setGeometry(0, 0, width(), height()); -} - -#include "mainwidget.moc" diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/mainwidget.h /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/mainwidget.h --- kdiamond-kde4-0.1/src/mainwidget.h 2008-02-08 02:24:33.000000000 -0500 +++ kdiamond-kde4-0.2/src/mainwidget.h 1969-12-31 19:00:00.000000000 -0500 @@ -1,35 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 Stefan Majewsky - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - ***************************************************************************/ - -#ifndef KDIAMOND_MAINWIDGET_H -#define KDIAMOND_MAINWIDGET_H - -#include - -class MainWidget : public QWidget -{ - public: - MainWidget(QWidget *parent); - void setContainedWidget(QWidget *widget); - protected: - virtual void resizeEvent(QResizeEvent *event); - private: - QWidget *m_widget; -}; - -#endif // KDIAMOND_MAINWIDGET_H diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/mainwindow.cpp /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/mainwindow.cpp --- kdiamond-kde4-0.1/src/mainwindow.cpp 2008-02-08 03:55:03.000000000 -0500 +++ kdiamond-kde4-0.2/src/mainwindow.cpp 2008-02-15 10:32:26.000000000 -0500 @@ -18,41 +18,60 @@ #include "mainwindow.h" #include "board.h" -#include "consts.h" +#include "container.h" #include "game.h" -#include "greeter.h" -#include "mainwidget.h" +#include "renderer.h" #include "settings.h" +#include #include -#include #include #include #include +#include +#include #include +#include #include +#include +#include #include +#include #include #include +#include MainWindow::MainWindow(QWidget *parent) : KXmlGuiWindow(parent) { + //init timers and randomizer (necessary for the board) + m_updateTimer = new QTimer; + connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updateTime()), Qt::DirectConnection); + m_updateTimer->start(KDiamond::UpdateInterval); + m_updateTime = new QTime; + m_updateTime->start(); qsrand(time(0)); - m_game = 0; - m_gameStartable = false; //prevent KGameDifficulty from automatically starting a new game on initalization of level - m_main = new MainWidget(this); - setCentralWidget(m_main); - m_greeter = new Greeter(this); - connect(m_greeter, SIGNAL(startNewGame()), this, SLOT(startNewGame())); - m_main->setContainedWidget(m_greeter); - //early GUI - setupActions(); + //init GUI - actions + KStandardGameAction::gameNew(this, SLOT(startGame()), actionCollection()); + KStandardGameAction::highscores(this, SLOT(showHighscores()), actionCollection()); + KStandardGameAction::pause(this, SIGNAL(pause(bool)), actionCollection()); + KStandardGameAction::quit(kapp, SLOT(quit()), actionCollection()); + KStandardAction::preferences(this, SLOT(configureSettings()), actionCollection()); + KStandardAction::configureNotifications(this, SLOT(configureNotifications()), actionCollection()); + KToggleAction *showMinutes = actionCollection()->add("show_minutes"); + showMinutes->setText(i18n("Show minutes on timer")); + showMinutes->setChecked(Settings::showMinutes()); + connect(showMinutes, SIGNAL(triggered(bool)), this, SLOT(showMinutesOnTimer(bool))); + //init GUI - statusbar etc. statusBar()->insertPermanentItem(i18n("Points: %1", 0), 1, 1); statusBar()->insertPermanentItem(i18np("Time left: 1 second", "Time left: %1 seconds", 0), 2, 1); setAutoSaveSettings(); + //init GUI - center area + m_game = 0; + m_container = new Container(this); + setCentralWidget(m_container); //difficulty - KGameDifficulty::init(this, this, SLOT(startNewGame())); + KGameDifficulty::init(this, this, SLOT(startGame())); KGameDifficulty::addStandardLevel(KGameDifficulty::VeryEasy); KGameDifficulty::addStandardLevel(KGameDifficulty::Easy); KGameDifficulty::addStandardLevel(KGameDifficulty::Medium); @@ -64,16 +83,9 @@ KGameDifficulty::setLevel(KGameDifficulty::Easy); else KGameDifficulty::setLevel((KGameDifficulty::standardLevel) (Settings::skill())); - //late GUI + //late GUI initiation setupGUI(QSize(550, 400)); - setCaption(i18n("KDiamond")); - m_gameStartable = true; - //init timers - m_updateTimer = new QTimer; - connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updateTime()), Qt::DirectConnection); - m_updateTimer->start(KDiamond::UpdateInterval); - m_updateTime = new QTime; - m_updateTime->start(); + setCaption(i18nc("The application's name", "KDiamond")); } MainWindow::~MainWindow() @@ -83,65 +95,41 @@ delete m_updateTimer; if (m_game != 0) delete m_game; - if (m_greeter != 0) - delete m_greeter; -} - -void MainWindow::setupActions() -{ - KStandardGameAction::gameNew(this, SLOT(startNewGame()), actionCollection()); - KStandardGameAction::highscores(this, SLOT(showHighscores()), actionCollection()); - KStandardGameAction::quit(this, SLOT(close()), actionCollection()); } -void MainWindow::startNewGame() -{ - if (!m_gameStartable) - return; - //remove what was on the screen - if (m_game != 0) - stopGame(false); - if (m_greeter != 0) - { - delete m_greeter; - m_greeter = 0; - } - //start new game - m_game = new Game(KGameDifficulty::level(), this); - m_main->setContainedWidget(m_game->board()); -} - -void MainWindow::stopGame(bool showGreeter) +void MainWindow::startGame() { //save (eventually changed) difficulty level KGameDifficulty::standardLevel level = KGameDifficulty::level(); Settings::setSkill((int) level); - //stop game + //delete old game if (m_game != 0) { delete m_game; m_game = 0; } - if (showGreeter) - { - if (m_greeter == 0) - { - m_greeter = new Greeter(); - connect(m_greeter, SIGNAL(startNewGame()), this, SLOT(startNewGame())); - } - m_main->setContainedWidget(m_greeter); - } + //start new game + m_game = new Game(KGameDifficulty::level(), this); + connect(this, SIGNAL(pause(bool)), m_game, SLOT(pause(bool))); + connect(this, SIGNAL(pause(bool)), m_game->board(), SLOT(pause(bool))); + connect(m_game, SIGNAL(pointsChanged(int)), this, SLOT(updatePoints(int))); + connect(m_game, SIGNAL(remainingTimeChanged(int)), this, SLOT(updateRemainingTime(int))); + connect(m_game, SIGNAL(gameFinished(int)), this, SLOT(finishGame(int))); + m_container->setWidget(m_game); + //reset the Pause button's toggle state + ((KToggleAction *) actionCollection()->action("game_pause"))->setChecked(false); + //reset status bar + updatePoints(0); + updateRemainingTime(KDiamond::GameDuration); } -void MainWindow::finishGame(int finalPoints) +void MainWindow::finishGame(int points) { - //stop game - stopGame(true); - updateTimeLeft(0); + updateRemainingTime(0); //report score KScoreDialog dialog(KScoreDialog::Name | KScoreDialog::Score, this); dialog.setConfigGroup(KGameDifficulty::levelString()); - dialog.addScore(finalPoints); + dialog.addScore(points); dialog.exec(); } @@ -151,11 +139,22 @@ dialog.exec(); } +void MainWindow::close() +{ + Settings::self()->writeConfig(); +} + +void MainWindow::closeEvent(QCloseEvent *event) +{ + close(); + event->accept(); +} + void MainWindow::updateTime() { int milliseconds = m_updateTime->elapsed(); m_updateTime->restart(); - emit update(milliseconds); + emit updateScheduled(milliseconds); } void MainWindow::updatePoints(int points) @@ -163,20 +162,72 @@ statusBar()->changeItem(i18n("Points: %1", points), 1); } -void MainWindow::updateTimeLeft(int secondsLeft) +void MainWindow::updateRemainingTime(int remainingSeconds) { - statusBar()->changeItem(i18np("Time left: 1 second", "Time left: %1 seconds", secondsLeft), 2); + //store the time: if remainingSeconds == -1, the old time is just re-rendered (used by the configuration action MainWindow::showMinutesOnTimer) + static int storeRemainingSeconds = 0; + if (remainingSeconds == -1) + remainingSeconds = storeRemainingSeconds; + else + storeRemainingSeconds = remainingSeconds; + //split time in seconds and minutes if wanted + int seconds, minutes; + if (Settings::showMinutes()) + { + seconds = remainingSeconds % 60; + minutes = remainingSeconds / 60; + } + else + { + seconds = remainingSeconds; + minutes = 0; //the minutes do not appear in the output when minutes == 0 + } + //compose new string + QString sOutput; + if (minutes == 0) + sOutput = i18n("Time left: %1", i18np("1 second", "%1 seconds", seconds)); + else if (seconds == 0) + sOutput = i18n("Time left: %1", i18np("1 minute", "%1 minutes", minutes)); + else + sOutput = i18nc("The two parameters are strings like '2 minutes' or '1 second'.", "Time left: %1, %2").arg(i18np("1 minute", "%1 minutes", minutes), i18np("1 second", "%1 seconds", seconds)); + statusBar()->changeItem(sOutput, 2); } -void MainWindow::close() +void MainWindow::showMinutesOnTimer(bool showMinutes) { - Settings::self()->writeConfig(); + Settings::setShowMinutes(showMinutes); + updateRemainingTime(-1); } -void MainWindow::closeEvent(QCloseEvent *event) +void MainWindow::configureNotifications() { - close(); - event->accept(); + KNotifyConfigWidget::configure(this); +} + +void MainWindow::configureSettings() +{ + if (KConfigDialog::showDialog("settings")) + return; + KConfigDialog *dialog = new KConfigDialog(this, "settings", Settings::self()); + dialog->addPage(new KGameThemeSelector(dialog, Settings::self(), KGameThemeSelector::NewStuffDisableDownload), i18n("Theme"), "games-config-theme"); + connect(dialog, SIGNAL(settingsChanged(const QString&)), this, SLOT(loadSettings())); + dialog->setHelp(QString(), "kdiamond"); + dialog->show(); +} + +void MainWindow::loadSettings() +{ + if (!Renderer::loadTheme(Settings::theme())) + { + KMessageBox::error(this, i18n("Failed to load \"%1\" theme. Please check your installation.", Settings::theme())); + return; + } + //redraw game scene if necessary + if (m_game != 0) + { + m_game->updateTheme(); //resets all pixmaps + m_game->scene()->invalidate(m_game->scene()->sceneRect(), QGraphicsScene::BackgroundLayer); + } } #include "mainwindow.moc" diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/mainwindow.h /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/mainwindow.h --- kdiamond-kde4-0.1/src/mainwindow.h 2008-02-08 03:54:09.000000000 -0500 +++ kdiamond-kde4-0.2/src/mainwindow.h 2008-02-15 10:32:26.000000000 -0500 @@ -19,52 +19,54 @@ #ifndef KDIAMOND_MAINWINDOW_H #define KDIAMOND_MAINWINDOW_H +#ifndef KDIAMOND_CONTAINER_H + class Container; +#endif #ifndef KDIAMOND_GAME_H class Game; #endif -#ifndef KDIAMOND_GREETER_H - class Greeter; -#endif -#ifndef KDIAMOND_MAINWIDGET_H - class MainWidget; -#endif -#include - -class QCloseEvent; -class QResizeEvent; class QTime; class QTimer; +#include + +namespace KDiamond +{ + //maximum update interval in milliseconds + const int UpdateInterval = 10; +} class MainWindow : public KXmlGuiWindow { Q_OBJECT public: - explicit MainWindow(QWidget *parent = 0); - virtual ~MainWindow(); + MainWindow(QWidget *parent = 0); + ~MainWindow(); public slots: - void startNewGame(); - void stopGame(bool showGreeter); - void finishGame(int finalPoints); + void startGame(); + void finishGame(int points); + void showHighscores(); void close(); + + void configureNotifications(); + void configureSettings(); + void loadSettings(); + void showMinutesOnTimer(bool showMinutes); signals: - void update(int milliseconds); + void pause(bool paused); + void updateScheduled(int milliseconds); protected: - void setupActions(); virtual void closeEvent(QCloseEvent *); protected slots: - void showHighscores(); void updateTime(); void updatePoints(int points); - void updateTimeLeft(int secondsLeft); + void updateRemainingTime(int remainingSeconds); private: - bool m_gameStartable; Game *m_game; - Greeter *m_greeter; - MainWidget *m_main; + Container *m_container; QTime *m_updateTime; QTimer *m_updateTimer; }; -#endif // KDIAMOND_MAINWINDOW_H +#endif //KDIAMOND_MAINWINDOW_H diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/pics/CMakeLists.txt /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/pics/CMakeLists.txt --- kdiamond-kde4-0.1/src/pics/CMakeLists.txt 1969-12-31 19:00:00.000000000 -0500 +++ kdiamond-kde4-0.2/src/pics/CMakeLists.txt 2008-02-15 10:32:26.000000000 -0500 @@ -0,0 +1 @@ +kde4_install_icons(${ICON_INSTALL_DIR}) Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/pics/hi128-app-kdiamond.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/pics/hi128-app-kdiamond.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/pics/hi16-app-kdiamond.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/pics/hi16-app-kdiamond.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/pics/hi22-app-kdiamond.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/pics/hi22-app-kdiamond.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/pics/hi32-app-kdiamond.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/pics/hi32-app-kdiamond.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/pics/hi48-app-kdiamond.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/pics/hi48-app-kdiamond.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/pics/hi64-app-kdiamond.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/pics/hi64-app-kdiamond.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/pics/hisc-app-kdiamond.svgz and /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/pics/hisc-app-kdiamond.svgz differ diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/renderer.cpp /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/renderer.cpp --- kdiamond-kde4-0.1/src/renderer.cpp 2008-02-07 09:59:44.000000000 -0500 +++ kdiamond-kde4-0.2/src/renderer.cpp 2008-02-15 10:32:26.000000000 -0500 @@ -17,59 +17,173 @@ ***************************************************************************/ #include "renderer.h" +#include "board.h" +#include "diamond.h" +#include "settings.h" #include #include +#include #include -#include +#include +//global instances (only visible in this file!) +KSvgRenderer *g_renderer; KPixmapCache *g_cache; +//storage for metrics +int g_sceneWidth, g_sceneHeight, g_diamondEdgeLength; +QSize g_diamondSize, g_sceneSize; +//storage for theme properties +QString g_currentTheme; +int g_removeAnimFrameCount; +bool g_hasBorder; -void Renderer::init() +bool Renderer::init() { - g_cache = new KPixmapCache("kdiamond-pixmaps"); - g_cache->setCacheLimit(2048); //reserve up to 2 megabytes (that should be enough) + g_renderer = new KSvgRenderer(); + g_cache = new KPixmapCache("kdiamond-cache"); + g_cache->setCacheLimit(3 * 1024); + g_cache->discard(); + //No cleanup is necessary. The functions are needed during the whole running time of the program, after that the memory will be cleaned up automatically. + return Renderer::loadTheme(Settings::theme()); } -void Renderer::drawDiamond(QPainter *painter, const QRectF &bounds, KDiamond::Color color) +bool Renderer::loadTheme(const QString &name) +{ + bool discardCache = !g_currentTheme.isEmpty(); + if (!g_currentTheme.isEmpty() && g_currentTheme == name) + return true; //requested to load the theme that is already loaded + KGameTheme theme; + //try to load theme + if (!theme.load(name)) + { + if (!theme.loadDefault()) + return false; + } + g_currentTheme = name; + g_removeAnimFrameCount = theme.property("RemoveAnimFrames").toInt(); + g_hasBorder = theme.property("HasBorder").toInt() > 0; + //load graphics + if (!g_renderer->load(theme.graphics())) + return false; + //flush cache + if (discardCache) + g_cache->discard(); + return true; +} + +void Renderer::boardResized(int width, int height, int leftOffset, int topOffset, int diamondEdgeLength, int diamondCountOnEdge) +{ + //new metrics + g_sceneWidth = width; + g_sceneHeight = height; + g_diamondEdgeLength = diamondEdgeLength; + int borderEdgeLength = (diamondCountOnEdge + 2.0 * KDiamond::BorderPadding) * diamondEdgeLength; + //new sizes + g_diamondSize = QSize(g_diamondEdgeLength, g_diamondEdgeLength); + g_sceneSize = QSize(g_sceneWidth, g_sceneHeight); + //pre-render the background (it is more complex than the other pixmaps because it may include the border) + QString pixName = QString("kdiamond-background_%1-%2").arg(width).arg(height); + QPixmap pix; + if (!g_cache->find(pixName, pix)) + { + pix = QPixmap(g_sceneSize); + pix.fill(Qt::transparent); + QPainter p(&pix); + g_renderer->render(&p, "kdiamond-background"); + if (g_hasBorder) + g_renderer->render(&p, "kdiamond-border", QRectF(leftOffset - KDiamond::BorderPadding * diamondEdgeLength, topOffset - KDiamond::BorderPadding * diamondEdgeLength, borderEdgeLength, borderEdgeLength)); + p.end(); + g_cache->insert(pixName, pix); + } +} + +int Renderer::removeAnimFrameCount() +{ + return g_removeAnimFrameCount; +} + +bool Renderer::hasBorder() +{ + return g_hasBorder; +} + +QString colorToString(KDiamond::Color color) { - QPixmap pixmap; - QSize size = bounds.size().toSize(); switch (color) { case KDiamond::RedDiamond: - pixmap = g_cache->loadFromSvg(KStandardDirs::locate("data", "kdiamond/kdiamond-red.svg"), size); - break; + return "kdiamond-red"; case KDiamond::GreenDiamond: - pixmap = g_cache->loadFromSvg(KStandardDirs::locate("data", "kdiamond/kdiamond-green.svg"), size); - break; + return "kdiamond-green"; case KDiamond::BlueDiamond: - pixmap = g_cache->loadFromSvg(KStandardDirs::locate("data", "kdiamond/kdiamond-blue.svg"), size); - break; + return "kdiamond-blue"; case KDiamond::YellowDiamond: - pixmap = g_cache->loadFromSvg(KStandardDirs::locate("data", "kdiamond/kdiamond-yellow.svg"), size); - break; + return "kdiamond-yellow"; case KDiamond::WhiteDiamond: - pixmap = g_cache->loadFromSvg(KStandardDirs::locate("data", "kdiamond/kdiamond-white.svg"), size); - break; + return "kdiamond-white"; case KDiamond::BlackDiamond: - pixmap = g_cache->loadFromSvg(KStandardDirs::locate("data", "kdiamond/kdiamond-black.svg"), size); - break; + return "kdiamond-black"; case KDiamond::OrangeDiamond: - pixmap = g_cache->loadFromSvg(KStandardDirs::locate("data", "kdiamond/kdiamond-orange.svg"), size); - break; + return "kdiamond-orange"; + default: + return "kdiamond-selection"; + } +} + +QPixmap pixmapFromCache(const QString &svgName, const QSize &size) +{ + if (size.isEmpty()) + return QPixmap(); + QPixmap pix; + QString pixName = svgName + QString("_%1-%2").arg(size.width()).arg(size.height()); + + if (!g_cache->find(pixName, pix)) + { + pix = QPixmap(size); + pix.fill(Qt::transparent); + QPainter p(&pix); + g_renderer->render(&p, svgName); + p.end(); + g_cache->insert(pixName, pix); + } + return pix; +} + +QPixmap Renderer::diamond(KDiamond::Color color) +{ + QString svgName = colorToString(color); + //cache the move animation for this diamond + if (color != KDiamond::Selection) + { + for (int i = 0; i < g_removeAnimFrameCount; ++i) + { + QString frameSvgName = svgName + QString("-%1").arg(i); + QString framePixName = frameSvgName + QString("_%1-%1").arg(g_diamondEdgeLength); + QPixmap pix; + if (!g_cache->find(framePixName, pix)) + { + pix = QPixmap(g_diamondSize); + pix.fill(Qt::transparent); + QPainter p(&pix); + g_renderer->render(&p, frameSvgName); + p.end(); + g_cache->insert(framePixName, pix); + } + } } - painter->drawPixmap(bounds, pixmap, QRectF(0.0, 0.0, bounds.width(), bounds.height())); + //return the static pixmap + return pixmapFromCache(svgName, g_diamondSize); } -void Renderer::drawBackground(QPainter *painter, const QRectF &bounds) +QPixmap Renderer::removeFrame(KDiamond::Color color, int frame) { - QPixmap pixmap = g_cache->loadFromSvg(KStandardDirs::locate("data", "kdiamond/kdiamond-background.svg"), bounds.size().toSize()); - painter->drawPixmap(bounds, pixmap, QRectF(0.0, 0.0, bounds.width(), bounds.height())); + if (frame >= g_removeAnimFrameCount || color == KDiamond::Selection) + return QPixmap(); + return pixmapFromCache(colorToString(color) + QString("-%1").arg(frame), g_diamondSize); } -void Renderer::drawShadow(QPainter *painter, const QRectF &bounds) +QPixmap Renderer::background() { - QPixmap pixmap = g_cache->loadFromSvg(KStandardDirs::locate("data", "kdiamond/kdiamond-selected.svg"), bounds.size().toSize()); - painter->drawPixmap(bounds, pixmap, QRectF(0.0, 0.0, bounds.width(), bounds.height())); + return pixmapFromCache("kdiamond-background", g_sceneSize); } diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/renderer.h /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/renderer.h --- kdiamond-kde4-0.1/src/renderer.h 2008-02-07 09:59:52.000000000 -0500 +++ kdiamond-kde4-0.2/src/renderer.h 2008-02-15 10:32:26.000000000 -0500 @@ -19,17 +19,21 @@ #ifndef KDIAMOND_RENDERER_H #define KDIAMOND_RENDERER_H -#include "consts.h" #include "diamond.h" -class QSvgRenderer; +class QPixmap; -class Renderer { - public: - static void init(); - static void drawBackground(QPainter *painter, const QRectF &bounds); - static void drawDiamond(QPainter *painter, const QRectF &bounds, KDiamond::Color color); - static void drawShadow(QPainter *painter, const QRectF &bounds); -}; +namespace Renderer { + bool init(); + bool loadTheme(const QString &name); + void boardResized(int width, int height, int leftOffset, int topOffset, int diamondEdgeLength, int diamondCountOnEdge); + + int removeAnimFrameCount(); + bool hasBorder(); + + QPixmap diamond(KDiamond::Color color); + QPixmap removeFrame(KDiamond::Color color, int frame); + QPixmap background(); +} #endif // KDIAMOND_RENDERER_H diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/src/settings.kcfgc /tmp/bioChyMyGn/kdiamond-kde4-0.2/src/settings.kcfgc --- kdiamond-kde4-0.1/src/settings.kcfgc 2008-02-07 02:13:44.000000000 -0500 +++ kdiamond-kde4-0.2/src/settings.kcfgc 2008-02-15 10:32:26.000000000 -0500 @@ -1,4 +1,4 @@ File=kdiamond.kcfg ClassName=Settings Singleton=true -Mutators=skill +Mutators=true diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/themes/classic.desktop /tmp/bioChyMyGn/kdiamond-kde4-0.2/themes/classic.desktop --- kdiamond-kde4-0.1/themes/classic.desktop 1969-12-31 19:00:00.000000000 -0500 +++ kdiamond-kde4-0.2/themes/classic.desktop 2008-02-15 10:32:26.000000000 -0500 @@ -0,0 +1,12 @@ +[KGameTheme] +VersionFormat=1 +Name=Classic Theme +Description=The classic theme for KDiamond. +FileName=classic.svgz +Author=Felix Lemke +AuthorEmail=lemke.felix@ages-skripte.org +Preview=classic.png + +# there is no animation at the moment, so do only try to load one frame; then fail and show an empty pixmap +RemoveAnimFrames=1 +HasBorder=0 Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/themes/classic.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/themes/classic.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/themes/classic.svgz and /tmp/bioChyMyGn/kdiamond-kde4-0.2/themes/classic.svgz differ diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/themes/CMakeLists.txt /tmp/bioChyMyGn/kdiamond-kde4-0.2/themes/CMakeLists.txt --- kdiamond-kde4-0.1/themes/CMakeLists.txt 1969-12-31 19:00:00.000000000 -0500 +++ kdiamond-kde4-0.2/themes/CMakeLists.txt 2008-02-15 10:32:26.000000000 -0500 @@ -0,0 +1,9 @@ +set(kdiamond_THEME_SRCS + classic.desktop + classic.png + classic.svgz + default.desktop + default.svgz + default.png +) +install(FILES ${kdiamond_THEME_SRCS} DESTINATION ${DATA_INSTALL_DIR}/kdiamond/themes) diff -Nru /tmp/NJcEA2uTer/kdiamond-kde4-0.1/themes/default.desktop /tmp/bioChyMyGn/kdiamond-kde4-0.2/themes/default.desktop --- kdiamond-kde4-0.1/themes/default.desktop 1969-12-31 19:00:00.000000000 -0500 +++ kdiamond-kde4-0.2/themes/default.desktop 2008-02-15 10:32:26.000000000 -0500 @@ -0,0 +1,13 @@ +[KGameTheme] +VersionFormat=1 +Name=KDiamonds Default Theme +Description=Default theme for KDiamond. +FileName=default.svgz +Author=Eugene Trounev +AuthorEmail=eugene.trounev@gmail.com +Preview=default.png + +# number of frames in the "remove" animation +RemoveAnimFrames=7 +# this theme has a border to display around the board +HasBorder=1 Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/themes/default.png and /tmp/bioChyMyGn/kdiamond-kde4-0.2/themes/default.png differ Binary files /tmp/NJcEA2uTer/kdiamond-kde4-0.1/themes/default.svgz and /tmp/bioChyMyGn/kdiamond-kde4-0.2/themes/default.svgz differ