summaryrefslogtreecommitdiff
path: root/muse_qt4_evolution/muse/midiedit/trackpattern.h
blob: d9d91aeeece8ecbfed8214c1b2cfa2dbe1bbf1ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
//=================================================================
//  trackpattern.h
//  TrackPattern class for miditracker, QDock, QTree, Part, matrix
//    miditracker.h
//  (C) Copyright 2006 Nil Geisweiller (a_lin@user.sourceforge.net)
//=================================================================

#ifndef __TRACKERPATTERN_H__
#define __TRACKERPATTERN_H__

#include <vector>
#include "miditrack.h"
#include "part.h"

class PartList;

//----------------------------------------------------------
// EventPat
//  has to be derived, can be note or control
//----------------------------------------------------------
class EventPat {
 private:
 protected:
  bool _isReadable; //true iff the time of the event is the exact row time
  bool _isEmpty;
 public:
  EventPat(bool isEmpty, bool isReadable);
  EventPat(); //_isEmpty=true and_isReadable=true at the initialization
  ~EventPat();

  void setEmpty(bool);
  bool getEmpty();
  void setReadable(bool);
  bool getReadable();
};

//----------------------------------------------------------
// VoiceEventPat
//----------------------------------------------------------
class VoiceEventPat : public EventPat {
  private:
  int _noteNum; //absolute note number including octave
  int _velocity; //if velocity is 0 note is off
 public:
  VoiceEventPat(int noteNum, int velocity); // _isReadable is initialized true
  VoiceEventPat(bool isEmpty, bool isReadable);
  VoiceEventPat(); //_isEmpty = true, _isReadable = true
  ~VoiceEventPat();

  void setNoteNum(int n);
  int getNoteNum();
  void setVelocity(int n);
  int getVelocity();
  QString str(); //return the string to display on the entry of the pattern
};

//----------------------------------------------------------
// CtrlEventPat
//----------------------------------------------------------
class CtrlEventPat : public EventPat {
 private:
  int _ctrlNum;
  int _value; //if velocity is 0 note is off
 public:
  CtrlEventPat(int ctrlNum, int value); // _isReadable is initialized true
  CtrlEventPat(); // _isReadable is initialized false
  ~CtrlEventPat();

  void setCtrlNum(int n);
  int getCtrlNum();
  void setValue(int n);
  int getValue();
  QString str(); //return the string to display on the entry of the pattern
};

//----------------------------------------------------------
// BasePat
//----------------------------------------------------------
class BasePat {
 protected:
  QString _name;
  unsigned _firstTick;
  unsigned _lastTick;
  int _quant;
 public:
  BasePat();
  BasePat(QString name, unsigned firstTick, unsigned lastTick, int quant);
  ~BasePat();

  QString getName();

  bool isRow(unsigned tick); //return true iff tick coincides with one row
  unsigned tick2row(unsigned tick);  
};

//----------------------------------------------------------
// VoicePat
//----------------------------------------------------------
class VoicePat : public BasePat {
 private:
  std::vector<VoiceEventPat*> _eventsCol; //column of VoiceEventPat to display
  EventList* _events; //actual list of events, only one at a time
 public:
  VoicePat(QString name, unsigned firstTick, unsigned lastTick, int quant);
  ~VoicePat();
  
  std::vector<VoiceEventPat*> getEventsCol();

  bool add(const Event* e, unsigned tick); //add the Event e into the EventList
                                           //and update properly _events
                                           //return true if success, that is
                                           //there is an empty space of the
                                           //event
  bool isFreeSpace(const Event* e, unsigned tick); //return true iff there
                                                   //is space to add the
                                                   //event e without
                                                   //overlapping other events
};

//----------------------------------------------------------
// CtrlPat
//----------------------------------------------------------
class CtrlPat {
 private:
  std::vector<CtrlEventPat> _events; //column of CtrlEventPat
 public:
  CtrlPat(QString name);
  ~CtrlPat();
};

//------------------------------------------------------
// BaseTrackPat
//------------------------------------------------------
class BaseTrackPat : public QDockWidget {
  Q_OBJECT

