canvas.cpp 6.5 KB

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