Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

minesweep.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of the Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 #include "minesweep.h"
00022 #include "minefield.h"
00023 
00024 #include <opie2/oresource.h>
00025 
00026 #include <qtopia/qpeapplication.h>
00027 #include <qtopia/config.h>
00028 
00029 #include <qtoolbar.h>
00030 #include <qmenubar.h>
00031 #include <qpushbutton.h>
00032 #include <qlcdnumber.h>
00033 #include <qtimer.h>
00034 #include <qlabel.h>
00035 
00036 #include <stdlib.h>
00037 #include <time.h>
00038 
00039 
00040 
00041 
00042 static const char *pix_new[]={
00043 "20 20 3 1",
00044 "  c None",
00045 "# c #00FF00",
00046 ". c #000000",
00047 "                    ",
00048 "       ......       ",
00049 "     ..######..     ",
00050 "    .##########.    ",
00051 "   .############.   ",
00052 "  .##############.  ",
00053 "  .##############.  ",
00054 " .################. ",
00055 " .################. ",
00056 " .################. ",
00057 " .################. ",
00058 " .################. ",
00059 " .################. ",
00060 "  .##############.  ",
00061 "  .##############.  ",
00062 "   .############.   ",
00063 "    .##########.    ",
00064 "     ..######..     ",
00065 "       ......       ",
00066 "                    "};
00067 
00068 
00069 /* XPM */
00070 static const char * happy_xpm[] = {
00071 "20 20 3 1",
00072 "       c None",
00073 ".      c #ffff3f      ",
00074 "#      c #000000",
00075 "                    ",
00076 "       ######       ",
00077 "     ##......##     ",
00078 "    #..........#    ",
00079 "   #............#   ",
00080 "  #..............#  ",
00081 "  #..............#  ",
00082 " #....##....##....# ",
00083 " #....##....##....# ",
00084 " #................# ",
00085 " #................# ",
00086 " #................# ",
00087 " #...#........#...# ",
00088 "  #.##........##.#  ",
00089 "  #...########...#  ",
00090 "   #...######...#   ",
00091 "    #..........#    ",
00092 "     ##......##     ",
00093 "       ######       ",
00094 "                    "};
00095 
00096 
00097 /* XPM */
00098 static const char * worried_xpm[] = {
00099 "20 20 3 1",
00100 "       c None",
00101 ".      c #ffff3f",
00102 "#      c #000000",
00103 "                    ",
00104 "       ######       ",
00105 "     ##......##     ",
00106 "    #..........#    ",
00107 "   #............#   ",
00108 "  #..............#  ",
00109 "  #..............#  ",
00110 " #....##....##....# ",
00111 " #....##....##....# ",
00112 " #................# ",
00113 " #................# ",
00114 " #................# ",
00115 " #................# ",
00116 "  #....######....#  ",
00117 "  #..............#  ",
00118 "   #............#   ",
00119 "    #..........#    ",
00120 "     ##......##     ",
00121 "       ######       ",
00122 "                    "};
00123 
00124 
00125 /* XPM */
00126 static const char * dead_xpm[] = {
00127 "20 20 3 1",
00128 "       c None",
00129 ".      c #ffff3f",
00130 "#      c #000000",
00131 "                    ",
00132 "       ######       ",
00133 "     ##......##     ",
00134 "    #..........#    ",
00135 "   #............#   ",
00136 "  #..............#  ",
00137 "  #..#.#...#.#...#  ",
00138 " #....#.....#.....# ",
00139 " #...#.#...#.#....# ",
00140 " #................# ",
00141 " #................# ",
00142 " #................# ",
00143 " #......####......# ",
00144 "  #....#    #....#  ",
00145 "  #...#......#...#  ",
00146 "   #............#   ",
00147 "    #..........#    ",
00148 "     ##......##     ",
00149 "       ######       ",
00150 "                    "};
00151 
00152 
00153 class ResultIndicator : private QLabel
00154 {
00155 public:
00156     static void showResult( QWidget *ref, bool won );
00157 private:
00158     ResultIndicator( QWidget *parent, const char *name, WFlags f)
00159         :QLabel( parent, name, f ) {}
00160 
00161     void timerEvent( QTimerEvent *);
00162     void center();
00163     bool twoStage;
00164     int timerId;
00165 };
00166 
00167 void ResultIndicator::showResult( QWidget *ref, bool won )
00168 {
00169     ResultIndicator *r = new ResultIndicator( ref, 0, WStyle_Customize | WStyle_Tool | WType_TopLevel );
00170 
00171     r->setAlignment( AlignCenter );
00172     r->setFrameStyle( Sunken|StyledPanel );
00173     if ( won ) {
00174         r->setText( MineSweep::tr("You won!") );
00175         r->center();
00176         r->show();
00177         r->twoStage = FALSE;
00178         r->timerId = r->startTimer(1500);
00179     } else {
00180         QPalette p( red );
00181         r->setPalette( p );
00182         r->setText( MineSweep::tr("You exploded!") );
00183         r->resize( ref->size() );
00184         r->move( ref->mapToGlobal(QPoint(0,0)) );
00185         r->show();
00186         r->twoStage = TRUE;
00187         r->timerId =r->startTimer(200);
00188     }
00189 }
00190 
00191 void ResultIndicator::center()
00192 {
00193     QWidget *w = parentWidget();
00194 
00195     QPoint pp = w->mapToGlobal( QPoint(0,0) );
00196     QSize s = sizeHint()*3;
00197     s.setWidth( QMIN(s.width(), w->width()) );
00198     pp = QPoint( pp.x() + w->width()/2 - s.width()/2,
00199                 pp.y() + w->height()/ 2 - s.height()/2 );
00200 
00201     setGeometry( QRect(pp, s) );
00202 
00203 }
00204 
00205 void ResultIndicator::timerEvent( QTimerEvent *te )
00206 {
00207     if ( te->timerId() != timerId )
00208         return;
00209     killTimer( timerId );
00210     if ( twoStage ) {
00211         center();
00212         twoStage = FALSE;
00213         timerId = startTimer( 1000 );
00214     } else {
00215         delete this;
00216     }
00217 }
00218 
00219 
00220 class MineFrame : public QFrame
00221 {
00222 public:
00223     MineFrame( QWidget *parent, const char *name = 0 )
00224         :QFrame( parent, name ), field(0) {}
00225     void setField( MineField *f ) {
00226         field = f;
00227         setMinimumSize( field->sizeHint() );
00228     }
00229 protected:
00230     void resizeEvent( QResizeEvent *e ) {
00231         field->setAvailableRect( contentsRect());
00232         QFrame::resizeEvent(e);
00233     }
00234 private:
00235     MineField *field;
00236 };
00237 
00238 
00239 
00240 MineSweep::MineSweep( QWidget* parent, const char* name, WFlags f )
00241 : QMainWindow( parent, name, f )
00242 {
00243     srand(::time(0));
00244     setCaption( tr("Mine Sweep") );
00245     QPEApplication::setInputMethodHint(this, QPEApplication::AlwaysOff );
00246     setIcon( Opie::Core::OResource::loadPixmap( "minesweep/MineSweep" ) );
00247 
00248     QToolBar *toolBar = new QToolBar( this );
00249     toolBar->setHorizontalStretchable( TRUE );
00250 
00251     QMenuBar *menuBar = new QMenuBar( toolBar );
00252 
00253     QPopupMenu *gameMenu = new QPopupMenu( this );
00254     gameMenu->insertItem( tr("Beginner"), this, SLOT( beginner() ) );
00255     gameMenu->insertItem( tr("Advanced"), this, SLOT( advanced() ) );
00256 
00257     if (qApp->desktop()->width() >= 240) {
00258         gameMenu->insertItem( tr("Expert"), this, SLOT( expert() ) );
00259     }
00260 
00261     menuBar->insertItem( tr("Game"), gameMenu );
00262 
00263     guessLCD = new QLCDNumber( toolBar );
00264     toolBar->setStretchableWidget( guessLCD );
00265 
00266     QPalette lcdPal( red );
00267     lcdPal.setColor( QColorGroup::Background, QApplication::palette().active().background() );
00268     lcdPal.setColor( QColorGroup::Button, QApplication::palette().active().button() );
00269 
00270 //    guessLCD->setPalette( lcdPal );
00271     guessLCD->setSegmentStyle( QLCDNumber::Flat );
00272     guessLCD->setFrameStyle( QFrame::NoFrame );
00273     guessLCD->setNumDigits( 2 );
00274     guessLCD->setBackgroundMode( PaletteButton );
00275     newGameButton = new QPushButton( toolBar );
00276     newGameButton->setPixmap( QPixmap( pix_new ) );
00277     newGameButton->setFocusPolicy(QWidget::NoFocus);
00278     connect( newGameButton, SIGNAL(clicked()), this, SLOT(newGame()) );
00279 
00280     timeLCD = new QLCDNumber( toolBar );
00281 //    timeLCD->setPalette( lcdPal );
00282     timeLCD->setSegmentStyle( QLCDNumber::Flat );
00283     timeLCD->setFrameStyle( QFrame::NoFrame );
00284     timeLCD->setNumDigits( 5 ); // "mm:ss"
00285     timeLCD->setBackgroundMode( PaletteButton );
00286 
00287     setToolBarsMovable ( FALSE );
00288 
00289     addToolBar( toolBar );
00290 
00291     MineFrame *mainframe = new MineFrame( this );
00292     mainframe->setFrameShape( QFrame::Box );
00293     mainframe->setFrameShadow( QFrame::Raised );
00294 
00295     mainframe->setLineWidth(2);
00296 
00297     field = new MineField( mainframe );
00298     mainframe->setField( field );
00299     QFont fnt = field->font();
00300     fnt.setBold( TRUE );
00301     field->setFont( QFont( fnt ) );
00302     field->setFocus();
00303     setCentralWidget( mainframe );
00304 
00305     connect( field, SIGNAL( gameOver(bool) ), this, SLOT( gameOver(bool) ) );
00306     connect( field, SIGNAL( mineCount(int) ), this, SLOT( setCounter(int) ) );
00307     connect( field, SIGNAL( gameStarted()), this, SLOT( startPlaying() ) );
00308 
00309     timer = new QTimer( this );
00310     connect( timer, SIGNAL( timeout() ), this, SLOT( updateTime() ) );
00311 
00312     readConfig();
00313 }
00314 
00315 MineSweep::~MineSweep()
00316 {
00317     writeConfig();
00318 }
00319 
00320 void MineSweep::gameOver( bool won )
00321 {
00322     field->showMines();
00323     if ( won ) {
00324         newGameButton->setPixmap( QPixmap( happy_xpm ) );
00325     } else {
00326         newGameButton->setPixmap( QPixmap( dead_xpm ) );
00327     }
00328     ResultIndicator::showResult( this, won );
00329     timer->stop();
00330 }
00331 
00332 void MineSweep::newGame()
00333 {
00334     newGame(field->level());
00335 }
00336 
00337 void MineSweep::newGame(int level)
00338 {
00339     timeLCD->display( "0:00" );
00340     field->setup( level );
00341     newGameButton->setPixmap( QPixmap( pix_new ) );
00342     timer->stop();
00343 }
00344 
00345 void MineSweep::startPlaying()
00346 {
00347     newGameButton->setPixmap( QPixmap( worried_xpm ) );
00348     starttime = QDateTime::currentDateTime();
00349     timer->start( 1000 );
00350 }
00351 
00352 void MineSweep::beginner()
00353 {
00354     newGame(1);
00355 }
00356 
00357 void MineSweep::advanced()
00358 {
00359     newGame(2);
00360 }
00361 
00362 void MineSweep::expert()
00363 {
00364     newGame(3);
00365 }
00366 
00367 void MineSweep::setCounter( int c )
00368 {
00369     if ( !guessLCD )
00370         return;
00371 
00372     guessLCD->display( c );
00373 }
00374 
00375 void MineSweep::updateTime()
00376 {
00377     if ( !timeLCD )
00378         return;
00379 
00380     int s = starttime.secsTo(QDateTime::currentDateTime());
00381     if ( s/60 > 99 )
00382         timeLCD->display( "-----" );
00383     else
00384         timeLCD->display( QString().sprintf("%2d:%02d",s/60,s%60) );
00385 }
00386 
00387 void MineSweep::writeConfig() const
00388 {
00389     Config cfg("MineSweep");
00390     cfg.setGroup("Panel");
00391     cfg.writeEntry("Time",
00392         timer->isActive() ? starttime.secsTo(QDateTime::currentDateTime()) : -1);
00393     field->writeConfig(cfg);
00394 }
00395 
00396 void MineSweep::readConfig()
00397 {
00398     Config cfg("MineSweep");
00399     field->readConfig(cfg);
00400     cfg.setGroup("Panel");
00401     int s = cfg.readNumEntry("Time",-1);
00402     if ( s<0 ) {
00403         newGame();
00404     } else {
00405         startPlaying();
00406         starttime = QDateTime::currentDateTime().addSecs(-s);
00407         updateTime();
00408     }
00409 }

Generated on Sat Nov 5 16:17:23 2005 for OPIE by  doxygen 1.4.2