~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to demos/bombs/bombs.cpp

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////////
 
2
// Name:        bombs.cpp
 
3
// Purpose:     Bombs game
 
4
// Author:      P. Foggia 1996
 
5
// Modified by: Wlodzimierz Skiba (ABX) since 2003
 
6
// Created:     1996
 
7
// RCS-ID:      $Id: bombs.cpp 70789 2012-03-04 00:28:58Z VZ $
 
8
// Copyright:   (c) 1996 P. Foggia
 
9
// Licence:     wxWindows licence
 
10
///////////////////////////////////////////////////////////////////////////////
 
11
 
 
12
#include "wx/wxprec.h"
 
13
 
 
14
#ifdef __BORLANDC__
 
15
#   pragma hdrstop
 
16
#endif
 
17
 
 
18
#ifndef  WX_PRECOMP
 
19
#   include "wx/wx.h"
 
20
#endif //precompiled headers
 
21
 
 
22
#include "wx/stockitem.h"
 
23
 
 
24
#include "bombs.h"
 
25
 
 
26
#include <stdlib.h>
 
27
 
 
28
#ifndef __WXWINCE__
 
29
#   include <time.h>
 
30
#endif
 
31
 
 
32
#ifndef wxHAS_IMAGES_IN_RESOURCES
 
33
#   include "bombs.xpm"
 
34
#endif
 
35
 
 
36
IMPLEMENT_APP(BombsApp)
 
37
 
 
38
#ifdef __WXWINCE__
 
39
    STDAPI_(__int64) CeGetRandomSeed();
 
40
#endif
 
41
 
 
42
// Called to initialize the program
 
43
bool BombsApp::OnInit()
 
44
{
 
45
#ifdef __WXWINCE__
 
46
    srand((unsigned) CeGetRandomSeed());
 
47
#else
 
48
    srand((unsigned) time(NULL));
 
49
#endif
 
50
 
 
51
    m_frame = new BombsFrame(&m_game);
 
52
 
 
53
    m_frame->NewGame(bombsID_EASY, false);
 
54
 
 
55
    return true;
 
56
}
 
57
 
 
58
BEGIN_EVENT_TABLE(BombsFrame, wxFrame)
 
59
    EVT_MENU(wxID_NEW,           BombsFrame::OnNewGame)
 
60
    EVT_MENU(bombsID_EASY,       BombsFrame::OnEasyGame)
 
61
    EVT_MENU(bombsID_MEDIUM,     BombsFrame::OnMediumGame)
 
62
    EVT_MENU(bombsID_HARD,       BombsFrame::OnHardGame)
 
63
    EVT_MENU(bombsID_EASYCORNER, BombsFrame::OnEasyCorner)
 
64
    EVT_MENU(wxID_EXIT,          BombsFrame::OnExit)
 
65
    EVT_MENU(wxID_ABOUT,         BombsFrame::OnAbout)
 
66
END_EVENT_TABLE()
 
67
 
 
68
BombsFrame::BombsFrame(BombsGame *game)
 
69
    : wxFrame(NULL, wxID_ANY, wxT("wxBombs"), wxDefaultPosition,
 
70
        wxSize(300, 300), wxDEFAULT_DIALOG_STYLE|wxMINIMIZE_BOX)
 
