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