~s-cecilio/lenmus/v5.3

« back to all changes in this revision

Viewing changes to src/exercises/TheoKeySignCtrol.cpp

  • Committer: cecilios
  • Date: 2012-09-11 16:59:18 UTC
  • Revision ID: svn-v4:2587a929-2f0e-0410-ae78-fe6f687d5efe:branches/TRY-5.0:730
Paths: fixed problem with installation folders. Fixed Chinese ISO language code

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//--------------------------------------------------------------------------------------
2
 
//    LenMus Phonascus: The teacher of music
3
 
//    Copyright (c) 2002-2007 Cecilio Salmeron
4
 
//
5
 
//    This program is free software; you can redistribute it and/or modify it under the 
6
 
//    terms of the GNU General Public License as published by the Free Software Foundation;
7
 
//    either version 2 of the License, or (at your option) any later version.
8
 
//
9
 
//    This program is distributed in the hope that it will be useful, but WITHOUT ANY 
10
 
//    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
11
 
//    PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
 
//
13
 
//    You should have received a copy of the GNU General Public License along with this 
14
 
//    program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, 
15
 
//    Fifth Floor, Boston, MA  02110-1301, USA.
16
 
//
17
 
//    For any comment, suggestion or feature request, please contact the manager of 
18
 
//    the project at cecilios@users.sourceforge.net
19
 
//
20
 
//-------------------------------------------------------------------------------------
21
 
/*! @file TheoKeySignCtrol.cpp
22
 
    @brief Implementation file for class lmTheoKeySignCtrol
23
 
    @ingroup html_controls
24
 
*/
25
 
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
26
 
#pragma implementation "TheoKeySignCtrol.h"
27
 
#endif
28
 
 
29
 
// For compilers that support precompilation, includes "wx.h".
30
 
#include "wx/wxprec.h"
31
 
 
32
 
#ifdef __BORLANDC__
33
 
#pragma hdrstop
34
 
#endif
35
 
 
36
 
#include "TheoKeySignCtrol.h"
37
 
#include "UrlAuxCtrol.h"
38
 
#include "Constrains.h"
39
 
#include "Generators.h"
40
 
#include "../auxmusic/Conversion.h"
41
 
 
42
 
#include "../globals/Colors.h"
43
 
extern lmColors* g_pColors;
44
 
 
45
 
// access to global external variables
46
 
extern bool g_fReleaseVersion;            // in TheApp.cpp
47
 
extern bool g_fReleaseBehaviour;        // in TheApp.cpp
48
 
extern bool g_fShowDebugLinks;            // in TheApp.cpp
49
 
extern bool g_fAutoNewProblem;          // in Preferences.cpp
50
 
 
51
 
//access to error's logger
52
 
#include "../app/Logger.h"
53
 
extern lmLogger* g_pLogger;
54
 
 
55
 
 
56
 
 
57
 
//------------------------------------------------------------------------------------
58
 
// Implementation of lmTheoKeySignCtrol
59
 
 
60
 
 
61
 
 
62
 
 
63
 
//Layout definitions
64
 
const int BUTTONS_DISTANCE    = 5;        //pixels
65
 
const int NUM_LINKS = 3;                //links for actions
66
 
 
67
 
//IDs for controls
68
 
enum {
69
 
    ID_LINK_SEE_SOURCE = 3000,
70
 
    ID_LINK_DUMP,
71
 
    ID_BUTTON,
72
 
    ID_LINK = ID_BUTTON + lmTHEO_KEYSIGN_NUM_BUTTONS,
73
 
    ID_LINK_NEW_PROBLEM,
74
 
    ID_LINK_SOLUTION
75
 
};
76
 
 
77
 
BEGIN_EVENT_TABLE(lmTheoKeySignCtrol, wxWindow)
78
 
    EVT_COMMAND_RANGE   (ID_BUTTON, ID_BUTTON+lmTHEO_KEYSIGN_NUM_BUTTONS-1, wxEVT_COMMAND_BUTTON_CLICKED, lmTheoKeySignCtrol::OnRespButton)
79
 
    EVT_SIZE            (lmTheoKeySignCtrol::OnSize)
80
 
 
81
 
    LM_EVT_URL_CLICK    (ID_LINK_SEE_SOURCE, lmTheoKeySignCtrol::OnDebugShowSourceScore)