71
{
 
72
    m_game = game;
 
73
    m_easyCorner = false;
 
74
    m_lastLevel = bombsID_EASY;
 
75
 
 
76
    SetIcon(wxICON(bombs));
 
77
 
 
78
#if wxUSE_STATUSBAR
 
79
    CreateStatusBar();
 
80
#endif
 
81
 
 
82
    // Create a menu bar for the frame
 
83
    wxMenuBar *menuBar = new wxMenuBar;
 
84
    wxMenu *menuFile = new wxMenu;
 
85
    wxMenu *menuLevel = new wxMenu;
 
86
    menuLevel->AppendRadioItem(bombsID_EASY, wxT("&Easy (10x10)\tCtrl-1"));
 
87
    menuLevel->AppendRadioItem(bombsID_MEDIUM, wxT("&Medium (15x15)\tCtrl-2"));
 
88
    menuLevel->AppendRadioItem(bombsID_HARD, wxT("&Hard (25x20)\tCtrl-3"));
 
89
 
 
90
    menuFile->Append(wxID_NEW, wxT("&New game\tCtrl-N"));
 
91
    menuFile->Append(bombsID_LEVEL, wxT("&Level"),menuLevel, wxT("Starts a new game"));
 
92
    menuFile->AppendCheckItem(bombsID_EASYCORNER, wxT("&Easy corner"));
 
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
    m_lastLevel = level;
 
141
 
 
142
    switch(level)
 
143
    {
 
144
    case bombsID_EASY:
 
145
        numHorzCells = numVertCells = 10;
 
146
        break;
 
147
 
 
148
    case bombsID_MEDIUM:
 
149
        numHorzCells = numVertCells = 15;
 
150
        break;
 
151
 
 
152
    case bombsID_HARD:
 
153
        numHorzCells = 25; numVertCells = 20;
 
154
        break;
 
155
 
 
156
    default :
 
157
        wxFAIL_MSG(wxT("Invalid level"));
 
158
        break;
 
159
    }
 
160
 
 
161
    m_game->Init(numHorzCells, numVertCells, m_easyCorner);
 
162
 
 
163
    GetMenuBar()->Check(level, true);
 
164
 
 
165
    m_canvas->UpdateGridSize();
 
166
    SetClientSize(m_canvas->GetGridSizeInPixels());
 
167
}
 
168
 
 
169
void BombsFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
 
170
{
 
171
    wxMessageBox(
 
172
        wxT("wxBombs (c) 1996 by P. Foggia\n<foggia@amalfi.dis.unina.it>"),
 
173
        wxT("About wxBombs") );
 
174
}
 
175
 
 
176
void BombsFrame::OnNewGame(wxCommandEvent& WXUNUSED(event))
 
177
{
 
178
    NewGame(m_lastLevel, true);
 
179
}
 
180
 
 
181
void BombsFrame::OnEasyGame(wxCommandEvent& WXUNUSED(event))
 
182
{
 
183
    NewGame(bombsID_EASY, true);
 
184
}
 
185
 
 
186
void BombsFrame::OnMediumGame(wxCommandEvent& WXUNUSED(event))
 
187
{
 
188
    NewGame(bombsID_MEDIUM, true);
 
189
}
 
190
 
 
191
void BombsFrame::OnHardGame(wxCommandEvent& WXUNUSED(event))
 
192
{
 
193
    NewGame(bombsID_HARD, true);
 
194
}
 
195
 
 
196
void BombsFrame::OnEasyCorner(wxCommandEvent& WXUNUSED(event))
 
197
{
 
198
    wxString msg;
 
199
    if(m_easyCorner)
 
200
        msg = wxT("enable");
 
201
    else
 
202
        msg = wxT("disable");
 
203
 
 
204
    msg = wxT("Do you really want to ") + msg + wxT(" having\ntop left corner always empty for easier start?");
 
205
 
 
206
    int ok = wxMessageBox(
 
207
               msg,
 
208
               wxT("Confirm"),
 
209
               wxYES_NO | wxICON_QUESTION,
 
210
               this
 
211
             );
 
212
 
 
213
    if(ok!=wxYES)return;
 
214
 
 
215
    m_easyCorner = !m_easyCorner;
 
216
 
 
217
    NewGame(m_lastLevel, true);
 
218
}
 
219
 
 
220
BEGIN_EVENT_TABLE(BombsCanvas, wxPanel)
 
221
    EVT_PAINT(BombsCanvas::OnPaint)
 
222
    EVT_MOUSE_EVENTS(BombsCanvas::OnMouseEvent)
 
223
    EVT_CHAR(BombsCanvas::OnChar)
 
224
END_EVENT_TABLE()
 
