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