]> git.saurik.com Git - wxWidgets.git/blob - demos/bombs/bombs.cpp
fixed clip rect when logical coords != device ones
[wxWidgets.git] / demos / bombs / bombs.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: bombs.cpp
3 // Purpose: Bombs game
4 // Author: P. Foggia 1996
5 // Modified by:
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 #ifndef WX_PRECOMP
19 #include "wx/wx.h"
20 #endif //precompiled headers
21
22 #include "bombs.h"
23
24 #include <time.h>
25 #include <stdlib.h>
26
27 #if defined(__WXGTK__) || defined(__WXMOTIF__)
28 #include "bombs.xpm"
29 #endif
30
31 IMPLEMENT_APP(AppClass)
32
33 // Called to initialize the program
34 bool AppClass::OnInit()
35 {
36 srand((unsigned)time(NULL));
37
38 // Initialize all the top-level window members to NULL.
39 BombsFrame = NULL;
40 level=IDM_EASY;
41
42 BombsFrame =
43 new BombsFrameClass(NULL, "wxBombs", wxPoint(155, 165), wxSize(300, 300), wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION);
44
45 int xmax=BombsFrame->BombsCanvas->field_width*BombsFrame->BombsCanvas->x_cell*X_UNIT;
46 int ymax=BombsFrame->BombsCanvas->field_height*BombsFrame->BombsCanvas->y_cell*Y_UNIT;
47 BombsFrame->SetClientSize(xmax, ymax);
48
49 return TRUE;
50 }
51
52 BEGIN_EVENT_TABLE(BombsFrameClass, wxFrame)
53 EVT_MENU(IDM_EASY, BombsFrameClass::OnEasy)
54 EVT_MENU(IDM_MEDIUM, BombsFrameClass::OnMedium)
55 EVT_MENU(IDM_DIFFICULT, BombsFrameClass::OnDifficult)
56 EVT_MENU(IDM_EXIT, BombsFrameClass::OnExit)
57 EVT_MENU(IDM_ABOUT, BombsFrameClass::OnAbout)
58 EVT_MENU(IDM_RESTART, BombsFrameClass::OnRestart)
59 EVT_CLOSE(BombsFrameClass::OnCloseWindow)
60 END_EVENT_TABLE()
61
62 BombsFrameClass::BombsFrameClass(wxFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
63 wxFrame(parent, -1, title, pos, size, style)
64 {
65 // Initialize child subwindow members.
66 BombsCanvas = NULL;
67
68 SetIcon(wxICON(bombs));
69
70 CreateStatusBar();
71
72 // Create a menu bar for the frame
73 wxMenuBar *menuBar1 = new wxMenuBar;
74 wxMenu *menu1 = new wxMenu;
75 menu1->Append(IDM_EXIT, "E&xit"); // , "Quit the program");
76 menu1->AppendSeparator();
77 menu1->Append(IDM_ABOUT, "&About..."); // , "Infos on wxBombs");
78 menuBar1->Append(menu1, "&File");
79 wxMenu *menu2 = new wxMenu;
80 menu2->Append(IDM_RESTART, "&Restart"); // , "Clear the play field");
81 menu2->AppendSeparator();
82 menu2->Append(IDM_EASY, "&Easy", wxEmptyString, TRUE); // "10x10 play field", TRUE);
83 menu2->Append(IDM_MEDIUM, "&Medium", wxEmptyString, TRUE); // "15x15 play field", TRUE);
84 menu2->Append(IDM_DIFFICULT, "&Difficult", wxEmptyString, TRUE); // "25x20 play field", TRUE);
85 menuBar1->Append(menu2, "&Game");
86 SetMenuBar(menuBar1);
87 menuBar=menuBar1;
88 menuBar->Check(wxGetApp().level, TRUE);
89
90 // Create child subwindows.
91 BombsCanvas = new BombsCanvasClass(this);
92
93 // Ensure the subwindows get resized o.k.
94 // OnSize(width, height);
95
96 // Centre frame on the screen.
97 Centre(wxBOTH);
98
99 // Show the frame.
100 Show(TRUE);
101 }
102
103 BombsFrameClass::~BombsFrameClass(void)
104 {
105 }
106
107 void BombsFrameClass::OnCloseWindow(wxCloseEvent& event)
108 {
109 this->Destroy();
110 }
111
112 void BombsFrameClass::OnExit(wxCommandEvent& event)
113 {
114 this->Destroy();
115 }
116
117 void BombsFrameClass::OnRestart(wxCommandEvent& event)
118 {
119 BombsCanvas->UpdateFieldSize();
120 int xmax=BombsCanvas->field_width*BombsCanvas->x_cell*X_UNIT;
121 int ymax=BombsCanvas->field_height*BombsCanvas->y_cell*Y_UNIT;
122 wxGetApp().BombsFrame->SetClientSize(xmax, ymax);
123 }
124
125 void BombsFrameClass::OnAbout(wxCommandEvent& event)
126 {
127 wxMessageBox("wxBombs (c) 1996 by P. Foggia\n<foggia@amalfi.dis.unina.it>", "About wxBombs");
128 }
129
130 void BombsFrameClass::OnEasy(wxCommandEvent& event)
131 {
132 menuBar->Check(wxGetApp().level, FALSE);
133 wxGetApp().level=IDM_EASY;
134 menuBar->Check(wxGetApp().level, TRUE);
135 }
136
137 void BombsFrameClass::OnMedium(wxCommandEvent& event)
138 {
139 menuBar->Check(wxGetApp().level, FALSE);
140 wxGetApp().level=IDM_MEDIUM;
141 menuBar->Check(wxGetApp().level, TRUE);
142 }
143
144 void BombsFrameClass::OnDifficult(wxCommandEvent& event)
145 {
146 menuBar->Check(wxGetApp().level, FALSE);
147 wxGetApp().level=IDM_DIFFICULT;
148 menuBar->Check(wxGetApp().level, TRUE);
149 }
150
151 BEGIN_EVENT_TABLE(BombsCanvasClass, wxWindow)
152 EVT_PAINT(BombsCanvasClass::OnPaint)
153 EVT_MOUSE_EVENTS(BombsCanvasClass::OnEvent)
154 END_EVENT_TABLE()
155
156 BombsCanvasClass::BombsCanvasClass(wxFrame *parent, const wxPoint& pos, const wxSize& size, long style):
157 wxWindow(parent, -1, pos, size, style)
158 {
159 int sx, sy;
160 wxClientDC dc(this);
161 wxFont font= BOMBS_FONT;
162 dc.SetFont(font);
163
164 long chw, chh;
165 char buf[]="M";
166
167 dc.GetTextExtent(buf, &chw, &chh);
168 dc.SetFont(wxNullFont);
169
170 dc.SetMapMode(wxMM_METRIC);
171
172 int xcm = dc.LogicalToDeviceX(10.0);
173 int ycm = dc.LogicalToDeviceY(10.0);
174 // To have a square cell, there must be :
175 // sx*ycm == sy*xcm
176 if (chw*ycm < chh*xcm)
177 { sy=chh;
178 sx=chh*xcm/ycm;
179 }
180 else
181 { sx=chw;
182 sy=chw*ycm/xcm;
183 }
184 x_cell = (sx+3+X_UNIT)/X_UNIT;
185 y_cell = (sy+3+Y_UNIT)/Y_UNIT;
186 dc.SetMapMode(wxMM_TEXT);
187 bmp=NULL;
188 UpdateFieldSize();
189 }
190
191 BombsCanvasClass::~BombsCanvasClass(void)
192 {
193 if (bmp)
194 delete bmp;
195 }
196
197 // Called when canvas needs to be repainted.
198 void BombsCanvasClass::OnPaint(wxPaintEvent& event)
199 {
200 wxPaintDC dc(this);
201
202 // Insert your drawing code here.
203 if (!bmp)
204 { bmp=new wxBitmap(field_width*x_cell*X_UNIT+1,
205 field_height*y_cell*Y_UNIT+1);
206 if (bmp)
207 { wxMemoryDC memDC;
208 memDC.SelectObject(* bmp);
209 DrawField(&memDC, 0, 0, field_width-1, field_height-1);
210 memDC.SelectObject(wxNullBitmap);
211 }
212 }
213 if (bmp)
214 { wxMemoryDC memDC;
215 memDC.SelectObject(* bmp);
216 dc.Blit(0, 0, field_width*x_cell*X_UNIT+1,
217 field_height*y_cell*Y_UNIT+1,
218 &memDC, 0, 0, wxCOPY);
219 memDC.SelectObject(wxNullBitmap);
220 }
221 else
222 DrawField(& dc, 0, 0, field_width-1, field_height-1);
223 }
224
225 // Updates the field size depending on wxGetApp().level and
226 // redraws the canvas
227 void BombsCanvasClass::UpdateFieldSize()
228 { field_width=20;
229 field_height=20;
230
231 switch(wxGetApp().level)
232 { case IDM_EASY:
233 field_width=10;
234 field_height=10;
235 break;
236 case IDM_MEDIUM:
237 field_width=15;
238 field_height=15;
239 break;
240 case IDM_DIFFICULT:
241 field_width=25;
242 field_height=20;
243 break;
244 }
245 wxGetApp().Game.Init(field_width, field_height);
246
247 if (bmp)
248 delete bmp;
249 bmp=NULL;
250
251 wxWindow::Refresh();
252 }