work towards new pause and menu systems
[ghostsoverboard] / mainwindow.cpp
1 /**************************************************************************
2         Ghosts Overboard - a game for Maemo 5
3
4         Copyright (C) 2011  Heli Hyvättinen
5
6         This file is part of Ghosts Overboard
7
8         Ghosts Overboard is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 2 of the License, or
11         (at your option) any later version.
12
13         This program is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21 **************************************************************************/
22
23 #include "mainwindow.h"
24 #include <QPixmap>
25 #include <QTimer>
26 #include <QDebug>
27 #include <QAction>
28 #include <QMenuBar>
29 #include <QMessageBox>
30 #include <QApplication>
31 #include <QLabel>
32 #include <QPushButton>
33 #include <QVBoxLayout>
34
35
36
37 MainWindow::MainWindow(QWidget *parent)
38     : QMainWindow(parent)
39 {
40     setWindowIcon(QIcon(":/pix/laiva_3aave.png"));
41     setWindowTitle("Ghosts Overboard");
42
43     pScene_ = new SeaScene ();
44     connect(pScene_,SIGNAL(allGhostsPicked()),this,SLOT(nextLevel()));
45
46     pView_  = new SeaView ();
47
48
49     pView_->setScene(pScene_);
50     setCentralWidget(pView_);
51
52     pPauseAction_ = new QAction(tr("Pause"),this);
53     pPauseAction_->setCheckable(true);
54     addAction(pPauseAction_);
55     connect(pPauseAction_,SIGNAL(triggered(bool)),pScene_,SLOT(pause(bool)));
56     menuBar()->addAction(pPauseAction_);
57     connect(pView_,SIGNAL(pauseChanged()),pPauseAction_,SLOT(toggle()));
58
59     QAction * pRestartLevelAction = new QAction(tr("Restart level"),this);
60     addAction(pRestartLevelAction);
61     connect(pRestartLevelAction,SIGNAL(triggered()),this,SLOT(restartLevel()));
62     menuBar()->addAction(pRestartLevelAction);
63
64     QAction * pRestartGameAction = new QAction(tr("Restart game"),this);
65     addAction(pRestartGameAction);
66     connect(pRestartGameAction,SIGNAL(triggered()),this,SLOT(restartGame()));
67     menuBar()->addAction(pRestartGameAction);
68
69     pVibrateAction_ = new QAction(tr("Vibration effects"),this);
70     pVibrateAction_->setCheckable(true);
71     addAction(pVibrateAction_);
72     connect(pVibrateAction_,SIGNAL(triggered(bool)),pScene_,SLOT(vibrationActivate(bool)));
73     menuBar()->addAction(pVibrateAction_);
74
75
76     QAction * pAboutAction = new QAction(tr("About"),this);
77     addAction(pAboutAction);
78     connect(pAboutAction,SIGNAL(triggered()),this,SLOT(about()));
79     menuBar()->addAction(pAboutAction);
80
81
82
83     Level level1(5,10);
84     levelList_.append(level1);
85     Level level2(5,10,2,50);
86     levelList_.append(level2);
87     Level level3(5,15,2,50);
88     levelList_.append(level3);
89     Level level4(5,15,4,50);
90     levelList_.append(level4);
91     Level level5(5,15,5,100);
92     levelList_.append(level5);
93
94     currentLevel_ = 0;
95
96
97     //the boundaries of the scene are set to match the size of the view window, which is not
98     //available in the constructor --> timer needed
99     QTimer::singleShot(100,this,SLOT(initializeBoundaries()));
100 }
101
102 MainWindow::~MainWindow()
103 {
104
105 }
106
107 void MainWindow::initializeBoundaries()
108 {
109         //the boundaries of the scene are set to match the size of the view window, and
110         //the view is set to show exactly the whole scene area
111
112     //this occasionally gives a tiny scene, so using a fixed size fit for N900/Maemo5 until a fix is found
113
114 //    QPoint topleft (0,0);
115 //    QSize windowsize = pView_->size();
116 //    QRectF rectangle (topleft,windowsize);
117
118     QRectF rectangle(0,0,800,424);
119
120     pScene_->setSceneRect(rectangle);
121     pView_->setSceneRect(rectangle);
122
123     // qDebug() << "Initialized boundaries" << rectangle.right() << rectangle.bottom() << pView_->width() << pView_->height();
124
125     restartLevel();
126 }
127
128
129 void MainWindow::restartLevel()
130 {
131     pScene_->setupMap(levelList_.value(currentLevel_));  //value() returns default constructor Level if index is invalid, so no risk of crash
132     pScene_->vibrationActivate(pVibrateAction_->isChecked());  //Vibration effects are lost without this
133    // qDebug() << pVibrateAction_->isChecked();
134 }
135
136 void MainWindow::about()
137 {
138     QMessageBox::about(this, tr("About %1").arg(QApplication::applicationName()),
139                        tr("Version %1"
140                           "<p>Copyright 2011 Heli Hyv&auml;ttinen"
141                           "<p>License: General Public License v2"
142                           "<p>Bug Reports: https://bugs.maemo.org/ "
143                           "enter_bug.cgi?product=Ghosts%20Overboard"
144                           ).arg(QApplication::applicationVersion()));
145
146
147
148 }
149
150 void MainWindow::nextLevel()
151 {
152
153     currentLevel_++;
154
155     if (levelList_.empty())
156         pScene_->setupMap(Level());
157
158
159     if ( currentLevel_ < levelList_.size() )
160     {
161        restartLevel();
162     }
163
164     else //Victory!
165     {
166
167        QDialog* pVictoryDialog = new QDialog(this);
168        pVictoryDialog->setWindowTitle(tr("You won!"));
169
170
171        QPushButton* pPlayAgainButton = new QPushButton(tr("Play again"));
172 //       QPushButton* pQuitButton = new QPushButton(tr("Quit game"));
173
174        QPixmap victoryIcon (":/pix/aavesaari.png");
175        QLabel* pVictoryLabel = new QLabel();
176        pVictoryLabel->setPixmap(victoryIcon);
177
178        QLabel* pTextLabel = new QLabel(tr("Congratulations! <p>You have saved all the ghosts."));
179
180
181        QVBoxLayout* pMainLayout = new QVBoxLayout;
182
183        QHBoxLayout* pTopLayout = new QHBoxLayout;
184        pMainLayout->addLayout(pTopLayout);
185
186        pTopLayout->addWidget(pVictoryLabel);
187        pTopLayout->addWidget(pTextLabel);
188
189
190
191        QHBoxLayout* pButtonLayout = new QHBoxLayout();
192        pMainLayout->addLayout(pButtonLayout);
193
194  //      pButtonLayout->addWidget(pQuitButton);
195        pButtonLayout->addWidget(pPlayAgainButton);
196
197
198
199        pVictoryDialog->setLayout(pMainLayout);
200
201        connect(pPlayAgainButton, SIGNAL(clicked()),pVictoryDialog,SLOT(accept()));
202
203        pVictoryDialog->exec();
204
205         //Never mind if the user cancels the dialog: restart the game anyway
206
207        restartGame();
208     }
209 }
210
211 bool MainWindow::event(QEvent *event)
212 {
213
214     switch (event->type())
215     {
216         //pause if app goes to background
217         case QEvent::WindowDeactivate:
218
219             if (pScene_)
220                 pScene_->pause(true);
221             break;
222
223         //un-pause if app gomes back to foreground unless it was paused before going to background
224         case QEvent::WindowActivate:
225
226
227             if (pPauseAction_ && !pPauseAction_->isChecked())
228             {
229                 if (pScene_)
230                     pScene_->pause(false);
231             }
232             break;
233
234         //Just to keep the compiler from complaining...
235         default:
236             break;
237
238      }
239
240
241
242     //pass the event to the ancestor for handling
243     return QMainWindow::event(event);
244
245  }
246
247 void MainWindow::restartGame()
248 {
249     currentLevel_ = 0;
250     restartLevel();
251 }