 protected:
  QTreeWidget* _tree;
  QMainWindow* _parent;

  unsigned _rowMag; //contains the number of rows
  unsigned _firstRow; //absolute index of the first row
  unsigned _lastRow; //absolute index of the last row, included
  unsigned _relativeCurrentRow; //index of the current according to the tree
  unsigned _absoluteCurrentRow; //index of the current row according to the
                                //event matrix
  unsigned _absoluteNbrRow; //contains the number of rows of the matrix

  int _fontHeight;

  bool _update; //if true then the tree must updated

 public:
  BaseTrackPat(QMainWindow* parent, unsigned anr = 0);
  ~BaseTrackPat();

  void setRowMag(); //set _rowMag with the number of rows to display according
                    //to the size of the window, adjust _lastRow accordingly,
                    //assum that first row is set appropriately
  void setFirstRow(unsigned f); //set _firstRow with f, that is the absolute index
                                //of the first row, adjust _lastRow appropriately
  void setRelativeCurrentRow(unsigned r); //set _relativeCurrentRow with r
                                          //and _absoluteCurrentRow accordingly
  void setAbsoluteCurrentRow(unsigned a); //set _absoluteCurrentRow with a
                                          //and _relativeCurrentRow accordingly

  unsigned getRowMag();
  unsigned getFirstRow();
  unsigned getLastRow();
  unsigned getRelativeCurrentRow();
  unsigned getAbsoluteCurrentRow();

  unsigned getAbsoluteNbrRow();

  void moveRelativeCurrentRow(unsigned newIndex); //update _firstRow, _lastrow
                                                  //relativeCurrentRow,
                                                  //absoluteCurrentRow, considering
                                                  //that the new relative index is
                                                  //newIndex

  void resizeEvent(QResizeEvent* /*event*/);

  virtual void clearMatrix() {}
  virtual void buildMatrix() {}
  virtual void fillPattern() {} //fill the treeWidget with the right window of times
                                //according to _firstRow and _lastRow


  void selectCurrentRow(); //block the signals and select the current row

 signals:
  void moveCurrentRow(unsigned i); //send the signal that the current row is moved
                                   //at the relative index i
 private slots:
  void currentItemChanged(QTreeWidgetItem* nitem);
  void moveRowFromSignal(unsigned index);
  void updatePattern(int songChangeType);
};

//------------------------------------------------------
// TrackPattern
//------------------------------------------------------
class TrackPattern : public BaseTrackPat, public BasePat {
 private:
  PartList* _partList; //partList concerned by a track
  MidiTrack* _track;
  std::vector<VoicePat*> _voiceColumns; //matrix of voice events
  std::vector<CtrlPat*> _ctrlColumns; //matrix of ctrl events
 public:
  TrackPattern(QMainWindow* parent, QString name, 
	       unsigned firstTick, unsigned lastTick,
	       int quant, PartList* pl, MidiTrack* t, unsigned anr = 0);
  ~TrackPattern();

  void add(const Event* e, unsigned tick); //add the Event e and
                                           //build consequently
                                           //the matrix,
                                           //creating new voices when necessary
  MidiTrack* getTrack() {return _track;}
  void setQuant(int quant);

  virtual void clearMatrix();
  virtual void buildMatrix();
  virtual void fillPattern();
};

//------------------------------------------------------
// TimingEvent
//------------------------------------------------------
class TimingEvent {
 private:
  int _bar;
  int _beat;
  unsigned _tick;
  unsigned _row;

 public:
  TimingEvent(unsigned row);
  ~TimingEvent();

  void setBarBeatTick(unsigned tick);

  QString barBeatTickStr();
  QString rowStr();
};

class TimingPattern : public BasePat, public BaseTrackPat {
 private:
  //QTreeWidget* _tree;
  std::vector<TimingEvent*> _timingEvents;
 public:
  TimingPattern(QMainWindow* parent, QString name, unsigned firstTick,
		unsigned lastTick, int quant);
  ~TimingPattern();

  virtual void clearMatrix();
  virtual void buildMatrix();
  virtual void fillPattern();
};

#endif