Define _CRT_NONSTDC_NO_WARNINGS for zlib compilation with MSVC.
[wxWidgets.git] / demos / forty / canvas.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: canvas.cpp
3 // Purpose: Forty Thieves patience game
4 // Author: Chris Breeze
5 // Modified by:
6 // Created: 21/07/97
7 // Copyright: (c) 1993-1998 Chris Breeze
8 // Licence: wxWindows licence
9 //---------------------------------------------------------------------------
10 // Last modified: 22nd July 1998 - ported to wxWidgets 2.0
11 /////////////////////////////////////////////////////////////////////////////
12
13 // For compilers that support precompilation, includes "wx/wx.h".
14 #include "wx/wxprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #ifndef WX_PRECOMP
21 #include "wx/wx.h"
22 #endif
23
24 #include "forty.h"
25 #include "card.h"
26 #include "game.h"
27 #include "scorefil.h"
28 #include "playerdg.h"
29 #include "canvas.h"
30
31 BEGIN_EVENT_TABLE(FortyCanvas, wxScrolledWindow)
32 EVT_MOUSE_EVENTS(FortyCanvas::OnMouseEvent)
33 END_EVENT_TABLE()
34
35 FortyCanvas::FortyCanvas(wxWindow* parent, const wxPoint& pos, const wxSize& size) :
36 wxScrolledWindow(parent, wxID_ANY, pos, size, 0),
37 m_helpingHand(true),
38 m_rightBtnUndo(true),
39 m_playerDialog(0),
40 m_leftBtnDown(false)
41 {
42 SetScrollbars(0, 0, 0, 0);
43
44 #ifdef __WXGTK__
45 m_font = wxTheFontList->FindOrCreateFont(12, wxROMAN, wxNORMAL, wxNORMAL);
46 #else
47 m_font = wxTheFontList->FindOrCreateFont(10, wxSWISS, wxNORMAL, wxNORMAL);
48 #endif
49 SetBackgroundColour(FortyApp::BackgroundColour());
50
51 m_handCursor = new wxCursor(wxCURSOR_HAND);
52 m_arrowCursor = new wxCursor(wxCURSOR_ARROW);
53
54 wxString name = wxTheApp->GetAppName();
55 if ( name.empty() ) name = wxT("forty");
56 m_scoreFile = new ScoreFile(name);
57 m_game = new Game(0, 0, 0);
58 m_game->Deal();
59 }
60
61
62 FortyCanvas::~FortyCanvas()
63 {
64 UpdateScores();
65 delete m_game;
66 delete m_scoreFile;
67 delete m_handCursor;
68 delete m_arrowCursor;
69 }
70
71
72 /*
73 Write the current player's score back to the score file
74 */
75 void FortyCanvas::UpdateScores()
76 {
77 if (!m_player.empty() && m_scoreFile && m_game)
78 {
79 m_scoreFile->WritePlayersScore(
80 m_player,
81 m_game->GetNumWins(),
82 m_game->GetNumGames(),
83 m_game->GetScore()
84 );
85 }
86 }
87
88
89 void FortyCanvas::OnDraw(wxDC& dc)
90 {
91 dc.SetFont(* m_font);
92 m_game->Redraw(dc);
93 #if 0
94 // if player name not set (and selection dialog is not displayed)
95 // then ask the player for their name
96 if (m_player.empty() && !m_playerDialog)
97 {
98 m_playerDialog = new PlayerSelectionDialog(this, m_scoreFile);
99 m_playerDialog->ShowModal();
100 m_player = m_playerDialog->GetPlayersName();
101 if ( !m_player.empty() )
102 {
103 // user entered a name - lookup their score
104 int wins, games, score;
105 m_scoreFile->ReadPlayersScore(m_player, wins, games, score);
106 m_game->NewPlayer(wins, games, score);
107 m_game->DisplayScore(dc);
108 m_playerDialog->Destroy();
109 m_playerDialog = 0;
110 Refresh(false);
111 }
112 else
113 {
114 // user cancelled the dialog - exit the app
115 ((wxFrame*)GetParent())->Close(true);
116 }
117 }
118 #endif
119 }
120
121 void FortyCanvas::ShowPlayerDialog()
122 {
123 // if player name not set (and selection dialog is not displayed)
124 // then ask the player for their name
125 if (m_player.empty() && !m_playerDialog)
126 {
127 m_playerDialog = new PlayerSelectionDialog(this, m_scoreFile);
128 m_playerDialog->ShowModal();
129 m_player = m_playerDialog->GetPlayersName();
130 if ( !m_player.empty() )
131 {
132 // user entered a name - lookup their score
133 int wins, games, score;
134 m_scoreFile->ReadPlayersScore(m_player, wins, games, score);
135 m_game->NewPlayer(wins, games, score);
136
137 wxClientDC dc(this);
138 dc.SetFont(* m_font);
139 m_game->DisplayScore(dc);
140 m_playerDialog->Destroy();
141 m_playerDialog = 0;
142 Refresh(false);
143 }
144 else
145 {
146 // user cancelled the dialog - exit the app
147 ((wxFrame*)GetParent())->Close(true);
148 }
149 }
150 }
151
152 /*
153 Called when the main frame is closed
154 */
155 bool FortyCanvas::OnCloseCanvas()
156 {
157 if (m_game->InPlay() &&
158 wxMessageBox(wxT("Are you sure you want to\nabandon the current game?"),
159 wxT("Warning"), wxYES_NO | wxICON_QUESTION) == wxNO)
160 {
161 return false;
162 }
163 return true;
164 }
165
166 void FortyCanvas::OnMouseEvent(wxMouseEvent& event)
167 {
168 int mouseX = (int)event.GetX();
169 int mouseY = (int)event.GetY();
170
171 wxClientDC dc(this);
172 PrepareDC(dc);
173 dc.SetFont(* m_font);
174
175 if (event.LeftDClick())
176 {
177 if (m_leftBtnDown)
178 {
179 m_leftBtnDown = false;
180 ReleaseMouse();
181 m_game->LButtonUp(dc, mouseX, mouseY);
182 }
183 m_game->LButtonDblClk(dc, mouseX, mouseY);
184 }
185 else if (event.LeftDown())
186 {
187 if (!m_leftBtnDown)
188 {
189 m_leftBtnDown = true;
190 CaptureMouse();
191 m_game->LButtonDown(dc, mouseX, mouseY);
192 }
193 }
194 else if (event.LeftUp())
195 {
196 if (m_leftBtnDown)
197 {
198 m_leftBtnDown = false;
199 ReleaseMouse();
200 m_game->LButtonUp(dc, mouseX, mouseY);
201 }
202 }
203 else if (event.RightDown() && !event.LeftIsDown())
204 {
205 // only allow right button undo if m_rightBtnUndo is true
206 if (m_rightBtnUndo)
207 {
208 if (event.ControlDown() || event.ShiftDown())
209 {
210 m_game->Redo(dc);
211 }
212 else
213 {
214 m_game->Undo(dc);
215 }
216 }
217 }
218 else if (event.Dragging())
219 {
220 m_game->MouseMove(dc, mouseX, mouseY);
221 }
222
223 if (!event.LeftIsDown())
224 {
225 SetCursorStyle(mouseX, mouseY);
226 }
227 }
228
229 void FortyCanvas::SetCursorStyle(int x, int y)
230 {
231 // Only set cursor to a hand if 'helping hand' is enabled and
232 // the card under the cursor can go somewhere
233 if (m_game->CanYouGo(x, y) && m_helpingHand)
234 {
235 SetCursor(* m_handCursor);
236 }
237 else
238 {
239 SetCursor(* m_arrowCursor);
240 }
241
242 }
243
244 void FortyCanvas::NewGame()
245 {
246 m_game->Deal();
247 Refresh();
248 }
249
250 void FortyCanvas::Undo()
251 {
252 wxClientDC dc(this);
253 PrepareDC(dc);
254 dc.SetFont(* m_font);
255 m_game->Undo(dc);
256 }
257
258 void FortyCanvas::Redo()
259 {
260 wxClientDC dc(this);
261 PrepareDC(dc);
262 dc.SetFont(* m_font);
263 m_game->Redo(dc);
264 }
265
266 void FortyCanvas::LayoutGame()
267 {
268 m_game->Layout();
269 }