source: trunk/src/MainFrame.cpp @ 137

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

added theme dialog

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