]> git.saurik.com Git - wxWidgets.git/blob - demos/bombs/bombs.cpp
Need wxFULL_REPAINT_ON_SIZE for the background to erase properly (needs to be
[wxWidgets.git] / demos / bombs / bombs.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: bombs.cpp
3 // Purpose: Bombs game
4 // Author: P. Foggia 1996
5 // Modified by: Wlodzimierz Skiba (ABX) 2003
6 // Created: 1996
7 // RCS-ID: $Id$
8 // Copyright: (c) 1996 P. Foggia
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 # pragma implementation
14 #endif
15
16 #include "wx/wxprec.h"
17
18 #ifdef __BORLANDC__
19 # pragma hdrstop
20 #endif
21
22 #ifndef WX_PRECOMP
23 # include "wx/wx.h"
24 #endif //precompiled headers
25
26 #include "wx/stockitem.h"
27
28 #include "bombs.h"
29
30 #include <stdlib.h>
31
32 #ifndef __WXWINCE__
33 # include <time.h>
34 #endif
35
36 #if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) \
37 || defined(__WXMAC__) || defined(__WXMGL__)
38 # include "bombs.xpm"
39 #endif
40
41 IMPLEMENT_APP(BombsApp)
42
43 #ifdef __WXWINCE__
44 STDAPI_(__int64) CeGetRandomSeed();
45 #endif
46
47 // Called to initialize the program
48 bool BombsApp::OnInit()
49 {
50 #ifdef __WXWINCE__
51 srand((unsigned) CeGetRandomSeed());
52 #else
53 srand((unsigned) time(NULL));
54 #endif
55
56 m_frame = new BombsFrame(&m_game);
57
58 m_frame->NewGame(bombsID_EASY, false);
59
60 return true;
61 }
62
63 BEGIN_EVENT_TABLE(BombsFrame, wxFrame)
64 EVT_MENU(bombsID_EASY, BombsFrame::OnNewEasyGame)
65 EVT_MENU(bombsID_MEDIUM, BombsFrame::OnNewMediumGame)
66 EVT_MENU(bombsID_HARD, BombsFrame::OnNewHardGame)
67 EVT_MENU(wxID_EXIT, BombsFrame::OnExit)
68 EVT_MENU(wxID_ABOUT, BombsFrame::OnAbout)
69 END_EVENT_TABLE()
70
71 BombsFrame::BombsFrame(BombsGame *game)
72 : wxFrame(NULL, wxID_ANY, wxT("wxBombs"), wxDefaultPosition,
73 wxSize(300, 300), wxDEFAULT_DIALOG_STYLE|wxMINIMIZE_BOX)
74 {
75 m_game = game;
76
77 SetIcon(wxICON(bombs));
78
79 #if wxUSE_STATUSBAR
80 CreateStatusBar();
81 #endif
82
83 // Create a menu bar for the frame
84 wxMenuBar *menuBar = new wxMenuBar;
85 wxMenu *menuFile = new wxMenu;
86 wxMenu *menuLevel = new wxMenu;
87 menuLevel->AppendRadioItem(bombsID_EASY, wxT("&Easy (10x10)\tCtrl-1"));
88 menuLevel->AppendRadioItem(bombsID_MEDIUM, wxT("&Medium (15x15)\tCtrl-2"));
89 menuLevel->AppendRadioItem(bombsID_HARD, wxT("&Hard (25x20)\tCtrl-3"));
90
91 menuFile->Append(bombsID_NEWGAME, wxT("&New Game"),
92 menuLevel, wxT("Starts a new game"));
93
94 menuFile->AppendSeparator();
95 menuFile->Append(wxID_EXIT, wxGetStockLabel(wxID_EXIT), wxT("Quits the application"));
96
97 menuBar->Append(menuFile, wxT("&File"));
98
99
100 wxMenu *menuHelp = new wxMenu;
101 menuHelp->Append(wxID_ABOUT, wxT("&About"),
102 wxT("Displays the program information") );
103
104 menuBar->Append(menuHelp, wxT("&Help"));
105
106 SetMenuBar(menuBar);
107
108 // Create child subwindows.
109 m_canvas = new BombsCanvas(this, m_game);
110
111 // Ensure the subwindows get resized o.k.
112 // OnSize(width, height);
113
114 // Centre frame on the screen.
115 Centre(wxBOTH);
116
117 // Show the frame.
118 Show();
119 }
120
121 void BombsFrame::OnExit(wxCommandEvent& WXUNUSED(event))
122 {
123 Close();
124 }
125
126 void BombsFrame::NewGame(int level, bool query)
127 {
128 if(query)
129 {
130 int ok = wxMessageBox(
131 wxT("Start new game regardless previous board?"),
132 wxT("Confirm"),
133 wxYES_NO | wxICON_QUESTION,
134 this
135 );
136 if(ok!=wxYES)return;
137 }
138
139 int numHorzCells = 20, numVertCells = 20;
140
141 switch(level)
142 {
143 case bombsID_EASY:
144 numHorzCells = numVertCells = 10;
145 break;
146
147 case bombsID_MEDIUM:
148 numHorzCells = numVertCells = 15;
149 break;
150
151 case bombsID_HARD:
152 numHorzCells = 25; numVertCells = 20;
153 break;
154
155 default :
156 wxFAIL_MSG(wxT("Invalid level"));
157 break;
158 }
159
160 m_game->Init(numHorzCells, numVertCells);
161
162 GetMenuBar()->Check(level, true);
163
164 m_canvas->UpdateGridSize();
165 SetClientSize(m_canvas->GetGridSizeInPixels());
166 }
167
168 void BombsFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
169 {
170 wxMessageBox(
171 wxT("wxBombs (c) 1996 by P. Foggia\n<foggia@amalfi.dis.unina.it>"),
172 wxT("About wxBombs") );
173 }
174
175 void BombsFrame::OnNewEasyGame(wxCommandEvent& WXUNUSED(event))
176 {
177 NewGame(bombsID_EASY, true);
178 }
179
180 void BombsFrame::OnNewMediumGame(wxCommandEvent& WXUNUSED(event))
181 {
182 NewGame(bombsID_MEDIUM, true);
183 }
184
185 void BombsFrame::OnNewHardGame(wxCommandEvent& WXUNUSED(event))
186 {
187 NewGame(bombsID_HARD, true);
188 }
189
190 BEGIN_EVENT_TABLE(BombsCanvas, wxPanel)
191 EVT_PAINT(BombsCanvas::OnPaint)
192 EVT_MOUSE_EVENTS(BombsCanvas::OnMouseEvent)
193 EVT_CHAR(BombsCanvas::OnChar)
194 END_EVENT_TABLE()
195
196 BombsCanvas::BombsCanvas(wxFrame *parent, BombsGame *game)
197 : wxPanel(parent, wxID_ANY)
198 {
199 m_game = game;
200 int sx, sy;
201 wxClientDC dc(this);
202 wxFont font= BOMBS_FONT;
203 dc.SetFont(font);
204
205 long chw, chh;
206 wxString buf = wxT("M");
207
208 dc.GetTextExtent(buf, &chw, &chh);
209 dc.SetFont(wxNullFont);
210
211 dc.SetMapMode(wxMM_METRIC);
212
213 int xcm = dc.LogicalToDeviceX(10);
214 int ycm = dc.LogicalToDeviceY(10);
215 // To have a square cell, there must be :
216 // sx*ycm == sy*xcm
217 if (chw*ycm < chh*xcm)
218 {
219 sy = chh;
220 sx = chh*xcm/ycm;
221 }
222 else
223 {
224 sx = chw;
225 sy = chw*ycm/xcm;
226 }
227
228 m_cellWidth = (sx+3+X_UNIT)/X_UNIT;
229 m_cellHeight = (sy+3+Y_UNIT)/Y_UNIT;
230 dc.SetMapMode(wxMM_TEXT);
231 m_bmp = NULL;
232 }
233
234 BombsCanvas::~BombsCanvas()
235 {
236 if (m_bmp)
237 {
238 delete m_bmp;
239 m_bmp = NULL;
240 }
241 }
242
243 // Called when canvas needs to be repainted.
244 void BombsCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
245 {
246 wxPaintDC dc(this);
247
248 const int numHorzCells = m_game->GetWidth();
249 const int numVertCells = m_game->GetHeight();
250 // Insert your drawing code here.
251 if (!m_bmp)
252 {
253 wxSize size = dc.GetSize();
254 m_bmp = new wxBitmap(size.GetWidth(), size.GetHeight());
255 if (m_bmp)
256 {
257 wxMemoryDC memDC;
258 memDC.SelectObject(*m_bmp);
259 DrawField(&memDC, 0, 0, numHorzCells-1, numVertCells-1);
260 memDC.SelectObject(wxNullBitmap);
261 }
262 }
263
264 if (m_bmp)
265 {
266 wxMemoryDC memDC;
267 memDC.SelectObject(*m_bmp);
268 wxSize size = dc.GetSize();
269 dc.Blit(0, 0, size.GetWidth(), size.GetHeight(),
270 &memDC, 0, 0, wxCOPY);
271 memDC.SelectObject(wxNullBitmap);
272 }
273 else
274 {
275 DrawField(&dc, 0, 0, numHorzCells-1, numVertCells-1);
276 }
277 }
278
279 void BombsCanvas::UpdateGridSize()
280 {
281
282 if (m_bmp)
283 {
284 delete m_bmp;
285 m_bmp = NULL;
286 }
287
288 Refresh();
289 }
290
291 wxSize BombsCanvas::GetGridSizeInPixels() const
292 {
293 return wxSize(m_cellWidth*X_UNIT*m_game->GetWidth(),
294 m_cellHeight*Y_UNIT*m_game->GetHeight());
295 }
296