82
 
    LM_EVT_URL_CLICK    (ID_LINK_DUMP, lmTheoKeySignCtrol::OnDebugDumpScore)
83
 
 
84
 
    LM_EVT_URL_CLICK    (ID_LINK_NEW_PROBLEM, lmTheoKeySignCtrol::OnNewProblem)
85
 
    LM_EVT_URL_CLICK    (ID_LINK_SOLUTION, lmTheoKeySignCtrol::OnDisplaySolution)
86
 
END_EVENT_TABLE()
87
 
 
88
 
IMPLEMENT_CLASS(lmTheoKeySignCtrol, wxWindow)
89
 
 
90
 
static wxString sMajor[15];
91
 
static wxString sMinor[15];
92
 
 
93
 
 
94
 
lmTheoKeySignCtrol::lmTheoKeySignCtrol(wxWindow* parent, wxWindowID id, 
95
 
                           lmTheoKeySignConstrains* pConstrains,
96
 
                           const wxPoint& pos, const wxSize& size, int style)
97
 
    : wxWindow(parent, id, pos, size, style )
98
 
{
99
 
    //initializations
100
 
    SetBackgroundColour(*wxWHITE);
101
 
    for (int i=0; i < lmTHEO_KEYSIGN_NUM_BUTTONS; i++) {
102
 
        m_pAnswerButton[i] = (wxButton*)NULL;
103
 
    }
104
 
    m_nIndexKeyName = 0;
105
 
    m_fButtonsEnabled = false;
106
 
    m_fProblemCreated = false;
107
 
    m_pScore = (lmScore*)NULL;
108
 
    m_pScoreCtrol = (lmScoreAuxCtrol*)NULL;
109
 
    m_pConstrains = pConstrains;
110
 
 
111
 
    //language dependent strings. Can not be statically initiallized because
112
 
    //then they do not get translated
113
 
    sMajor[0] = _("C major");
114
 
    sMajor[1] = _("G major");
115
 
    sMajor[2] = _("D major");
116
 
    sMajor[3] = _("A major");
117
 
    sMajor[4] = _("E major");
118
 
    sMajor[5] = _("B major");
119
 
    sMajor[6] = _("F # major");
120
 
    sMajor[7] = _("C # major");
121
 
    sMajor[8] = _("C b major");
122
 
    sMajor[9] = _("G b major");
123
 
    sMajor[10] = _("D b major");
124
 
    sMajor[11] = _("A b major");
125
 
    sMajor[12] = _("E b major");
126
 
    sMajor[13] = _("B b major");
127
 
    sMajor[14] = _("F major");
128
 
 
129
 
    sMinor[0] = _("A minor");
130
 
    sMinor[1] = _("E minor");
131
 
    sMinor[2] = _("B minor");
132
 
    sMinor[3] = _("F # minor");
133
 
    sMinor[4] = _("C # minor");
134
 
    sMinor[5] = _("G # minor");
135
 
    sMinor[6] = _("D # minor");
136
 
    sMinor[7] = _("A # minor");
137
 
    sMinor[8] = _("A b minor");
138
 
    sMinor[9] = _("E b minor");
139
 
    sMinor[10] = _("B b minor");
140
 
    sMinor[11] = _("F minor");
141
 
    sMinor[12] = _("C minor");
142
 
    sMinor[13] = _("G minor");
143
 
    sMinor[14] = _("D minor");
144
 
 
145
 
    //the window is divided into two regions: top, for score on left and counters and links
146
 
    //on the right, and bottom region, for answer buttons 
147
 
    wxBoxSizer* pMainSizer = new wxBoxSizer( wxVERTICAL );
148
 
 
149
 
    // debug buttons
150
 
    if (g_fShowDebugLinks && !g_fReleaseVersion) {
151
 
        wxBoxSizer* pDbgSizer = new wxBoxSizer( wxHORIZONTAL );
152
 
        pMainSizer->Add(pDbgSizer, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT, 5);
153
 
 
154
 
        // "See source score"
155
 
        pDbgSizer->Add(
156
 
            new lmUrlAuxCtrol(this, ID_LINK_SEE_SOURCE, _("See source score") ),
157
 
            wxSizerFlags(0).Left().Border(wxALL, 10) );
158
 
        // "Dump score"
159
 
        pDbgSizer->Add(
160
 
            new lmUrlAuxCtrol(this, ID_LINK_DUMP, _("Dump score") ),
161
 
            wxSizerFlags(0).Left().Border(wxALL, 10) );
162
 
    }
163
 
 
164
 
    // sizer for the scoreCtrol and the CountersCtrol
165
 
    wxBoxSizer* pTopSizer = new wxBoxSizer( wxHORIZONTAL );
166
 
    pMainSizer->Add(
167
 
        pTopSizer,
168
 
        wxSizerFlags(0).Left().Border(wxLEFT|wxRIGHT, 10) );
169
 
 
170
 
    // create score ctrl 
171
 
    m_pScoreCtrol = new lmScoreAuxCtrol(this, -1, m_pScore, wxDefaultPosition, wxSize(350,150), eSIMPLE_BORDER);
172
 
    pTopSizer->Add(m_pScoreCtrol,
173
 
                   wxSizerFlags(1).Left().Border(wxTOP|wxBOTTOM, 10));
174
 
    m_pScoreCtrol->SetMargins(lmToLogicalUnits(10, lmMILLIMETERS),      //left=1cm
175
 
                              lmToLogicalUnits(10, lmMILLIMETERS),      //right=1cm
176
 
                              lmToLogicalUnits(10, lmMILLIMETERS));     //top=1cm
177
 
    m_pScoreCtrol->SetScale((float)1.3);
178
 
 
179
 
    // right/wrong answers counters control
180
 
    m_pCounters = new lmCountersCtrol(this, wxID_ANY);
181
 
    pTopSizer->Add(
182
 
        m_pCounters,
183
 
        wxSizerFlags(0).Left().Border(wxLEFT|wxRIGHT, 10) );
184
 
    
185
 
 
186
 
        //links 
187
 
 
188
 
    wxBoxSizer* pLinksSizer = new wxBoxSizer( wxHORIZONTAL );
189
 
    pMainSizer->Add(
190
 
        pLinksSizer,
191
 
        wxSizerFlags(0).Center().Border(wxALL, 10) );
192
 
 
193
 
    // "new problem" button
194
 
    pLinksSizer->Add(
195
 
        new lmUrlAuxCtrol(this, ID_LINK_NEW_PROBLEM, _("New problem") ),
196
 
        wxSizerFlags(0).Left().Border(wxLEFT|wxRIGHT|wxBOTTOM, 20) );
197
 
    
198
 
    // "show solution" button
199
 
    pLinksSizer->Add(
200
 
        new lmUrlAuxCtrol(this, ID_LINK_SOLUTION, _("Show solution") ),
201
 
        wxSizerFlags(0).Left().Border(wxLEFT|wxRIGHT|wxBOTTOM, 20) );
202
 
    
203
 
 
204
 
    //create 15 buttons for the answers: three rows, five buttons per row
205
 
    wxBoxSizer* pRowSizer;
206
 
    wxButton* pButton;
207
 
    int iB = 0;
208
 
    const int NUM_ROWS = 3;
209
 
    const int NUM_COLS = 5;
210
 
    for (int iRow=0; iRow < NUM_ROWS; iRow++) {
211
 
        pRowSizer = new wxBoxSizer( wxHORIZONTAL );
212
 
        pMainSizer->Add(    
213
 
            pRowSizer,
214
 
            wxSizerFlags(0).Left());
215
 
        pRowSizer->Add(20+BUTTONS_DISTANCE, 24, 0);    //spacer to center labels
216
 
 
217
 
        for (int iCol=0; iCol < NUM_COLS; iCol++) {
218
 
            iB = iCol + iRow * NUM_COLS;    // button index: 0 .. 24         
219
 
            pButton = new wxButton( this, ID_BUTTON + iB, _T(""),
220
 
                wxDefaultPosition, wxSize(90, 24));
221
 
            m_pAnswerButton[iB++] = pButton;
222
 
            pRowSizer->Add(
223
 
                pButton,
224
 
                wxSizerFlags(0).Border(wxALL, BUTTONS_DISTANCE) );
225
 
        }
226
 
    }
227
 
 
228
 
    SetSizer( pMainSizer );                // use the sizer for window layout
229
 
    pMainSizer->SetSizeHints( this );        // set size hints to honour minimum size
230
 
 
231
 
    NewProblem();
232
 
}
233
 
 
234
 
