Now supports multiple levels.
[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 QGraphicsView ();
47
48     pView_->setScene(pScene_);
49     setCentralWidget(pView_);
50
51     pPauseAction_ = new QAction(tr("Pause"),this);
52     pPauseAction_->setCheckable(true);
53     addAction(pPauseAction_);
54     connect(pPauseAction_,SIGNAL(triggered(bool)),pScene_,SLOT(pause(bool)));
55     menuBar()->addAction(pPauseAction_);
56
57     QAction * pRestartLevelAction = new QAction(tr("Restart level"),this);
58     addAction(pRestartLevelAction);
59     connect(pRestartLevelAction,SIGNAL(triggered()),this,SLOT(restartLevel()));
60     menuBar()->addAction(pRestartLevelAction);
61
62
63     QAction * pAboutAction = new QAction(tr("About"),this);
64     addAction(pAboutAction);
65     connect(pAboutAction,SIGNAL(triggered()),this,SLOT(about()));
66     menuBar()->addAction(pAboutAction);
67
68     QAction * pRestartGameAction = new QAction(tr("Restart game"),this);
69     addAction(pRestartGameAction);
70     connect(pRestartGameAction,SIGNAL(triggered()),this,SLOT(restartGame()));
71     menuBar()->addAction(pRestartGameAction);
72
73     Level level1(5,10);
74     levelList_.append(level1);
75     Level level2(5,10,2,50);
76     levelList_.append(level2);
77     Level level3(5,15,3,100);
78     levelList_.append(level3);
79     Level level4(10,15,5,50);
80     levelList_.append(level4);
81     Level level5(10,15,5,100);
82     levelList_.append(level5);
83
84     currentLevel_ = 0;
85
86     //the boundaries of the scene are set to match the size of the view window, which is not
87     //available in the constructor --> timer needed
88     QTimer::singleShot(100,this,SLOT(initializeBoundaries()));
89 }
90
91 MainWindow::~MainWindow()
92 {
93
94 }
95
96 void MainWindow::initializeBoundaries()
97 {
98         //the boundaries of the scene are set to match the size of the view window, and
99         //the view is set to show exactly the whole scene area
100
101     //this occasionally gives a tiny scene, so using a fixed size fit for N900/Maemo5 until a fix is found
102
103 //    QPoint topleft (0,0);
104 //    QSize windowsize = pView_->size();
105 //    QRectF rectangle (topleft,windowsize);
106
107     QRectF rectangle(0,0,800,424);
108
109     pScene_->setSceneRect(rectangle);
110     pView_->setSceneRect(rectangle);
111
112     // qDebug() << "Initialized boundaries" << rectangle.right() << rectangle.bottom() << pView_->width() << pView_->height();
113
114     restartLevel();
115 }
116
117
118 void MainWindow::restartLevel()
119 {
120     pScene_->setupMap(levelList_.at(currentLevel_));
121 }
122
123 void MainWindow::about()
124 {
125     QMessageBox::about(this, tr("About %1").arg(QApplication::applicationName()),
126                        tr("Version %1"
127                           "<p>Copyright 2011 Heli Hyv&auml;ttinen"
128                           "<p>License: General Public License v2"
129                           "<p>Bug Reports: https://bugs.maemo.org/ "
130                           "enter_bug.cgi?product=Ghosts%20Overboard"
131                           ).arg(QApplication::applicationVersion()));
132
133
134
135 }
136
137 void MainWindow::nextLevel()
138 {
139
140     currentLevel_++;
141
142     if (levelList_.empty())
143         pScene_->setupMap(Level());
144
145
146     if ( currentLevel_ < levelList_.size() )
147     {
148         pScene_->setupMap(levelList_.at(currentLevel_));
149     }
150
151     else //Victory!
152     {
153
154        QDialog* pVictoryDialog = new QDialog(this);
155        pVictoryDialog->setWindowTitle(tr("You won!"));
156
157
158        QPushButton* pPlayAgainButton = new QPushButton(tr("Play again"));
159 //       QPushButton* pQuitButton = new QPushButton(tr("Quit game"));
160
161        QPixmap victoryIcon (":/pix/aavesaari.png");
162        QLabel* pVictoryLabel = new QLabel();
163        pVictoryLabel->setPixmap(victoryIcon);
164
165        QLabel* pTextLabel = new QLabel(tr("Congratulations! <p>You have saved all the ghosts."));
166
167
168        QVBoxLayout* pMainLayout = new QVBoxLayout;
169
170        QHBoxLayout* pTopLayout = new QHBoxLayout;
171        pMainLayout->addLayout(pTopLayout);
172
173        pTopLayout->addWidget(pVictoryLabel);
174        pTopLayout->addWidget(pTextLabel);
175
176
177
178        QHBoxLayout* pButtonLayout = new QHBoxLayout();
179        pMainLayout->addLayout(pButtonLayout);
180
181  //      pButtonLayout->addWidget(pQuitButton);
182        pButtonLayout->addWidget(pPlayAgainButton);
183
184
185
186        pVictoryDialog->setLayout(pMainLayout);
187
188        connect(pPlayAgainButton, SIGNAL(clicked()),pVictoryDialog,SLOT(accept()));
189
190        pVictoryDialog->exec();
191
192         //Never mind if the user cancels the dialog: restart the game anyway
193
194        restartGame();
195     }
196 }
197
198 bool MainWindow::event(QEvent *event)
199 {
200
201     switch (event->type())
202     {
203         //pause if app goes to background
204         case QEvent::WindowDeactivate:
205
206             if (pScene_)
207                 pScene_->pause(true);
208             break;
209
210         //un-pause if app gomes back to foreground unless it was paused before going to background
211         case QEvent::WindowActivate:
212
213
214             if (pPauseAction_ && !pPauseAction_->isChecked())
215             {
216                 if (pScene_)
217                     pScene_->pause(false);
218             }
219             break;
220
221         //Just to keep the compiler from complaining...
222         default:
223             break;
224
225      }
226
227
228
229     //pass the event to the ancestor for handling
230     return QMainWindow::event(event);
231
232  }
233
234 void MainWindow::restartGame()
235 {
236     currentLevel_ = 0;
237     pScene_->setupMap(levelList_.value(currentLevel_)); //value() returns default constructor Level, so no need to check if list empty
238
239 }