225
 
 
226
BombsCanvas::BombsCanvas(wxFrame *parent, BombsGame *game)
 
227
    : wxPanel(parent, wxID_ANY)
 
228
{
 
229
    m_game = game;
 
230
    int sx, sy;
 
231
    wxClientDC dc(this);
 
232
    wxFont font= BOMBS_FONT;
 
233
    dc.SetFont(font);
 
234
 
 
235
    wxCoord chw, chh;
 
236
    wxString buf = wxT("M");
 
237
 
 
238
    dc.GetTextExtent(buf, &chw, &chh);
 
239
    dc.SetFont(wxNullFont);
 
240
 
 
241
    dc.SetMapMode(wxMM_METRIC);
 
242
 
 
243
    int xcm = dc.LogicalToDeviceX(10);
 
244
    int ycm = dc.LogicalToDeviceY(10);
 
245
    // To have a square cell, there must be :
 
246
    //    sx*ycm == sy*xcm
 
247
    if (chw*ycm < chh*xcm)
 
248
    {
 
249
        sy = chh;
 
250
        sx = chh*xcm/ycm;
 
251
    }
 
252
    else
 
253
    {
 
254
        sx = chw;
 
255
        sy = chw*ycm/xcm;
 
256
    }
 
257
 
 
258
    m_cellWidth = (sx+3+X_UNIT)/X_UNIT;
 
259
    m_cellHeight = (sy+3+Y_UNIT)/Y_UNIT;
 
260
    dc.SetMapMode(wxMM_TEXT);
 
261
    m_bmp = NULL;
 
262
}
 
263
 
 
264
BombsCanvas::~BombsCanvas()
 
265
{
 
266
    if (m_bmp)
 
267
    {
 
268
        delete m_bmp;
 
269
        m_bmp = NULL;
 
270
    }
 
271
}
 
272
 
 
273
// Called when canvas needs to be repainted.
 
274
void BombsCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
 
275
{
 
276
    wxPaintDC dc(this);
 
277
 
 
278
    const int numHorzCells = m_game->GetWidth();
 
279
    const int numVertCells = m_game->GetHeight();
 
280
    // Insert your drawing code here.
 
281
    if (!m_bmp)
 
282
    {
 
283
        wxSize size = dc.GetSize();
 
284
        m_bmp = new wxBitmap(size.GetWidth(), size.GetHeight());
 
285
        if (m_bmp)
 
286
        {
 
287
            wxMemoryDC memDC;
 
288
            memDC.SelectObject(*m_bmp);
 
289
            DrawField(&memDC, 0, 0, numHorzCells-1, numVertCells-1);
 
290
            memDC.SelectObject(wxNullBitmap);
 
291
        }
 
292
    }
 
293
 
 
294
    if (m_bmp)
 
295
    {
 
296
        wxMemoryDC memDC;
 
297
        memDC.SelectObject(*m_bmp);
 
298
        wxSize size = dc.GetSize();
 
299
        dc.Blit(0, 0, size.GetWidth(), size.GetHeight(),
 
300
            &memDC, 0, 0, wxCOPY);
 
301
      memDC.SelectObject(wxNullBitmap);
 
302
    }
 
303
    else
 
304
    {
 
305
        DrawField(&dc, 0, 0, numHorzCells-1, numVertCells-1);
 
306
    }
 
307
}
 
308
 
 
309
void BombsCanvas::UpdateGridSize()
 
310
{
 
311
 
 
312
    if (m_bmp)
 
313
    {
 
314
        delete m_bmp;
 
315
        m_bmp = NULL;
 
316
    }
 
317
    SetSize(GetGridSizeInPixels());
 
318
    Refresh();
 
319
}
 
320
 
 
321
wxSize BombsCanvas::GetGridSizeInPixels() const
 
322
{
 
323
    return wxSize(m_cellWidth*X_UNIT*m_game->GetWidth(),
 
324
        m_cellHeight*Y_UNIT*m_game->GetHeight());
 
325
}
 
326