lmTheoKeySignCtrol::~lmTheoKeySignCtrol()
235
 
{
236
 
    if (m_pScoreCtrol) {
237
 
        delete m_pScoreCtrol;
238
 
        m_pScoreCtrol = (lmScoreAuxCtrol*)NULL;
239
 
    }
240
 
 
241
 
    if (m_pConstrains) {
242
 
        delete m_pConstrains;
243
 
        m_pConstrains = (lmTheoKeySignConstrains*) NULL;
244
 
    }
245
 
 
246
 
    if (m_pScore) {
247
 
        delete m_pScore;
248
 
        m_pScore = (lmScore*)NULL;
249
 
    }
250
 
}
251
 
 
252
 
void lmTheoKeySignCtrol::EnableButtons(bool fEnable)
253
 
{
254
 
    for (int i=0; i < lmTHEO_KEYSIGN_NUM_BUTTONS; i++) {
255
 
        if (m_pAnswerButton[i])
256
 
            m_pAnswerButton[i]->Enable(fEnable);
257
 
    }
258
 
    m_fButtonsEnabled = fEnable;
259
 
 
260
 
}
261
 
 
262
 
//----------------------------------------------------------------------------------------
263
 
// Event handlers
264
 
 
265
 
void lmTheoKeySignCtrol::OnSize(wxSizeEvent& event)
266
 
