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 
BEGIN_EVENT_TABLE(FortyCanvas,wxScrolledWindow)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 
~FortyCanvas()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 */
UpdateScores()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 
OnDraw(wxDC & dc)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 
ShowPlayerDialog()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 */
OnCloseCanvas()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 
OnMouseEvent(wxMouseEvent & event)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 
SetCursorStyle(int x,int y)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 
NewGame()244 void FortyCanvas::NewGame()
245 {
246     m_game->Deal();
247     Refresh();
248 }
249 
Undo()250 void FortyCanvas::Undo()
251 {
252     wxClientDC dc(this);
253     PrepareDC(dc);
254     dc.SetFont(* m_font);
255     m_game->Undo(dc);
256 }
257 
Redo()258 void FortyCanvas::Redo()
259 {
260     wxClientDC dc(this);
261     PrepareDC(dc);
262     dc.SetFont(* m_font);
263     m_game->Redo(dc);
264 }
265 
LayoutGame()266 void FortyCanvas::LayoutGame()
267 {
268        m_game->Layout();
269 }
270