File indexing completed on 2024-05-05 08:04:51

0001 /*
0002     SPDX-FileCopyrightText: 2009 Mathias Kraus <k.hias@gmx.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "infooverlay.h"
0008 #include "game.h"
0009 #include "gamescene.h"
0010 #include "player.h"
0011 #include "settings.h"
0012 
0013 #include <QGraphicsView>
0014 #include <QGraphicsScene>
0015 #include <QGraphicsRectItem>
0016 #include <KLocalizedString>
0017 #include <KGameRenderer>
0018 #include <KGameRenderedItem>
0019 
0020 InfoOverlay::InfoOverlay (Game* p_game, GameScene* p_scene) : QObject()
0021 {
0022     m_game = p_game;
0023     m_gameScene = p_scene;
0024     m_svgScaleFactor = 1;
0025 
0026     int nWinPoints = m_game->getWinPoints();
0027     const QList <Player*> playerList = m_game->getPlayers();
0028 
0029     KGameRenderer* renderer;
0030     renderer = m_gameScene->renderer(Granatier::Element::SCORE);
0031 
0032     //create the labels
0033     for(const auto& player: playerList)
0034     {
0035         QList <KGameRenderedItem*> svgItemList;
0036         auto* playerName = new QGraphicsTextItem(player->getPlayerName());
0037         playerName->setFont(QFont(QStringLiteral("Helvetica"), static_cast<int>(Granatier::CellSize * 0.35), QFont::Bold, false));
0038         playerName->setDefaultTextColor(QColor("#FFFF00"));
0039         playerName->setZValue(2001);
0040 
0041         for(int j = 0; j < nWinPoints; j++)
0042         {
0043             auto* score = new KGameRenderedItem(renderer, QStringLiteral("score_star_disabled"));
0044             score->setZValue(2001);
0045             svgItemList.append(score);
0046         }
0047         m_mapScore.insert(player, svgItemList);
0048         m_mapPlayerNames.insert(player, playerName);
0049     }
0050 
0051     QString strContinue (i18n("Press Space to continue"));
0052 
0053     m_continueLabel = new QGraphicsTextItem(strContinue);
0054     m_continueLabel->setFont(QFont(QStringLiteral("Helvetica"), static_cast<int>(Granatier::CellSize * 0.35), QFont::Bold, false));
0055     m_continueLabel->setDefaultTextColor(QColor("#FFFF00"));
0056     m_continueLabel->setZValue(2001);
0057 
0058     m_newGameLabel = new QGraphicsTextItem(i18n("Press Space to start a new Game"));
0059     m_newGameLabel->setFont(QFont(QStringLiteral("Helvetica"), static_cast<int>(Granatier::CellSize * 0.35), QFont::Bold, false));
0060     m_newGameLabel->setDefaultTextColor(QColor("#FFFF00"));
0061     m_newGameLabel->setZValue(2001);
0062 
0063     m_gameOverLabel = new QGraphicsTextItem;;
0064     m_gameOverLabel->setFont(QFont(QStringLiteral("Helvetica"), static_cast<int>(Granatier::CellSize * 0.5), QFont::Bold, false));
0065     m_gameOverLabel->setDefaultTextColor(QColor("#FFFF00"));
0066     m_gameOverLabel->setZValue(2001);
0067 
0068     m_getReadyLabel = new QGraphicsTextItem(i18n("GET READY !!!"));
0069     m_getReadyLabel->setFont(QFont(QStringLiteral("Helvetica"), static_cast<int>(Granatier::CellSize * 0.6), QFont::Bold, false));
0070     m_getReadyLabel->setDefaultTextColor(QColor("#FFFF00"));
0071     m_getReadyLabel->setZValue(2001);
0072 
0073     m_startGameLabel = new QGraphicsTextItem(i18n("Press Space to start"));
0074     m_startGameLabel->setFont(QFont(QStringLiteral("Helvetica"), static_cast<int>(Granatier::CellSize * 0.35), QFont::Bold, false));
0075     m_startGameLabel->setDefaultTextColor(QColor("#FFFF00"));
0076     m_startGameLabel->setZValue(2001);
0077 
0078     m_pauseLabel = new QGraphicsTextItem(i18n("PAUSED"));
0079     m_pauseLabel->setFont(QFont(QStringLiteral("Helvetica"), static_cast<int>(Granatier::CellSize * 0.8), QFont::Bold, false));
0080     m_pauseLabel->setDefaultTextColor(QColor("#FFFF00"));
0081     m_pauseLabel->setZValue(2001);
0082 
0083     m_continueAfterPauseLabel = new QGraphicsTextItem(strContinue);
0084     m_continueAfterPauseLabel->setFont(QFont(QStringLiteral("Helvetica"), static_cast<int>(Granatier::CellSize * 0.35), QFont::Bold, false));
0085     m_continueAfterPauseLabel->setDefaultTextColor(QColor("#FFFF00"));
0086     m_continueAfterPauseLabel->setZValue(2001);
0087 
0088     m_dimmOverlay = new QGraphicsRectItem();
0089     m_dimmOverlay->setBrush(QBrush(QColor(0,0,0,175)));
0090     if(Settings::self()->showAllTiles() == 1)
0091     {
0092         m_dimmOverlay->setBrush(QBrush(QColor(0,0,0,0)));
0093     }
0094     m_dimmOverlay->setZValue(2000);
0095     m_dimmOverlay->setRect(m_gameScene->sceneRect().x(), m_gameScene->sceneRect().y(),
0096                            m_gameScene->width(), m_gameScene->height());
0097 }
0098 
0099 InfoOverlay::~InfoOverlay()
0100 {
0101     //remove the items from the scene
0102     hideItems();
0103 
0104     // Find the score items and remove them
0105     for(const auto& scoreItems: std::as_const(m_mapScore))
0106     {
0107         qDeleteAll(scoreItems);
0108     }
0109     m_mapScore.clear(); //TODO: necessary?
0110     // Find the player name labels and remove them
0111     qDeleteAll(m_mapPlayerNames);
0112     m_mapPlayerNames.clear(); //TODO: necessary?
0113 
0114     delete m_continueLabel;
0115     delete m_newGameLabel;
0116     delete m_gameOverLabel;
0117     delete m_getReadyLabel;
0118     delete m_startGameLabel;
0119     delete m_pauseLabel;
0120     delete m_dimmOverlay;
0121     delete m_continueAfterPauseLabel;
0122 }
0123 
0124 void InfoOverlay::showGetReady ()
0125 {
0126     hideItems();
0127 
0128     if (!m_gameScene->items().contains(m_dimmOverlay))
0129     {
0130         m_gameScene->addItem(m_dimmOverlay);
0131     }
0132 
0133     if (!m_gameScene->items().contains(m_getReadyLabel))
0134     {
0135         m_gameScene->addItem(m_getReadyLabel);
0136     }
0137 
0138     if (!m_gameScene->items().contains(m_startGameLabel))
0139     {
0140         m_gameScene->addItem(m_startGameLabel);
0141     }
0142 }
0143 
0144 void InfoOverlay::showPause ()
0145 {
0146     hideItems();
0147 
0148     if (!m_gameScene->items().contains(m_dimmOverlay))
0149     {
0150         m_gameScene->addItem(m_dimmOverlay);
0151     }
0152 
0153     if (!m_gameScene->items().contains(m_pauseLabel))
0154     {
0155         m_gameScene->addItem(m_pauseLabel);
0156     }
0157 
0158     if (!m_gameScene->items().contains(m_continueAfterPauseLabel))
0159     {
0160         m_gameScene->addItem(m_continueAfterPauseLabel);
0161     }
0162 }
0163 
0164 void InfoOverlay::showScore ()
0165 {
0166     int nWinPoints = m_game->getWinPoints();
0167     QList <Player*> players = m_game->getPlayers();
0168     KGameRenderedItem* svgItem;
0169 
0170     hideItems();
0171 
0172     if (!m_gameScene->items().contains(m_dimmOverlay))
0173     {
0174         m_gameScene->addItem(m_dimmOverlay);
0175     }
0176 
0177     for(auto & player : players)
0178     {
0179         if (!m_gameScene->items().contains(m_mapPlayerNames.value(player)))
0180         {
0181             // display the player name
0182             m_gameScene->addItem(m_mapPlayerNames.value(player));
0183         }
0184 
0185         for(int j = 0; j < nWinPoints; j++)
0186         {
0187             svgItem = m_mapScore.value(player).at(j);
0188             if (player->points() > j)
0189             {
0190                 svgItem->setSpriteKey(QStringLiteral("score_star_enabled"));
0191             }
0192 
0193             // if the score was not displayed yet
0194             if (!m_gameScene->items().contains(svgItem))
0195             {
0196                 // display the score
0197                 m_gameScene->addItem(svgItem);
0198             }
0199         }
0200     }
0201 
0202     if(m_game->getGameOver() == false)
0203     {
0204         if (!m_gameScene->items().contains(m_continueLabel))
0205         {
0206             m_gameScene->addItem(m_continueLabel);
0207         }
0208     }
0209     else
0210     {
0211         if (!m_gameScene->items().contains(m_newGameLabel))
0212         {
0213             m_gameScene->addItem(m_newGameLabel);
0214         }
0215         if (m_gameScene->items().contains(m_gameOverLabel))
0216         {
0217             m_gameScene->removeItem(m_gameOverLabel);
0218         }
0219         m_gameOverLabel->setPlainText(i18n("The winner is %1", m_game->getWinner()));
0220         m_gameOverLabel->setPos(m_gameScene->sceneRect().x() + (m_gameScene->width() - m_gameOverLabel->boundingRect().width())/2,
0221                                 m_gameOverLabel->y());
0222         m_gameScene->addItem(m_gameOverLabel);
0223     }
0224 }
0225 
0226 void InfoOverlay::hideItems ()
0227 {
0228     int nWinPoints = m_game->getWinPoints();
0229     QList <Player*> players = m_game->getPlayers();
0230 
0231     for(auto & player : players)
0232     {
0233         if (m_gameScene->items().contains(m_mapPlayerNames.value(player)))
0234         {
0235             // display the player name
0236             m_gameScene->removeItem(m_mapPlayerNames.value(player));
0237         }
0238 
0239         for(int j = 0; j < nWinPoints; j++)
0240         {
0241             KGameRenderedItem* svgItem = m_mapScore.value(player).at(j);
0242             // if the score is displayed
0243             if (m_gameScene->items().contains(svgItem))
0244             {
0245                 // remove the score
0246                 m_gameScene->removeItem(svgItem);
0247             }
0248         }
0249     }
0250 
0251     if (m_gameScene->items().contains(m_continueLabel))
0252     {
0253         m_gameScene->removeItem(m_continueLabel);
0254     }
0255 
0256     if (m_gameScene->items().contains(m_newGameLabel))
0257     {
0258         m_gameScene->removeItem(m_newGameLabel);
0259     }
0260 
0261     if (m_gameScene->items().contains(m_gameOverLabel))
0262     {
0263         m_gameScene->removeItem(m_gameOverLabel);
0264     }
0265 
0266     if (m_gameScene->items().contains(m_getReadyLabel))
0267     {
0268         m_gameScene->removeItem(m_getReadyLabel);
0269     }
0270 
0271     if (m_gameScene->items().contains(m_startGameLabel))
0272     {
0273         m_gameScene->removeItem(m_startGameLabel);
0274     }
0275 
0276     if (m_gameScene->items().contains(m_pauseLabel))
0277     {
0278         m_gameScene->removeItem(m_pauseLabel);
0279     }
0280 
0281     if (m_gameScene->items().contains(m_continueAfterPauseLabel))
0282     {
0283         m_gameScene->removeItem(m_continueAfterPauseLabel);
0284     }
0285 
0286     if (m_gameScene->items().contains(m_dimmOverlay))
0287     {
0288         m_gameScene->removeItem(m_dimmOverlay);
0289     }
0290 }
0291 
0292 void InfoOverlay::resizeDimmOverlay(qreal x, qreal y, qreal width, qreal height)
0293 {
0294     m_dimmOverlay->setRect(x, y, width, height);
0295 }
0296 
0297 void InfoOverlay::updateGraphics(qreal svgScaleFactor)
0298 {
0299     m_svgScaleFactor = svgScaleFactor;
0300     
0301     if(m_gameScene->views().isEmpty())
0302     {
0303         return;
0304     }
0305 
0306     int nWinPoints = m_game->getWinPoints();
0307     QList <Player*> playerList = m_game->getPlayers();
0308     int nMaxPlayerNameLength = 0;
0309     int nTop = 0;
0310     int nLeft = 0;
0311 
0312     QGraphicsTextItem* playerName;
0313     QGraphicsTextItem em(QStringLiteral("M"));
0314     em.setFont(QFont(QStringLiteral("Helvetica"), static_cast<int>(Granatier::CellSize * 0.35), QFont::Bold, false));
0315     //calculate max player name length and top-left position
0316     for(int i = 0; i < playerList.count(); i++)
0317     {
0318         playerName = m_mapPlayerNames.value(playerList.at(i));
0319         if(nMaxPlayerNameLength < playerName->boundingRect().width())
0320         {
0321             nMaxPlayerNameLength = static_cast<int>(playerName->boundingRect().width());
0322         }
0323         if(i == playerList.count() - 1)
0324         {
0325             nLeft = static_cast<int>(m_gameScene->sceneRect().x() + m_gameScene->width()/2 - (nMaxPlayerNameLength + em.boundingRect().width()/2 + nWinPoints * (Granatier::CellSize * 0.6 + em.boundingRect().width()/5))/2);
0326             nTop = static_cast<int>(m_gameScene->sceneRect().y() + m_gameScene->height()/2 - (playerList.count()+2)/2 * em.boundingRect().height());
0327         }
0328     }
0329 
0330     QSize svgSize;
0331     QPoint topLeft(0, 0);
0332     topLeft = m_gameScene->views().constFirst()->mapFromScene(topLeft);
0333 
0334     KGameRenderedItem* score;
0335     for(int i = 0; i < playerList.count(); i++)
0336     {
0337         playerName = m_mapPlayerNames.value(playerList.at(i));
0338         playerName->setPos(nLeft, nTop + i * em.boundingRect().height() * 1.1);
0339 
0340         for(int j = 0; j < nWinPoints; j++)
0341         {
0342             score = m_mapScore.value(playerList.at(i)).at(j);
0343 
0344             QPoint bottomRight(static_cast<int>(Granatier::CellSize * 0.6), static_cast<int>(Granatier::CellSize * 0.6));
0345             bottomRight = m_gameScene->views().constFirst()->mapFromScene(bottomRight);
0346 
0347             svgSize.setHeight(bottomRight.y() - topLeft.y());
0348             svgSize.setWidth(bottomRight.x() - topLeft.x());
0349 
0350             score->setRenderSize(svgSize);
0351             score->setScale(svgScaleFactor);
0352 
0353             score->setPos(nLeft + nMaxPlayerNameLength + em.boundingRect().width()/2 + j * (Granatier::CellSize * 0.6 + em.boundingRect().width()/5),
0354                           playerName->pos().y() + em.boundingRect().height()/2.5 - (Granatier::CellSize * 0.6) / 2);
0355 
0356         }
0357     }
0358 
0359     m_continueLabel->setPos(m_gameScene->sceneRect().x() + (m_gameScene->width() - m_continueLabel->boundingRect().width())/2,
0360                             nTop + (playerList.count()+1) * (m_continueLabel->boundingRect().height()));
0361     m_newGameLabel->setPos(m_gameScene->sceneRect().x() + (m_gameScene->width() - m_newGameLabel->boundingRect().width())/2,
0362                            nTop + (playerList.count()+1) * (m_newGameLabel->boundingRect().height()));
0363     m_gameOverLabel->setPos(m_gameScene->sceneRect().x() + (m_gameScene->width() - m_gameOverLabel->boundingRect().width())/2,
0364                             nTop - m_gameOverLabel->boundingRect().height());
0365     m_getReadyLabel->setPos(m_gameScene->sceneRect().x() + (m_gameScene->width() - m_getReadyLabel->boundingRect().width()) / 2,
0366                             m_gameScene->sceneRect().y() + (m_gameScene->height() - m_getReadyLabel->boundingRect().height() -  m_startGameLabel->boundingRect().height()) / 2);
0367     m_startGameLabel->setPos(m_gameScene->sceneRect().x() + (m_gameScene->width() - m_startGameLabel->boundingRect().width()) / 2,
0368                              m_gameScene->sceneRect().y() + (m_gameScene->height() + m_getReadyLabel->boundingRect().height() - m_startGameLabel->boundingRect().height()) / 2);
0369     m_pauseLabel->setPos(m_gameScene->sceneRect().x() + (m_gameScene->width() - m_pauseLabel->boundingRect().width()) / 2,
0370                          m_gameScene->sceneRect().y() + (m_gameScene->height() - m_pauseLabel->boundingRect().height() - m_continueAfterPauseLabel->boundingRect().height()) / 2);
0371     m_continueAfterPauseLabel->setPos(m_gameScene->sceneRect().x() + (m_gameScene->width() - m_continueAfterPauseLabel->boundingRect().width()) / 2,
0372                                       m_gameScene->sceneRect().y() + (m_gameScene->height() + m_pauseLabel->boundingRect().height() - m_continueAfterPauseLabel->boundingRect().height()) / 2);
0373 }
0374 
0375 void InfoOverlay::themeChanged()
0376 {
0377     KGameRenderer* renderer = m_gameScene->renderer(Granatier::Element::SCORE);
0378     KGameRenderedItem* tempItem;
0379 
0380     for(auto& score: m_mapScore)
0381     {
0382         for(auto& star: score)
0383         {
0384             tempItem = star;
0385             star = new KGameRenderedItem(renderer, tempItem->spriteKey());
0386             star->setZValue(tempItem->zValue());
0387             star->setPos(tempItem->pos());
0388 
0389             if(m_gameScene->items().contains(tempItem))
0390             {
0391                 m_gameScene->removeItem(tempItem);
0392                 m_gameScene->addItem(star);
0393             }
0394             delete tempItem;
0395         }
0396     }
0397 
0398     updateGraphics(m_svgScaleFactor);
0399 }
0400 
0401 #include "moc_infooverlay.cpp"