{
267
 
    //wxLogMessage(_T("OnSize en IntrervalsControl"));
268
 
    Layout();
269
 
 
270
 
}
271
 
 
272
 
void lmTheoKeySignCtrol::OnNewProblem(wxCommandEvent& event)
273
 
{
274
 
    NewProblem();
275
 
}
276
 
 
277
 
void lmTheoKeySignCtrol::OnDisplaySolution(wxCommandEvent& event)
278
 
{
279
 
    m_pCounters->IncrementWrong();
280
 
    DisplaySolution();
281
 
    EnableButtons(false);           //student must not give now the answer
282
 
}
283
 
 
284
 
void lmTheoKeySignCtrol::OnRespButton(wxCommandEvent& event)
285
 
{
286
 
    int nIndex = event.GetId() - ID_BUTTON;
287
 
 
288
 
    //verify if success or failure
289
 
    bool fSuccess = (nIndex == m_nIndexKeyName);
290
 
    
291
 
    //produce feedback sound, and update counters
292
 
    if (fSuccess) {
293
 
        m_pCounters->IncrementRight();
294
 
    } else {
295
 
        m_pCounters->IncrementWrong();
296
 
    }
297
 
        
298
 
    //if failure or not auto-new problem, display the solution.
299
 
    //Else, if success and auto-new problem, generate a new problem
300
 
    if (!fSuccess || !g_fAutoNewProblem) {
301
 
        if (!fSuccess) {
302
 
            //failure: mark wrong button in red and right one in green
303
 
            m_pAnswerButton[m_nIndexKeyName]->SetBackgroundColour(g_pColors->Success());
304
 
            m_pAnswerButton[nIndex]->SetBackgroundColour(g_pColors->Failure());
305
 
        }
306
 
        //show the solucion
307
 
        DisplaySolution();
308
 
        EnableButtons(false);
309
 
 
310
 
    } else {
311
 
        NewProblem();
312
 
    }
313
 
    
314
 
}
315
 
 
316
 
void lmTheoKeySignCtrol::NewProblem()
317
 
