source: trunk/src/MainFrame.cpp @ 205

Revision 205, 43.4 KB checked in by guyru, 3 years ago (diff)

Load the last reset date correctly and only report to the statistics a new game once.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/***************************************************************************
2 *   Copyright (C) 2006-2008 by Guy Rutenberg   *
3 *   guyrutenberg@gmail.com   *
4 *                                                                         *
5 *   This program is free software; you can redistribute it and/or modify  *
6 *   it under the terms of the GNU General Public License as published by  *
7 *   the Free Software Foundation; either version 2 of the License, or     *
8 *   (at your option) any later version.                                   *
9 *                                                                         *
10 *   This program is distributed in the hope that it will be useful,       *
11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13 *   GNU General Public License for more details.                          *
14 *                                                                         *
15 *   You should have received a copy of the GNU General Public License     *
16 *   along with this program; if not, write to the                         *
17 *   Free Software Foundation, Inc.,                                       *
18 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19 ***************************************************************************/
20
21 /***********************************************
22 *      This File contains the definitions      *
23 *      of MainFrame's functions                *
24 ***********************************************/
25
26//#define DEBUG
27
28#include <wx/wx.h>
29
30#include "MainFrame.h"
31#include "wxDynamicBitmap.h"
32#include "highscores_dialog.h"
33#include "about.h"
34#include "configuration.h"
35#include "settings_dialog.h"
36#include "statistics_dialog.h"
37#include "../config.h"
38#include <iostream>
39#include <sstream>
40#include <cstdlib>
41#include <wx/version.h>
42#include <wx/filename.h>
43#include <wx/stdpaths.h>
44#include <wx/mstream.h>
45
46 //include the images for the dice       
47namespace dice {
48#include "one.xpm"
49#include "two.xpm"
50#include "three.xpm"
51#include "four.xpm"
52#include "five.xpm"
53#include "six.xpm"
54} // namespace dice
55
56#include "icon32.xpm"
57
58//default values - design
59#define SPACE_SIZE 1
60#define DICE_SPACE 3
61#ifdef WIN32
62        #define KEEP_SPACE 13
63        #define VERTICAL_ROLL_SIZEX 64
64        #define VERTICAL_ROLL_SIZEY 53
65#else
66        #define KEEP_SPACE 5
67        #define VERTICAL_ROLL_SIZEX 64
68        #define VERTICAL_ROLL_SIZEY 64
69#endif
70#define VER_DICE_SPACER 10
71
72using namespace main_frame;
73
74MainFrame::MainFrame(const wxString& title, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE)
75        : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, size, style)
76{
77        //give the frame an icon
78        SetIcon(wxIcon(icon32_xpm));
79
80        #ifndef PORTABLE
81                wxString config_file = wxStandardPaths::Get().GetUserConfigDir() + wxT("/.openyahtzee");
82                wxString old_config_file = wxFileName::GetHomeDir() + wxT("/.OpenYahtzee");
83                //rename old configuration file
84                if (wxFileExists(old_config_file)) {
85                        wxRenameFile(old_config_file,config_file,false);
86                }
87        #else
88                wxFileName tmp_config_file(wxStandardPaths::Get().GetExecutablePath());
89                tmp_config_file.SetFullName(wxT("openyahtzee.dat"));
90                wxString config_file = tmp_config_file.GetFullPath();
91        #endif
92
93       
94        std::string config_file_str;
95        config_file_str = config_file.utf8_str();
96        m_config.reset(new configuration::Configuration(config_file_str));
97        m_stats.reset(new statistics::Statistics(m_config.get()));
98
99        m_evt_handler = new MainFrameEvtHandler(this);
100       
101        bitmap_dice[0] = new wxBitmap(dice::one_xpm);
102        bitmap_dice[1] = new wxBitmap(dice::two_xpm);
103        bitmap_dice[2] = new wxBitmap(dice::three_xpm);
104        bitmap_dice[3] = new wxBitmap(dice::four_xpm);
105        bitmap_dice[4] = new wxBitmap(dice::five_xpm);
106        bitmap_dice[5] = new wxBitmap(dice::six_xpm);
107       
108        //randomize the random-number generator based on the time
109        srand( (unsigned)time( NULL ) );
110       
111        AddMenus();
112
113        AddControlsAndLayout();
114       
115        //make the text boxes uneditable to the user   
116        wxTextCtrl *textctrl;
117        for(int i = ID_ACESTEXT;i<=ID_GRANDTOTAL;i++) {
118                textctrl = (wxTextCtrl*) FindWindow(i);
119                textctrl->SetEditable(false);
120        }
121       
122        //disable the undo button
123        (GetMenuBar()->FindItem(wxID_UNDO))->Enable(false);
124
125        ConnectEventTable();
126       
127        ResetRolls();
128        m_yahtzee = false;
129        m_yahtzeebonus = false;
130        m_numofplaysleft = 13;
131}
132
133/**
134 * Adds the menus and menu items to the MainFrame.
135 */
136void MainFrame::AddMenus()
137{
138        /*Create the menus*/
139        wxMenu *gameMenu = new wxMenu;  //create Game menu
140        wxMenu *help_menu = new wxMenu; //create Help menu
141       
142       
143        //insert menu items into menu Help
144        help_menu->Append(ID_HOWTOPLAY, wxT("How to Play\tF1"));
145        help_menu->Append(ID_FAQ, wxT("Frequently Asked Questions"));
146        help_menu->Append(ID_SENDCOMMENT, wxT("&Send Feedback"));
147        help_menu->Append(wxID_ABOUT);
148
149        //insert menu items into menu Game
150        gameMenu->Append(wxID_NEW,wxT("&New Game\tF2"));
151        gameMenu->Append(wxID_UNDO,wxT("&Undo\tCtrl+Z"));
152        gameMenu->Append(ID_SHOWHIGHSCORE,wxT("Show Highscores\tCtrl+H"));
153        gameMenu->Append(ID_STATISTICS,wxT("Statistics..."));
154        gameMenu->Append(ID_SETTINGS,wxT("Settings"));
155        gameMenu->Append(wxID_EXIT);
156       
157        // Declare the menu-bar and append the freshly created menus to the menu bar...
158        wxMenuBar *menuBar = new wxMenuBar();
159        menuBar->Append(gameMenu, wxT("&Game"));
160        menuBar->Append(help_menu, wxT("&Help"));
161       
162        // ... and attach this menu bar to the frame
163        SetMenuBar(menuBar);
164}
165
166/**
167 * Add the controls to the frame and use sizers to lay them out.
168 */
169void MainFrame::AddControlsAndLayout()
170{
171        wxPanel* panel = new wxPanel(this, ID_PANEL,
172                wxDefaultPosition, wxDefaultSize);
173
174        wxBoxSizer *topSizer;
175        wxFlexGridSizer *diceSizer;
176
177        if (m_config->get("horizontal-layout")=="True") {
178                topSizer = new wxBoxSizer( wxVERTICAL );
179                sectionsSizer = new wxBoxSizer( wxHORIZONTAL );
180                diceSizer = new wxFlexGridSizer(2, 0, 0, 0);
181        } else {
182                topSizer = new wxBoxSizer( wxHORIZONTAL );
183                sectionsSizer = new wxBoxSizer( wxVERTICAL );
184                diceSizer = new wxFlexGridSizer(1, 0, 0);;
185        }
186
187        uppersection = new wxStaticBoxSizer( new wxStaticBox(
188                panel, wxID_ANY, wxT("Upper Section") ), wxVERTICAL);
189       
190        lowersection = new wxStaticBoxSizer(new wxStaticBox(
191                panel, wxID_ANY, wxT("Lower Section") ), wxVERTICAL);
192       
193        wxFlexGridSizer* uppergrid = new wxFlexGridSizer(2, 0, 10);
194        wxFlexGridSizer* lowergrid = new wxFlexGridSizer(2, 0, 10);
195
196        //BEGIN layout for the upper section of the score board
197        uppergrid->Add(new wxButton(panel,ID_ACES,wxT("Aces")),
198                0, wxALL, SPACE_SIZE);
199        uppergrid->Add(new wxTextCtrl(panel, ID_ACESTEXT),1,wxALL,SPACE_SIZE);
200        uppergrid->Add(new wxButton(panel,ID_TWOS,wxT("Twos")),
201                0, wxALL, SPACE_SIZE);
202        uppergrid->Add(new wxTextCtrl(panel, ID_TWOSTEXT),1,wxALL,SPACE_SIZE);
203        uppergrid->Add(new wxButton(panel,ID_THREES,wxT("Threes")),
204                0, wxALL, SPACE_SIZE);
205        uppergrid->Add(new wxTextCtrl(panel, ID_THREESTEXT),1,wxALL,SPACE_SIZE);
206        uppergrid->Add(new wxButton(panel,ID_FOURS,wxT("Fours")),
207                0, wxALL, SPACE_SIZE);
208        uppergrid->Add(new wxTextCtrl(panel, ID_FOURSTEXT),1,wxALL,SPACE_SIZE);
209        uppergrid->Add(new wxButton(panel,ID_FIVES,wxT("Fives")),
210                0, wxALL, SPACE_SIZE);
211        uppergrid->Add(new wxTextCtrl(panel, ID_FIVESTEXT),1,wxALL,SPACE_SIZE);
212        uppergrid->Add(new wxButton(panel,ID_SIXES,wxT("Sixes")),
213                0, wxALL, SPACE_SIZE);
214        uppergrid->Add(new wxTextCtrl(panel, ID_SIXESTEXT),1,wxALL,SPACE_SIZE);
215        uppergrid->Add(new wxStaticText(panel, wxID_ANY, wxT("Total score:")),
216                0, wxALL, SPACE_SIZE);
217        uppergrid->Add(new wxTextCtrl(panel, ID_UPPERSECTIONTOTAL),
218                1, wxALL, SPACE_SIZE);
219        uppergrid->Add(new wxStaticText(panel, wxID_ANY, wxT("Bonus:")),
220                0, wxALL, SPACE_SIZE);
221        uppergrid->Add(new wxTextCtrl(panel, ID_BONUS),1,wxALL,SPACE_SIZE);
222        uppergrid->Add(new wxStaticText(panel, wxID_ANY,
223                wxT("Total of upper section:")), 0, wxALL, SPACE_SIZE);
224        uppergrid->Add(new wxTextCtrl(panel, ID_UPPERTOTAL),
225                1, wxALL, SPACE_SIZE);
226        //END layout for the upper section of the score board
227
228        //BEGIN layout for the lower section of the score board
229        lowergrid->Add(new wxButton(panel,ID_THREEOFAKIND,wxT("3 of a kind")),
230                0, wxALL, SPACE_SIZE);
231        lowergrid->Add(new wxTextCtrl(panel, ID_THREEOFAKINDTEXT),
232                1, wxALL, SPACE_SIZE);
233        lowergrid->Add(new wxButton(panel,ID_FOUROFAKIND,wxT("4 of a kind")),
234                0, wxALL, SPACE_SIZE);
235        lowergrid->Add(new wxTextCtrl(panel, ID_FOUROFAKINDTEXT),
236                1, wxALL, SPACE_SIZE);
237        lowergrid->Add(new wxButton(panel,ID_FULLHOUSE,wxT("Full House")),
238                0, wxALL, SPACE_SIZE);
239        lowergrid->Add(new wxTextCtrl(panel, ID_FULLHOUSETEXT),
240                1, wxALL, SPACE_SIZE);
241        lowergrid->Add(new wxButton(panel, ID_SMALLSEQUENCE,
242                wxT("Sequence of 4")), 0, wxALL,SPACE_SIZE);
243        lowergrid->Add(new wxTextCtrl(panel, ID_SMALLSEQUENCETEXT),
244                1, wxALL, SPACE_SIZE);
245        lowergrid->Add(new wxButton(panel, ID_LARGESEQUENCE,
246                wxT("Sequence of 5")), 0, wxALL, SPACE_SIZE);
247        lowergrid->Add(new wxTextCtrl(panel, ID_LARGESEQUENCETEXT),
248                1, wxALL, SPACE_SIZE);
249        lowergrid->Add(new wxButton(panel, ID_YAHTZEE, wxT("Yahtzee")),
250                0, wxALL, SPACE_SIZE);
251        lowergrid->Add(new wxTextCtrl(panel,ID_YAHTZEETEXT),1,wxALL,SPACE_SIZE);
252        lowergrid->Add(new wxButton(panel, ID_CHANCE, wxT("Chance")),
253                0, wxALL, SPACE_SIZE);
254        lowergrid->Add(new wxTextCtrl(panel, ID_CHANCETEXT),1,wxALL,SPACE_SIZE);
255        lowergrid->Add(new wxStaticText(panel, wxID_ANY,
256                wxT("Yahtzee Bonus")), 0, wxALL, SPACE_SIZE);
257        lowergrid->Add(new wxTextCtrl(panel, ID_YAHTZEEBONUSTEXT),
258                1, wxALL, SPACE_SIZE);
259        lowergrid->Add(new wxStaticText(panel, wxID_ANY,
260                wxT("Total of lower section:")),0,wxALL,SPACE_SIZE);
261        lowergrid->Add(new wxTextCtrl(panel, ID_LOWERTOTAL),1,wxALL,SPACE_SIZE);
262        lowergrid->Add(new wxStaticText(panel, wxID_ANY, wxT("Grand Total:")),
263                0, wxALL, SPACE_SIZE);
264        lowergrid->Add(new wxTextCtrl(panel, ID_GRANDTOTAL),1,wxALL,SPACE_SIZE);
265        //END layout for the lower section of the score board
266
267        uppersection->Add(uppergrid);
268        lowersection->Add(lowergrid);
269        sectionsSizer->Add(uppersection, 0, wxALL, 5);
270        sectionsSizer->Add(lowersection, 0, wxALL, 5);
271
272        //BEGIN layout for the dice section of the score board
273        if (m_config->get("horizontal-layout")=="True") {
274                diceSizer->Add(new wxDynamicBitmap(panel, ID_DICE1,
275                        bitmap_dice[0]), 0, wxALL, DICE_SPACE);
276                diceSizer->Add(new wxDynamicBitmap(panel,
277                        ID_DICE2, bitmap_dice[1]), 0, wxALL, DICE_SPACE);
278                diceSizer->Add(new wxDynamicBitmap(panel,
279                        ID_DICE3, bitmap_dice[2]), 0, wxALL,DICE_SPACE);
280                diceSizer->Add(new wxDynamicBitmap(panel,
281                        ID_DICE4, bitmap_dice[3]), 0, wxALL,DICE_SPACE);
282                diceSizer->Add(new wxDynamicBitmap(panel,
283                        ID_DICE5, bitmap_dice[4]), 0, wxALL,DICE_SPACE);
284                diceSizer->Add(new wxButton(panel, ID_ROLL, wxT("Roll!"),
285                        wxDefaultPosition, wxSize(64,64)), 0, wxALL,DICE_SPACE);
286                diceSizer->Add(new wxCheckBox(panel, ID_DICE1KEEP,
287                        wxT("Keep")), 0, wxBOTTOM | wxLEFT,KEEP_SPACE);
288                diceSizer->Add(new wxCheckBox(panel, ID_DICE2KEEP,
289                        wxT("Keep")), 0, wxBOTTOM | wxLEFT, KEEP_SPACE);
290                diceSizer->Add(new wxCheckBox(panel, ID_DICE3KEEP,
291                        wxT("Keep")), 0, wxBOTTOM | wxLEFT, KEEP_SPACE);
292                diceSizer->Add(new wxCheckBox(panel, ID_DICE4KEEP,
293                        wxT("Keep")), 0, wxBOTTOM | wxLEFT, KEEP_SPACE);
294                diceSizer->Add(new wxCheckBox(panel, ID_DICE5KEEP,
295                        wxT("Keep")), 0, wxBOTTOM | wxLEFT, KEEP_SPACE);
296        } else {
297                diceSizer->Add(new wxDynamicBitmap(panel, ID_DICE1,
298                        bitmap_dice[0]), 0, wxALL, DICE_SPACE);
299                diceSizer->Add(new wxCheckBox(panel, ID_DICE1KEEP,
300                        wxT("Keep")), 0, wxLEFT, KEEP_SPACE);
301                diceSizer->AddSpacer(VER_DICE_SPACER);
302                diceSizer->Add(new wxDynamicBitmap(panel,ID_DICE2,
303                        bitmap_dice[1]), 0, wxALL, DICE_SPACE);
304                diceSizer->Add(new wxCheckBox(panel, ID_DICE2KEEP,
305                        wxT("Keep")), 0, wxLEFT, KEEP_SPACE);
306                diceSizer->AddSpacer(VER_DICE_SPACER);
307                diceSizer->Add(new wxDynamicBitmap(panel, ID_DICE3,
308                        bitmap_dice[2]), 0, wxALL, DICE_SPACE);
309                diceSizer->Add(new wxCheckBox(panel, ID_DICE3KEEP,
310                        wxT("Keep")), 0, wxLEFT, KEEP_SPACE);
311                diceSizer->AddSpacer(VER_DICE_SPACER);
312                diceSizer->Add(new wxDynamicBitmap(panel, ID_DICE4,
313                        bitmap_dice[3]), 0, wxALL, DICE_SPACE);
314                diceSizer->Add(new wxCheckBox(panel, ID_DICE4KEEP,
315                        wxT("Keep")), 0, wxLEFT, KEEP_SPACE);
316                diceSizer->AddSpacer(VER_DICE_SPACER);
317                diceSizer->Add(new wxDynamicBitmap(panel, ID_DICE5,
318                        bitmap_dice[4]), 0, wxALL, DICE_SPACE);
319                diceSizer->Add(new wxCheckBox(panel, ID_DICE5KEEP,
320                        wxT("Keep")), 0, wxLEFT, KEEP_SPACE);
321                diceSizer->AddSpacer(VER_DICE_SPACER);
322                diceSizer->Add(new wxButton(panel, ID_ROLL, wxT("Roll!"),
323                        wxDefaultPosition, wxSize(VERTICAL_ROLL_SIZEX,
324                        VERTICAL_ROLL_SIZEY)), 0, wxALL, DICE_SPACE);
325        }
326        //END layout for the dice section of the score board *******/
327       
328        topSizer->Add(sectionsSizer);
329        topSizer->Add(diceSizer);       
330
331        panel->SetSizer(topSizer);
332       
333        topSizer->Fit(this);
334        topSizer->SetSizeHints(this);
335}
336
337/**
338 * Connects the tables to the event handlers
339 */
340void MainFrame::ConnectEventTable()
341{
342        //BEGIN connecting the menu items' events
343        Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnQuit));
344        Connect(wxID_ABOUT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnAbout));
345        Connect(ID_HOWTOPLAY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnHelpMenuLink));
346        Connect(ID_FAQ, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnHelpMenuLink));
347        Connect(ID_SENDCOMMENT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnSendComment));
348        Connect(wxID_NEW, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnNewGame));
349        Connect(wxID_UNDO, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnUndo));
350        Connect(ID_SHOWHIGHSCORE, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnShowHighscore));
351        Connect(ID_STATISTICS, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnStatistics));
352        Connect(ID_SETTINGS, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnSettings));
353        //END connecting the menu items' events
354
355        Connect(ID_ROLL, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::DoubleRollLock));
356
357        //BEGIN connecting the scoreboard buttons to the events
358        Connect(ID_ACES,ID_SIXES, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnUpperButtons));
359        Connect(ID_THREEOFAKIND, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::On3ofakindButton));
360        Connect(ID_FOUROFAKIND, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::On4ofakindButton));
361        Connect(ID_FULLHOUSE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnFullHouseButton));
362        Connect(ID_SMALLSEQUENCE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnSmallSequenceButton));
363        Connect(ID_LARGESEQUENCE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnLargeSequenceButton));
364        Connect(ID_YAHTZEE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnYahtzeeButton));
365        Connect(ID_CHANCE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnChanceButton));
366        Connect(ID_DICE1,ID_DICE5, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MainFrame::OnDiceClick));
367        Connect(ID_DICE1KEEP,ID_DICE5KEEP, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (MainFrame::OnKeepClick));
368        //END connecting the scoreboard buttons to the event
369
370        /* The following code connects the on wxEVT_ENTER_WINDOW and
371         * wxEVT_LEAVE_WINDOW events to the score buttons to handle the score
372         * hints. For some unknown technical problem we have to directly connect
373         * the events, otherwise the wxEVT_LEAVE_WINDOW doesn't get generated.
374         * We have to use event handler other than MainFrame's as the regular
375         * event handler leads to segmantation fault.
376         */
377        wxButton *temp;
378        for (int i = ID_ACES; i<=ID_CHANCE; i++) {
379                temp = ((wxButton *)FindWindow(i));
380                temp->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(MainFrameEvtHandler::OnScoreMouseLeave), NULL, m_evt_handler);
381                temp->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(MainFrameEvtHandler::OnScoreMouseEnter), NULL, m_evt_handler);
382        }
383}
384
385
386/*********EVENT PROCCESSING FUNCTIONS********/
387
388void MainFrame::OnAbout(wxCommandEvent& event)
389{
390        about::AboutDialog *about = new about::AboutDialog(this);
391        about->ShowModal();
392        delete about;
393}
394
395void MainFrame::OnHelpMenuLink (wxCommandEvent& event)
396{
397        wxString link;
398        switch (event.GetId()) {
399        case ID_HOWTOPLAY:
400                link = wxT("http://www.openyahtzee.org/wiki/HowToPlay");
401                break;
402        case ID_FAQ:
403                link = wxT("http://www.openyahtzee.org/wiki/FAQ");
404                break;
405        }
406       
407        wxLaunchDefaultBrowser(link);
408}
409
410
411/**
412 * Starts up the user browser and connects to the Open Yahtzee website's
413 * feedback page.
414 * \param event
415 */
416void MainFrame::OnSendComment (wxCommandEvent& event)
417{
418        wxString link = wxT("http://www.guyrutenberg.com/contact-me");
419       
420        wxLaunchDefaultBrowser(link);
421}
422
423void MainFrame::OnQuit(wxCommandEvent& event)
424{
425        // Destroy the frame
426        Close();
427}
428
429/**
430 * This is the event handler of the New Game menu item. It starts a new
431 * game and clears the board from the last game.
432 * \param event
433 */
434void MainFrame::OnNewGame(wxCommandEvent& event)
435{
436        //disable the undo button so it won't be enabled when a new game is started.
437        (GetMenuBar()->FindItem(wxID_UNDO))->Enable(false);
438       
439        ResetRolls();
440        m_yahtzee = false;
441        m_numofplaysleft = 13;
442       
443        for (int i = ID_ACESTEXT; i<= ID_GRANDTOTAL; i++)
444                ((wxTextCtrl*) FindWindow(i))->Clear();
445        for (int i = ID_ACES; i<= ID_CHANCE; i++)
446                ((wxButton*) FindWindow(i))->Enable(true);
447}
448
449/**
450 * This function handles the undo events. It's connected to the Undo menu item.
451 *
452 * Note that the function only allows undoing of scoring actions and not dice
453 * rolls. Also it won't allow the undoing of the last move of the game because
454 * of a technical problem relating to the case an high-score was made and then
455 * the user undo the last move and rescore another high-score and so on.
456 * \param event
457 */
458void MainFrame::OnUndo(wxCommandEvent& event)
459{
460        m_rolls = m_rollsundo;
461
462        //after the user scored the button was enabled, check if it should be disabled
463        if (m_rolls <= 0) //we don't have remaining rolls
464                ((wxButton*) FindWindow(ID_ROLL)) -> Enable(false);
465       
466        // change the displayed roll counter
467        wxString caption = wxString::Format(wxT("Roll! (%i)"),m_rolls);
468        FindWindow(ID_ROLL)->SetLabel(caption);
469
470        //restore the 'keep' checkboxes
471        for (int i=0; i<5; i++)
472                ((wxCheckBox*) FindWindow(i + ID_DICE1KEEP)) -> Enable(true);
473       
474        //reset the users last choice
475        FindWindow(m_lastmove)->Enable(true);
476
477        //clear the score;
478        ((wxTextCtrl*)FindWindow(ID_ACESTEXT + (m_lastmove - ID_ACES)))->SetValue(wxT(""));
479       
480        //Undo the Yahtzee flag if needed
481        if (m_lastmove == ID_YAHTZEE) {
482                m_yahtzee = false;
483        }
484
485        //undo also the yahtzee bonus if needed
486        if (m_yahtzeebonus) {
487                long temp;
488                wxString tempstr;
489       
490                tempstr = ((wxTextCtrl*) FindWindow(ID_YAHTZEEBONUSTEXT)) -> GetValue();
491                tempstr.ToLong(&temp,10);
492                temp -= 100; //this line reduces the points given for the yahtzee bonus
493                tempstr.Printf(wxT("%i"),temp);
494                ((wxTextCtrl*) FindWindow(ID_YAHTZEEBONUSTEXT)) -> SetValue(tempstr);
495        }
496
497        //recalculate the subtotals
498        CalculateSubTotal();
499
500        (GetMenuBar()->FindItem(wxID_UNDO))->Enable(false);
501        //cancel the counting for the choice that was canceled
502        m_numofplaysleft++;
503}
504
505/**
506 * This function enables the undo button and stores the last move
507 * \param id
508 */
509inline void MainFrame::EnableUndo(int id)
510{
511        if (m_numofplaysleft) {
512                (GetMenuBar()->FindItem(wxID_UNDO))->Enable(true);
513                m_lastmove = id;
514        }
515}
516
517/**
518 * Shows the high-score dialog. Connected to the Game->"Show High Score" menu item.
519 * \param event
520 */
521void MainFrame::OnShowHighscore(wxCommandEvent& event)
522{
523        highscores_dialog::HighscoresDialog *dialog = new highscores_dialog::HighscoresDialog(this, m_config.get());
524
525        dialog->ShowModal();
526
527        delete dialog;
528}
529
530void MainFrame::OnStatistics(wxCommandEvent &event)
531{
532        statistics_dialog::StatisticsDialog *dialog = new statistics_dialog::StatisticsDialog(this, m_stats.get());
533        dialog->ShowModal();
534        delete dialog;
535}
536
537/**
538 * Shows the settings dialog. This event-handler is connected to Game->Settings
539 * menu item.
540 * \param event
541 */
542void MainFrame::OnSettings( wxCommandEvent& event)
543{
544        settings_dialog::SettingsDialog* settings_dialog = new settings_dialog::SettingsDialog(this, m_config.get());
545
546        if (settings_dialog->ShowModal()!=wxID_OK) {
547                delete settings_dialog;
548                return;
549        }
550
551        ((wxTextCtrl*) FindWindow(ID_UPPERSECTIONTOTAL)) -> SetValue(wxT(""));
552        ((wxTextCtrl*) FindWindow(ID_LOWERTOTAL)) -> SetValue(wxT(""));
553        CalculateSubTotal();
554
555        Relayout();
556
557        delete settings_dialog;
558}
559
560/**
561 * Event handler for the Roll button. It checks the settings if it should
562 * animate the dice and then rolls them accordingly. It also checks for the
563 * status of the "keep" checkboxes.
564 * \param event
565 */
566void MainFrame::OnRollButton ()
567{
568        short int dice[5];      //holds the dices score
569       
570        // If this is the first roll of the game, notify the statistics
571        // object
572        if (m_numofplaysleft == 13 && m_rolls == 3)
573                m_stats->game_started();
574
575        //fill the dice array with the old values
576        dice[0]=m_score_dice.GetDice(1);
577        dice[1]=m_score_dice.GetDice(2);
578        dice[2]=m_score_dice.GetDice(3);
579        dice[3]=m_score_dice.GetDice(4);
580        dice[4]=m_score_dice.GetDice(5);
581        //roll the dice...
582        if (m_config->get("dice-animation")=="True") {
583                int dice_throws[5] = {0,0,0,0,0};
584                for (int i=0; i<5; i++) { //set the number of rolls for each dice
585                        if (!((wxCheckBox*) FindWindow(i + ID_DICE1KEEP))->IsChecked()) {
586                                dice_throws[i] = (rand()%15)+3; //ensures the number is at least one.
587                        }
588                }
589                while (dice_throws[0] || dice_throws[1] || dice_throws[2] || dice_throws[3] || dice_throws[4]) {
590                        for (int i=0 ; i<5; i++){
591                                if(dice_throws[i]){
592                                        dice_throws[i]--;
593                                        dice[i] = (int)(6.0*rand()/RAND_MAX)+1;
594                                        ((wxDynamicBitmap*) FindWindow(i +
595                                                ID_DICE1)) -> SetBitmap(
596                                                bitmap_dice[dice[i]-1]);
597                                }
598                        }
599                        ::wxMilliSleep(100);
600                }
601        } else {
602                for (int i=0; i<5; i++) {
603                        if (!((wxCheckBox*) FindWindow(i + ID_DICE1KEEP))->IsChecked()) {
604                                dice[i] = (int)(6.0*rand()/RAND_MAX)+1;
605                                ((wxDynamicBitmap*) FindWindow(i + ID_DICE1))->
606                                        SetBitmap(bitmap_dice[dice[i]-1]);
607                        }
608                }
609        }
610
611        m_score_dice.SetDice(dice);
612        m_score_dice.SetYahtzeeJoker(YahtzeeJoker());
613        --m_rolls;
614       
615        // change the displayed roll counter
616        wxString caption = wxString::Format(wxT("Roll! (%i)"),m_rolls);
617        FindWindow(ID_ROLL)->SetLabel(caption);
618
619        #ifndef DEBUG
620        if (m_rolls <= 0) {
621                ((wxButton*) FindWindow(ID_ROLL)) -> Enable(false);
622                FindWindow(ID_ROLL)->SetLabel(wxT("Roll!"));
623        }
624
625        #endif
626       
627        //enable the keep checkboxes
628        for (int i=0; i<5; i++)
629                ((wxCheckBox*) FindWindow(i + ID_DICE1KEEP)) -> Enable(true);
630       
631        //we rolled the dices so undoing isn't allowed
632        (GetMenuBar()->FindItem(wxID_UNDO))->Enable(false);
633        m_yahtzeebonus = false; //if we scored yahtzee bonus before we don't care anymore.
634}
635
636void MainFrame::DoubleRollLock(wxCommandEvent& event)
637{
638        /* The function works by connecting to idle event, and raising a
639         * flag when it process a valid click on the Roll button. When the
640         * another click happens and the flag is up, it means it is
641         * accidental. When the idle events is triggered it means that we
642         * no longer roll the dice, so we lower the flag.
643         */
644        static bool skip_roll = false;
645        if (event.GetEventType() == wxEVT_IDLE) {
646                skip_roll = false;
647                Disconnect(wxEVT_IDLE,  wxCommandEventHandler(MainFrame::DoubleRollLock));
648                return;
649        }
650       
651        if (skip_roll)
652                return;
653        skip_roll = true;
654       
655        Connect(wxEVT_IDLE, wxCommandEventHandler(MainFrame::DoubleRollLock));
656        OnRollButton();
657}
658
659/**
660 * This is the event-handler for all of the scoring buttons of the upper section.
661 *
662 * It gets the id of the button that called the event handler by comparing it
663 * to the id of the aces button it figures what button was pressed, And updates
664 * the suiting score textbox (again by comparing the id to the one of the aces
665 * checbox).
666 * \param event
667 */
668void MainFrame::OnUpperButtons (wxCommandEvent& event)
669{
670        wxString out;
671        short int temp;
672        if (!IsValidClick())
673                return;
674
675        YahtzeeBonus();
676
677        switch(event.GetId()) {
678        case ID_ACES:
679                temp = m_score_dice.Aces();
680                break;
681        case ID_TWOS:
682                temp = m_score_dice.Twos();
683                break;
684        case ID_THREES:
685                temp = m_score_dice.Threes();
686                break;
687        case ID_FOURS:
688                temp = m_score_dice.Fours();
689                break;
690        case ID_FIVES:
691                temp = m_score_dice.Fives();
692                break;
693        case ID_SIXES:
694                temp = m_score_dice.Sixes();
695                break;
696        }
697       
698        out.Printf(wxT("%i"),temp);
699        wxTextCtrl *text_ctrl = dynamic_cast<wxTextCtrl*>(FindWindow(event.GetId() - ID_ACES + ID_ACESTEXT));
700        text_ctrl->SetValue(out);
701        text_ctrl->SetBackgroundColour(*wxWHITE);
702        text_ctrl->Refresh();
703       
704        PostScore(event.GetId());
705}
706
707/**
708 * Event handler for the "3 of a kind" score button.
709 * \param event
710 */
711void MainFrame::On3ofakindButton(wxCommandEvent& event)
712{
713        if (!IsValidClick())
714                return;
715       
716        YahtzeeBonus();
717        wxString out;
718       
719        out.Printf(wxT("%i"),m_score_dice.ThreeOfAKind());
720        wxTextCtrl *text_ctrl = dynamic_cast<wxTextCtrl*>(FindWindow(ID_THREEOFAKINDTEXT));
721        text_ctrl->SetValue(out);
722        text_ctrl->SetBackgroundColour(*wxWHITE);
723        text_ctrl->Refresh();
724       
725        PostScore(event.GetId());
726}
727
728/**
729 * Event handler for the "4 of a kind" score button.
730 * \param event
731 */
732void MainFrame::On4ofakindButton(wxCommandEvent& event)
733{
734        if (!IsValidClick())
735                return;
736       
737        YahtzeeBonus();
738        wxString out;
739
740        out.Printf(wxT("%i"),m_score_dice.FourOfAKind());
741        wxTextCtrl *text_ctrl = dynamic_cast<wxTextCtrl*>(FindWindow(ID_FOUROFAKINDTEXT));
742        text_ctrl->SetValue(out);
743        text_ctrl->SetBackgroundColour(*wxWHITE);
744        text_ctrl->Refresh();
745       
746        PostScore(event.GetId());
747}
748
749/**
750 * Event handler for the full-house score button.
751 * \param event
752 */
753void MainFrame::OnFullHouseButton(wxCommandEvent& event)
754{
755        wxString out;
756
757        if (!IsValidClick())
758                return;
759       
760        YahtzeeBonus();
761
762        out.Printf(wxT("%i"), m_score_dice.FullHouse());
763        wxTextCtrl *text_ctrl = dynamic_cast<wxTextCtrl*>(FindWindow(ID_FULLHOUSETEXT));
764        text_ctrl->SetValue(out);
765        text_ctrl->SetBackgroundColour(*wxWHITE);
766        text_ctrl->Refresh();
767       
768        PostScore(event.GetId());
769}
770
771/**
772 * Event handler for the small-sequence score button.
773 * \param event
774 */
775void MainFrame::OnSmallSequenceButton(wxCommandEvent& event)
776{
777        wxString out;
778
779        if (!IsValidClick())
780                return;
781
782        YahtzeeBonus();
783       
784        out.Printf(wxT("%i"), m_score_dice.SmallSequence());
785        wxTextCtrl *text_ctrl = dynamic_cast<wxTextCtrl*>(FindWindow(ID_SMALLSEQUENCETEXT));
786        text_ctrl->SetValue(out);
787        text_ctrl->SetBackgroundColour(*wxWHITE);
788        text_ctrl->Refresh();
789       
790        PostScore(event.GetId());
791}
792
793/**
794 * Event handler for the large-sequence score button.
795 * \param event
796 */
797void MainFrame::OnLargeSequenceButton(wxCommandEvent& event)
798{
799        wxString out;
800       
801        if (!IsValidClick())
802                return;
803
804        YahtzeeBonus();
805
806        out.Printf(wxT("%i"), m_score_dice.LargeSequence());
807        wxTextCtrl *text_ctrl = dynamic_cast<wxTextCtrl*>(FindWindow(ID_LARGESEQUENCETEXT));
808        text_ctrl->SetValue(out);
809        text_ctrl->SetBackgroundColour(*wxWHITE);
810        text_ctrl->Refresh();
811
812       
813        PostScore(event.GetId());
814}
815
816/**
817 * Event handler for the yahtzee score button.
818 * \param event
819 */
820void MainFrame::OnYahtzeeButton(wxCommandEvent& event)
821{
822        wxString out;
823       
824        if (!IsValidClick())
825                return;
826       
827        if (m_score_dice.IsYahtzee()) m_yahtzee = true;
828        out.Printf(wxT("%i"), m_score_dice.Yahtzee());
829        wxTextCtrl *text_ctrl = dynamic_cast<wxTextCtrl*>(FindWindow(ID_YAHTZEETEXT));
830        text_ctrl->SetValue(out);
831        text_ctrl->SetBackgroundColour(*wxWHITE);
832        text_ctrl->Refresh();
833
834        PostScore(event.GetId());
835}
836
837/**
838 * Evnet handler for the chance score button.
839 * \param event
840 */
841void MainFrame::OnChanceButton (wxCommandEvent& event)
842{
843        wxString out;
844        if (!IsValidClick())
845                return;
846
847        YahtzeeBonus();
848
849        out.Printf(wxT("%i"),m_score_dice.Chance());
850        wxTextCtrl *text_ctrl = dynamic_cast<wxTextCtrl*>(FindWindow(ID_CHANCETEXT));
851        text_ctrl->SetValue(out);
852        text_ctrl->SetBackgroundColour(*wxWHITE);
853        text_ctrl->Refresh();
854        PostScore(event.GetId());
855}
856
857/**
858 * Event handler for mouse clicks on the dice.
859 *
860 * When clicking on the dice this event-handler ticks the appropriate "keep" checkbox.
861 * \param event
862 */
863void MainFrame::OnDiceClick (wxCommandEvent& event)
864{
865        //tick the checkbox
866        if (((wxCheckBox*) FindWindow(event.GetId()-ID_DICE1 + ID_DICE1KEEP))->IsEnabled()){
867                bool newvalue = (((wxCheckBox*) FindWindow(event.GetId()-ID_DICE1 + ID_DICE1KEEP))->GetValue())?false:true;
868                ((wxCheckBox*) FindWindow(event.GetId()-ID_DICE1 + ID_DICE1KEEP)) -> SetValue(newvalue);
869        }
870
871        //dispatch a click event on the checkbox
872        wxCommandEvent clickevent((event.GetId()-ID_DICE1 + ID_DICE1KEEP),wxEVT_COMMAND_CHECKBOX_CLICKED);
873        clickevent.SetEventObject( this );
874        clickevent.SetId(event.GetId()-ID_DICE1 + ID_DICE1KEEP);
875        this->OnKeepClick(clickevent); ///\todo find a better way to call the event handler.
876}
877
878void MainFrame::OnKeepClick (wxCommandEvent& event)
879{
880        wxCheckBox *temp = (wxCheckBox*) FindWindow(event.GetId());
881        ((wxDynamicBitmap*) FindWindow(event.GetId()-ID_DICE1KEEP + ID_DICE1))->SetGrayScale(temp->GetValue());
882}
883
884
885//********************************************
886//******        General Functions       ******
887//********************************************
888
889/**
890 * This function handles everything related to reseting the dice rolls after scoring.
891 */
892void MainFrame::ResetRolls()
893{
894        m_rollsundo = m_rolls;
895        m_rolls = 3;
896        ((wxButton*) FindWindow(ID_ROLL)) -> Enable(true);
897
898        // reset the roll count in the caption
899        FindWindow(ID_ROLL)->SetLabel(wxT("Roll! (3)"));
900        for (int i=0; i<5; i++){
901                ((wxCheckBox*) FindWindow(i + ID_DICE1KEEP)) -> SetValue(false);
902                ((wxCheckBox*) FindWindow(i + ID_DICE1KEEP)) -> Enable(false);
903                ((wxDynamicBitmap*) FindWindow(i+ID_DICE1)) -> SetGrayScale(false);
904        }
905}
906
907/**
908 * This function checks for a Yahtzee Bonus situation and if one exists it scores accordingly.
909 */
910void MainFrame::YahtzeeBonus()
911{
912        long temp;
913        wxString tempstr;
914       
915        //if the player didn't have any yathzees yet he can't have the bonus;
916        if (!m_yahtzee)
917                return;
918        if (m_score_dice.IsYahtzee()) {
919                tempstr = ((wxTextCtrl*) FindWindow(ID_YAHTZEEBONUSTEXT)) -> GetValue();
920                tempstr.ToLong(&temp,10);
921                temp += 100;
922                tempstr.Printf(wxT("%i"),temp);
923                ((wxTextCtrl*) FindWindow(ID_YAHTZEEBONUSTEXT)) -> SetValue(tempstr);
924                m_yahtzeebonus = true;
925        }       
926}
927
928/**
929 * This function checks whether we have a Yahtzee Joker situation.
930 * \return true if there is Yahtzee Joker, false otherwise.
931 */
932bool MainFrame::YahtzeeJoker()
933{
934        if (m_score_dice.IsYahtzee() && !(FindWindow(ID_ACES +
935                m_score_dice.GetDice(1)-1)->IsEnabled()) &&
936                !(FindWindow(ID_YAHTZEE)->IsEnabled())) {
937                return true;
938        }
939        return false;
940}
941
942/**
943 * This function handles the end of game.
944 *
945 * When a game ends it calculates the total score and submit it to the high
946 * score list.
947 */
948void MainFrame::EndofGame()
949{
950        if(m_numofplaysleft>0)
951                return;
952       
953        wxString tempstr;
954        long temp;
955        long upperscore = 0;
956        long lowerscore = 0;
957
958        for (int i = ID_ACESTEXT; i<=ID_SIXESTEXT; i++){
959                tempstr = ((wxTextCtrl*) FindWindow(i)) -> GetValue();
960                tempstr.ToLong(&temp,10);
961                upperscore +=temp;
962        }
963       
964        tempstr.Printf(wxT("%i"),upperscore);
965        ((wxTextCtrl*) FindWindow(ID_UPPERSECTIONTOTAL)) -> SetValue(tempstr);
966       
967        //check for bonus
968        if(upperscore>=63) {
969                ((wxTextCtrl*) FindWindow(ID_BONUS)) -> SetValue(wxT("35"));
970                upperscore +=35;
971        } else
972                ((wxTextCtrl*) FindWindow(ID_BONUS)) -> SetValue(wxT("0"));
973       
974        tempstr.Printf(wxT("%i"),upperscore);
975        ((wxTextCtrl*) FindWindow(ID_UPPERTOTAL)) -> SetValue(tempstr);
976       
977        //calculate total on lower section
978        for (int i = ID_THREEOFAKINDTEXT; i<=ID_YAHTZEEBONUSTEXT; i++) {
979                tempstr = ((wxTextCtrl*) FindWindow(i)) -> GetValue();
980                tempstr.ToLong(&temp,10);
981                lowerscore +=temp;
982        }
983       
984        tempstr.Printf(wxT("%i"),lowerscore);
985        ((wxTextCtrl*) FindWindow(ID_LOWERTOTAL)) -> SetValue(tempstr);
986        tempstr.Printf(wxT("%i"),upperscore + lowerscore);
987        ((wxTextCtrl*) FindWindow(ID_GRANDTOTAL)) -> SetValue(tempstr);
988
989        //disable the roll button;
990        ((wxButton*) FindWindow(ID_ROLL)) -> Enable(false);
991
992        tempstr.Printf(wxT("Your final score is %i points!"),lowerscore+upperscore);
993        wxMessageBox(tempstr, wxT("Game Ended"), wxOK | wxICON_INFORMATION, this);
994
995        m_stats->game_finished(lowerscore+upperscore);
996
997        //submit to high score
998        HighScoreHandler(lowerscore+upperscore);
999       
1000}
1001
1002/**
1003 * This function checks if a given score qualifies for the high score list and
1004 * adds it to the list if it does.
1005 * @param score The score submitted to the high score list.
1006 */
1007void MainFrame::HighScoreHandler(int score)
1008{
1009        std::string name,date;
1010        wxCommandEvent newevent;
1011
1012       
1013        if(!m_config->isHighscore(score)) {
1014                return;
1015        }
1016       
1017        wxString msg = wxT("Your score made it to the high score table.\nPlease enter your name below:");
1018
1019        wxString last_name = wxString::FromUTF8(m_config->get("last-name").c_str());
1020
1021        wxTextEntryDialog infodialog(this,msg,wxT("Please enter your name"),last_name ,wxOK | wxCENTRE);
1022        infodialog.ShowModal();
1023
1024        name = infodialog.GetValue().utf8_str();
1025        m_config->set("last-name",name)->save();
1026
1027        //get the date
1028        wxDateTime now = wxDateTime::Now();
1029        date = now.FormatDate().utf8_str();
1030        date += " ";
1031        date += now.FormatISOTime().SubString(0,4).utf8_str();
1032
1033        int rank = m_config->submitHighscore(score, name, date);
1034
1035        //now show the high score table
1036        highscores_dialog::HighscoresDialog *dialog = new highscores_dialog::HighscoresDialog(this, m_config.get(),rank);
1037
1038        dialog->ShowModal();
1039
1040        delete dialog;
1041
1042}
1043
1044///this function handles all the post scoring stuff such as disabling the right button.
1045/**
1046 * This function is always called after scoring and it handles all the post-score
1047 * stuff such as reseting the dice rolls, enabling the undo button, calculating
1048 * the sub-total scores and ending the game if necessary.
1049 * \param id
1050 */
1051void MainFrame::PostScore(int id)
1052{
1053        //now after the scoring reset the rolls
1054        ResetRolls();
1055
1056        CalculateSubTotal();
1057
1058        //and disable the button
1059        FindWindow(id)->Enable(false);
1060        m_numofplaysleft--;
1061        EnableUndo(id);
1062        EndofGame();
1063}
1064
1065/**
1066 * This function calculates the sub-total scores and should be called after
1067 * every score. It does so only if this feature is requested in the settings
1068 * dialog.
1069 */
1070void MainFrame::CalculateSubTotal()
1071{
1072        if (m_config->get("calculate-subtotal")=="False")
1073                return;
1074        long upperscore = 0;
1075        long lowerscore = 0;
1076        wxString tempstr;
1077        long temp;
1078
1079
1080        for (int i = ID_ACESTEXT; i<=ID_SIXESTEXT; i++){
1081                tempstr = ((wxTextCtrl*) FindWindow(i)) -> GetValue();
1082                tempstr.ToLong(&temp,10);
1083                upperscore +=temp;
1084        }
1085       
1086        tempstr.Printf(wxT("%i"),upperscore);
1087        ((wxTextCtrl*) FindWindow(ID_UPPERSECTIONTOTAL)) -> SetValue(tempstr);
1088        if (upperscore >= 63) {
1089                ((wxTextCtrl*) FindWindow(ID_BONUS))->SetValue(wxT("35"));
1090        } else {
1091                // this is needed in case of an undo
1092                ((wxTextCtrl*) FindWindow(ID_BONUS))->SetValue(wxT(""));
1093        }
1094
1095        for (int i = ID_THREEOFAKINDTEXT; i<=ID_YAHTZEEBONUSTEXT; i++) {
1096                tempstr = ((wxTextCtrl*) FindWindow(i)) -> GetValue();
1097                tempstr.ToLong(&temp,10);
1098                lowerscore +=temp;
1099        }
1100       
1101        tempstr.Printf(wxT("%i"),lowerscore);
1102        ((wxTextCtrl*) FindWindow(ID_LOWERTOTAL)) -> SetValue(tempstr);
1103}
1104
1105
1106void MainFrame::Relayout()
1107{
1108        wxBoxSizer *topSizer;
1109        wxFlexGridSizer *diceSizer;
1110        bool roll_button_enabled;
1111
1112        lowersection->GetStaticBox()->Destroy();
1113        uppersection->GetStaticBox()->Destroy();
1114        sectionsSizer->Remove(lowersection);
1115        sectionsSizer->Remove(uppersection);
1116
1117        if (m_config->get("horizontal-layout")=="True") {
1118                topSizer = new wxBoxSizer( wxVERTICAL );
1119                sectionsSizer = new wxBoxSizer( wxHORIZONTAL );
1120                diceSizer = new wxFlexGridSizer(2, 0, 0, 0);
1121        } else {
1122                topSizer = new wxBoxSizer( wxHORIZONTAL );
1123                sectionsSizer = new wxBoxSizer( wxVERTICAL );
1124                diceSizer = new wxFlexGridSizer(1, 0, 0);;
1125        }
1126
1127        uppersection = new wxStaticBoxSizer( new wxStaticBox( FindWindow(ID_PANEL), wxID_ANY, wxT("Upper Section") ), wxVERTICAL);
1128        lowersection = new wxStaticBoxSizer( new wxStaticBox( FindWindow(ID_PANEL), wxID_ANY, wxT("Lower Section") ), wxVERTICAL);
1129       
1130        wxFlexGridSizer* uppergrid = new wxFlexGridSizer(2, 0, 10);
1131        wxFlexGridSizer* lowergrid = new wxFlexGridSizer(2, 0, 10);
1132
1133        //BEGIN layout for the upper section of the score board
1134        uppergrid->Add(FindWindow(ID_ACES),0,wxALL,SPACE_SIZE);
1135        uppergrid->Add(FindWindow(ID_ACESTEXT),1,wxALL,SPACE_SIZE);
1136        uppergrid->Add(FindWindow(ID_TWOS),0,wxALL,SPACE_SIZE);
1137        uppergrid->Add(FindWindow(ID_TWOSTEXT),1,wxALL,SPACE_SIZE);
1138        uppergrid->Add(FindWindow(ID_THREES),0,wxALL,SPACE_SIZE);
1139        uppergrid->Add(FindWindow(ID_THREESTEXT),1,wxALL,SPACE_SIZE);
1140        uppergrid->Add(FindWindow(ID_FOURS),0,wxALL,SPACE_SIZE);
1141        uppergrid->Add(FindWindow(ID_FOURSTEXT),1,wxALL,SPACE_SIZE);
1142        uppergrid->Add(FindWindow(ID_FIVES),0,wxALL,SPACE_SIZE);
1143        uppergrid->Add(FindWindow(ID_FIVESTEXT),1,wxALL,SPACE_SIZE);
1144        uppergrid->Add(FindWindow(ID_SIXES),0,wxALL,SPACE_SIZE);
1145        uppergrid->Add(FindWindow(ID_SIXESTEXT),1,wxALL,SPACE_SIZE);
1146        uppergrid->Add(FindWindowByLabel(wxT("Total score:")),0,wxALL,SPACE_SIZE);
1147        uppergrid->Add(FindWindow(ID_UPPERSECTIONTOTAL),1,wxALL,SPACE_SIZE);
1148        uppergrid->Add(FindWindowByLabel(wxT("Bonus:")),0,wxALL,SPACE_SIZE);
1149        uppergrid->Add(FindWindow(ID_BONUS),1,wxALL,SPACE_SIZE);
1150        uppergrid->Add(FindWindowByLabel(wxT("Total of upper section:")),0,wxALL,SPACE_SIZE);
1151        uppergrid->Add(FindWindow(ID_UPPERTOTAL),1,wxALL,SPACE_SIZE);
1152        //END layout for the upper section of the score board
1153
1154        //BEGIN layout for the lower section of the score board
1155        lowergrid->Add(FindWindow(ID_THREEOFAKIND),0,wxALL,SPACE_SIZE);
1156        lowergrid->Add(FindWindow(ID_THREEOFAKINDTEXT),1,wxALL,SPACE_SIZE);
1157        lowergrid->Add(FindWindow(ID_FOUROFAKIND),0,wxALL,SPACE_SIZE);
1158        lowergrid->Add(FindWindow(ID_FOUROFAKINDTEXT),1,wxALL,SPACE_SIZE);
1159        lowergrid->Add(FindWindow(ID_FULLHOUSE),0,wxALL,SPACE_SIZE);
1160        lowergrid->Add(FindWindow(ID_FULLHOUSETEXT),1,wxALL,SPACE_SIZE);
1161        lowergrid->Add(FindWindow(ID_SMALLSEQUENCE),0,wxALL,SPACE_SIZE);
1162        lowergrid->Add(FindWindow(ID_SMALLSEQUENCETEXT),1,wxALL,SPACE_SIZE);
1163        lowergrid->Add(FindWindow(ID_LARGESEQUENCE),0,wxALL,SPACE_SIZE);
1164        lowergrid->Add(FindWindow(ID_LARGESEQUENCETEXT),1,wxALL,SPACE_SIZE);
1165        lowergrid->Add(FindWindow(ID_YAHTZEE),0,wxALL,SPACE_SIZE);
1166        lowergrid->Add(FindWindow(ID_YAHTZEETEXT),1,wxALL,SPACE_SIZE);
1167        lowergrid->Add(FindWindow(ID_CHANCE),0,wxALL,SPACE_SIZE);
1168        lowergrid->Add(FindWindow(ID_CHANCETEXT),1,wxALL,SPACE_SIZE);
1169        lowergrid->Add(FindWindowByLabel(wxT("Yahtzee Bonus")),0,wxALL,SPACE_SIZE);
1170        lowergrid->Add(FindWindow(ID_YAHTZEEBONUSTEXT),1,wxALL,SPACE_SIZE);
1171        lowergrid->Add(FindWindowByLabel(wxT("Total of lower section:")),0,wxALL,SPACE_SIZE);
1172        lowergrid->Add(FindWindow(ID_LOWERTOTAL),1,wxALL,SPACE_SIZE);
1173        lowergrid->Add(FindWindowByLabel(wxT("Grand Total:")),0,wxALL,SPACE_SIZE);
1174        lowergrid->Add(FindWindow(ID_GRANDTOTAL),1,wxALL,SPACE_SIZE);
1175        //END layout for the lower section of the score board
1176
1177        uppersection->Add(uppergrid);
1178        lowersection->Add(lowergrid);
1179        sectionsSizer->Add(uppersection,0,wxALL,5);
1180        sectionsSizer->Add(lowersection,0,wxALL,5);
1181
1182        //Change the roll button size if we need to
1183        roll_button_enabled = FindWindow(ID_ROLL)->IsEnabled();
1184        if (m_config->get("horizontal-layout")=="True") {
1185                FindWindow(ID_ROLL)->Destroy();
1186                new wxButton(FindWindow(ID_PANEL), ID_ROLL, wxT("Roll!"),wxDefaultPosition,wxSize(64,64));
1187        } else {
1188                FindWindow(ID_ROLL)->Destroy();
1189                new wxButton(FindWindow(ID_PANEL), ID_ROLL, wxT("Roll!"),wxDefaultPosition,wxSize(VERTICAL_ROLL_SIZEX,VERTICAL_ROLL_SIZEY));
1190        }
1191        FindWindow(ID_ROLL)->Enable(roll_button_enabled);
1192
1193        // if there are rolls left we should display the count of them
1194        if (roll_button_enabled) {
1195                wxString caption = wxString::Format(wxT("Roll! (%i)"),m_rolls);
1196                FindWindow(ID_ROLL)->SetLabel(caption);
1197        }
1198
1199       
1200        //BEGIN layout for the dice section of the score board
1201        if (m_config->get("horizontal-layout")=="True") {
1202                diceSizer->Add(FindWindow(ID_DICE1),0,wxALL,DICE_SPACE);
1203                diceSizer->Add(FindWindow(ID_DICE2),0,wxALL,DICE_SPACE);
1204                diceSizer->Add(FindWindow(ID_DICE3),0,wxALL,DICE_SPACE);
1205                diceSizer->Add(FindWindow(ID_DICE4),0,wxALL,DICE_SPACE);
1206                diceSizer->Add(FindWindow(ID_DICE5),0,wxALL,DICE_SPACE);
1207                diceSizer->Add(FindWindow(ID_ROLL),0,wxALL,DICE_SPACE);
1208                diceSizer->Add(FindWindow(ID_DICE1KEEP),0,wxBOTTOM | wxLEFT,KEEP_SPACE);
1209                diceSizer->Add(FindWindow(ID_DICE2KEEP),0,wxBOTTOM | wxLEFT,KEEP_SPACE);
1210                diceSizer->Add(FindWindow(ID_DICE3KEEP),0,wxBOTTOM | wxLEFT,KEEP_SPACE);
1211                diceSizer->Add(FindWindow(ID_DICE4KEEP),0,wxBOTTOM | wxLEFT,KEEP_SPACE);
1212                diceSizer->Add(FindWindow(ID_DICE5KEEP),0,wxBOTTOM | wxLEFT,KEEP_SPACE);
1213        } else {
1214                diceSizer->Add(FindWindow(ID_DICE1),0,wxALL,DICE_SPACE);
1215                diceSizer->Add(FindWindow(ID_DICE1KEEP),0,wxLEFT,KEEP_SPACE);
1216                diceSizer->AddSpacer(VER_DICE_SPACER);
1217                diceSizer->Add(FindWindow(ID_DICE2),0,wxALL,DICE_SPACE);
1218                diceSizer->Add(FindWindow(ID_DICE2KEEP),0,wxLEFT,KEEP_SPACE);
1219                diceSizer->AddSpacer(VER_DICE_SPACER);
1220                diceSizer->Add(FindWindow(ID_DICE3),0,wxALL,DICE_SPACE);
1221                diceSizer->Add(FindWindow(ID_DICE3KEEP),0,wxLEFT,KEEP_SPACE);
1222                diceSizer->AddSpacer(VER_DICE_SPACER);
1223                diceSizer->Add(FindWindow(ID_DICE4),0,wxALL,DICE_SPACE);
1224                diceSizer->Add(FindWindow(ID_DICE4KEEP),0,wxLEFT,KEEP_SPACE);
1225                diceSizer->AddSpacer(VER_DICE_SPACER);
1226                diceSizer->Add(FindWindow(ID_DICE5),0,wxALL,DICE_SPACE);
1227                diceSizer->Add(FindWindow(ID_DICE5KEEP),0,wxLEFT,KEEP_SPACE);
1228                diceSizer->AddSpacer(VER_DICE_SPACER);
1229                diceSizer->Add(FindWindow(ID_ROLL),0,wxALL,DICE_SPACE);
1230        }
1231        //END layout for the dice section of the score board *******/
1232
1233       
1234        topSizer->Add(sectionsSizer);
1235        topSizer->Add(diceSizer);       
1236       
1237        topSizer->SetSizeHints(this);
1238
1239        topSizer->Layout();
1240        FindWindow(ID_PANEL)->SetSizerAndFit(topSizer);
1241       
1242        topSizer->Fit(this);
1243       
1244}
1245
1246/**
1247 * Check whether the dice should be rolled or if the user already rolled them.
1248 * \return true if the dice are valid (rolled).
1249 */
1250bool MainFrame::IsValidDice()
1251{
1252        if ( m_rolls < 3 )
1253                return true;
1254        return false;
1255}
1256
1257/**
1258 *
1259 */
1260void MainFrameEvtHandler::OnScoreMouseEnter (wxMouseEvent& event)
1261{
1262        int id;
1263        wxTextCtrl *text_control;
1264        wxString out;
1265        if (m_main_frame->m_config->get("score-hints")=="False") {
1266                event.Skip();
1267                return;
1268        }
1269        if (! m_main_frame->IsValidDice()){
1270                event.Skip();
1271                return;
1272        }
1273       
1274        id = ((wxWindow *)event.GetEventObject())->GetId();
1275        text_control = ((wxTextCtrl*)m_main_frame->FindWindow(id-ID_ACES+ID_ACESTEXT));
1276        switch (id) {
1277        case ID_ACES:
1278                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Aces());
1279                break;
1280        case ID_TWOS:
1281                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Twos());
1282                break;
1283        case ID_THREES:
1284                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Threes());
1285                break;
1286        case ID_FOURS:
1287                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Fours());
1288                break;
1289        case ID_FIVES:
1290                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Fives());
1291                break;
1292        case ID_SIXES:
1293                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Sixes());
1294                break;
1295        case ID_THREEOFAKIND:
1296                out.Printf(wxT("%i"), m_main_frame->m_score_dice.ThreeOfAKind());
1297                break;
1298        case ID_FOUROFAKIND:
1299                out.Printf(wxT("%i"), m_main_frame->m_score_dice.FourOfAKind());
1300                break;
1301        case ID_FULLHOUSE:
1302                out.Printf(wxT("%i"), m_main_frame->m_score_dice.FullHouse());
1303                break;
1304        case ID_SMALLSEQUENCE:
1305                out.Printf(wxT("%i"), m_main_frame->m_score_dice.SmallSequence());
1306                break;
1307        case ID_LARGESEQUENCE:
1308                out.Printf(wxT("%i"), m_main_frame->m_score_dice.LargeSequence());
1309                break;
1310        case ID_YAHTZEE:
1311                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Yahtzee());
1312                break;
1313        case ID_CHANCE:
1314                out.Printf(wxT("%i"), m_main_frame->m_score_dice.Chance());
1315                break;
1316        }
1317        text_control->SetValue(out);           
1318        text_control->SetBackgroundColour(wxColour(239,239,239));
1319       
1320        event.Skip(); //allow default proccesing
1321}
1322
1323/**
1324 *
1325 */
1326void MainFrameEvtHandler::OnScoreMouseLeave (wxMouseEvent& event)
1327{
1328        //we dont have the id of the control that generated the event
1329        wxTextCtrl *text_control;
1330       
1331        if (! m_main_frame->IsValidDice()){
1332                event.Skip();
1333                return;
1334        }
1335
1336        for (int i = ID_ACESTEXT; i<=ID_CHANCETEXT; i++) {
1337                text_control = (wxTextCtrl *)m_main_frame->FindWindow(i);
1338                if (text_control->GetBackgroundColour()==wxColour(239,239,239)){
1339                        text_control->Clear();
1340                        text_control->SetBackgroundColour(*wxWHITE);
1341                }
1342        }
1343
1344        event.Skip(); //allow default proccesing
1345}
1346
1347bool MainFrame::IsValidClick()
1348{
1349        if (m_rolls >= 3) {
1350                wxMessageBox(wxT("First you need to roll, and after you roll you may score."),
1351                        wxT("Open Yahtzee"), wxOK | wxICON_INFORMATION, this);
1352                return false;
1353        }
1354        return true;
1355}
1356
1357MainFrame::~MainFrame() {
1358        // free pointers
1359        delete m_evt_handler;
1360
1361        for (int i = 0; i<6; i++) {
1362                delete bitmap_dice[i];
1363        }
1364}
Note: See TracBrowser for help on using the repository browser.