File indexing completed on 2024-04-21 04:02:01
0001 /* 0002 SPDX-FileCopyrightText: 1998 Andreas Wüst <AndreasWuest@gmx.de> 0003 SPDX-FileCopyrightText: 2006 Dmitry Suzdalev <dimsuz@gmail.com> 0004 SPDX-FileCopyrightText: 2007 Simon Hürlimann <simon.huerlimann@huerlisi.ch> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "toplevel.h" 0010 0011 #include "gamewidget.h" 0012 #include "playfield.h" 0013 #include "prefs.h" 0014 #include "commondefs.h" 0015 #include "chooselevelsetdialog.h" 0016 #include "katomic_debug.h" 0017 0018 #include <KGameStandardAction> 0019 0020 #include <KLocalizedString> 0021 #include <KSelectAction> 0022 #include <KActionCollection> 0023 0024 #include <QIcon> 0025 #include <QStatusBar> 0026 #include <QLabel> 0027 0028 0029 AtomTopLevel::AtomTopLevel() 0030 { 0031 QString lastPlayedLevelSet = Preferences::lastPlayedLevelSet(); 0032 if (lastPlayedLevelSet.isEmpty()) 0033 lastPlayedLevelSet = QStringLiteral(DEFAULT_LEVELSET_NAME); 0034 0035 m_gameWid = new GameWidget( lastPlayedLevelSet, this); 0036 m_gameWid->setObjectName( QStringLiteral("gamewidget" )); 0037 createMenu(); 0038 loadSettings(); 0039 setCentralWidget(m_gameWid); 0040 0041 mLevel = new QLabel(i18n("Level:")); 0042 mCurrentScore = new QLabel(i18n("Current score:")); 0043 mHighScore = new QLabel(i18n("Highscore:")); 0044 mMoleculeName = new QLabel; 0045 statusBar()->addWidget(mLevel); 0046 statusBar()->addPermanentWidget(mCurrentScore); 0047 statusBar()->addPermanentWidget(mHighScore); 0048 statusBar()->addWidget(mMoleculeName); 0049 0050 updateStatusBar( m_gameWid->currentLevel(), m_gameWid->currentScore(), m_gameWid->currentHighScore() ); 0051 0052 connect(m_gameWid, &GameWidget::statsChanged, this, &AtomTopLevel::updateStatusBar); 0053 connect(m_gameWid, &GameWidget::levelChanged, this, &AtomTopLevel::levelHasChanged); 0054 0055 // update next/prev actions 0056 levelHasChanged(m_gameWid->currentLevel()); 0057 setupGUI(); 0058 } 0059 0060 AtomTopLevel::~AtomTopLevel() 0061 { 0062 } 0063 0064 bool AtomTopLevel::queryClose() 0065 { 0066 // saves last played level and levelset 0067 m_gameWid->saveLastPlayedLevel(); 0068 Preferences::self()->save(); 0069 return true; 0070 } 0071 0072 void AtomTopLevel::createMenu() 0073 { 0074 // Game 0075 KGameStandardAction::restart(m_gameWid, &GameWidget::restartLevel, actionCollection()); 0076 // FIXME: comment this until highscore dialog will be implemented. 0077 // (katomic needs special one) 0078 // KGameStandardAction::highscores(m_gameWid, &GameWidget::showHighscores, actionCollection()); 0079 KGameStandardAction::load(m_gameWid, &GameWidget::loadGame, actionCollection()); 0080 KGameStandardAction::save(m_gameWid, &GameWidget::saveGame, actionCollection()); 0081 KGameStandardAction::quit(this, &QWidget::close, actionCollection()); 0082 0083 // Move 0084 m_undoAct = KGameStandardAction::undo(m_gameWid->playfield(), &PlayField::undo, actionCollection()); 0085 m_redoAct = KGameStandardAction::redo(m_gameWid->playfield(), &PlayField::redo, actionCollection()); 0086 0087 0088 m_prevLevelAct = actionCollection()->addAction( QStringLiteral( "prev_level" ) ); 0089 m_prevLevelAct->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-left" ) ) ); 0090 m_prevLevelAct->setText( i18n( "Previous Level" ) ); 0091 KActionCollection::setDefaultShortcut(m_prevLevelAct, Qt::CTRL | Qt::Key_P ); 0092 addAction( m_prevLevelAct ); 0093 connect( m_prevLevelAct, &QAction::triggered, m_gameWid, &GameWidget::prevLevel ); 0094 0095 m_nextLevelAct = actionCollection()->addAction( QStringLiteral( "next_level" ) ); 0096 m_nextLevelAct->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-right" ) ) ); 0097 m_nextLevelAct->setText( i18n( "Next Level" ) ); 0098 KActionCollection::setDefaultShortcut(m_nextLevelAct, Qt::CTRL | Qt::Key_N ); 0099 addAction( m_nextLevelAct ); 0100 connect( m_nextLevelAct, &QAction::triggered, m_gameWid, &GameWidget::nextLevel ); 0101 0102 QAction* chooseLevelSet = actionCollection()->addAction( QStringLiteral( "choose_level_set" ) ); 0103 chooseLevelSet->setText( i18n( "Choose level set..." ) ); 0104 addAction( chooseLevelSet ); 0105 connect(chooseLevelSet, &QAction::triggered, this, &AtomTopLevel::chooseLevelSet); 0106 0107 m_animSpeedAct = new KSelectAction(i18n("Animation Speed"), this); 0108 actionCollection()->addAction( QStringLiteral( "anim_speed" ), m_animSpeedAct); 0109 const QStringList acts{ 0110 i18n("Slow"), 0111 i18n("Normal"), 0112 i18n("Fast"), 0113 }; 0114 m_animSpeedAct->setItems(acts); 0115 connect(m_animSpeedAct, &KSelectAction::indexTriggered, 0116 this, &AtomTopLevel::slotAnimSpeedChanged); 0117 0118 QAction *undoAll = actionCollection()->addAction( QStringLiteral( "move_undo_all" ) ); 0119 undoAll->setIcon( QIcon::fromTheme( QStringLiteral( "media-skip-backward" )) ); 0120 undoAll->setText( i18n("Undo All") ); 0121 connect( undoAll, &QAction::triggered, m_gameWid->playfield(), &PlayField::undoAll ); 0122 0123 QAction *redoAll = actionCollection()->addAction( QStringLiteral( "move_redo_all" ) ); 0124 redoAll->setIcon( QIcon::fromTheme( QStringLiteral( "media-skip-forward" )) ); 0125 redoAll->setText( i18n("Redo All") ); 0126 connect( redoAll, &QAction::triggered, m_gameWid->playfield(), &PlayField::redoAll ); 0127 0128 m_undoAct->setEnabled(false); 0129 m_redoAct->setEnabled(false); 0130 undoAll->setEnabled(false); 0131 redoAll->setEnabled(false); 0132 0133 connect (m_gameWid->playfield(), &PlayField::enableRedo, m_redoAct, &QAction::setEnabled); 0134 connect (m_gameWid->playfield(), &PlayField::enableUndo, m_undoAct, &QAction::setEnabled); 0135 connect (m_gameWid->playfield(), &PlayField::enableUndo, undoAll, &QAction::setEnabled); 0136 connect (m_gameWid->playfield(), &PlayField::enableRedo, redoAll, &QAction::setEnabled); 0137 0138 QAction * atomUpAct = actionCollection()->addAction( QStringLiteral( "atom_up" )); 0139 atomUpAct->setText(i18n("Atom Up")); 0140 KActionCollection::setDefaultShortcut(atomUpAct, Qt::Key_Up); 0141 addAction(atomUpAct); 0142 connect(atomUpAct, &QAction::triggered, m_gameWid, &GameWidget::moveUp); 0143 0144 QAction * atomDownAct = actionCollection()->addAction( QStringLiteral( "atom_down" )); 0145 atomDownAct->setText(i18n("Atom Down")); 0146 KActionCollection::setDefaultShortcut(atomDownAct,Qt::Key_Down); 0147 addAction(atomDownAct); 0148 connect(atomDownAct, &QAction::triggered, m_gameWid, &GameWidget::moveDown); 0149 0150 QAction * atomLeftAct = actionCollection()->addAction( QStringLiteral( "atom_left" )); 0151 atomLeftAct->setText(i18n("Atom Left")); 0152 KActionCollection::setDefaultShortcut(atomLeftAct,Qt::Key_Left); 0153 addAction(atomLeftAct); 0154 connect(atomLeftAct, &QAction::triggered, m_gameWid, &GameWidget::moveLeft); 0155 0156 QAction * atomRightAct = actionCollection()->addAction( QStringLiteral( "atom_right" )); 0157 atomRightAct->setText(i18n("Atom Right")); 0158 KActionCollection::setDefaultShortcut(atomRightAct,Qt::Key_Right); 0159 addAction(atomRightAct); 0160 connect(atomRightAct, &QAction::triggered, m_gameWid, &GameWidget::moveRight); 0161 0162 QAction * nextAtomAct = actionCollection()->addAction( QStringLiteral( "next_atom" )); 0163 nextAtomAct->setText(i18n("Next Atom")); 0164 KActionCollection::setDefaultShortcut(nextAtomAct,Qt::Key_Tab); 0165 addAction(nextAtomAct); 0166 connect(nextAtomAct, &QAction::triggered, m_gameWid->playfield(), &PlayField::nextAtom); 0167 0168 QAction * prevAtomAct = actionCollection()->addAction( QStringLiteral( "prev_atom" )); 0169 prevAtomAct->setText(i18n("Previous Atom")); 0170 KActionCollection::setDefaultShortcut(prevAtomAct, Qt::SHIFT | Qt::Key_Tab); 0171 addAction(prevAtomAct); 0172 connect(prevAtomAct, &QAction::triggered, m_gameWid->playfield(), &PlayField::previousAtom); 0173 } 0174 0175 void AtomTopLevel::loadSettings() 0176 { 0177 m_animSpeedAct->setCurrentItem( Preferences::animationSpeed() ); 0178 m_gameWid->playfield()->setAnimationSpeed( Preferences::animationSpeed() ); 0179 } 0180 0181 void AtomTopLevel::slotAnimSpeedChanged(int speed) 0182 { 0183 m_gameWid->playfield()->setAnimationSpeed(speed); 0184 Preferences::setAnimationSpeed(speed); 0185 Preferences::self()->save(); 0186 } 0187 0188 void AtomTopLevel::updateStatusBar( int level, int score, int highscore ) 0189 { 0190 mLevel->setText(i18n("Level: %1 (%2)", level, m_gameWid->levelSet().visibleName())); 0191 mCurrentScore->setText(i18n("Current score: %1", score)); 0192 QString str; 0193 if(highscore == 0) 0194 str = QLatin1Char('-'); 0195 else 0196 str.setNum(highscore); 0197 mHighScore->setText(i18n("Highscore: %1", str)); 0198 } 0199 0200 void AtomTopLevel::enableHackMode() 0201 { 0202 //qCDebug(KATOMIC_LOG) << "Enabling hack mode"; 0203 m_prevLevelAct->setDisabled(false); 0204 m_nextLevelAct->setDisabled(false); 0205 m_gameWid->enableSwitchToAnyLevel(); 0206 } 0207 0208 void AtomTopLevel::levelHasChanged(int level) 0209 { 0210 // Update level name 0211 mMoleculeName->setText(m_gameWid->currentMolecule()); 0212 // don't gray out actions in hackmode, else do 0213 if(!m_gameWid->switchToAnyLevelAllowed()) 0214 updateActionsForLevel(level); 0215 } 0216 0217 void AtomTopLevel::updateActionsForLevel(int) 0218 { 0219 m_prevLevelAct->setEnabled( m_gameWid->isPrevLevelAvailable() ); 0220 m_nextLevelAct->setEnabled( m_gameWid->isNextLevelAvailable() ); 0221 } 0222 0223 void AtomTopLevel::chooseLevelSet() 0224 { 0225 // will delete itself on close 0226 ChooseLevelSetDialog* dlg = new ChooseLevelSetDialog(this); 0227 connect(dlg, &ChooseLevelSetDialog::levelSetChanged, this, &AtomTopLevel::changeLevelSet); 0228 0229 dlg->setCurrentLevelSet(m_gameWid->levelSet().name()); 0230 dlg->show(); 0231 } 0232 0233 void AtomTopLevel::changeLevelSet(const QString& levelSet) 0234 { 0235 if (!levelSet.isEmpty()) 0236 m_gameWid->setLevelSet(levelSet); 0237 } 0238 0239 #include "moc_toplevel.cpp"