{
318
 
 
319
 
    ResetExercise();
320
 
 
321
 
    // choose mode
322
 
    lmRandomGenerator oGenerator;
323
 
    if (m_pConstrains->GetScaleMode() == eMayorAndMinorModes) {
324
 
        m_fMajorMode = oGenerator.FlipCoin();
325
 
    }
326
 
    else {
327
 
        m_fMajorMode = (m_pConstrains->GetScaleMode() == eMajorMode);
328
 
    }
329
 
 
330
 
    // choose key signature and prepare answer
331
 
    bool fFlats = oGenerator.FlipCoin();
332
 
    int nAnswer;
333
 
    int nAccidentals = oGenerator.RandomNumber(0, m_pConstrains->GetMaxAccidentals());
334
 
    EKeySignatures nKey;
335
 
    if (m_fMajorMode) {
336
 
        if (fFlats) {
337
 
            // Major mode, flats
338
 
            switch(nAccidentals)
339
 
            {
340
 
                case 0:
341
 
                    nKey = earmDo;
342
 
                    nAnswer = 0;            // Do Mayor, La menor, no accidentals
343
 
                    m_nIndexKeyName = 1;
344
 
                    break;
345
 
                case 1:
346
 
                    nKey = earmFa;
347
 
                    nAnswer = 14;           // Fa Mayor, Re menor"
348
 
                    m_nIndexKeyName = 7;
349
 
                    break;
350
 
               case 2:
351
 
                    nKey = earmSib;
352
 
                    nAnswer = 13;   // Si b Mayor, Sol menor"
353
 
                    m_nIndexKeyName = 13;
354
 
                    break;
355
 
                case 3:
356
 
                    nKey = earmMib;
357
 
                    nAnswer = 12;   // Mi b Mayor, Do menor"
358
 
                    m_nIndexKeyName = 5;
359
 
                    break;
360
 
                case 4:
361
 
                    nKey = earmLab;
362
 
                    nAnswer = 11;   // La b Mayor, Fa menor"
363
 
                    m_nIndexKeyName = 11;
364
 
                    break;
365
 
                case 5:
366
 
                    nKey = earmReb;
367
 
                    nAnswer = 10;   // Re b Mayor, Si b menor"
368
 
                    m_nIndexKeyName = 3;
369
 
                    break;
370
 
                case 6:
371
 
                    nKey = earmSolb;
372
 
                    nAnswer = 9;   // Sol b Mayor, Mi b menor"
373
 
                    m_nIndexKeyName = 9;
374
 
                    break;
375
 
                case 7:
376
 
                    nKey = earmDob;
377
 
                    nAnswer = 8;   // Do b Mayor, La b menor"
378
 
                    m_nIndexKeyName = 0;
379
 
                    break;
380
 
            }
381
 
        } else {
382
 
            // Major mode, sharps
383
 
            switch(nAccidentals)
384
 
            {
385
 
                case 0:
386
 
                    nKey = earmDo;
387
 
                    nAnswer = 0;   // Do Mayor, La menor"
388
 
                    m_nIndexKeyName = 1;
389
 
                    break;
390
 
                case 1:
391
 
                    nKey = earmSol;
392
 
                    nAnswer = 1;   // Sol Mayor, Mi menor"
393
 
                    m_nIndexKeyName = 10;
394
 
                    break;
395
 
                case 2:
396
 
                    nKey = earmRe;
397
 
                    nAnswer = 2;   // Re Mayor, Si menor"
398
 
                    m_nIndexKeyName = 4;
399
 
                    break;
400
 
                case 3:
401
 
                    nKey = earmLa;
402
 
                    nAnswer = 3;   // La Mayor, Fa # menor"
403
 
                    m_nIndexKeyName = 12;
404
 
                    break;
405
 
                case 4:
406
 
                    nKey = earmMi;
407
 
                    nAnswer = 4;   // Mi Mayor, Do # menor"
408
 
                    m_nIndexKeyName = 6;
409
 
                    break;
410
 
                case 5:
411
 
                    nKey = earmSi;
412
 
                    nAnswer = 5;   // Si Mayor, Sol # menor"
413
 
                    m_nIndexKeyName = 14;
414
 
                    break;
415
 
                case 6:
416
 
                    nKey = earmFas;
417
 
                    nAnswer = 6;   // Fa # Mayor, Re # menor"
418
 
                    m_nIndexKeyName = 8;
419
 
                    break;
420
 
                case 7:
421
 
                    nKey = earmDos;
422
 
                    nAnswer = 7;   // Do # Mayor, La # menor"
423
 
                    m_nIndexKeyName = 2;
424
 
                    break;
425
 
            }
426
 
        }
427
 
    } else {
428
 
        if (fFlats) {
429
 
            // Minor mode, flats
430
 
            switch(nAccidentals)
431
 
            {
432
 
                case 0:
433
 
                    nKey = earmLam;
434
 
                    nAnswer = 0;   // Do Mayor, La menor"
435
 
                    m_nIndexKeyName = 11;
436
 
                    break;
437
 
                case 1:
438
 
                    nKey = earmRem;
439
 
                    nAnswer = 14;   // Fa Mayor, Re menor"
440
 
                    m_nIndexKeyName = 2;
441
 
                    break;
442
 
                case 2:
443
 
                    nKey = earmSolm;
444
 
                    nAnswer = 13;   // Si b Mayor, Sol menor"
445
 
                    m_nIndexKeyName = 8;
446
 
                    break;
447
 
                case 3:
448
 
                    nKey = earmDom;
449
 
                    nAnswer = 12;   // Mi b Mayor, Do menor"
450
 
                    m_nIndexKeyName = 0;
451
 
                    break;
452
 
                case 4:
453
 
                    nKey = earmFam;
454
 
                    nAnswer = 11;   // La b Mayor, Fa menor"
455
 
                    m_nIndexKeyName = 6;
456
 
                    break;
457
 
                case 5:
458
 
                    nKey = earmSibm;
459
 
                    nAnswer = 10;   // Re b Mayor, Si b menor"
460
 
                    m_nIndexKeyName = 13;
461
 
                    break;
462
 
                case 6:
463
 
                    nKey = earmMibm;
464
 
                    nAnswer = 9;   // Sol b Mayor, Mi b menor"
465
 
                    m_nIndexKeyName = 4;
466
 
                    break;
467
 
                case 7:
468
 
                    nKey = earmLabm;
469
 
                    nAnswer = 8;   // Do b Mayor, La b menor"
470
 
                    m_nIndexKeyName = 10;
471
 
                    break;
472
 
            }
473
 
        } else {
474
 
            // Minor mode, sharps
475
 
            switch(nAccidentals)
476
 
            {
477
 
                case 0:
478
 
                    nKey = earmLam;
479
 
                    nAnswer = 0;   // Do Mayor, La menor"
480
 
                    m_nIndexKeyName = 11;
481
 
                    break;
482
 
                case 1:
483
 
                    nKey = earmMim;
484
 
                    nAnswer = 1;   // Sol Mayor, Mi menor"
485
 
                    m_nIndexKeyName = 5;
486
 
                    break;
487
 
                case 2:
488
 
                    nKey = earmSim;
489
 
                    nAnswer = 2;   // Re Mayor, Si menor"
490
 
                    m_nIndexKeyName = 14;
491
 
                    break;
492
 
                case 3:
493
 
                    nKey = earmFasm;
494
 
                    nAnswer = 3;   // La Mayor, Fa # menor"
495
 
                    m_nIndexKeyName = 7;
496
 
                    break;
497
 
                case 4:
498
 
                    nKey = earmDosm;
499
 
                    nAnswer = 4;   // Mi Mayor, Do # menor"
500
 
                    m_nIndexKeyName = 1;
501
 
                    break;
502
 
                case 5:
503
 
                    nKey = earmSolsm;
504
 
                    nAnswer = 5;   // Si Mayor, Sol # menor"
505
 
                    m_nIndexKeyName = 9;
506
 
                    break;
507
 
                case 6:
508
 
                    nKey = earmResm;
509
 
                    nAnswer = 6;   // Fa # Mayor, Re # menor"
510
 
                    m_nIndexKeyName = 3;
511
 
                    break;
512
 
                case 7:
513
 
                    nKey = earmLasm;
514
 
                    nAnswer = 7;   // Do # Mayor, La # menor"
515
 
                    m_nIndexKeyName = 12;
516
 
                    break;
517
 
            }
518
 
        }
519
 
    }
520
 
 
521
 
    // choose type of problem
522
 
    if (m_pConstrains->GetProblemType() == eBothKeySignProblems) {
523
 
        m_fIdentifyKey = oGenerator.FlipCoin();
524
 
    }
525
 
    else {
526
 
        m_fIdentifyKey = (m_pConstrains->GetProblemType() == eIdentifyKeySignature);
527
 
    }
528
 
 
529
 
    g_pLogger->LogTrace(_T("lmTheoKeySignCtrol"),
530
 
        _T("[lmTheoKeySignCtrol::NewProblem] m_fIdentifyKey=%s, m_fMajorMode=%s, fFlats=%s, nKey=%d, nAnswer=%d, m_nIndexKeyName=%d"),
531
 
            (m_fIdentifyKey ? _T("yes") : _T("no")),
532
 
            (m_fMajorMode ? _T("yes") : _T("no")),
533
 
            (fFlats ? _T("yes") : _T("no")),
534
 
            nKey, nAnswer, m_nIndexKeyName);
535
 
 
536
 
 
537
 
    // store index to right answer button (for guess-number-of-accidentals problems)
538
 
    if (!m_fIdentifyKey) {
539
 
        m_nIndexKeyName = KeySignatureToNumFifths(nKey);
540
 
        if (m_nIndexKeyName < 0) m_nIndexKeyName = 7 - m_nIndexKeyName;
541
 
    }
542
 
 
543
 
    // choose clef
544
 
    EClefType nClef = oGenerator.GenerateClef(m_pConstrains->GetClefConstrains());
545
 
 
546
 
    // write buttons' labels, depending on mode
547
 
    if (m_fIdentifyKey) {
548
 
        if (m_fMajorMode) {
549
 
            m_pAnswerButton[0]->SetLabel(_("C flat major"));
550
 
            m_pAnswerButton[1]->SetLabel(_("C major"));
551
 
            m_pAnswerButton[2]->SetLabel(_("C sharp major"));
552
 
            m_pAnswerButton[3]->SetLabel(_("D flat major"));
553
 
            m_pAnswerButton[4]->SetLabel(_("D major"));
554
 
            m_pAnswerButton[5]->SetLabel(_("E flat major"));
555
 
            m_pAnswerButton[6]->SetLabel(_("E major"));
556
 
            m_pAnswerButton[7]->SetLabel(_("F major"));
557
 
            m_pAnswerButton[8]->SetLabel(_("F sharp major"));
558
 
            m_pAnswerButton[9]->SetLabel(_("G flat major"));
559
 
            m_pAnswerButton[10]->SetLabel(_("G major"));
560
 
            m_pAnswerButton[11]->SetLabel(_("A flat major"));
561
 
            m_pAnswerButton[12]->SetLabel(_("A major"));
562
 
            m_pAnswerButton[13]->SetLabel(_("B flat major"));
563
 
            m_pAnswerButton[14]->SetLabel(_("B major"));
564
 
            //14,0,7,12,2,10,4,8,6,13,1,11,3,9,5
565
 
        }
566
 
        else {
567
 
            m_pAnswerButton[0]->SetLabel(_("C minor"));
568
 
            m_pAnswerButton[1]->SetLabel(_("C sharp minor"));
569
 
            m_pAnswerButton[2]->SetLabel(_("D minor"));
570
 
            m_pAnswerButton[3]->SetLabel(_("D sharp minor"));
571
 
            m_pAnswerButton[4]->SetLabel(_("E flat minor"));
572
 
            m_pAnswerButton[5]->SetLabel(_("E minor"));
573
 
            m_pAnswerButton[6]->SetLabel(_("F minor"));
574
 
            m_pAnswerButton[7]->SetLabel(_("F sharp minor"));
575
 
            m_pAnswerButton[8]->SetLabel(_("G minor"));
576
 
            m_pAnswerButton[9]->SetLabel(_("G sharp minor"));
577
 
            m_pAnswerButton[10]->SetLabel(_("A flat minor"));
578
 
            m_pAnswerButton[11]->SetLabel(_("A minor"));
579
 
            m_pAnswerButton[12]->SetLabel(_("A sharp minor"));
580
 
            m_pAnswerButton[13]->SetLabel(_("B flat minor"));
581
 
            m_pAnswerButton[14]->SetLabel(_("B minor"));
582
 
        }
583
 
    }
584
 
    else {
585
 
        // type of problem: write key
586
 
        m_pAnswerButton[0]->SetLabel(_("No accidentals"));
587
 
        m_pAnswerButton[1]->SetLabel(_("1 #"));
588
 
        m_pAnswerButton[2]->SetLabel(_("2 #"));
589
 
        m_pAnswerButton[3]->SetLabel(_("3 #"));
590
 
        m_pAnswerButton[4]->SetLabel(_("4 #"));
591
 
        m_pAnswerButton[5]->SetLabel(_("5 #"));
592
 
        m_pAnswerButton[6]->SetLabel(_("6 #"));
593
 
        m_pAnswerButton[7]->SetLabel(_("7 #"));
594
 
        m_pAnswerButton[8]->SetLabel(_("1 b"));
595
 
        m_pAnswerButton[9]->SetLabel(_("2 b"));
596
 
        m_pAnswerButton[10]->SetLabel(_("3 b"));
597
 
        m_pAnswerButton[11]->SetLabel(_("4 b"));
598
 
        m_pAnswerButton[12]->SetLabel(_("5 b"));
599
 
        m_pAnswerButton[13]->SetLabel(_("6 b"));
600
 
        m_pAnswerButton[14]->SetLabel(_("7 b"));
601
 
    }
602
 
 
603
 
    //create the score
604
 
    m_pScore = new lmScore();
605
 
    m_pScore->SetTopSystemDistance( lmToLogicalUnits(5, lmMILLIMETERS) );   //5mm
606
 
    m_pScore->AddInstrument(1,0,0,_T(""));                   //one vstaff, MIDI channel 0, MIDI instr 0
607
 
    lmVStaff *pVStaff = m_pScore->GetVStaff(1, 1);    //get first vstaff of instr.1
608
 
    pVStaff->AddClef( nClef );
609
 
    pVStaff->AddKeySignature(nKey);
610
 
    pVStaff->AddBarline(etb_EndBarline, lmNO_VISIBLE);
611
 
 
612
 
    //wxLogMessage(wxString::Format(
613
 
    //    _T("[lmTheoKeySignCtrol::NewProblem] m_nIndexKeyName=%d, oIntv.GetIntervalNum()=%d"),
614
 
    //    m_nIndexKeyName, oIntv.GetIntervalNum() ));
615
 
    
616
 
    //display the problem
617
 
    m_pCounters->NextTeam();
618
 
    if (m_fIdentifyKey) {
619
 
        //direct problem
620
 
        m_sAnswer = sMajor[nAnswer] + _T(", ") + sMinor[nAnswer];
621
 
        m_pScoreCtrol->DisplayScore(m_pScore);
622
 
    } else {
623
 
        //inverse problem
624
 
        m_sAnswer = (m_fMajorMode ? sMajor[nAnswer] : sMinor[nAnswer] );
625
 
        m_pScoreCtrol->DisplayMessage(m_sAnswer, lmToLogicalUnits(5, lmMILLIMETERS));
626
 
    }
627
 
    m_fProblemCreated = true;
628
 
    EnableButtons(true);
629
 
    
630
 
}
631
 
 
632
 
