~s-cecilio/lenmus/v5.3

« back to all changes in this revision

Viewing changes to src/score/ColStaffObjs.cpp

  • Committer: cecilios
  • Date: 2006-03-05 11:33:10 UTC
  • Revision ID: svn-v4:2587a929-2f0e-0410-ae78-fe6f687d5efe:trunk:2
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// RCS-ID: $Id: ColStaffObjs.cpp,v 1.3 2006/02/23 19:22:56 cecilios Exp $
 
2
//--------------------------------------------------------------------------------------
 
3
//    LenMus Phonascus: The teacher of music
 
4
//    Copyright (c) 2002-2006 Cecilio Salmeron
 
5
//
 
6
//    This program is free software; you can redistribute it and/or modify it under the 
 
7
//    terms of the GNU General Public License as published by the Free Software Foundation;
 
8
//    either version 2 of the License, or (at your option) any later version.
 
9
//
 
10
//    This program is distributed in the hope that it will be useful, but WITHOUT ANY 
 
11
//    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
 
12
//    PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 
13
//
 
14
//    You should have received a copy of the GNU General Public License along with this 
 
15
//    program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, 
 
16
//    Fifth Floor, Boston, MA  02110-1301, USA.
 
17
//
 
18
//    For any comment, suggestion or feature request, please contact the manager of 
 
19
//    the project at cecilios@users.sourceforge.net
 
20
//
 
21
//-------------------------------------------------------------------------------------
 
22
/*! @file ColStaffObjs.cpp
 
23
    @brief Implementation file for class lmColStaffObjs
 
24
    @ingroup score_kernel
 
25
*/
 
26
 
 
27
//----------------------------------------------------------------------------------------------------
 
28
/*! @class lmColStaffObjs
 
29
    @ingroup score_kernel
 
30
    @brief A Collection of StaffObjs
 
31
 
 
32
 Esta clase encapsula las estructuras de datos y sus m�todos de mantenimiento y acceso, para soportar
 
33
 la representaci�n interna de una colecci�n de StaffObjs (una CStaff, con sus compases y StaffObjs).
 
34
 
 
35
 Inicialmente se modelizaba dentro de CStaff. El problema era que a medida que se complicaba el modelo
 
36
 de objetos se veian afectadas muchas funciones de CStaff. Para independizar
 
37
 a las funciones de la implementaci�n concreta de la secuencia de StaffObjs se ha creado esta
 
38
 clase. As�, podr� cambiarse en el futuro su implenetaci�n (por ejemplo, para mejorar rendimiento)
 
39
 sin que se vea afectado el resto de clases.
 
40
 
 
41
 Lo �nico que hay que respetar son las siguientes restricciones:
 
42
 - Un compas termina siempre con un lmStaffObj de tipo Barra.
 
43
 - Cualquiera que sea el tipo de recorrido elegido, respeta que los StaffObjs de un compas no se
 
44
   recuperan antes que los del siguiente compas. Adem�s, respeta que la barra de fin de compas sea
 
45
   el �ltimo elemento que se recupera de un compas.
 
46
 
 
47
 Para facilitar las futuras modificaciones en las estructuras de datos que implementan esta
 
48
 clase, cuando se crea un iterador se especifica el tipo de recorrido necesario. La implementaci�n
 
49
 debe siempre respetar esos criterios. Los c�digos y sus significados son:
 
50
 
 
51
 - eTR_AsStored:
 
52
       Se recorren por el orden en que se encuentran definidos en las estructuras de datos.
 
53
       No tiene que respetar ninguna restricci�n, sino que debe proporcionar los StaffObjs
 
54
       en el orden en que realmente se encuentren almacenados.
 
55
       Esta ordenaci�n se utiliza para depuraci�n, en el m�todo Dump.
 
56
       Tambi�n se usa cuando hay que acceder a todos los StaffObjs de la CStaff y el orden
 
57
       de acceso es totalmente indiferente, ya que siempre ser� el acceso m�s r�pido. Por
 
58
       ejemplo en CStaff.EstablecerPapel
 
59
 
 
60
 - eTR_ByTime:
 
61
       The StaffObjs are recovered ordered by increasing time pos
 
62
 
 
63
 - eTR_OptimizeAccess:
 
64
       the recovery order inside a measure is not important. So use the ordering that results in
 
65
       the fastest access time
 
66
 
 
67
 - Cualquiera que sea el tipo de recorrido elegido, respeta que los StaffObjs de un compas no se
 
68
   recuperan antes que los del siguiente compas. Adem�s, respeta que la barra de fin de compas sea
 
69
   el �ltimo elemento que se recupera de un compas.
 
70
 
 
71
*/
 
72
//----------------------------------------------------------------------------------------------------
 
