source: trunk/src/MainFrame.cpp @ 156

Last change on this file since 156 was 156, checked in by guyru, 5 years ago

rename configuration file from .OpenYahtzee? to .openyahtzee

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