void lmTheoKeySignCtrol::DisplaySolution()
633
 
{
634
 
    if (m_fIdentifyKey) {
635
 
        m_pScoreCtrol->DisplayMessage(m_sAnswer, lmToLogicalUnits(5, lmMILLIMETERS), false);
636
 
    } else {
637
 
        m_pScoreCtrol->DisplayScore(m_pScore, false);
638
 
    }
639
 
    
640
 
    m_fProblemCreated = false;
641
 
    
642
 
}
643
 
 
644
 
void lmTheoKeySignCtrol::OnDebugShowSourceScore(wxCommandEvent& event)
645
 
{
646
 
    m_pScoreCtrol->SourceLDP();
647
 
}
648
 
 
649
 
void lmTheoKeySignCtrol::OnDebugDumpScore(wxCommandEvent& event)
650
 
{
651
 
    m_pScoreCtrol->Dump();
652
 
}
653
 
 
654
 
void lmTheoKeySignCtrol::ResetExercise()
655
 
{
656
 
    for (int i=0; i < lmTHEO_KEYSIGN_NUM_BUTTONS; i++) {
657
 
        if (m_pAnswerButton[i]) {
658
 
            m_pAnswerButton[i]->SetBackgroundColour( g_pColors->Normal() );
659
 
        }
660
 
    }
661
 
    EnableButtons(false);
662
 
 
663
 
    if (m_pScore) {
664
 
        delete m_pScore;
665
 
        m_pScore = (lmScore*)NULL;
666
 
    }
667
 
    
668
 
}
669