73
 
 
74
#ifdef __GNUG__
 
75
// #pragma implementation
 
76
#endif
 
77
 
 
78
// For compilers that support precompilation, includes "wx/wx.h".
 
79
#include "wx/wxprec.h"
 
80
 
 
81
#ifdef __BORLANDC__
 
82
#pragma hdrstop
 
83
#endif
 
84
 
 
85
#ifndef WX_PRECOMP
 
86
#include "wx/wx.h"
 
87
#endif
 
88
 
 
89
#include "Score.h"
 
90
#include "wx/debug.h"
 
91
 
 
92
 
 
93
//====================================================================================================
 
94
//Constructors and destructors
 
95
//====================================================================================================
 
96
lmColStaffObjs::lmColStaffObjs()
 
97
{
 
98
    m_fStartMeasure = true;
 
99
    m_rTimePos = 0;                   //reset time counters
 
100
    m_rMaxTimePos = 0;
 
101
}
 
102
 
 
103
lmColStaffObjs::~lmColStaffObjs()
 
104
{
 
105
    //wxLogMessage(wxString::Format(
 
106
    //    _T("[lmColStaffObjs::~lmColStaffObjs] Deleting lmColStaffObjs: num objs = %d"), GetNumStaffObjs() ) );
 
107
    m_cStaffobjs.DeleteContents(true);
 
108
    m_cStaffobjs.Clear();
 
109
 
 
110
    m_aStartMeasure.Clear();
 
111
    //wxLogMessage(wxString::Format(
 
112
    //    _T("[lmColStaffObjs::~lmColStaffObjs] After deleting lmColStaffObjs: num objs = %d"), GetNumStaffObjs() ) );
 
113
 
 
114
}
 
115
 
 
116
 
 
117
//====================================================================================================
 
118
//Funciones de creaci�n, inserci�n y borrado
 
119
//====================================================================================================
 
120
 
 
121
 
 
122
void lmColStaffObjs::Store(lmStaffObj *pSO)
 
123
{
 
124
    /*
 
125
    Stores a lmStaffObj in this StaffObjs collection.
 
126
    Controls division into bars and assign time position to the lmStaffObj
 
127
    
 
128
    Input parameters:
 
129
       pSO: pointer to the lmStaffObj to store
 
130
 
 
131
    */
 
132
 
 
133
    //store time position
 
134
    pSO->SetTimePos(m_rTimePos);
 
135
    
 
136
    //increment time counters
 
137
    if (pSO->GetType() == eTPO_NoteRest) {
 
138
        //only NoteRests increment time counters
 
139
        lmNoteRest* pNR = (lmNoteRest*)pSO;
 
140
        if (pNR->IsRest()) {
 
141
            m_rTimePos += pNR->GetDuration();
 
142
        } else {
 
143
            //It is a note. Verify if it is part of a chord
 
144
            lmNote* pNote = (lmNote*)pSO;
 
145
            if (!pNote->IsInChord()) {
 
146
                //@attention time counter is going to be incremented also for chord base notes,
 
147
                //what is right.
 
148
                //As we are in the process of building the score object from the source code,
 
149
                //chord base notes have not yet being marked as "InChord". This is because
 
150
                //the chord is created when the next note is processed.
 
151
                m_rTimePos += pNote->GetDuration();
 
152
            } else {
 
153
                //for (the same reason, this point is reached only by notes that are in a chord
 
154
                //(but not the base note).
 
155
                //Assing to this note the time position of the note base. Do not increment
 
156
                //time counter as it has been already incremented when storing the base note.
 
157
                lmNote* pNoteBase = (pNote->GetChord())->GetBaseNote();
 
158
                pSO->SetTimePos(pNoteBase->GetTimePos());
 
159
            }
 
160
        }
 
161
        
 
162
    } else {
 
163
        //it is not a lmNoteRest. Increment time counter in the amount coded in the lmStaffObj
 
164
        m_rTimePos += pSO->GetTimePosIncrement();
 
165
    }
 
166
    
 
167
    //Time counter update. Update now the maximun value reached.
 
168
    m_rMaxTimePos = wxMax(m_rMaxTimePos, m_rTimePos);
 
169
    
 
170
    //if (the lmStaffObj being stored is a barline it is necessary to ensure that
 
171
    //its time position match up the measure duration, as there could have been back and forward
 
172
    //displacements.
 
173
    if (pSO->GetType() == eTPO_Barline) {
 
174
        //the object is a barline. Assing to it the maximum time position
 
175
        pSO->SetTimePos(m_rMaxTimePos);
 
176
    }
 
177
    
 
178
    //store the lmStaffObj in the collection. StaffObjs are stored by arrival order
 
179
    wxStaffObjsListNode* pNode = m_cStaffobjs.Append(pSO);
 
180
    
 
181
    //if this lmStaffObj is the first one of a measure, store a pointer to the node in the
 
182
    //measures table
 
183
    if (m_fStartMeasure) 
 
184
    {
 
185
        m_fStartMeasure = false;
 
186
        m_aStartMeasure.Add(pNode);
 
187
    }
 
188
    
 
189
    //store, inside the lmStaffObj, the measure number in which the lmStaffObj is included
 
190
    pSO->SetNumMeasure((wxInt32)m_aStartMeasure.GetCount() );
 
191
 
 
192
    //Finally, if this lmStaffObj is a barline, signal that a new measure must be started
 
193
    //for the next lmStaffObj and reset time counters
 
194
    if (pSO->GetType() == eTPO_Barline)
 
195
    {
 
196
        m_fStartMeasure = true;
 
197
        m_rTimePos = 0;            //reset time counters
 
198
        m_rMaxTimePos = 0;
 
199
    }
 
200
    
 
201
}
 
