summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/minesweep/minefield.cpp144
-rw-r--r--noncore/games/minesweep/minefield.h7
-rw-r--r--noncore/games/minesweep/minesweep.cpp34
3 files changed, 110 insertions, 75 deletions
diff --git a/noncore/games/minesweep/minefield.cpp b/noncore/games/minesweep/minefield.cpp
index 04cfb97..1790110 100644
--- a/noncore/games/minesweep/minefield.cpp
+++ b/noncore/games/minesweep/minefield.cpp
@@ -1,725 +1,751 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20#include "minefield.h" 20#include "minefield.h"
21 21
22#include <qpe/config.h> 22#include <qtopia/config.h>
23#include <qtopia/qpeapplication.h>
23 24
24#include <qpainter.h> 25#include <qpainter.h>
25#include <qdrawutil.h> 26#include <qdrawutil.h>
26#include <qpixmap.h> 27#include <qpixmap.h>
27#include <qimage.h> 28#include <qimage.h>
28#include <qtimer.h> 29#include <qtimer.h>
29 30
30#include <stdlib.h> 31#include <stdlib.h>
31 32
32static const char *pix_flag[]={ 33static const char *pix_flag[]={
33"13 13 3 1", 34"13 13 3 1",
34"# c #000000", 35"# c #000000",
35"x c #ff0000", 36"x c #ff0000",
36". c None", 37". c None",
37".............", 38".............",
38".............", 39".............",
39".....#xxxxxx.", 40".....#xxxxxx.",
40".....#xxxxxx.", 41".....#xxxxxx.",
41".....#xxxxxx.", 42".....#xxxxxx.",
42".....#xxxxxx.", 43".....#xxxxxx.",
43".....#.......", 44".....#.......",
44".....#.......", 45".....#.......",
45".....#.......", 46".....#.......",
46".....#.......", 47".....#.......",
47"...#####.....", 48"...#####.....",
48"..#######....", 49"..#######....",
49"............."}; 50"............."};
50 51
51static const char *pix_mine[]={ 52static const char *pix_mine[]={
52"13 13 3 1", 53"13 13 3 1",
53"# c #000000", 54"# c #000000",
54". c None", 55". c None",
55"a c #ffffff", 56"a c #ffffff",
56"......#......", 57"......#......",
57"......#......", 58"......#......",
58"..#.#####.#..", 59"..#.#####.#..",
59"...#######...", 60"...#######...",
60"..##aa#####..", 61"..##aa#####..",
61"..##aa#####..", 62"..##aa#####..",
62"#############", 63"#############",
63"..#########..", 64"..#########..",
64"..#########..", 65"..#########..",
65"...#######...", 66"...#######...",
66"..#.#####.#..", 67"..#.#####.#..",
67"......#......", 68"......#......",
68"......#......"}; 69"......#......"};
69 70
70 71
71static const int maxGrid = 28; 72static const int maxGrid = 28;
72static const int minGrid = 9; 73static const int minGrid = 12;
73 74
74 75
75 76
76class Mine : public Qt 77class Mine : public Qt
77{ 78{
78public: 79public:
79 enum MineState { 80 enum MineState {
80 Hidden = 0, 81 Hidden = 0,
81 Empty, 82 Empty,
82 Mined, 83 Mined,
83 Flagged, 84 Flagged,
84#ifdef MARK_UNSURE 85#ifdef MARK_UNSURE
85 Unsure, 86 Unsure,
86#endif 87#endif
87 Exploded, 88 Exploded,
88 Wrong 89 Wrong
89 }; 90 };
90 91
91 Mine( MineField* ); 92 Mine( MineField* );
92 void paint( QPainter * p, const QColorGroup & cg, const QRect & cr ); 93 void paint( QPainter * p, const QColorGroup & cg, const QRect & cr );
93 94
94 QSize sizeHint() const { return QSize( maxGrid, maxGrid ); } 95 QSize sizeHint() const { return QSize( maxGrid, maxGrid ); }
95 96
96 void activate( bool sure = TRUE ); 97 void activate( bool sure = TRUE );
97 void setHint( int ); 98 void setHint( int );
98 99
99 void setState( MineState ); 100 void setState( MineState );
100 MineState state() const { return st; } 101 MineState state() const { return st; }
101 102
102 bool isMined() const { return mined; } 103 bool isMined() const { return mined; }
103 void setMined( bool m ) { mined = m; } 104 void setMined( bool m ) { mined = m; }
104 105
105 static void paletteChange(); 106 static void paletteChange();
106 107
107private: 108private:
108 bool mined; 109 bool mined;
109 int hint; 110 int hint;
110 111
111 MineState st; 112 MineState st;
112 MineField *field; 113 MineField *field;
113 114
114 static QPixmap* knownField; 115 static QPixmap* knownField;
115 static QPixmap* unknownField; 116 static QPixmap* unknownField;
116 static QPixmap* flag_pix; 117 static QPixmap* flag_pix;
117 static QPixmap* mine_pix; 118 static QPixmap* mine_pix;
118}; 119};
119 120
120QPixmap* Mine::knownField = 0; 121QPixmap* Mine::knownField = 0;
121QPixmap* Mine::unknownField = 0; 122QPixmap* Mine::unknownField = 0;
122QPixmap* Mine::flag_pix = 0; 123QPixmap* Mine::flag_pix = 0;
123QPixmap* Mine::mine_pix = 0; 124QPixmap* Mine::mine_pix = 0;
124 125
125Mine::Mine( MineField *f ) 126Mine::Mine( MineField *f )
126{ 127{
127 mined = FALSE; 128 mined = FALSE;
128 st = Hidden; 129 st = Hidden;
129 hint = 0; 130 hint = 0;
130 field = f; 131 field = f;
131} 132}
132 133
133void Mine::activate( bool sure ) 134void Mine::activate( bool sure )
134{ 135{
135 if ( !sure ) { 136 if ( !sure ) {
136 switch ( st ) { 137 switch ( st ) {
137 case Hidden: 138 case Hidden:
138 setState( Flagged ); 139 setState( Flagged );
139 break; 140 break;
140 case Flagged: 141 case Flagged:
141#ifdef MARK_UNSURE 142#ifdef MARK_UNSURE
142 setState( Unsure ); 143 setState( Unsure );
143 break; 144 break;
144 case Unsure: 145 case Unsure:
145#endif 146#endif
146 setState( Hidden ); 147 setState( Hidden );
147 default: 148 default:
148 break; 149 break;
149 } 150 }
150 } else if ( st == Flagged ) { 151 } else if ( st == Flagged ) {
151 return; 152 return;
152 } else { 153 } else {
153 if ( mined ) { 154 if ( mined ) {
154 setState( Exploded ); 155 setState( Exploded );
155 } else { 156 } else {
156 setState( Empty ); 157 setState( Empty );
157 } 158 }
158 } 159 }
159} 160}
160 161
161void Mine::setState( MineState s ) 162void Mine::setState( MineState s )
162{ 163{
163 st = s; 164 st = s;
164} 165}
165 166
166void Mine::setHint( int h ) 167void Mine::setHint( int h )
167{ 168{
168 hint = h; 169 hint = h;
169} 170}
170 171
171void Mine::paletteChange() 172void Mine::paletteChange()
172{ 173{
173 delete knownField; 174 delete knownField;
174 knownField = 0; 175 knownField = 0;
175 delete unknownField; 176 delete unknownField;
176 unknownField = 0; 177 unknownField = 0;
177 delete mine_pix; 178 delete mine_pix;
178 mine_pix = 0; 179 mine_pix = 0;
179 delete flag_pix; 180 delete flag_pix;
180 flag_pix = 0; 181 flag_pix = 0;
181} 182}
182 183
183void Mine::paint( QPainter* p, const QColorGroup &cg, const QRect& cr ) 184void Mine::paint( QPainter* p, const QColorGroup &cg, const QRect& cr )
184{ 185{
185 int x = cr.x(); 186 int x = cr.x();
186 int y = cr.y(); 187 int y = cr.y();
187 if ( !knownField ) { 188 if ( !knownField || knownField->width() != cr.width() ||
189 knownField->height() != cr.height() ) {
190 delete knownField;
188 knownField = new QPixmap( cr.width(), cr.height() ); 191 knownField = new QPixmap( cr.width(), cr.height() );
189 QPainter pp( knownField ); 192 QPainter pp( knownField );
190 QBrush br( cg.button().dark(115) ); 193 QBrush br( cg.button().dark(115) );
191 qDrawWinButton( &pp, cr, cg, TRUE, &br ); 194 qDrawWinButton( &pp, QRect( 0, 0, cr.width(), cr.height() ), cg, TRUE, &br );
192 } 195 }
193 196
194 const int pmmarg=cr.width()/5; 197 const int pmmarg=cr.width()/5;
195 198
196 if ( !unknownField ) { 199 if ( !unknownField || unknownField->width() != cr.width() ||
200 unknownField->height() != cr.height() ) {
201 delete unknownField;
197 unknownField = new QPixmap( cr.width(), cr.height() ); 202 unknownField = new QPixmap( cr.width(), cr.height() );
198 QPainter pp( unknownField ); 203 QPainter pp( unknownField );
199 QBrush br( cg.button() ); 204 QBrush br( cg.button() );
200 qDrawWinButton( &pp, cr, cg, FALSE, &br ); 205 qDrawWinButton( &pp, QRect( 0, 0, cr.width(), cr.height() ), cg, FALSE, &br );
201 } 206 }
202 207
203 if ( !flag_pix ) { 208 if ( !flag_pix || flag_pix->width() != cr.width()-pmmarg*2 ||
209 flag_pix->height() != cr.height()-pmmarg*2 ) {
210 delete flag_pix;
204 flag_pix = new QPixmap( cr.width()-pmmarg*2, cr.height()-pmmarg*2 ); 211 flag_pix = new QPixmap( cr.width()-pmmarg*2, cr.height()-pmmarg*2 );
205 flag_pix->convertFromImage( QImage(pix_flag).smoothScale(cr.width()-pmmarg*2, cr.height()-pmmarg*2) ); 212 flag_pix->convertFromImage( QImage(pix_flag).smoothScale(cr.width()-pmmarg*2, cr.height()-pmmarg*2) );
206 } 213 }
207 214
208 if ( !mine_pix ) { 215 if ( !mine_pix || mine_pix->width() != cr.width()-pmmarg*2 ||
216 mine_pix->height() != cr.height()-pmmarg*2 ) {
217 delete mine_pix;
209 mine_pix = new QPixmap( cr.width()-pmmarg*2, cr.height()-pmmarg*2 ); 218 mine_pix = new QPixmap( cr.width()-pmmarg*2, cr.height()-pmmarg*2 );
210 mine_pix->convertFromImage( QImage(pix_mine).smoothScale(cr.width()-pmmarg*2, cr.height()-pmmarg*2) ); 219 mine_pix->convertFromImage( QImage(pix_mine).smoothScale(cr.width()-pmmarg*2, cr.height()-pmmarg*2) );
211 } 220 }
212 221
213 p->save(); 222 p->save();
214 223
215 switch(st) { 224 switch(st) {
216 case Hidden: 225 case Hidden:
217 p->drawPixmap( x, y, *unknownField ); 226 p->drawPixmap( x, y, *unknownField );
218 break; 227 break;
219 case Empty: 228 case Empty:
220 p->drawPixmap( x, y, *knownField ); 229 p->drawPixmap( x, y, *knownField );
221 if ( hint > 0 ) { 230 if ( hint > 0 ) {
222 switch( hint ) { 231 switch( hint ) {
223 case 1: 232 case 1:
224 p->setPen( blue ); 233 p->setPen( blue );
225 break; 234 break;
226 case 2: 235 case 2:
227 p->setPen( green.dark() ); 236 p->setPen( green.dark() );
228 break; 237 break;
229 case 3: 238 case 3:
230 p->setPen( red ); 239 p->setPen( red );
231 break; 240 break;
232 case 4: 241 case 4:
233 p->setPen( darkYellow.dark() ); 242 p->setPen( darkYellow.dark() );
234 break; 243 break;
235 case 5: 244 case 5:
236 p->setPen( darkMagenta ); 245 p->setPen( darkMagenta );
237 break; 246 break;
238 case 6: 247 case 6:
239 p->setPen( darkRed ); 248 p->setPen( darkRed );
240 break; 249 break;
241 default: 250 default:
242 p->setPen( black ); 251 p->setPen( black );
243 break; 252 break;
244 } 253 }
245 p->drawText( cr, AlignHCenter | AlignVCenter, QString::number( hint ) ); 254 p->drawText( cr, AlignHCenter | AlignVCenter, QString::number( hint ) );
246 } 255 }
247 break; 256 break;
248 case Mined: 257 case Mined:
249 p->drawPixmap( x, y, *knownField ); 258 p->drawPixmap( x, y, *knownField );
250 p->drawPixmap( x+pmmarg, y+pmmarg, *mine_pix ); 259 p->drawPixmap( x+pmmarg, y+pmmarg, *mine_pix );
251 break; 260 break;
252 case Exploded: 261 case Exploded:
253 p->drawPixmap( x, y, *knownField ); 262 p->drawPixmap( x, y, *knownField );
254 p->drawPixmap( x+pmmarg, y+pmmarg, *mine_pix ); 263 p->drawPixmap( x+pmmarg, y+pmmarg, *mine_pix );
255 p->setPen( red ); 264 p->setPen( red );
256 p->drawText( cr, AlignHCenter | AlignVCenter, "X" ); 265 p->drawText( cr, AlignHCenter | AlignVCenter, "X" );
257 break; 266 break;
258 case Flagged: 267 case Flagged:
259 p->drawPixmap( x, y, *unknownField ); 268 p->drawPixmap( x, y, *unknownField );
260 p->drawPixmap( x+pmmarg, y+pmmarg, *flag_pix ); 269 p->drawPixmap( x+pmmarg, y+pmmarg, *flag_pix );
261 break; 270 break;
262#ifdef MARK_UNSURE 271#ifdef MARK_UNSURE
263 case Unsure: 272 case Unsure:
264 p->drawPixmap( x, y, *unknownField ); 273 p->drawPixmap( x, y, *unknownField );
265 p->drawText( cr, AlignHCenter | AlignVCenter, "?" ); 274 p->drawText( cr, AlignHCenter | AlignVCenter, "?" );
266 break; 275 break;
267#endif 276#endif
268 case Wrong: 277 case Wrong:
269 p->drawPixmap( x, y, *unknownField ); 278 p->drawPixmap( x, y, *unknownField );
270 p->drawPixmap( x+pmmarg, y+pmmarg, *flag_pix ); 279 p->drawPixmap( x+pmmarg, y+pmmarg, *flag_pix );
271 p->setPen( red ); 280 p->setPen( red );
272 p->drawText( cr, AlignHCenter | AlignVCenter, "X" ); 281 p->drawText( cr, AlignHCenter | AlignVCenter, "X" );
273 break; 282 break;
274 } 283 }
275 284
276 p->restore(); 285 p->restore();
277} 286}
278 287
279/* 288/*
280 MineField implementation 289 MineField implementation
281*/ 290*/
282 291
283MineField::MineField( QWidget* parent, const char* name ) 292MineField::MineField( QWidget* parent, const char* name )
284: QScrollView( parent, name ) 293: QScrollView( parent, name )
285{ 294{
295 viewport()->setBackgroundMode( NoBackground );
286 setState( GameOver ); 296 setState( GameOver );
287 297
288 setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ) ); 298 setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ) );
289 299
290 setFocusPolicy( QWidget::NoFocus ); 300 setFocusPolicy( QWidget::NoFocus );
291 301
292 holdTimer = new QTimer( this ); 302 holdTimer = new QTimer( this );
293 connect( holdTimer, SIGNAL( timeout() ), this, SLOT( held() ) ); 303 connect( holdTimer, SIGNAL( timeout() ), this, SLOT( held() ) );
294 304
295 flagAction = NoAction; 305 flagAction = NoAction;
296 ignoreClick = FALSE; 306 ignoreClick = FALSE;
297 currRow = currCol = -1; 307 currRow = currCol = -1;
298 minecount=0; 308 minecount=0;
299 mineguess=0; 309 mineguess=0;
300 nonminecount=0; 310 nonminecount=0;
301 cellSize = -1; 311 cellSize = -1;
302 mines = 0; 312
313 numRows = numCols = 0;
314 mines = NULL;
303} 315}
304 316
305MineField::~MineField() 317MineField::~MineField()
306{ 318{
307 int i; 319 for ( int i = 0; i < numCols*numRows; i++ )
308 if ( mines ) 320 delete mines[i];
309 { 321 delete[] mines;
310 for ( i = 0; i < numCols*numRows; i++ )
311 {
312 delete mines[i];
313 }
314 delete[] mines;
315 }
316} 322}
317 323
318void MineField::setState( State st ) 324void MineField::setState( State st )
319{ 325{
320 stat = st; 326 stat = st;
321} 327}
322 328
323void MineField::setup( int level ) 329void MineField::setup( int level )
324{ 330{
325 lev = level; 331 lev = level;
326 setState( Waiting ); 332 setState( Waiting );
327 //viewport()->setUpdatesEnabled( FALSE ); 333 //viewport()->setUpdatesEnabled( FALSE );
328 334
329 int i; 335 int i;
330 if ( mines ) 336 for ( i = 0; i < numCols*numRows; i++ )
331 { 337 delete mines[i];
332 for ( i = 0; i < numCols*numRows; i++ ) 338 delete[] mines;
333 {
334 delete mines[i];
335 }
336 delete[] mines;
337 }
338 339
339 switch( lev ) { 340 switch( lev ) {
340 case 1: 341 case 1:
341 numRows = 9 ; 342 numRows = 9 ;
342 numCols = 9 ; 343 numCols = 9 ;
343 minecount = 12; 344 minecount = 12;
344 break; 345 break;
345 case 2: 346 case 2:
346 numRows = 16; 347 numRows = 13;
347 numCols = 16; 348 numCols = 13;
348 minecount = 45; 349 minecount = 33;
349 break; 350 break;
350 case 3: 351 case 3:
351 numCols = 18; 352 numCols = 18;
352 numRows = 18; 353 numRows = 18;
353 minecount = 66 ; 354 minecount = 66 ;
354 break; 355 break;
355 } 356 }
356 mines = new Mine*[numRows*numCols]; 357 mines = new Mine* [numRows*numCols];
357 for ( i = 0; i < numCols*numRows; i++ ) 358 for ( i = 0; i < numCols*numRows; i++ )
358 mines[i] = new Mine( this ); 359 mines[i] = new Mine( this );
359 360
360 361
361 nonminecount = numRows*numCols - minecount; 362 nonminecount = numRows*numCols - minecount;
362 mineguess = minecount; 363 mineguess = minecount;
363 emit mineCount( mineguess ); 364 emit mineCount( mineguess );
364 Mine::paletteChange(); 365 Mine::paletteChange();
365 366
366 if ( availableRect.isValid() ) 367 if ( availableRect.isValid() )
367 setCellSize(findCellSize()); 368 setCellSize(findCellSize());
368 // viewport()->setUpdatesEnabled( TRUE ); 369 // viewport()->setUpdatesEnabled( TRUE );
369 //viewport()->repaint( TRUE ); 370 //viewport()->repaint( TRUE );
370 updateContents( 0, 0, numCols*cellSize, numRows*cellSize ); 371 updateContents( 0, 0, numCols*cellSize, numRows*cellSize );
371 updateGeometry(); 372 updateGeometry();
372} 373}
373 374
374void MineField::drawContents( QPainter * p, int clipx, int clipy, int clipw, int cliph ) 375void MineField::drawContents( QPainter * p, int clipx, int clipy, int clipw, int cliph )
375{ 376{
376 int c1 = clipx / cellSize; 377 int c1 = clipx / cellSize;
377 int c2 = ( clipx + clipw - 1 ) / cellSize; 378 int c2 = ( clipx + clipw - 1 ) / cellSize;
378 int r1 = clipy / cellSize; 379 int r1 = clipy / cellSize;
379 int r2 = ( clipy + cliph - 1 ) / cellSize; 380 int r2 = ( clipy + cliph - 1 ) / cellSize;
380 381
381 for ( int c = c1; c <= c2 ; c++ ) { 382 for ( int c = c1; c <= c2 ; c++ ) {
382 for ( int r = r1; r <= r2 ; r++ ) { 383 for ( int r = r1; r <= r2 ; r++ ) {
383 int x = c * cellSize; 384 int x = c * cellSize;
384 int y = r * cellSize; 385 int y = r * cellSize;
385 Mine *m = mine( r, c ); 386 Mine *m = mine( r, c );
386 if ( m ) 387 if ( m )
387 m->paint( p, colorGroup(), QRect(x, y, cellSize, cellSize ) ); 388 m->paint( p, colorGroup(), QRect(x, y, cellSize, cellSize ) );
388 } 389 }
389 } 390 }
390} 391}
391 392
392 393
393// Chicken and egg problem: We need to know how big the parent is 394// Chicken and egg problem: We need to know how big the parent is
394// before we can decide how big to make the table. 395// before we can decide how big to make the table.
395 396
396void MineField::setAvailableRect( const QRect &r ) 397void MineField::setAvailableRect( const QRect &r )
397{ 398{
398 availableRect = r; 399 availableRect = r;
399 int newCellSize = findCellSize(); 400 int newCellSize = findCellSize();
400 if ( newCellSize != cellSize ) { 401
402
403 if ( newCellSize == cellSize ) {
404 setCellSize( cellSize );
405 } else {
401 viewport()->setUpdatesEnabled( FALSE ); 406 viewport()->setUpdatesEnabled( FALSE );
402 setCellSize( newCellSize ); 407 setCellSize( newCellSize );
403 viewport()->setUpdatesEnabled( TRUE ); 408 viewport()->setUpdatesEnabled( TRUE );
404 viewport()->repaint( TRUE ); 409 viewport()->repaint( TRUE );
405 } 410 }
406} 411}
407 412
408int MineField::findCellSize() 413int MineField::findCellSize()
409{ 414{
410 int w = availableRect.width() - 1; 415 int w = availableRect.width() - 2;
411 int h = availableRect.height() - 1; 416 int h = availableRect.height() - 2;
412 int cellsize; 417 int cellsize;
413 418
414 cellsize = QMIN( w/numCols, h/numRows ); 419 cellsize = QMIN( w/numCols, h/numRows );
415 cellsize = QMIN( QMAX( cellsize, minGrid ), maxGrid ); 420 cellsize = QMIN( QMAX( cellsize, minGrid ), maxGrid );
416 return cellsize; 421 return cellsize;
417} 422}
418 423
419 424
420void MineField::setCellSize( int cellsize ) 425void MineField::setCellSize( int cellsize )
421{ 426{
422 cellSize = cellsize; 427 int b = 2;
423 428
424 int w = availableRect.width();
425 int h = availableRect.height();
426
427 int w2 = cellsize*numCols; 429 int w2 = cellsize*numCols;
428 int h2 = cellsize*numRows; 430 int h2 = cellsize*numRows;
429 431
430 resizeContents( w2, h2 ); 432 int w = QMIN( availableRect.width(), w2+b );
431 433 int h = QMIN( availableRect.height(), h2+b );
432 int b = 5; 434
433 435 //
434 setGeometry( availableRect.x() + (w-w2)/2, availableRect.y() + (h-h2)/2, 436 // Don't rely on the change in cellsize to force a resize,
435 w2+b, h2+b ); 437 // as it's possible to have the same size cells when going
436 // QMIN(w,w2+b), QMIN(h,h2+b) ); 438 // from a large play area to a small one.
439 //
440 resizeContents(w2, h2);
441
442 if ( availableRect.height() < h2 &&
443 availableRect.width() - w > style().scrollBarExtent().width() ) {
444 w += style().scrollBarExtent().width();
445 }
446
447 setGeometry( availableRect.x() + (availableRect.width()-w)/2,
448 availableRect.y() + (availableRect.height()-h)/2, w, h );
449 cellSize = cellsize;
437} 450}
438 451
439 452
440void MineField::placeMines() 453void MineField::placeMines()
441{ 454{
442 int mines = minecount; 455 int mines = minecount;
443 while ( mines ) { 456 while ( mines ) {
444 int col = int((double(rand()) / double(RAND_MAX)) * numCols); 457 int col = int((double(rand()) / double(RAND_MAX)) * numCols);
445 int row = int((double(rand()) / double(RAND_MAX)) * numRows); 458 int row = int((double(rand()) / double(RAND_MAX)) * numRows);
446 459
447 Mine* m = mine( row, col ); 460 Mine* m = mine( row, col );
448 461
449 if ( m && !m->isMined() && m->state() == Mine::Hidden ) { 462 if ( m && !m->isMined() && m->state() == Mine::Hidden ) {
450 m->setMined( TRUE ); 463 m->setMined( TRUE );
451 mines--; 464 mines--;
452 } 465 }
453 } 466 }
454} 467}
455 468
456 469
457void MineField::updateCell( int r, int c ) 470void MineField::updateCell( int r, int c )
458{ 471{
459 updateContents( c*cellSize, r*cellSize, cellSize, cellSize ); 472 updateContents( c*cellSize, r*cellSize, cellSize, cellSize );
460} 473}
461 474
462 475
463void MineField::contentsMousePressEvent( QMouseEvent* e ) 476void MineField::contentsMousePressEvent( QMouseEvent* e )
464{ 477{
465 int c = e->pos().x() / cellSize; 478 int c = e->pos().x() / cellSize;
466 int r = e->pos().y() / cellSize; 479 int r = e->pos().y() / cellSize;
467 if ( onBoard( r, c ) ) 480 if ( onBoard( r, c ) )
468 cellPressed( r, c ); 481 cellPressed( r, c );
469 else 482 else
470 currCol = currRow = -1; 483 currCol = currRow = -1;
471} 484}
472 485
473void MineField::contentsMouseReleaseEvent( QMouseEvent* e ) 486void MineField::contentsMouseReleaseEvent( QMouseEvent* e )
474{ 487{
475 int c = e->pos().x() / cellSize; 488 int c = e->pos().x() / cellSize;
476 int r = e->pos().y() / cellSize; 489 int r = e->pos().y() / cellSize;
477 if ( onBoard( r, c ) && c == currCol && r == currRow ) 490 if ( onBoard( r, c ) && c == currCol && r == currRow )
478 cellClicked( r, c ); 491 cellClicked( r, c );
479 492
480 493
481 if ( flagAction == FlagNext ) { 494 if ( flagAction == FlagNext ) {
482 flagAction = NoAction; 495 flagAction = NoAction;
483 } 496 }
484} 497}
485 498
486 499
487 500
488/* 501/*
489 state == Waiting means no "hold" 502 state == Waiting means no "hold"
490 503
491 504
492*/ 505*/
493void MineField::cellPressed( int row, int col ) 506void MineField::cellPressed( int row, int col )
494{ 507{
495 if ( state() == GameOver ) 508 if ( state() == GameOver )
496 return; 509 return;
497 currRow = row; 510 currRow = row;
498 currCol = col; 511 currCol = col;
499 if ( state() == Playing ) 512 if ( state() == Playing )
500 holdTimer->start( 150, TRUE ); 513 holdTimer->start( 150, TRUE );
501} 514}
502 515
503void MineField::held() 516void MineField::held()
504{ 517{
505 flagAction = FlagNext; 518 flagAction = FlagNext;
506 updateMine( currRow, currCol ); 519 updateMine( currRow, currCol );
507 ignoreClick = TRUE; 520 ignoreClick = TRUE;
508} 521}
509 522
510 523
511 524
512 525
513void MineField::keyPressEvent( QKeyEvent* e ) 526void MineField::keyPressEvent( QKeyEvent* e )
514{ 527{
515#if defined(Q_WS_QWS) || defined(_WS_QWS_) 528#if defined(Q_WS_QWS) || defined(_WS_QWS_)
516 flagAction = ( e->key() == Key_Up ) ? FlagOn : NoAction; 529 flagAction = ( e->key() == Key_Up ) ? FlagOn : NoAction;
517#else 530#else
518 flagAction = ( ( e->state() & ShiftButton ) == ShiftButton ) ? FlagOn : NoAction; 531 flagAction = ( ( e->state() & ShiftButton ) == ShiftButton ) ? FlagOn : NoAction;
519#endif 532#endif
520} 533}
521 534
522void MineField::keyReleaseEvent( QKeyEvent* ) 535void MineField::keyReleaseEvent( QKeyEvent* )
523{ 536{
524 flagAction = NoAction; 537 flagAction = NoAction;
525} 538}
526 539
527int MineField::getHint( int row, int col ) 540int MineField::getHint( int row, int col )
528{ 541{
529 int hint = 0; 542 int hint = 0;
530 for ( int c = col-1; c <= col+1; c++ ) 543 for ( int c = col-1; c <= col+1; c++ )
531 for ( int r = row-1; r <= row+1; r++ ) { 544 for ( int r = row-1; r <= row+1; r++ ) {
532 Mine* m = mine( r, c ); 545 Mine* m = mine( r, c );
533 if ( m && m->isMined() ) 546 if ( m && m->isMined() )
534 hint++; 547 hint++;
535 } 548 }
536 549
537 return hint; 550 return hint;
538} 551}
539 552
540void MineField::setHint( int row, int col ) 553void MineField::setHint( int row, int col )
541{ 554{
542 Mine *m = mine( row, col ); 555 Mine *m = mine( row, col );
543 if ( !m ) 556 if ( !m )
544 return; 557 return;
545 558
546 int hint = getHint( row, col ); 559 int hint = getHint( row, col );
547 560
548 if ( !hint ) { 561 if ( !hint ) {
549 for ( int c = col-1; c <= col+1; c++ ) 562 for ( int c = col-1; c <= col+1; c++ )
550 for ( int r = row-1; r <= row+1; r++ ) { 563 for ( int r = row-1; r <= row+1; r++ ) {
551 Mine* m = mine( r, c ); 564 Mine* m = mine( r, c );
552 if ( m && m->state() == Mine::Hidden ) { 565 if ( m && m->state() == Mine::Hidden ) {
553 m->activate( TRUE ); 566 m->activate( TRUE );
554 nonminecount--; 567 nonminecount--;
555 setHint( r, c ); 568 setHint( r, c );
556 updateCell( r, c ); 569 updateCell( r, c );
557 } 570 }
558 } 571 }
559 } 572 }
560 573
561 m->setHint( hint ); 574 m->setHint( hint );
562 updateCell( row, col ); 575 updateCell( row, col );
563} 576}
564 577
565/* 578/*
566 Only place mines after first click, since it is pointless to 579 Only place mines after first click, since it is pointless to
567 kill the player before the game has started. 580 kill the player before the game has started.
568*/ 581*/
569 582
570void MineField::cellClicked( int row, int col ) 583void MineField::cellClicked( int row, int col )
571{ 584{
572 if ( state() == GameOver ) 585 if ( state() == GameOver )
573 return; 586 return;
574 if ( state() == Waiting ) { 587 if ( state() == Waiting ) {
575 Mine* m = mine( row, col ); 588 Mine* m = mine( row, col );
576 if ( !m ) 589 if ( !m )
577 return; 590 return;
578 m->setState( Mine::Empty ); 591 m->setState( Mine::Empty );
579 nonminecount--; 592 nonminecount--;
580 placeMines(); 593 placeMines();
581 setState( Playing ); 594 setState( Playing );
582 emit gameStarted(); 595 emit gameStarted();
583 updateMine( row, col ); 596 updateMine( row, col );
584 } else { // state() == Playing 597 } else { // state() == Playing
585 holdTimer->stop(); 598 holdTimer->stop();
586 if ( ignoreClick ) 599 if ( ignoreClick )
587 ignoreClick = FALSE; 600 ignoreClick = FALSE;
588 else 601 else
589 updateMine( row, col ); 602 updateMine( row, col );
590 } 603 }
591} 604}
592 605
593void MineField::updateMine( int row, int col ) 606void MineField::updateMine( int row, int col )
594{ 607{
595 Mine* m = mine( row, col ); 608 Mine* m = mine( row, col );
596 if ( !m ) 609 if ( !m )
597 return; 610 return;
598 611
599 bool wasFlagged = m->state() == Mine::Flagged; 612 bool wasFlagged = m->state() == Mine::Flagged;
600 bool wasEmpty = m->state() == Mine::Empty; 613 bool wasEmpty = m->state() == Mine::Empty;
601 614
602 m->activate( flagAction == NoAction ); 615 m->activate( flagAction == NoAction );
603 616
604 if ( m->state() == Mine::Exploded ) { 617 if ( m->state() == Mine::Exploded ) {
605 emit gameOver( FALSE ); 618 emit gameOver( FALSE );
606 setState( GameOver ); 619 setState( GameOver );
607 return; 620 return;
608 } else if ( m->state() == Mine::Empty ) { 621 } else if ( m->state() == Mine::Empty ) {
609 setHint( row, col ); 622 setHint( row, col );
610 if ( !wasEmpty ) 623 if ( !wasEmpty )
611 nonminecount--; 624 nonminecount--;
612 } 625 }
613 626
614 if ( flagAction != NoAction ) { 627 if ( flagAction != NoAction ) {
615 if ( m->state() == Mine::Flagged ) { 628 if ( m->state() == Mine::Flagged ) {
616 --mineguess; 629 if (mineguess > 0) {
617 emit mineCount( mineguess ); 630 --mineguess;
618 if ( m->isMined() ) 631 emit mineCount( mineguess );
619 --minecount; 632 if ( m->isMined() )
633 --minecount;
634 } else {
635 m->setState(Mine::Hidden);
636 }
620 } else if ( wasFlagged ) { 637 } else if ( wasFlagged ) {
621 ++mineguess; 638 ++mineguess;
622 emit mineCount( mineguess ); 639 emit mineCount( mineguess );
623 if ( m->isMined() ) 640 if ( m->isMined() )
624 ++minecount; 641 ++minecount;
625 } 642 }
626 } 643 }
627 644
628 updateCell( row, col ); 645 updateCell( row, col );
629 646
630 if ( !minecount && !mineguess || !nonminecount ) { 647 if ( !minecount && !mineguess || !nonminecount ) {
631 emit gameOver( TRUE ); 648 emit gameOver( TRUE );
632 setState( GameOver ); 649 setState( GameOver );
633 } 650 }
634} 651}
635 652
636void MineField::showMines() 653void MineField::showMines()
637{ 654{
638 for ( int c = 0; c < numCols; c++ ) 655 for ( int c = 0; c < numCols; c++ )
639 for ( int r = 0; r < numRows; r++ ) { 656 for ( int r = 0; r < numRows; r++ ) {
640 Mine* m = mine( r, c ); 657 Mine* m = mine( r, c );
641 if ( !m ) 658 if ( !m )
642 continue; 659 continue;
643 if ( m->isMined() && m->state() == Mine::Hidden ) 660 if ( m->isMined() && m->state() == Mine::Hidden )
644 m->setState( Mine::Mined ); 661 m->setState( Mine::Mined );
645 if ( !m->isMined() && m->state() == Mine::Flagged ) 662 if ( !m->isMined() && m->state() == Mine::Flagged )
646 m->setState( Mine::Wrong ); 663 m->setState( Mine::Wrong );
647 664
648 updateCell( r, c ); 665 updateCell( r, c );
649 } 666 }
650} 667}
651 668
652void MineField::paletteChange( const QPalette &o ) 669void MineField::paletteChange( const QPalette &o )
653{ 670{
654 Mine::paletteChange(); 671 Mine::paletteChange();
655 QScrollView::paletteChange( o ); 672 QScrollView::paletteChange( o );
656} 673}
657 674
658void MineField::writeConfig(Config& cfg) const 675void MineField::writeConfig(Config& cfg) const
659{ 676{
660 cfg.setGroup("Field"); 677 cfg.setGroup("Field");
661 cfg.writeEntry("Level",lev); 678 cfg.writeEntry("Level",lev);
662 QString grid=""; 679 QString grid="";
663 if ( stat == Playing ) { 680 if ( stat == Playing ) {
664 for ( int x = 0; x < numCols; x++ ) 681 for ( int x = 0; x < numCols; x++ )
665 for ( int y = 0; y < numRows; y++ ) { 682 for ( int y = 0; y < numRows; y++ ) {
666 char code='A'+(x*17+y*101)%21; // Reduce the urge to cheat 683 char code='A'+(x*17+y*101)%21; // Reduce the urge to cheat
667 const Mine* m = mine( y, x ); 684 const Mine* m = mine( y, x );
668 int st = (int)m->state(); if ( m->isMined() ) st+=5; 685 int st = (int)m->state(); if ( m->isMined() ) st+=5;
669 grid += code + st; 686 grid += code + st;
670 } 687 }
671 } 688 }
672 cfg.writeEntry("Grid",grid); 689 cfg.writeEntry("Grid",grid);
673} 690}
674 691
675void MineField::readConfig(Config& cfg) 692void MineField::readConfig(Config& cfg)
676{ 693{
677 cfg.setGroup("Field"); 694 cfg.setGroup("Field");
678 lev = cfg.readNumEntry("Level",1); 695 lev = cfg.readNumEntry("Level",1);
679 setup(lev); 696 setup(lev);
680 flagAction = NoAction; 697 flagAction = NoAction;
681 ignoreClick = FALSE; 698 ignoreClick = FALSE;
682 currRow = currCol = 0; 699 currRow = currCol = 0;
683 QString grid = cfg.readEntry("Grid"); 700 QString grid = cfg.readEntry("Grid");
701 int x;
684 if ( !grid.isEmpty() ) { 702 if ( !grid.isEmpty() ) {
685 int i=0; 703 int i=0;
686 minecount=0; 704 minecount=0;
687 mineguess=0; 705 mineguess=0;
688 for ( int x = 0; x < numCols; x++ ) { 706 for ( x = 0; x < numCols; x++ ) {
689 for ( int y = 0; y < numRows; y++ ) { 707 for ( int y = 0; y < numRows; y++ ) {
690 char code='A'+(x*17+y*101)%21; // Reduce the urge to cheat 708 char code='A'+(x*17+y*101)%21; // Reduce the urge to cheat
691 int st = (char)(QChar)grid[i++]-code; 709 int st = (char)(QChar)grid[i++]-code;
692 Mine* m = mine( y, x ); 710 Mine* m = mine( y, x );
693 if ( st >= 5 ) { 711 if ( st >= 5 ) {
694 st-=5; 712 st-=5;
695 m->setMined(TRUE); 713 m->setMined(TRUE);
696 minecount++; 714 minecount++;
697 mineguess++; 715 mineguess++;
698 } 716 }
699 m->setState((Mine::MineState)st); 717 m->setState((Mine::MineState)st);
700 switch ( m->state() ) { 718 switch ( m->state() ) {
701 case Mine::Flagged: 719 case Mine::Flagged:
702 if (m->isMined()) 720 if (m->isMined())
703 minecount--; 721 minecount--;
704 mineguess--; 722 mineguess--;
705 break; 723 break;
706 case Mine::Empty: 724 case Mine::Empty:
707 --nonminecount; 725 --nonminecount;
708 break; 726 break;
709 default: 727 default:
710 break; 728 break;
711 } 729 }
712 } 730 }
713 } 731 }
714 for ( int x = 0; x < numCols; x++ ) { 732 for ( x = 0; x < numCols; x++ ) {
715 for ( int y = 0; y < numRows; y++ ) { 733 for ( int y = 0; y < numRows; y++ ) {
716 Mine* m = mine( y, x ); 734 Mine* m = mine( y, x );
717 if ( m->state() == Mine::Empty ) 735 if ( m->state() == Mine::Empty )
718 m->setHint(getHint(y,x)); 736 m->setHint(getHint(y,x));
719 } 737 }
720 } 738 }
721 } 739 }
722 setState( Playing ); 740 setState( Playing );
723 emit mineCount( mineguess ); 741 emit mineCount( mineguess );
724} 742}
725 743
744QSize MineField::sizeHint() const
745{
746 if ( qApp->desktop()->width() >= 240 )
747 return QSize(200,200);
748 else
749 return QSize(160, 160);
750}
751
diff --git a/noncore/games/minesweep/minefield.h b/noncore/games/minesweep/minefield.h
index 1349c35..e243d77 100644
--- a/noncore/games/minesweep/minefield.h
+++ b/noncore/games/minesweep/minefield.h
@@ -1,101 +1,104 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20#ifndef MINEFIELD_H 20#ifndef MINEFIELD_H
21#define MINEFIELD_H 21#define MINEFIELD_H
22 22
23#include <qscrollview.h> 23#include <qscrollview.h>
24 24
25class Mine; 25class Mine;
26class Config; 26class Config;
27 27
28class MineField : public QScrollView 28class MineField : public QScrollView
29{ 29{
30 Q_OBJECT 30 Q_OBJECT
31public: 31public:
32 MineField( QWidget* parent = 0, const char* name = 0 ); 32 MineField( QWidget* parent = 0, const char* name = 0 );
33 ~MineField(); 33 ~MineField();
34 34
35 enum State { Waiting, Playing, GameOver }; 35 enum State { Waiting, Playing, GameOver };
36 36
37 State state() const { return stat; } 37 State state() const { return stat; }
38 38
39 void readConfig(Config&); 39 void readConfig(Config&);
40 void writeConfig(Config&) const; 40 void writeConfig(Config&) const;
41 41
42 int level() const { return lev; } 42 int level() const { return lev; }
43 43
44 void setAvailableRect( const QRect & ); 44 void setAvailableRect( const QRect & );
45
46 QSize sizeHint() const;
47
45public slots: 48public slots:
46 void setup( int level ); 49 void setup( int level );
47 50
48 void showMines(); 51 void showMines();
49 52
50signals: 53signals:
51 void gameOver( bool won ); 54 void gameOver( bool won );
52 void gameStarted(); 55 void gameStarted();
53 void mineCount( int ); 56 void mineCount( int );
54 57
55protected: 58protected:
56 59
57 void contentsMousePressEvent( QMouseEvent* ); 60 void contentsMousePressEvent( QMouseEvent* );
58 void contentsMouseReleaseEvent( QMouseEvent* ); 61 void contentsMouseReleaseEvent( QMouseEvent* );
59 void keyPressEvent( QKeyEvent* ); 62 void keyPressEvent( QKeyEvent* );
60 void keyReleaseEvent( QKeyEvent* ); 63 void keyReleaseEvent( QKeyEvent* );
61 void drawContents( QPainter * p, int clipx, int clipy, int clipw, int cliph ); 64 void drawContents( QPainter * p, int clipx, int clipy, int clipw, int cliph );
62 65
63 int getHint( int row, int col ); 66 int getHint( int row, int col );
64 void setHint( int r, int c ); 67 void setHint( int r, int c );
65 void updateMine( int row, int col ); 68 void updateMine( int row, int col );
66 void paletteChange( const QPalette & ); 69 void paletteChange( const QPalette & );
67 void updateCell( int r, int c ); 70 void updateCell( int r, int c );
68 bool onBoard( int r, int c ) const { return r >= 0 && r < numRows && c >= 0 && c < numCols; } 71 bool onBoard( int r, int c ) const { return r >= 0 && r < numRows && c >= 0 && c < numCols; }
69 Mine *mine( int row, int col ) { return onBoard(row, col ) ? mines[row+numCols*col] : 0; } 72 Mine *mine( int row, int col ) { return onBoard(row, col ) ? mines[row+numCols*col] : 0; }
70 const Mine *mine( int row, int col ) const { return onBoard(row, col ) ? mines[row+numCols*col] : 0; } 73 const Mine *mine( int row, int col ) const { return onBoard(row, col ) ? mines[row+numCols*col] : 0; }
71 74
72protected slots: 75protected slots:
73 void cellPressed( int row, int col ); 76 void cellPressed( int row, int col );
74 void cellClicked( int row, int col ); 77 void cellClicked( int row, int col );
75 void held(); 78 void held();
76 79
77private: 80private:
78 int findCellSize(); 81 int findCellSize();
79 void setCellSize( int ); 82 void setCellSize( int );
80 83
81 State stat; 84 State stat;
82 void MineField::setState( State st ); 85 void MineField::setState( State st );
83 void MineField::placeMines(); 86 void MineField::placeMines();
84 enum FlagAction { NoAction, FlagOn, FlagNext }; 87 enum FlagAction { NoAction, FlagOn, FlagNext };
85 FlagAction flagAction; 88 FlagAction flagAction;
86 bool ignoreClick; 89 bool ignoreClick;
87 int currRow; 90 int currRow;
88 int currCol; 91 int currCol;
89 int numRows, numCols; 92 int numRows, numCols;
90 93
91 int minecount; 94 int minecount;
92 int mineguess; 95 int mineguess;
93 int nonminecount; 96 int nonminecount;
94 int lev; 97 int lev;
95 QRect availableRect; 98 QRect availableRect;
96 int cellSize; 99 int cellSize;
97 QTimer *holdTimer; 100 QTimer *holdTimer;
98 Mine **mines; 101 Mine **mines;
99}; 102};
100 103
101#endif // MINEFIELD_H 104#endif // MINEFIELD_H
diff --git a/noncore/games/minesweep/minesweep.cpp b/noncore/games/minesweep/minesweep.cpp
index 7214a73..d707dab 100644
--- a/noncore/games/minesweep/minesweep.cpp
+++ b/noncore/games/minesweep/minesweep.cpp
@@ -1,407 +1,413 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#include "minesweep.h" 21#include "minesweep.h"
22#include "minefield.h" 22#include "minefield.h"
23 23
24#include <qpe/qpeapplication.h> 24#include <qtopia/qpeapplication.h>
25#include <qpe/resource.h> 25#include <qtopia/resource.h>
26#include <qpe/config.h> 26#include <qtopia/config.h>
27 27
28#include <qpe/qpetoolbar.h> 28#include <qtoolbar.h>
29#include <qmenubar.h> 29#include <qmenubar.h>
30#include <qpopupmenu.h> 30#include <qpopupmenu.h>
31#include <qpushbutton.h> 31#include <qpushbutton.h>
32#include <qlcdnumber.h> 32#include <qlcdnumber.h>
33#include <qmessagebox.h> 33#include <qmessagebox.h>
34#include <qtimer.h> 34#include <qtimer.h>
35#include <qpalette.h> 35#include <qpalette.h>
36#include <qapplication.h> 36#include <qapplication.h>
37#include <qlayout.h> 37#include <qlayout.h>
38#include <qlabel.h> 38#include <qlabel.h>
39 39
40#include <stdlib.h> 40#include <stdlib.h>
41#include <time.h> 41#include <time.h>
42 42
43 43
44 44
45 45
46static const char *pix_new[]={ 46static const char *pix_new[]={
47"20 20 3 1", 47"20 20 3 1",
48" c None", 48" c None",
49"# c #00FF00", 49"# c #00FF00",
50". c #000000", 50". c #000000",
51" ", 51" ",
52" ...... ", 52" ...... ",
53" ..######.. ", 53" ..######.. ",
54" .##########. ", 54" .##########. ",
55" .############. ", 55" .############. ",
56" .##############. ", 56" .##############. ",
57" .##############. ", 57" .##############. ",
58" .################. ", 58" .################. ",
59" .################. ", 59" .################. ",
60" .################. ", 60" .################. ",
61" .################. ", 61" .################. ",
62" .################. ", 62" .################. ",
63" .################. ", 63" .################. ",
64" .##############. ", 64" .##############. ",
65" .##############. ", 65" .##############. ",
66" .############. ", 66" .############. ",
67" .##########. ", 67" .##########. ",
68" ..######.. ", 68" ..######.. ",
69" ...... ", 69" ...... ",
70" "}; 70" "};
71 71
72 72
73/* XPM */ 73/* XPM */
74static const char * happy_xpm[] = { 74static const char * happy_xpm[] = {
75"20 20 3 1", 75"20 20 3 1",
76 " c None", 76 " c None",
77 ".c #ffff3f ", 77 ".c #ffff3f ",
78 "#c #000000", 78 "#c #000000",
79" ", 79" ",
80" ###### ", 80" ###### ",
81" ##......## ", 81" ##......## ",
82" #..........# ", 82" #..........# ",
83" #............# ", 83" #............# ",
84" #..............# ", 84" #..............# ",
85" #..............# ", 85" #..............# ",
86" #....##....##....# ", 86" #....##....##....# ",
87" #....##....##....# ", 87" #....##....##....# ",
88" #................# ", 88" #................# ",
89" #................# ", 89" #................# ",
90" #................# ", 90" #................# ",
91" #...#........#...# ", 91" #...#........#...# ",
92" #.##........##.# ", 92" #.##........##.# ",
93" #...########...# ", 93" #...########...# ",
94" #...######...# ", 94" #...######...# ",
95" #..........# ", 95" #..........# ",
96" ##......## ", 96" ##......## ",
97" ###### ", 97" ###### ",
98" "}; 98" "};
99 99
100 100
101/* XPM */ 101/* XPM */
102static const char * worried_xpm[] = { 102static const char * worried_xpm[] = {
103"20 20 3 1", 103"20 20 3 1",
104 " c None", 104 " c None",
105 ".c #ffff3f", 105 ".c #ffff3f",
106 "#c #000000", 106 "#c #000000",
107" ", 107" ",
108" ###### ", 108" ###### ",
109" ##......## ", 109" ##......## ",
110" #..........# ", 110" #..........# ",
111" #............# ", 111" #............# ",
112" #..............# ", 112" #..............# ",
113" #..............# ", 113" #..............# ",
114" #....##....##....# ", 114" #....##....##....# ",
115" #....##....##....# ", 115" #....##....##....# ",
116" #................# ", 116" #................# ",
117" #................# ", 117" #................# ",
118" #................# ", 118" #................# ",
119" #................# ", 119" #................# ",
120" #....######....# ", 120" #....######....# ",
121" #..............# ", 121" #..............# ",
122" #............# ", 122" #............# ",
123" #..........# ", 123" #..........# ",
124" ##......## ", 124" ##......## ",
125" ###### ", 125" ###### ",
126" "}; 126" "};
127 127
128 128
129/* XPM */ 129/* XPM */
130static const char * dead_xpm[] = { 130static const char * dead_xpm[] = {
131"20 20 3 1", 131"20 20 3 1",
132 " c None", 132 " c None",
133 ".c #ffff3f", 133 ".c #ffff3f",
134 "#c #000000", 134 "#c #000000",
135" ", 135" ",
136" ###### ", 136" ###### ",
137" ##......## ", 137" ##......## ",
138" #..........# ", 138" #..........# ",
139" #............# ", 139" #............# ",
140" #..............# ", 140" #..............# ",
141" #..#.#...#.#...# ", 141" #..#.#...#.#...# ",
142" #....#.....#.....# ", 142" #....#.....#.....# ",
143" #...#.#...#.#....# ", 143" #...#.#...#.#....# ",
144" #................# ", 144" #................# ",
145" #................# ", 145" #................# ",
146" #................# ", 146" #................# ",
147" #......####......# ", 147" #......####......# ",
148" #....# #....# ", 148" #....# #....# ",
149" #...#......#...# ", 149" #...#......#...# ",
150" #............# ", 150" #............# ",
151" #..........# ", 151" #..........# ",
152" ##......## ", 152" ##......## ",
153" ###### ", 153" ###### ",
154" "}; 154" "};
155 155
156 156
157class ResultIndicator : private QLabel 157class ResultIndicator : private QLabel
158{ 158{
159public: 159public:
160 static void showResult( QWidget *ref, bool won ); 160 static void showResult( QWidget *ref, bool won );
161private: 161private:
162 ResultIndicator( QWidget *parent, const char *name, WFlags f) 162 ResultIndicator( QWidget *parent, const char *name, WFlags f)
163 :QLabel( parent, name, f ) {} 163 :QLabel( parent, name, f ) {}
164 164
165 void timerEvent( QTimerEvent *); 165 void timerEvent( QTimerEvent *);
166 void center(); 166 void center();
167 bool twoStage; 167 bool twoStage;
168 int timerId; 168 int timerId;
169}; 169};
170 170
171void ResultIndicator::showResult( QWidget *ref, bool won ) 171void ResultIndicator::showResult( QWidget *ref, bool won )
172{ 172{
173 ResultIndicator *r = new ResultIndicator( ref, 0, WStyle_Customize | WStyle_Tool | WType_TopLevel ); 173 ResultIndicator *r = new ResultIndicator( ref, 0, WStyle_Customize | WStyle_Tool | WType_TopLevel );
174 174
175 r->setAlignment( AlignCenter ); 175 r->setAlignment( AlignCenter );
176 r->setFrameStyle( Sunken|StyledPanel ); 176 r->setFrameStyle( Sunken|StyledPanel );
177 if ( won ) { 177 if ( won ) {
178 r->setText( MineSweep::tr("You won!") ); 178 r->setText( MineSweep::tr("You won!") );
179 r->center(); 179 r->center();
180 r->show(); 180 r->show();
181 r->twoStage = FALSE; 181 r->twoStage = FALSE;
182 r->timerId = r->startTimer(1500); 182 r->timerId = r->startTimer(1500);
183 } else { 183 } else {
184 QPalette p( red ); 184 QPalette p( red );
185 r->setPalette( p ); 185 r->setPalette( p );
186 r->setText( MineSweep::tr("You exploded!") ); 186 r->setText( MineSweep::tr("You exploded!") );
187 r->resize( ref->size() ); 187 r->resize( ref->size() );
188 r->move( ref->mapToGlobal(QPoint(0,0)) ); 188 r->move( ref->mapToGlobal(QPoint(0,0)) );
189 r->show(); 189 r->show();
190 r->twoStage = TRUE; 190 r->twoStage = TRUE;
191 r->timerId =r->startTimer(200); 191 r->timerId =r->startTimer(200);
192 } 192 }
193} 193}
194 194
195void ResultIndicator::center() 195void ResultIndicator::center()
196{ 196{
197 QWidget *w = parentWidget(); 197 QWidget *w = parentWidget();
198 198
199 QPoint pp = w->mapToGlobal( QPoint(0,0) ); 199 QPoint pp = w->mapToGlobal( QPoint(0,0) );
200 QSize s = sizeHint()*3; 200 QSize s = sizeHint()*3;
201 s.setWidth( QMIN(s.width(), w->width()) );
201 pp = QPoint( pp.x() + w->width()/2 - s.width()/2, 202 pp = QPoint( pp.x() + w->width()/2 - s.width()/2,
202 pp.y() + w->height()/ 2 - s.height()/2 ); 203 pp.y() + w->height()/ 2 - s.height()/2 );
203 204
204 setGeometry( QRect(pp, s) ); 205 setGeometry( QRect(pp, s) );
205 206
206} 207}
207 208
208void ResultIndicator::timerEvent( QTimerEvent *te ) 209void ResultIndicator::timerEvent( QTimerEvent *te )
209{ 210{
210 if ( te->timerId() != timerId ) 211 if ( te->timerId() != timerId )
211 return; 212 return;
212 killTimer( timerId ); 213 killTimer( timerId );
213 if ( twoStage ) { 214 if ( twoStage ) {
214 center(); 215 center();
215 twoStage = FALSE; 216 twoStage = FALSE;
216 timerId = startTimer( 1000 ); 217 timerId = startTimer( 1000 );
217 } else { 218 } else {
218 delete this; 219 delete this;
219 } 220 }
220} 221}
221 222
222 223
223class MineFrame : public QFrame 224class MineFrame : public QFrame
224{ 225{
225public: 226public:
226 MineFrame( QWidget *parent, const char *name = 0 ) 227 MineFrame( QWidget *parent, const char *name = 0 )
227 :QFrame( parent, name ) {} 228 :QFrame( parent, name ), field(0) {}
228 void setField( MineField *f ) { field = f; } 229 void setField( MineField *f ) {
230 field = f;
231 setMinimumSize( field->sizeHint() );
232 }
229protected: 233protected:
230 void resizeEvent( QResizeEvent *e ) { 234 void resizeEvent( QResizeEvent *e ) {
231 field->setAvailableRect( contentsRect()); 235 field->setAvailableRect( contentsRect());
232 QFrame::resizeEvent(e); 236 QFrame::resizeEvent(e);
233 } 237 }
234private: 238private:
235 MineField *field; 239 MineField *field;
236}; 240};
237 241
238 242
239 243
240MineSweep::MineSweep( QWidget* parent, const char* name, WFlags f ) 244MineSweep::MineSweep( QWidget* parent, const char* name, WFlags f )
241: QMainWindow( parent, name, f ) 245: QMainWindow( parent, name, f )
242{ 246{
243 QPEApplication::setInputMethodHint(this, QPEApplication::AlwaysOff );
244 srand(::time(0)); 247 srand(::time(0));
245 setCaption( tr("Mine Hunt") ); 248 setCaption( tr("Mine Hunt") );
246 setIcon( Resource::loadPixmap( "minesweep_icon" ) ); 249 QPEApplication::setInputMethodHint(this, QPEApplication::AlwaysOff );
250 setIcon( Resource::loadPixmap( "minesweep/MineHunt" ) );
247 251
248 QToolBar *toolBar = new QToolBar( this ); 252 QToolBar *toolBar = new QToolBar( this );
249 toolBar->setHorizontalStretchable( TRUE ); 253 toolBar->setHorizontalStretchable( TRUE );
250 254
251 QMenuBar *menuBar = new QMenuBar( toolBar ); 255 QMenuBar *menuBar = new QMenuBar( toolBar );
252 256
253 QPopupMenu *gameMenu = new QPopupMenu( this ); 257 QPopupMenu *gameMenu = new QPopupMenu( this );
254 gameMenu->insertItem( tr("Beginner"), this, SLOT( beginner() ) ); 258 gameMenu->insertItem( tr("Beginner"), this, SLOT( beginner() ) );
255 gameMenu->insertItem( tr("Advanced"), this, SLOT( advanced() ) ); 259 gameMenu->insertItem( tr("Advanced"), this, SLOT( advanced() ) );
256 gameMenu->insertItem( tr("Expert"), this, SLOT( expert() ) ); 260
261 if (qApp->desktop()->width() >= 240) {
262 gameMenu->insertItem( tr("Expert"), this, SLOT( expert() ) );
263 }
257 264
258 menuBar->insertItem( tr("Game"), gameMenu ); 265 menuBar->insertItem( tr("Game"), gameMenu );
259 266
260 guessLCD = new QLCDNumber( toolBar ); 267 guessLCD = new QLCDNumber( toolBar );
261 toolBar->setStretchableWidget( guessLCD ); 268 toolBar->setStretchableWidget( guessLCD );
262 269
263 QPalette lcdPal( red ); 270 QPalette lcdPal( red );
264 lcdPal.setColor( QColorGroup::Background, QApplication::palette().active().background() ); 271 lcdPal.setColor( QColorGroup::Background, QApplication::palette().active().background() );
265 lcdPal.setColor( QColorGroup::Button, QApplication::palette().active().button() ); 272 lcdPal.setColor( QColorGroup::Button, QApplication::palette().active().button() );
266 273
267// guessLCD->setPalette( lcdPal ); 274// guessLCD->setPalette( lcdPal );
268 guessLCD->setSegmentStyle( QLCDNumber::Flat ); 275 guessLCD->setSegmentStyle( QLCDNumber::Flat );
269 guessLCD->setFrameStyle( QFrame::NoFrame ); 276 guessLCD->setFrameStyle( QFrame::NoFrame );
270 guessLCD->setNumDigits( 2 ); 277 guessLCD->setNumDigits( 2 );
271 guessLCD->setBackgroundMode( PaletteButton ); 278 guessLCD->setBackgroundMode( PaletteButton );
272 newGameButton = new QPushButton( toolBar ); 279 newGameButton = new QPushButton( toolBar );
273 newGameButton->setPixmap( QPixmap( pix_new ) ); 280 newGameButton->setPixmap( QPixmap( pix_new ) );
274 newGameButton->setFocusPolicy(QWidget::NoFocus); 281 newGameButton->setFocusPolicy(QWidget::NoFocus);
275 connect( newGameButton, SIGNAL(clicked()), this, SLOT(newGame()) ); 282 connect( newGameButton, SIGNAL(clicked()), this, SLOT(newGame()) );
276 283
277 timeLCD = new QLCDNumber( toolBar ); 284 timeLCD = new QLCDNumber( toolBar );
278// timeLCD->setPalette( lcdPal ); 285// timeLCD->setPalette( lcdPal );
279 timeLCD->setSegmentStyle( QLCDNumber::Flat ); 286 timeLCD->setSegmentStyle( QLCDNumber::Flat );
280 timeLCD->setFrameStyle( QFrame::NoFrame ); 287 timeLCD->setFrameStyle( QFrame::NoFrame );
281 timeLCD->setNumDigits( 5 ); // "mm:ss" 288 timeLCD->setNumDigits( 5 ); // "mm:ss"
282 timeLCD->setBackgroundMode( PaletteButton ); 289 timeLCD->setBackgroundMode( PaletteButton );
283 290
284 setToolBarsMovable ( FALSE ); 291 setToolBarsMovable ( FALSE );
285 292
286 addToolBar( toolBar ); 293 addToolBar( toolBar );
287 294
288 MineFrame *mainframe = new MineFrame( this ); 295 MineFrame *mainframe = new MineFrame( this );
289 mainframe->setFrameShape( QFrame::Box ); 296 mainframe->setFrameShape( QFrame::Box );
290 mainframe->setFrameShadow( QFrame::Raised ); 297 mainframe->setFrameShadow( QFrame::Raised );
291 298
292 mainframe->setLineWidth(2); 299 mainframe->setLineWidth(2);
293 300
294 field = new MineField( mainframe ); 301 field = new MineField( mainframe );
295 mainframe->setField( field ); 302 mainframe->setField( field );
296 QFont fnt = field->font(); 303 QFont fnt = field->font();
297 fnt.setBold( TRUE ); 304 fnt.setBold( TRUE );
298 field->setFont( QFont( fnt ) ); 305 field->setFont( QFont( fnt ) );
299 field->setFocus(); 306 field->setFocus();
300 setCentralWidget( mainframe ); 307 setCentralWidget( mainframe );
301 308
302 connect( field, SIGNAL( gameOver( bool ) ), this, SLOT( gameOver( bool ) ) ); 309 connect( field, SIGNAL( gameOver(bool) ), this, SLOT( gameOver(bool) ) );
303 connect( field, SIGNAL( mineCount( int ) ), this, SLOT( setCounter( int ) ) ); 310 connect( field, SIGNAL( mineCount(int) ), this, SLOT( setCounter(int) ) );
304 connect( field, SIGNAL( gameStarted()), this, SLOT( startPlaying() ) ); 311 connect( field, SIGNAL( gameStarted()), this, SLOT( startPlaying() ) );
305 312
306 timer = new QTimer( this ); 313 timer = new QTimer( this );
307
308 connect( timer, SIGNAL( timeout() ), this, SLOT( updateTime() ) ); 314 connect( timer, SIGNAL( timeout() ), this, SLOT( updateTime() ) );
309 315
310 readConfig(); 316 readConfig();
311} 317}
312 318
313MineSweep::~MineSweep() 319MineSweep::~MineSweep()
314{ 320{
315 writeConfig(); 321 writeConfig();
316} 322}
317 323
318void MineSweep::gameOver( bool won ) 324void MineSweep::gameOver( bool won )
319{ 325{
320 field->showMines(); 326 field->showMines();
321 if ( won ) { 327 if ( won ) {
322 newGameButton->setPixmap( QPixmap( happy_xpm ) ); 328 newGameButton->setPixmap( QPixmap( happy_xpm ) );
323 } else { 329 } else {
324 newGameButton->setPixmap( QPixmap( dead_xpm ) ); 330 newGameButton->setPixmap( QPixmap( dead_xpm ) );
325 } 331 }
326 ResultIndicator::showResult( this, won ); 332 ResultIndicator::showResult( this, won );
327 timer->stop(); 333 timer->stop();
328} 334}
329 335
330void MineSweep::newGame() 336void MineSweep::newGame()
331{ 337{
332 newGame(field->level()); 338 newGame(field->level());
333} 339}
334 340
335void MineSweep::newGame(int level) 341void MineSweep::newGame(int level)
336{ 342{
337 timeLCD->display( "0:00" ); 343 timeLCD->display( "0:00" );
338 field->setup( level ); 344 field->setup( level );
339 newGameButton->setPixmap( QPixmap( pix_new ) ); 345 newGameButton->setPixmap( QPixmap( pix_new ) );
340 timer->stop(); 346 timer->stop();
341} 347}
342 348
343void MineSweep::startPlaying() 349void MineSweep::startPlaying()
344{ 350{
345 newGameButton->setPixmap( QPixmap( worried_xpm ) ); 351 newGameButton->setPixmap( QPixmap( worried_xpm ) );
346 starttime = QDateTime::currentDateTime(); 352 starttime = QDateTime::currentDateTime();
347 timer->start( 1000 ); 353 timer->start( 1000 );
348} 354}
349 355
350void MineSweep::beginner() 356void MineSweep::beginner()
351{ 357{
352 newGame(1); 358 newGame(1);
353} 359}
354 360
355void MineSweep::advanced() 361void MineSweep::advanced()
356{ 362{
357 newGame(2); 363 newGame(2);
358} 364}
359 365
360void MineSweep::expert() 366void MineSweep::expert()
361{ 367{
362 newGame(3); 368 newGame(3);
363} 369}
364 370
365void MineSweep::setCounter( int c ) 371void MineSweep::setCounter( int c )
366{ 372{
367 if ( !guessLCD ) 373 if ( !guessLCD )
368 return; 374 return;
369 375
370 guessLCD->display( c ); 376 guessLCD->display( c );
371} 377}
372 378
373void MineSweep::updateTime() 379void MineSweep::updateTime()
374{ 380{
375 if ( !timeLCD ) 381 if ( !timeLCD )
376 return; 382 return;
377 383
378 int s = starttime.secsTo(QDateTime::currentDateTime()); 384 int s = starttime.secsTo(QDateTime::currentDateTime());
379 if ( s/60 > 99 ) 385 if ( s/60 > 99 )
380 timeLCD->display( "-----" ); 386 timeLCD->display( "-----" );
381 else 387 else
382 timeLCD->display( QString().sprintf("%2d:%02d",s/60,s%60) ); 388 timeLCD->display( QString().sprintf("%2d:%02d",s/60,s%60) );
383} 389}
384 390
385void MineSweep::writeConfig() const 391void MineSweep::writeConfig() const
386{ 392{
387 Config cfg("MineSweep"); 393 Config cfg("MineSweep");
388 cfg.setGroup("Panel"); 394 cfg.setGroup("Panel");
389 cfg.writeEntry("Time", 395 cfg.writeEntry("Time",
390 timer->isActive() ? starttime.secsTo(QDateTime::currentDateTime()) : -1); 396 timer->isActive() ? starttime.secsTo(QDateTime::currentDateTime()) : -1);
391 field->writeConfig(cfg); 397 field->writeConfig(cfg);
392} 398}
393 399
394void MineSweep::readConfig() 400void MineSweep::readConfig()
395{ 401{
396 Config cfg("MineSweep"); 402 Config cfg("MineSweep");
397 field->readConfig(cfg); 403 field->readConfig(cfg);
398 cfg.setGroup("Panel"); 404 cfg.setGroup("Panel");
399 int s = cfg.readNumEntry("Time",-1); 405 int s = cfg.readNumEntry("Time",-1);
400 if ( s<0 ) { 406 if ( s<0 ) {
401 newGame(); 407 newGame();
402 } else { 408 } else {
403 startPlaying(); 409 startPlaying();
404 starttime = QDateTime::currentDateTime().addSecs(-s); 410 starttime = QDateTime::currentDateTime().addSecs(-s);
405 updateTime(); 411 updateTime();
406 } 412 }
407} 413}