File indexing completed on 2024-04-14 03:59:29
0001 /* 0002 SPDX-FileCopyrightText: 2008-2010 Stefan Majewsky <majewsky@gmx.net> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "mainwindow.h" 0008 #include "game.h" 0009 #include "infobar.h" 0010 #include "settings.h" 0011 #include "view.h" 0012 // KDEGames 0013 #include <KGameDifficulty> 0014 #include <KGameGraphicsViewRenderer> 0015 #include <KGameHighScoreDialog> 0016 #include <KGameStandardAction> 0017 // KF 0018 #include <KActionCollection> 0019 #include <KActionMenu> 0020 #include <KLocalizedString> 0021 #include <KNotifyConfigWidget> 0022 #include <KStandardAction> 0023 // Qt 0024 #include <QAction> 0025 #include <QPointer> 0026 0027 namespace KDiamond 0028 { 0029 class ThemeProvider : public KGameThemeProvider 0030 { 0031 public: 0032 explicit ThemeProvider(QObject *parent = nullptr) 0033 : KGameThemeProvider("Theme", parent) 0034 { 0035 discoverThemes(QStringLiteral("themes")); 0036 } 0037 }; 0038 0039 class Renderer : public KGameGraphicsViewRenderer 0040 { 0041 public: 0042 Renderer() : KGameGraphicsViewRenderer(new ThemeProvider, 10) 0043 { 0044 setFrameSuffix(QStringLiteral("-%1")); 0045 } 0046 }; 0047 } 0048 0049 MainWindow::MainWindow(QWidget *parent) 0050 : KXmlGuiWindow(parent) 0051 , m_gameState(new KDiamond::GameState) 0052 , m_game(nullptr) 0053 , m_view(new KDiamond::View) 0054 , m_infoBar(nullptr) 0055 , m_newAct(new KActionMenu(QIcon::fromTheme(QStringLiteral("document-new")), i18nc("new game", "&New"), this)) 0056 , m_newTimedAct(new QAction(i18n("Timed game"), this)) 0057 , m_newUntimedAct(new QAction(i18n("Untimed game"), this)) 0058 , m_renderer(new KDiamond::Renderer()) 0059 , m_selector(m_renderer->themeProvider(), KGameThemeSelector::EnableNewStuffDownload) 0060 { 0061 m_renderer->setDefaultPrimaryView(m_view); 0062 //init GUI - "New Action" 0063 m_newAct->setToolTip(i18n("Start a new game")); 0064 m_newAct->setWhatsThis(i18n("Start a new game.")); 0065 actionCollection()->addAction(QStringLiteral("game_new"), m_newAct); 0066 KActionCollection::setDefaultShortcuts(m_newAct, KStandardShortcut::openNew()); 0067 connect(m_newAct, &KActionMenu::triggered, this, &MainWindow::startGameDispatcher); 0068 m_newAct->addAction(m_newTimedAct); 0069 connect(m_newTimedAct, &QAction::triggered, this, &MainWindow::startGameDispatcher); 0070 m_newAct->addAction(m_newUntimedAct); 0071 connect(m_newUntimedAct, &QAction::triggered, this, &MainWindow::startGameDispatcher); 0072 //init GUI - the other actions 0073 KGameStandardAction::highscores(this, &MainWindow::showHighscores, actionCollection()); 0074 m_pauseAct = KGameStandardAction::pause(this, &MainWindow::pausedAction, actionCollection()); 0075 KGameStandardAction::quit(this, &QWidget::close, actionCollection()); 0076 m_hintAct = KGameStandardAction::hint(nullptr, nullptr, actionCollection()); 0077 KStandardAction::preferences(this, &MainWindow::showPreferences, actionCollection()); 0078 KStandardAction::configureNotifications(this, &MainWindow::configureNotifications, actionCollection()); 0079 //difficulty 0080 KGameDifficultyGUI::init(this); 0081 connect(KGameDifficulty::global(), &KGameDifficulty::currentLevelChanged, this, &MainWindow::startGameDispatcher); 0082 //late GUI initialisation 0083 setupGUI(QSize(300, 400)); //TODO: find better solution for a minimum size 0084 setCaption(i18nc("The application's name", "KDiamond")); 0085 setCentralWidget(m_view); 0086 //init statusbar 0087 m_infoBar = new KDiamond::InfoBar(statusBar()); 0088 connect(m_gameState, &KDiamond::GameState::stateChanged, this, &MainWindow::stateChange); 0089 connect(m_gameState, &KDiamond::GameState::pointsChanged, m_infoBar, &KDiamond::InfoBar::updatePoints); 0090 connect(m_gameState, &KDiamond::GameState::leftTimeChanged, m_infoBar, &KDiamond::InfoBar::updateRemainingTime); 0091 //init game 0092 startGameDispatcher(); 0093 } 0094 0095 MainWindow::~MainWindow() 0096 { 0097 Settings::self()->save(); 0098 delete m_renderer; 0099 delete m_game; 0100 delete m_gameState; 0101 } 0102 0103 void MainWindow::startGameDispatcher() 0104 { 0105 if (sender() == m_newUntimedAct) { 0106 startGame(KDiamond::UntimedGame); 0107 } else if (sender() == m_newTimedAct) { 0108 startGame(KDiamond::NormalGame); 0109 } else 0110 //attention: this may also be used by KGameDifficulty and the ctor 0111 { 0112 startGame(Settings::untimed() ? KDiamond::UntimedGame : KDiamond::NormalGame); 0113 } 0114 } 0115 0116 void MainWindow::startGame(KDiamond::Mode mode) 0117 { 0118 //delete old board 0119 delete m_game; 0120 //start new game 0121 m_gameState->startNewGame(); 0122 m_gameState->setMode(mode); 0123 m_game = new Game(m_gameState, m_renderer); 0124 connect(m_gameState, &KDiamond::GameState::stateChanged, m_game, &Game::stateChange); 0125 connect(m_gameState, &KDiamond::GameState::message, m_game, &Game::message); 0126 connect(m_game, &Game::numberMoves, m_infoBar, &KDiamond::InfoBar::updateMoves); 0127 connect(m_game, &Game::pendingAnimationsFinished, this, &MainWindow::gameIsOver); 0128 connect(m_hintAct, &QAction::triggered, m_game, &Game::showHint); 0129 m_view->setScene(m_game); 0130 //reset status bar 0131 m_infoBar->setUntimed(mode == KDiamond::UntimedGame); 0132 m_infoBar->updatePoints(0); 0133 m_infoBar->updateRemainingTime(KDiamond::GameDuration); 0134 } 0135 0136 void MainWindow::stateChange(KDiamond::State state) 0137 { 0138 m_pauseAct->setEnabled(state != KDiamond::Finished); 0139 m_pauseAct->setChecked(state == KDiamond::Paused); 0140 m_hintAct->setEnabled(state == KDiamond::Playing); 0141 } 0142 0143 void MainWindow::gameIsOver() 0144 { 0145 //create score info 0146 KGameHighScoreDialog::FieldInfo scoreInfo; 0147 scoreInfo[KGameHighScoreDialog::Score].setNum(m_gameState->points()); 0148 scoreInfo[KGameHighScoreDialog::Custom1] = m_gameState->mode() == KDiamond::UntimedGame ? i18n("Untimed") : i18n("Timed"); 0149 //report score 0150 QPointer<KGameHighScoreDialog> dialog = new KGameHighScoreDialog(KGameHighScoreDialog::Name | KGameHighScoreDialog::Score, this); 0151 dialog->addField(KGameHighScoreDialog::Custom1, i18n("Mode"), QStringLiteral("mode")); 0152 dialog->initFromDifficulty(KGameDifficulty::global()); 0153 dialog->addScore(scoreInfo); 0154 dialog->exec(); 0155 delete dialog; 0156 } 0157 0158 void MainWindow::showHighscores() 0159 { 0160 //pause game if necessary 0161 m_gameState->setState(KDiamond::Paused); 0162 if (m_gameState->state() != KDiamond::Finished) { 0163 actionCollection()->action(QStringLiteral("game_pause"))->setChecked(true); 0164 } 0165 //show dialog 0166 QPointer<KGameHighScoreDialog> dialog = new KGameHighScoreDialog(KGameHighScoreDialog::Name | KGameHighScoreDialog::Score, this); 0167 dialog->addField(KGameHighScoreDialog::Custom1, i18n("Mode"), QStringLiteral("mode")); 0168 dialog->initFromDifficulty(KGameDifficulty::global()); 0169 dialog->exec(); 0170 delete dialog; 0171 } 0172 0173 void MainWindow::showPreferences() 0174 { 0175 m_selector.showAsDialog(); 0176 } 0177 0178 0179 void MainWindow::pausedAction(bool paused) 0180 { 0181 m_gameState->setState(paused ? KDiamond::Paused : KDiamond::Playing); 0182 } 0183 0184 void MainWindow::configureNotifications() 0185 { 0186 KNotifyConfigWidget::configure(this); 0187 } 0188 0189 #include "moc_mainwindow.cpp"