forked from LMMS/lmms
/
PianoRoll.h
459 lines (364 loc) · 11.5 KB
/
PianoRoll.h
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
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
/*
* PianoRoll.h - declaration of class PianoRoll which is a window where you
* can set and edit notes in an easy way
*
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008 Andrew Kelley <superjoe30/at/gmail/dot/com>
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef PIANO_ROLL_H
#define PIANO_ROLL_H
#include <QVector>
#include <QWidget>
#include <QInputDialog>
#include "Editor.h"
#include "ComboBoxModel.h"
#include "SerializingObject.h"
#include "Note.h"
#include "lmms_basics.h"
#include "Song.h"
#include "ToolTip.h"
class QPainter;
class QPixmap;
class QScrollBar;
class QString;
class QMenu;
class QSignalMapper;
class ComboBox;
class NotePlayHandle;
class Pattern;
class TimeLineWidget;
class PianoRoll : public QWidget
{
Q_OBJECT
Q_PROPERTY( QColor barLineColor READ barLineColor WRITE setBarLineColor )
Q_PROPERTY( QColor beatLineColor READ beatLineColor WRITE setBeatLineColor )
Q_PROPERTY( QColor lineColor READ lineColor WRITE setLineColor )
Q_PROPERTY( QColor noteModeColor READ noteModeColor WRITE setNoteModeColor )
Q_PROPERTY( QColor noteColor READ noteColor WRITE setNoteColor )
Q_PROPERTY( QColor barColor READ barColor WRITE setBarColor )
Q_PROPERTY( QColor selectedNoteColor READ selectedNoteColor WRITE setSelectedNoteColor )
Q_PROPERTY( QColor textColor READ textColor WRITE setTextColor )
Q_PROPERTY( QColor textColorLight READ textColorLight WRITE setTextColorLight )
Q_PROPERTY( QColor textShadow READ textShadow WRITE setTextShadow )
Q_PROPERTY( QColor markedSemitoneColor READ markedSemitoneColor WRITE setMarkedSemitoneColor )
Q_PROPERTY( int noteOpacity READ noteOpacity WRITE setNoteOpacity )
Q_PROPERTY( bool noteBorders READ noteBorders WRITE setNoteBorders )
Q_PROPERTY( QColor backgroundShade READ backgroundShade WRITE setBackgroundShade )
public:
enum EditModes
{
ModeDraw,
ModeErase,
ModeSelect,
ModeEditPitchBend,
};
/*! \brief Resets settings to default when e.g. creating a new project */
void reset();
// functions to display the hover-text labeling a note's volume/panning
void showTextFloat(const QString &text, const QPoint &pos, int timeout=-1);
void showVolTextFloat(volume_t vol, const QPoint &pos, int timeout=-1);
void showPanTextFloat(panning_t pan, const QPoint &pos, int timeout=-1);
void setCurrentPattern( Pattern* newPattern );
inline void stopRecording()
{
m_recording = false;
}
inline bool isRecording() const
{
return m_recording;
}
const Pattern* currentPattern() const
{
return m_pattern;
}
bool hasValidPattern() const
{
return m_pattern != NULL;
}
Song::PlayModes desiredPlayModeForAccompany() const;
int quantization() const;
// qproperty access functions
QColor barLineColor() const;
void setBarLineColor( const QColor & c );
QColor beatLineColor() const;
void setBeatLineColor( const QColor & c );
QColor lineColor() const;
void setLineColor( const QColor & c );
QColor noteModeColor() const;
void setNoteModeColor( const QColor & c );
QColor noteColor() const;
void setNoteColor( const QColor & c );
QColor barColor() const;
void setBarColor( const QColor & c );
QColor selectedNoteColor() const;
void setSelectedNoteColor( const QColor & c );
QColor textColor() const;
void setTextColor( const QColor & c );
QColor textColorLight() const;
void setTextColorLight( const QColor & c );
QColor textShadow() const;
void setTextShadow( const QColor & c );
QColor markedSemitoneColor() const;
void setMarkedSemitoneColor( const QColor & c );
int noteOpacity() const;
void setNoteOpacity( const int i );
bool noteBorders() const;
void setNoteBorders( const bool b );
QColor backgroundShade() const;
void setBackgroundShade( const QColor & c );
protected:
virtual void keyPressEvent( QKeyEvent * ke );
virtual void keyReleaseEvent( QKeyEvent * ke );
virtual void leaveEvent( QEvent * e );
virtual void mousePressEvent( QMouseEvent * me );
virtual void mouseDoubleClickEvent( QMouseEvent * me );
virtual void mouseReleaseEvent( QMouseEvent * me );
virtual void mouseMoveEvent( QMouseEvent * me );
virtual void paintEvent( QPaintEvent * pe );
virtual void resizeEvent( QResizeEvent * re );
virtual void wheelEvent( QWheelEvent * we );
virtual void focusOutEvent( QFocusEvent * );
int getKey( int y ) const;
static void drawNoteRect( QPainter & p, int x, int y,
int width, const Note * n, const QColor & noteCol,
const QColor & selCol, const int noteOpc, const bool borderless );
void removeSelection();
void selectAll();
NoteVector getSelectedNotes();
void selectNotesOnKey();
int xCoordOfTick( int tick );
// for entering values with dblclick in the vol/pan bars
void enterValue( NoteVector* nv );
protected slots:
void play();
void record();
void recordAccompany();
void stop();
void startRecordNote( const Note & n );
void finishRecordNote( const Note & n );
void horScrolled( int new_pos );
void verScrolled( int new_pos );
void setEditMode(int mode);
void copySelectedNotes();
void cutSelectedNotes();
void pasteNotes();
void deleteSelectedNotes();
void updatePosition(const MidiTime & t );
void updatePositionAccompany(const MidiTime & t );
void zoomingChanged();
void quantizeChanged();
void quantizeNotes();
void updateSemiToneMarkerMenu();
void changeNoteEditMode( int i );
void markSemiTone( int i );
void hidePattern( Pattern* pattern );
void selectRegionFromPixels( int xStart, int xEnd );
signals:
void currentPatternChanged();
void semiToneMarkerMenuScaleSetEnabled(bool);
void semiToneMarkerMenuChordSetEnabled(bool);
private:
enum Actions
{
ActionNone,
ActionMoveNote,
ActionResizeNote,
ActionSelectNotes,
ActionChangeNoteProperty,
ActionResizeNoteEditArea
};
enum NoteEditMode
{
NoteEditVolume,
NoteEditPanning,
NoteEditCount // make sure this one is always last
};
enum SemiToneMarkerAction
{
stmaUnmarkAll,
stmaMarkCurrentSemiTone,
stmaMarkAllOctaveSemiTones,
stmaMarkCurrentScale,
stmaMarkCurrentChord,
stmaCopyAllNotesOnKey
};
enum PianoRollKeyTypes
{
PR_WHITE_KEY_SMALL,
PR_WHITE_KEY_BIG,
PR_BLACK_KEY
};
QVector<QString> m_nemStr; // gui names of each edit mode
QMenu * m_noteEditMenu; // when you right click below the key area
QList<int> m_markedSemiTones;
QMenu * m_semiToneMarkerMenu; // when you right click on the key area
PianoRoll();
PianoRoll( const PianoRoll & );
virtual ~PianoRoll();
void autoScroll(const MidiTime & t );
MidiTime newNoteLen() const;
void shiftPos(int amount);
void shiftSemiTone(int amount);
bool isSelection() const;
int selectionCount() const;
void testPlayNote( Note * n );
void testPlayKey( int _key, int _vol, int _pan );
void pauseTestNotes(bool pause = true );
QList<int> getAllOctavesForKey( int keyToMirror ) const;
int noteEditTop() const;
int keyAreaBottom() const;
int noteEditBottom() const;
int keyAreaTop() const;
int noteEditRight() const;
int noteEditLeft() const;
void dragNotes( int x, int y, bool alt, bool shift, bool ctrl );
static const int cm_scrollAmtHoriz = 10;
static const int cm_scrollAmtVert = 1;
static QPixmap * s_whiteKeyBigPm;
static QPixmap * s_whiteKeyBigPressedPm;
static QPixmap * s_whiteKeySmallPm;
static QPixmap * s_whiteKeySmallPressedPm;
static QPixmap * s_blackKeyPm;
static QPixmap * s_blackKeyPressedPm;
static QPixmap * s_toolDraw;
static QPixmap * s_toolErase;
static QPixmap * s_toolSelect;
static QPixmap * s_toolMove;
static QPixmap * s_toolOpen;
static PianoRollKeyTypes prKeyOrder[];
static TextFloat * s_textFloat;
ComboBoxModel m_zoomingModel;
ComboBoxModel m_quantizeModel;
ComboBoxModel m_noteLenModel;
ComboBoxModel m_scaleModel;
ComboBoxModel m_chordModel;
static const QVector<double> m_zoomLevels;
Pattern* m_pattern;
QScrollBar * m_leftRightScroll;
QScrollBar * m_topBottomScroll;
MidiTime m_currentPosition;
bool m_recording;
QList<Note> m_recordingNotes;
Note * m_currentNote;
Actions m_action;
NoteEditMode m_noteEditMode;
int m_selectStartTick;
int m_selectedTick;
int m_selectStartKey;
int m_selectedKeys;
// boundary box around all selected notes when dragging
int m_moveBoundaryLeft;
int m_moveBoundaryTop;
int m_moveBoundaryRight;
int m_moveBoundaryBottom;
// remember where the scrolling started when dragging so that
// we can handle dragging while scrolling with arrow keys
int m_mouseDownKey;
int m_mouseDownTick;
// remember the last x and y of a mouse movement
int m_lastMouseX;
int m_lastMouseY;
// x,y of when the user starts a drag
int m_moveStartX;
int m_moveStartY;
int m_oldNotesEditHeight;
int m_notesEditHeight;
int m_ppt; // pixels per tact
int m_totalKeysToScroll;
// remember these values to use them
// for the next note that is set
MidiTime m_lenOfNewNotes;
volume_t m_lastNoteVolume;
panning_t m_lastNotePanning;
int m_startKey; // first key when drawing
int m_lastKey;
EditModes m_editMode;
EditModes m_ctrlMode; // mode they were in before they hit ctrl
bool m_mouseDownRight; //true if right click is being held down
TimeLineWidget * m_timeLine;
bool m_scrollBack;
void copyToClipboard(const NoteVector & notes ) const;
void drawDetuningInfo( QPainter & _p, const Note * _n, int _x, int _y ) const;
bool mouseOverNote();
Note * noteUnderMouse();
// turn a selection rectangle into selected notes
void computeSelectedNotes( bool shift );
void clearSelectedNotes();
// did we start a mouseclick with shift pressed
bool m_startedWithShift;
friend class PianoRollWindow;
// qproperty fields
QColor m_barLineColor;
QColor m_beatLineColor;
QColor m_lineColor;
QColor m_noteModeColor;
QColor m_noteColor;
QColor m_barColor;
QColor m_selectedNoteColor;
QColor m_textColor;
QColor m_textColorLight;
QColor m_textShadow;
QColor m_markedSemitoneColor;
int m_noteOpacity;
bool m_noteBorders;
QColor m_backgroundShade;
signals:
void positionChanged( const MidiTime & );
} ;
class PianoRollWindow : public Editor, SerializingObject
{
Q_OBJECT
public:
PianoRollWindow();
const Pattern* currentPattern() const;
void setCurrentPattern(Pattern* pattern);
int quantization() const;
void play();
void stop();
void record();
void recordAccompany();
void stopRecording();
bool isRecording() const;
/*! \brief Resets settings to default when e.g. creating a new project */
void reset();
using SerializingObject::saveState;
using SerializingObject::restoreState;
virtual void saveSettings(QDomDocument & doc, QDomElement & de );
virtual void loadSettings( const QDomElement & de );
inline virtual QString nodeName() const
{
return "pianoroll";
}
QSize sizeHint() const;
signals:
void currentPatternChanged();
private slots:
void patternRenamed();
private:
void focusInEvent(QFocusEvent * event);
PianoRoll* m_editor;
ComboBox * m_zoomingComboBox;
ComboBox * m_quantizeComboBox;
ComboBox * m_noteLenComboBox;
ComboBox * m_scaleComboBox;
ComboBox * m_chordComboBox;
};
#endif