1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        forty.cpp
3 // Purpose:     Forty Thieves patience game
4 // Author:      Chris Breeze
5 // Modified by:
6 // Created:     21/07/97
7 // RCS-ID:      $Id: forty.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 "canvas.h"
26 #include "forty.h"
27 #include "card.h"
28 #include "scoredg.h"
29 #include "forty.xpm"
30 
31 #if wxUSE_HTML
32 #include "wx/textfile.h"
33 #include "wx/html/htmlwin.h"
34 #endif
35 
36 #include "wx/stockitem.h"
37 
38 BEGIN_EVENT_TABLE(FortyFrame, wxFrame)
39     EVT_MENU(wxID_NEW, FortyFrame::NewGame)
40     EVT_MENU(wxID_EXIT, FortyFrame::Exit)
41     EVT_MENU(wxID_ABOUT, FortyFrame::About)
42     EVT_MENU(wxID_HELP_CONTENTS, FortyFrame::Help)
43     EVT_MENU(wxID_UNDO, FortyFrame::Undo)
44     EVT_MENU(wxID_REDO, FortyFrame::Redo)
45     EVT_MENU(SCORES, FortyFrame::Scores)
46     EVT_MENU(RIGHT_BUTTON_UNDO, FortyFrame::ToggleRightButtonUndo)
47     EVT_MENU(HELPING_HAND, FortyFrame::ToggleHelpingHand)
48     EVT_MENU(LARGE_CARDS, FortyFrame::ToggleCardSize)
49     EVT_CLOSE(FortyFrame::OnCloseWindow)
50 END_EVENT_TABLE()
51 
52 // Create a new application object
53 IMPLEMENT_APP (FortyApp)
54 
55 wxColour* FortyApp::m_backgroundColour = 0;
56 wxColour* FortyApp::m_textColour = 0;
57 wxBrush*  FortyApp::m_backgroundBrush = 0;
58 
~FortyApp()59 FortyApp::~FortyApp()
60 {
61     delete m_backgroundColour;
62     delete m_textColour;
63     delete m_backgroundBrush;
64     delete Card::m_symbolBmap;
65     delete Card::m_pictureBmap;
66 
67 }
68 
OnInit()69 bool FortyApp::OnInit()
70 {
71     bool largecards = false;
72 #ifndef __WXWINCE__
73     m_helpFile = wxGetCwd() + wxFILE_SEP_PATH + wxT("about.htm");
74     if (!wxFileExists(m_helpFile))
75 #endif
76     {
77         m_helpFile = wxPathOnly(argv[0]) + wxFILE_SEP_PATH + wxT("about.htm");
78     }
79 
80     wxSize size(668,510);
81 
82     if ((argc > 1) && (!wxStrcmp(argv[1],_T("-L"))))
83     {
84         largecards = true;
85         size = wxSize(1000,750);
86     }
87 
88     FortyFrame* frame = new FortyFrame(
89             0,
90             _T("Forty Thieves"),
91             wxDefaultPosition,
92             size,
93             largecards
94     );
95 
96      // Show the frame
97     frame->Show(true);
98 
99     frame->GetCanvas()->ShowPlayerDialog();
100 
101     return true;
102 }
103 
BackgroundColour()104 const wxColour& FortyApp::BackgroundColour()
105 {
106     if (!m_backgroundColour)
107     {
108         m_backgroundColour = new wxColour(0, 128, 0);
109     }
110 
111     return *m_backgroundColour;
112 }
113 
BackgroundBrush()114 const wxBrush& FortyApp::BackgroundBrush()
115 {
116     if (!m_backgroundBrush)
117     {
118         m_backgroundBrush = new wxBrush(BackgroundColour(), wxSOLID);
119     }
120 
121     return *m_backgroundBrush;
122 }
123 
TextColour()124 const wxColour& FortyApp::TextColour()
125 {
126     if (!m_textColour)
127     {
128         m_textColour = new wxColour(*wxBLACK);
129     }
130 
131     return *m_textColour;
132 }
133 
134 // My frame constructor
FortyFrame(wxFrame * frame,const wxString & title,const wxPoint & pos,const wxSize & size,bool largecards)135 FortyFrame::FortyFrame(wxFrame* frame, const wxString& title, const wxPoint& pos, const wxSize& size, bool largecards):
136     wxFrame(frame, wxID_ANY, title, pos, size)
137 {
138 #ifdef __WXMAC__
139     wxApp::s_macAboutMenuItemId = wxID_ABOUT ;
140 #endif
141     // set the icon
142 #ifdef __WXMSW__
143     SetIcon(wxIcon(_T("CardsIcon")));
144 #else
145     SetIcon(wxIcon(forty_xpm));
146 #endif
147 
148     // Make a menu bar
149     wxMenu* gameMenu = new wxMenu;
150     gameMenu->Append(wxID_NEW, wxGetStockLabel(wxID_NEW), _T("Start a new game"));
151     gameMenu->Append(SCORES, _T("&Scores..."), _T("Displays scores"));
152     gameMenu->Append(wxID_EXIT, wxGetStockLabel(wxID_EXIT), _T("Exits Forty Thieves"));
153 
154     wxMenu* editMenu = new wxMenu;
155     editMenu->Append(wxID_UNDO, wxGetStockLabel(wxID_UNDO), _T("Undo the last move"));
156     editMenu->Append(wxID_REDO, wxGetStockLabel(wxID_REDO), _T("Redo a move that has been undone"));
157 
158     wxMenu* optionsMenu = new wxMenu;
159     optionsMenu->Append(RIGHT_BUTTON_UNDO,
160             _T("&Right button undo"),
161             _T("Enables/disables right mouse button undo and redo"),
162             true
163             );
164     optionsMenu->Append(HELPING_HAND,
165             _T("&Helping hand"),
166             _T("Enables/disables hand cursor when a card can be moved"),
167             true
168             );
169     optionsMenu->Append(LARGE_CARDS,
170             _T("&Large cards"),
171             _T("Enables/disables large cards for high resolution displays"),
172             true
173             );
174     optionsMenu->Check(HELPING_HAND, true);
175     optionsMenu->Check(RIGHT_BUTTON_UNDO, true);
176     optionsMenu->Check(LARGE_CARDS, largecards ? true : false);
177 
178     wxMenu* helpMenu = new wxMenu;
179     helpMenu->Append(wxID_HELP_CONTENTS, _T("&Help Contents"), _T("Displays information about playing the game"));
180     helpMenu->Append(wxID_ABOUT, _T("&About..."), _T("About Forty Thieves"));
181 
182     m_menuBar = new wxMenuBar;
183     m_menuBar->Append(gameMenu,    _T("&Game"));
184     m_menuBar->Append(editMenu,    _T("&Edit"));
185     m_menuBar->Append(optionsMenu, _T("&Options"));
186     m_menuBar->Append(helpMenu,    _T("&Help"));
187 
188     SetMenuBar(m_menuBar);
189 
190     if (largecards)
191         Card::SetScale(1.3);
192 
193     m_canvas = new FortyCanvas(this, wxDefaultPosition, size);
194 
195     wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
196     topsizer->Add( m_canvas, 1, wxEXPAND | wxALL, 0);
197     SetSizer( topsizer );
198 
199 #if wxUSE_STATUSBAR
200     CreateStatusBar();
201 #endif // wxUSE_STATUSBAR
202 
203     topsizer->SetSizeHints( this );
204 }
205 
OnCloseWindow(wxCloseEvent & event)206 void FortyFrame::OnCloseWindow(wxCloseEvent& event)
207 {
208     if (m_canvas->OnCloseCanvas() )
209     {
210         this->Destroy();
211     }
212     else
213         event.Veto();
214 }
215 
216 void
NewGame(wxCommandEvent &)217 FortyFrame::NewGame(wxCommandEvent&)
218 {
219     m_canvas->NewGame();
220 }
221 
222 void
Exit(wxCommandEvent &)223 FortyFrame::Exit(wxCommandEvent&)
224 {
225     Close(true);
226 }
227 
228 void
Help(wxCommandEvent & event)229 FortyFrame::Help(wxCommandEvent& event)
230 {
231 #if wxUSE_HTML
232     if (wxFileExists(wxGetApp().GetHelpFile()))
233     {
234         FortyAboutDialog dialog(this, wxID_ANY, wxT("Forty Thieves Instructions"));
235         if (dialog.ShowModal() == wxID_OK)
236         {
237         }
238     }
239     else
240 #endif
241     {
242         About(event);
243     }
244 }
245 
246 void
About(wxCommandEvent &)247 FortyFrame::About(wxCommandEvent&)
248 {
249         wxMessageBox(
250             _T("Forty Thieves\n\n")
251             _T("A free card game written with the wxWidgets toolkit\n")
252             _T("Author: Chris Breeze (c) 1992-2004\n")
253             _T("email: chris@breezesys.com"),
254             _T("About Forty Thieves"),
255             wxOK|wxICON_INFORMATION, this
256             );
257 }
258 
259 
260 void
Undo(wxCommandEvent &)261 FortyFrame::Undo(wxCommandEvent&)
262 {
263     m_canvas->Undo();
264 }
265 
266 void
Redo(wxCommandEvent &)267 FortyFrame::Redo(wxCommandEvent&)
268 {
269     m_canvas->Redo();
270 }
271 
272 void
Scores(wxCommandEvent &)273 FortyFrame::Scores(wxCommandEvent&)
274 {
275     m_canvas->UpdateScores();
276     ScoreDialog scores(this, m_canvas->GetScoreFile());
277     scores.Display();
278 }
279 
280 void
ToggleRightButtonUndo(wxCommandEvent & event)281 FortyFrame::ToggleRightButtonUndo(wxCommandEvent& event)
282 {
283     bool checked = m_menuBar->IsChecked(event.GetId());
284     m_canvas->EnableRightButtonUndo(checked);
285 }
286 
287 void
ToggleHelpingHand(wxCommandEvent & event)288 FortyFrame::ToggleHelpingHand(wxCommandEvent& event)
289 {
290     bool checked = m_menuBar->IsChecked(event.GetId());
291     m_canvas->EnableHelpingHand(checked);
292 }
293 
294 void
ToggleCardSize(wxCommandEvent & event)295 FortyFrame::ToggleCardSize(wxCommandEvent& event)
296 {
297         bool checked = m_menuBar->IsChecked(event.GetId());
298         Card::SetScale(checked ? 1.3 : 1);
299         m_canvas->LayoutGame();
300         m_canvas->Refresh();
301 }
302 
303 //----------------------------------------------------------------------------
304 // stAboutDialog
305 //----------------------------------------------------------------------------
306 
FortyAboutDialog(wxWindow * parent,wxWindowID id,const wxString & title,const wxPoint & position,const wxSize & size,long style)307 FortyAboutDialog::FortyAboutDialog( wxWindow *parent, wxWindowID id, const wxString &title,
308     const wxPoint &position, const wxSize& size, long style ) :
309     wxDialog( parent, id, title, position, size, style )
310 {
311     AddControls(this);
312 
313     Centre(wxBOTH);
314 }
315 
AddControls(wxWindow * parent)316 bool FortyAboutDialog::AddControls(wxWindow* parent)
317 {
318 #if wxUSE_HTML
319     wxString htmlText;
320     wxString htmlFile = wxGetApp().GetHelpFile();
321 
322     {
323         wxTextFile file(htmlFile);
324         if (file.Exists())
325         {
326             file.Open();
327             for ( htmlText = file.GetFirstLine();
328                   !file.Eof();
329                   htmlText << file.GetNextLine() << _T("\n") ) ;
330         }
331     }
332 
333     if (htmlText.empty())
334     {
335         htmlText.Printf(wxT("<html><head><title>Warning</title></head><body><P>Sorry, could not find resource for About dialog<P></body></html>"));
336     }
337 
338     // Customize the HTML
339     htmlText.Replace(wxT("$DATE$"), _T(__DATE__));
340 
341     wxSize htmlSize(400, 290);
342 
343     // Note: in later versions of wxWin this will be fixed so wxRAISED_BORDER
344     // does the right thing. Meanwhile, this is a workaround.
345 #ifdef __WXMSW__
346     long borderStyle = wxDOUBLE_BORDER;
347 #else
348     long borderStyle = wxRAISED_BORDER;
349 #endif
350 
351     wxHtmlWindow* html = new wxHtmlWindow(this, ID_ABOUT_HTML_WINDOW, wxDefaultPosition, htmlSize, borderStyle);
352     html -> SetBorders(10);
353     html -> SetPage(htmlText);
354 
355     //// Start of sizer-based control creation
356 
357     wxSizer *item0 = new wxBoxSizer( wxVERTICAL );
358 
359     wxWindow *item1 = parent->FindWindow( ID_ABOUT_HTML_WINDOW );
360     wxASSERT( item1 );
361     item0->Add( item1, 0, wxALIGN_CENTRE|wxALL, 5 );
362 
363     wxButton *item2 = new wxButton( parent, wxID_CLOSE );
364     item2->SetDefault();
365     item2->SetFocus();
366     SetAffirmativeId(wxID_CLOSE);
367 
368     item0->Add( item2, 0, wxALIGN_RIGHT|wxALL, 5 );
369 
370     parent->SetSizer( item0 );
371     parent->Layout();
372     item0->Fit( parent );
373     item0->SetSizeHints( parent );
374 #endif
375 
376     return true;
377 }
378