202
 
 
203
////====================================================================================================
 
204
////Methods for accesing specific items and information about the collection
 
205
////====================================================================================================
 
206
//
 
207
//lmStaffObj* lmColStaffObjs::GetFirst()
 
208
//{
 
209
//    m_pNode = m_cStaffobjs.GetFirst();
 
210
//    return (m_pNode ? (lmStaffObj *)m_pNode->GetData() : (lmStaffObj *)m_pNode);
 
211
//}
 
212
//
 
213
//lmStaffObj* lmColStaffObjs::GetNext()
 
214
//{
 
215
//    m_pNode = m_pNode->GetNext();
 
216
//    return (m_pNode ? (lmStaffObj *)m_pNode->GetData() : (lmStaffObj *)m_pNode);
 
217
//}
 
218
//
 
219
//
 
220
int lmColStaffObjs::GetNumStaffObjs()
 
221
{
 
222
    //returns the number of StaffObjs in the collection
 
223
    return m_cStaffobjs.GetCount();
 
224
}
 
225
 
 
226
wxInt32 lmColStaffObjs::GetNumMeasures()
 
227
{
 
228
    //returns the number of bars in the collection
 
229
    return (wxInt32)m_aStartMeasure.GetCount();
 
230
    
 
231
}
 
232
 
 
233
wxStaffObjsListNode* lmColStaffObjs::GetFirstInMeasure(int nMeasure)
 
234
{
 
235
    //returns the first lmStaffObj in measure number nMeasure (1..n)
 
236
    //This is not a walking method but an access method as:
 
237
    //   - the collection is not accessed
 
238
    //   - It does not either instantiate an iterator nor return any index to instantiate an
 
239
    //   iterator
 
240
    //---------------------------------------------------------------------------------------
 
241
    wxASSERT(nMeasure > 0 && nMeasure <= (wxInt32)m_aStartMeasure.GetCount());
 
242
    wxStaffObjsListNode* pNode = m_aStartMeasure.Item(nMeasure-1);
 
243
    wxASSERT(pNode);
 
244
    return pNode;
 
245
    
 
246
}
 
247
 
 
248
wxStaffObjsListNode* lmColStaffObjs::GetFirst()
 
249
{
 
250
    return m_cStaffobjs.GetFirst();
 
251
}
 
252
 
 
253
wxStaffObjsListNode* lmColStaffObjs::GetLast()
 
254
{
 
255
    return m_cStaffobjs.GetLast();
 
256
}
 
257
 
 
258
 
 
259
//====================================================================================================
 
260
//Other methods
 
261
//====================================================================================================
 
262
 
 
263
lmStaffObjIterator* lmColStaffObjs::CreateIterator(ETraversingOrder nOrder)
 
264
{
 
265
    //creates and returns an iterator
 
266
    lmStaffObjIterator* pIter = new lmStaffObjIterator(nOrder, this);
 
267
    return pIter;
 
268
    
 
269
}
 
270
 
 
271
void lmColStaffObjs::ShiftTime(float rTimeShift)
 
272
{
 
273
    /*
 
274
    Shifts time counters, forward or backwards
 
275
    */
 
276
 
 
277
    //update time counters and check that shift is inside current measure
 
278
    m_rTimePos += rTimeShift;
 
279
    if (m_rTimePos < 0) { m_rTimePos = 0; }      //can not jump back before the start of current measure
 
280
    //! @todo Check that does not go to the next measure
 
281
    //! @todo Display error message if jump out of current measure boundaries
 
282
//    if (m_rTimePos > m_rMaxTimePos) { m_rTimePos = m_rMaxTimePos   //can not jump out of this bar
 
283
 
 
284
}