1 | /* toplevel.cpp |
2 | |
3 | Copyright (C) 1998 Andreas Wüst <AndreasWuest@gmx.de> |
4 | Copyright (C) 2006 Dmitry Suzdalev <dimsuz@gmail.com> |
5 | Copyright (C) 2007 Simon Hürlimann <simon.huerlimann@huerlisi.ch> |
6 | |
7 | This program is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 2 of the License, or |
10 | (at your option) any later version. |
11 | |
12 | This program is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | GNU General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU General Public License |
18 | along with this program; if not, write to the Free Software |
19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
20 | |
21 | */ |
22 | |
23 | #include "toplevel.h" |
24 | |
25 | |
26 | #include <klocale.h> |
27 | #include <kconfig.h> |
28 | #include <kstandarddirs.h> |
29 | #include <kstandardaction.h> |
30 | #include <kstandardgameaction.h> |
31 | #include <kselectaction.h> |
32 | #include <kactioncollection.h> |
33 | #include <kdebug.h> |
34 | #include <kicon.h> |
35 | #include <kstatusbar.h> |
36 | |
37 | #include "gamewidget.h" |
38 | #include "playfield.h" |
39 | #include "prefs.h" |
40 | #include "commondefs.h" |
41 | #include "chooselevelsetdialog.h" |
42 | |
43 | static const int LEVEL_BAR_ID = 0; |
44 | static const int CUR_SCORE_BAR_ID = 1; |
45 | static const int HIGHSCORE_BAR_ID = 2; |
46 | static const int MOLECULE_NAME_ID = 3; |
47 | |
48 | AtomTopLevel::AtomTopLevel() |
49 | { |
50 | QString lastPlayedLevelSet = Preferences::lastPlayedLevelSet(); |
51 | if (lastPlayedLevelSet.isEmpty()) |
52 | lastPlayedLevelSet = DEFAULT_LEVELSET_NAME; |
53 | |
54 | m_gameWid = new GameWidget( lastPlayedLevelSet, this); |
55 | m_gameWid->setObjectName( QLatin1String("gamewidget" )); |
56 | createMenu(); |
57 | loadSettings(); |
58 | setCentralWidget(m_gameWid); |
59 | |
60 | statusBar()->insertItem( i18n("Level:" ), LEVEL_BAR_ID , 1); |
61 | statusBar()->insertPermanentItem( i18n("Current score:" ), CUR_SCORE_BAR_ID, 1); |
62 | statusBar()->insertPermanentItem( i18n("Highscore:" ), HIGHSCORE_BAR_ID, 1 ); |
63 | statusBar()->insertItem( QString(), MOLECULE_NAME_ID , 1); |
64 | statusBar()->setItemAlignment(0, Qt::AlignLeft | Qt::AlignVCenter); |
65 | |
66 | updateStatusBar( m_gameWid->currentLevel(), m_gameWid->currentScore(), m_gameWid->currentHighScore() ); |
67 | |
68 | connect(m_gameWid, SIGNAL(statsChanged(int,int,int)), SLOT(updateStatusBar(int,int,int))); |
69 | connect(m_gameWid, SIGNAL(levelChanged(int)), SLOT(levelHasChanged(int))); |
70 | |
71 | // update next/prev actions |
72 | levelHasChanged(m_gameWid->currentLevel()); |
73 | setupGUI(); |
74 | } |
75 | |
76 | AtomTopLevel::~AtomTopLevel() |
77 | { |
78 | } |
79 | |
80 | bool AtomTopLevel::queryClose() |
81 | { |
82 | // saves last played level and levelset |
83 | m_gameWid->saveLastPlayedLevel(); |
84 | Preferences::self()->writeConfig(); |
85 | return true; |
86 | } |
87 | |
88 | void AtomTopLevel::() |
89 | { |
90 | // Game |
91 | KStandardGameAction::restart(m_gameWid, SLOT(restartLevel()), actionCollection()); |
92 | // FIXME: comment this until highscore dialog will be implemented. |
93 | // (katomic needs spesial one) |
94 | // KStandardGameAction::highscores(m_gameWid, SLOT(showHighscores()), actionCollection()); |
95 | KStandardGameAction::load(m_gameWid, SLOT(loadGame()), actionCollection()); |
96 | KStandardGameAction::save(m_gameWid, SLOT(saveGame()), actionCollection()); |
97 | KStandardGameAction::quit(this, SLOT(close()), actionCollection()); |
98 | |
99 | // Move |
100 | m_undoAct = KStandardGameAction::undo(m_gameWid->playfield(), SLOT(undo()), actionCollection()); |
101 | m_redoAct = KStandardGameAction::redo(m_gameWid->playfield(), SLOT(redo()), actionCollection()); |
102 | |
103 | |
104 | m_prevLevelAct = actionCollection()->addAction( QLatin1String( "prev_level" ) ); |
105 | m_prevLevelAct->setIcon( KIcon( QLatin1String( "arrow-left" ) ) ); |
106 | m_prevLevelAct->setText( i18n( "Previous Level" ) ); |
107 | m_prevLevelAct->setShortcut( Qt::CTRL + Qt::Key_P ); |
108 | addAction( m_prevLevelAct ); |
109 | connect( m_prevLevelAct, SIGNAL(triggered(bool)), m_gameWid, SLOT(prevLevel()) ); |
110 | |
111 | m_nextLevelAct = actionCollection()->addAction( QLatin1String( "next_level" ) ); |
112 | m_nextLevelAct->setIcon( KIcon( QLatin1String( "arrow-right" ) ) ); |
113 | m_nextLevelAct->setText( i18n( "Next Level" ) ); |
114 | m_nextLevelAct->setShortcut( Qt::CTRL + Qt::Key_N ); |
115 | addAction( m_nextLevelAct ); |
116 | connect( m_nextLevelAct, SIGNAL(triggered(bool)), m_gameWid, SLOT(nextLevel()) ); |
117 | |
118 | QAction* chooseLevelSet = actionCollection()->addAction( QLatin1String( "choose_level_set" ) ); |
119 | chooseLevelSet->setText( i18n( "Choose level set..." ) ); |
120 | addAction( chooseLevelSet ); |
121 | connect( chooseLevelSet, SIGNAL(triggered(bool)), SLOT(chooseLevelSet()) ); |
122 | |
123 | m_animSpeedAct = new KSelectAction(i18n("Animation Speed" ), this); |
124 | actionCollection()->addAction( QLatin1String( "anim_speed" ), m_animSpeedAct); |
125 | QStringList acts; |
126 | acts << i18n("Slow" ) << i18n("Normal" ) << i18n("Fast" ); |
127 | m_animSpeedAct->setItems(acts); |
128 | connect( m_animSpeedAct, SIGNAL(triggered(int)), SLOT(slotAnimSpeedChanged(int)) ); |
129 | |
130 | QAction *undoAll = actionCollection()->addAction( QLatin1String( "move_undo_all" ) ); |
131 | undoAll->setIcon( KIcon( QLatin1String( "media-skip-backward" )) ); |
132 | undoAll->setText( i18n("Undo All" ) ); |
133 | connect( undoAll, SIGNAL(triggered(bool)), m_gameWid->playfield(), SLOT(undoAll()) ); |
134 | |
135 | QAction *redoAll = actionCollection()->addAction( QLatin1String( "move_redo_all" ) ); |
136 | redoAll->setIcon( KIcon( QLatin1String( "media-skip-forward" )) ); |
137 | redoAll->setText( i18n("Redo All" ) ); |
138 | connect( redoAll, SIGNAL(triggered(bool)), m_gameWid->playfield(), SLOT(redoAll()) ); |
139 | |
140 | m_undoAct->setEnabled(false); |
141 | m_redoAct->setEnabled(false); |
142 | undoAll->setEnabled(false); |
143 | redoAll->setEnabled(false); |
144 | |
145 | connect (m_gameWid->playfield(), SIGNAL (enableRedo(bool)), m_redoAct, SLOT(setEnabled(bool))); |
146 | connect (m_gameWid->playfield(), SIGNAL (enableUndo(bool)), m_undoAct, SLOT(setEnabled(bool))); |
147 | connect (m_gameWid->playfield(), SIGNAL (enableUndo(bool)), undoAll, SLOT(setEnabled(bool))); |
148 | connect (m_gameWid->playfield(), SIGNAL (enableRedo(bool)), redoAll, SLOT(setEnabled(bool))); |
149 | |
150 | KAction* atomUpAct = actionCollection()->addAction( QLatin1String( "atom_up" )); |
151 | atomUpAct->setText(i18n("Atom Up" )); |
152 | atomUpAct->setShortcut(Qt::Key_Up); |
153 | addAction(atomUpAct); |
154 | connect(atomUpAct, SIGNAL(triggered(bool)), m_gameWid, SLOT(moveUp())); |
155 | |
156 | KAction* atomDownAct = actionCollection()->addAction( QLatin1String( "atom_down" )); |
157 | atomDownAct->setText(i18n("Atom Down" )); |
158 | atomDownAct->setShortcut(Qt::Key_Down); |
159 | addAction(atomDownAct); |
160 | connect(atomDownAct, SIGNAL(triggered(bool)), m_gameWid, SLOT(moveDown())); |
161 | |
162 | KAction* atomLeftAct = actionCollection()->addAction( QLatin1String( "atom_left" )); |
163 | atomLeftAct->setText(i18n("Atom Left" )); |
164 | atomLeftAct->setShortcut(Qt::Key_Left); |
165 | addAction(atomLeftAct); |
166 | connect(atomLeftAct, SIGNAL(triggered(bool)), m_gameWid, SLOT(moveLeft())); |
167 | |
168 | KAction* atomRightAct = actionCollection()->addAction( QLatin1String( "atom_right" )); |
169 | atomRightAct->setText(i18n("Atom Right" )); |
170 | atomRightAct->setShortcut(Qt::Key_Right); |
171 | addAction(atomRightAct); |
172 | connect(atomRightAct, SIGNAL(triggered(bool)), m_gameWid, SLOT(moveRight())); |
173 | |
174 | KAction* nextAtomAct = actionCollection()->addAction( QLatin1String( "next_atom" )); |
175 | nextAtomAct->setText(i18n("Next Atom" )); |
176 | nextAtomAct->setShortcut(Qt::Key_Tab); |
177 | addAction(nextAtomAct); |
178 | connect(nextAtomAct, SIGNAL(triggered(bool)), m_gameWid->playfield(), SLOT(nextAtom())); |
179 | |
180 | KAction* prevAtomAct = actionCollection()->addAction( QLatin1String( "prev_atom" )); |
181 | prevAtomAct->setText(i18n("Previous Atom" )); |
182 | prevAtomAct->setShortcut(Qt::SHIFT+Qt::Key_Tab); |
183 | addAction(prevAtomAct); |
184 | connect(prevAtomAct, SIGNAL(triggered(bool)), m_gameWid->playfield(), SLOT(previousAtom())); |
185 | } |
186 | |
187 | void AtomTopLevel::loadSettings() |
188 | { |
189 | m_animSpeedAct->setCurrentItem( Preferences::animationSpeed() ); |
190 | m_gameWid->playfield()->setAnimationSpeed( Preferences::animationSpeed() ); |
191 | } |
192 | |
193 | void AtomTopLevel::slotAnimSpeedChanged(int speed) |
194 | { |
195 | m_gameWid->playfield()->setAnimationSpeed(speed); |
196 | Preferences::setAnimationSpeed(speed); |
197 | Preferences::self()->writeConfig(); |
198 | } |
199 | |
200 | void AtomTopLevel::updateStatusBar( int level, int score, int highscore ) |
201 | { |
202 | statusBar()->changeItem( i18n("Level: %1 (%2)" , level, m_gameWid->levelSet().visibleName()), LEVEL_BAR_ID ); |
203 | statusBar()->changeItem( i18n("Current score: %1" , score), CUR_SCORE_BAR_ID ); |
204 | QString str; |
205 | if(highscore == 0) |
206 | str = '-'; |
207 | else |
208 | str.setNum(highscore); |
209 | statusBar()->changeItem( i18n("Highscore: %1" , str), HIGHSCORE_BAR_ID ); |
210 | } |
211 | |
212 | void AtomTopLevel::enableHackMode() |
213 | { |
214 | kDebug() << "Enabling hack mode" ; |
215 | m_prevLevelAct->setDisabled(false); |
216 | m_nextLevelAct->setDisabled(false); |
217 | m_gameWid->enableSwitchToAnyLevel(); |
218 | } |
219 | |
220 | void AtomTopLevel::levelHasChanged(int level) |
221 | { |
222 | // Update level name |
223 | statusBar()->changeItem( m_gameWid->currentMolecule(), MOLECULE_NAME_ID); |
224 | // don't gray out actions in hackmode, else do |
225 | if(!m_gameWid->switchToAnyLevelAllowed()) |
226 | updateActionsForLevel(level); |
227 | } |
228 | |
229 | void AtomTopLevel::updateActionsForLevel(int) |
230 | { |
231 | m_prevLevelAct->setEnabled( m_gameWid->isPrevLevelAvailable() ); |
232 | m_nextLevelAct->setEnabled( m_gameWid->isNextLevelAvailable() ); |
233 | } |
234 | |
235 | void AtomTopLevel::chooseLevelSet() |
236 | { |
237 | // will delete itself on close |
238 | ChooseLevelSetDialog* dlg = new ChooseLevelSetDialog(this); |
239 | connect(dlg, SIGNAL(levelSetChanged(QString)), SLOT(changeLevelSet(QString))); |
240 | |
241 | dlg->setCurrentLevelSet(m_gameWid->levelSet().name()); |
242 | dlg->show(); |
243 | } |
244 | |
245 | void AtomTopLevel::changeLevelSet(const QString& levelSet) |
246 | { |
247 | if (!levelSet.isEmpty()) |
248 | m_gameWid->setLevelSet(levelSet); |
249 | } |
250 | |
251 | #include "toplevel.moc" |
252 | |