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