1 /* 2 * PianoRoll.h - declaration of class PianoRoll which is a window where you 3 * can set and edit notes in an easy way 4 * 5 * Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net> 6 * Copyright (c) 2008 Andrew Kelley <superjoe30/at/gmail/dot/com> 7 * 8 * This file is part of LMMS - https://lmms.io 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public 12 * License as published by the Free Software Foundation; either 13 * version 2 of the License, or (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public 21 * License along with this program (see COPYING); if not, write to the 22 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 23 * Boston, MA 02110-1301 USA. 24 * 25 */ 26 27 #ifndef PIANO_ROLL_H 28 #define PIANO_ROLL_H 29 30 #include <QVector> 31 #include <QWidget> 32 #include <QInputDialog> 33 34 #include "Editor.h" 35 #include "ComboBoxModel.h" 36 #include "SerializingObject.h" 37 #include "Note.h" 38 #include "lmms_basics.h" 39 #include "Song.h" 40 #include "ToolTip.h" 41 42 class QPainter; 43 class QPixmap; 44 class QScrollBar; 45 class QString; 46 class QMenu; 47 class QSignalMapper; 48 49 class ComboBox; 50 class NotePlayHandle; 51 class Pattern; 52 class TimeLineWidget; 53 54 class PianoRoll : public QWidget 55 { 56 Q_OBJECT 57 Q_PROPERTY( QColor barLineColor READ barLineColor WRITE setBarLineColor ) 58 Q_PROPERTY( QColor beatLineColor READ beatLineColor WRITE setBeatLineColor ) 59 Q_PROPERTY( QColor lineColor READ lineColor WRITE setLineColor ) 60 Q_PROPERTY( QColor noteModeColor READ noteModeColor WRITE setNoteModeColor ) 61 Q_PROPERTY( QColor noteColor READ noteColor WRITE setNoteColor ) 62 Q_PROPERTY( QColor barColor READ barColor WRITE setBarColor ) 63 Q_PROPERTY( QColor selectedNoteColor READ selectedNoteColor WRITE setSelectedNoteColor ) 64 Q_PROPERTY( QColor textColor READ textColor WRITE setTextColor ) 65 Q_PROPERTY( QColor textColorLight READ textColorLight WRITE setTextColorLight ) 66 Q_PROPERTY( QColor textShadow READ textShadow WRITE setTextShadow ) 67 Q_PROPERTY( QColor markedSemitoneColor READ markedSemitoneColor WRITE setMarkedSemitoneColor ) 68 Q_PROPERTY( int noteOpacity READ noteOpacity WRITE setNoteOpacity ) 69 Q_PROPERTY( bool noteBorders READ noteBorders WRITE setNoteBorders ) 70 Q_PROPERTY( QColor backgroundShade READ backgroundShade WRITE setBackgroundShade ) 71 public: 72 enum EditModes 73 { 74 ModeDraw, 75 ModeErase, 76 ModeSelect, 77 ModeEditDetuning, 78 }; 79 80 /*! \brief Resets settings to default when e.g. creating a new project */ 81 void reset(); 82 83 // functions to display the hover-text labeling a note's volume/panning 84 void showTextFloat(const QString &text, const QPoint &pos, int timeout=-1); 85 void showVolTextFloat(volume_t vol, const QPoint &pos, int timeout=-1); 86 void showPanTextFloat(panning_t pan, const QPoint &pos, int timeout=-1); 87 88 void setCurrentPattern( Pattern* newPattern ); 89 stopRecording()90 inline void stopRecording() 91 { 92 m_recording = false; 93 } 94 isRecording()95 inline bool isRecording() const 96 { 97 return m_recording; 98 } 99 currentPattern()100 const Pattern* currentPattern() const 101 { 102 return m_pattern; 103 } 104 hasValidPattern()105 bool hasValidPattern() const 106 { 107 return m_pattern != NULL; 108 } 109 110 Song::PlayModes desiredPlayModeForAccompany() const; 111 112 int quantization() const; 113 114 // qproperty access functions 115 QColor barLineColor() const; 116 void setBarLineColor( const QColor & c ); 117 QColor beatLineColor() const; 118 void setBeatLineColor( const QColor & c ); 119 QColor lineColor() const; 120 void setLineColor( const QColor & c ); 121 QColor noteModeColor() const; 122 void setNoteModeColor( const QColor & c ); 123 QColor noteColor() const; 124 void setNoteColor( const QColor & c ); 125 QColor barColor() const; 126 void setBarColor( const QColor & c ); 127 QColor selectedNoteColor() const; 128 void setSelectedNoteColor( const QColor & c ); 129 QColor textColor() const; 130 void setTextColor( const QColor & c ); 131 QColor textColorLight() const; 132 void setTextColorLight( const QColor & c ); 133 QColor textShadow() const; 134 void setTextShadow( const QColor & c ); 135 QColor markedSemitoneColor() const; 136 void setMarkedSemitoneColor( const QColor & c ); 137 int noteOpacity() const; 138 void setNoteOpacity( const int i ); 139 bool noteBorders() const; 140 void setNoteBorders( const bool b ); 141 QColor backgroundShade() const; 142 void setBackgroundShade( const QColor & c ); 143 144 145 protected: 146 virtual void keyPressEvent( QKeyEvent * ke ); 147 virtual void keyReleaseEvent( QKeyEvent * ke ); 148 virtual void leaveEvent( QEvent * e ); 149 virtual void mousePressEvent( QMouseEvent * me ); 150 virtual void mouseDoubleClickEvent( QMouseEvent * me ); 151 virtual void mouseReleaseEvent( QMouseEvent * me ); 152 virtual void mouseMoveEvent( QMouseEvent * me ); 153 virtual void paintEvent( QPaintEvent * pe ); 154 virtual void resizeEvent( QResizeEvent * re ); 155 virtual void wheelEvent( QWheelEvent * we ); 156 virtual void focusOutEvent( QFocusEvent * ); 157 158 int getKey( int y ) const; 159 static void drawNoteRect( QPainter & p, int x, int y, 160 int width, const Note * n, const QColor & noteCol, 161 const QColor & selCol, const int noteOpc, const bool borderless ); 162 void removeSelection(); 163 void selectAll(); 164 NoteVector getSelectedNotes(); 165 void selectNotesOnKey(); 166 int xCoordOfTick( int tick ); 167 168 // for entering values with dblclick in the vol/pan bars 169 void enterValue( NoteVector* nv ); 170 171 protected slots: 172 void play(); 173 void record(); 174 void recordAccompany(); 175 void stop(); 176 177 void startRecordNote( const Note & n ); 178 void finishRecordNote( const Note & n ); 179 180 void horScrolled( int new_pos ); 181 void verScrolled( int new_pos ); 182 183 void setEditMode(int mode); 184 185 void copySelectedNotes(); 186 void cutSelectedNotes(); 187 void pasteNotes(); 188 void deleteSelectedNotes(); 189 190 void updatePosition(const MidiTime & t ); 191 void updatePositionAccompany(const MidiTime & t ); 192 193 void zoomingChanged(); 194 void quantizeChanged(); 195 void quantizeNotes(); 196 197 void updateSemiToneMarkerMenu(); 198 199 void changeNoteEditMode( int i ); 200 void markSemiTone( int i ); 201 202 void hidePattern( Pattern* pattern ); 203 204 void selectRegionFromPixels( int xStart, int xEnd ); 205 206 207 signals: 208 void currentPatternChanged(); 209 void semiToneMarkerMenuScaleSetEnabled(bool); 210 void semiToneMarkerMenuChordSetEnabled(bool); 211 212 213 private: 214 enum Actions 215 { 216 ActionNone, 217 ActionMoveNote, 218 ActionResizeNote, 219 ActionSelectNotes, 220 ActionChangeNoteProperty, 221 ActionResizeNoteEditArea 222 }; 223 224 enum NoteEditMode 225 { 226 NoteEditVolume, 227 NoteEditPanning, 228 NoteEditCount // make sure this one is always last 229 }; 230 231 enum SemiToneMarkerAction 232 { 233 stmaUnmarkAll, 234 stmaMarkCurrentSemiTone, 235 stmaMarkAllOctaveSemiTones, 236 stmaMarkCurrentScale, 237 stmaMarkCurrentChord, 238 stmaCopyAllNotesOnKey 239 }; 240 241 enum PianoRollKeyTypes 242 { 243 PR_WHITE_KEY_SMALL, 244 PR_WHITE_KEY_BIG, 245 PR_BLACK_KEY 246 }; 247 248 QVector<QString> m_nemStr; // gui names of each edit mode 249 QMenu * m_noteEditMenu; // when you right click below the key area 250 251 QList<int> m_markedSemiTones; 252 QMenu * m_semiToneMarkerMenu; // when you right click on the key area 253 int m_pianoKeySelected; 254 255 PianoRoll(); 256 PianoRoll( const PianoRoll & ); 257 virtual ~PianoRoll(); 258 259 void autoScroll(const MidiTime & t ); 260 261 MidiTime newNoteLen() const; 262 263 void shiftPos(int amount); 264 void shiftSemiTone(int amount); 265 bool isSelection() const; 266 int selectionCount() const; 267 void testPlayNote( Note * n ); 268 void testPlayKey( int _key, int _vol, int _pan ); 269 void pauseTestNotes(bool pause = true ); 270 271 QList<int> getAllOctavesForKey( int keyToMirror ) const; 272 273 int noteEditTop() const; 274 int keyAreaBottom() const; 275 int noteEditBottom() const; 276 int keyAreaTop() const; 277 int noteEditRight() const; 278 int noteEditLeft() const; 279 280 void dragNotes( int x, int y, bool alt, bool shift, bool ctrl ); 281 282 static const int cm_scrollAmtHoriz = 10; 283 static const int cm_scrollAmtVert = 1; 284 285 static QPixmap * s_whiteKeyBigPm; 286 static QPixmap * s_whiteKeyBigPressedPm; 287 static QPixmap * s_whiteKeySmallPm; 288 static QPixmap * s_whiteKeySmallPressedPm; 289 static QPixmap * s_blackKeyPm; 290 static QPixmap * s_blackKeyPressedPm; 291 static QPixmap * s_toolDraw; 292 static QPixmap * s_toolErase; 293 static QPixmap * s_toolSelect; 294 static QPixmap * s_toolMove; 295 static QPixmap * s_toolOpen; 296 297 static PianoRollKeyTypes prKeyOrder[]; 298 299 static TextFloat * s_textFloat; 300 301 ComboBoxModel m_zoomingModel; 302 ComboBoxModel m_quantizeModel; 303 ComboBoxModel m_noteLenModel; 304 ComboBoxModel m_scaleModel; 305 ComboBoxModel m_chordModel; 306 307 static const QVector<double> m_zoomLevels; 308 309 Pattern* m_pattern; 310 QScrollBar * m_leftRightScroll; 311 QScrollBar * m_topBottomScroll; 312 313 MidiTime m_currentPosition; 314 bool m_recording; 315 QList<Note> m_recordingNotes; 316 317 Note * m_currentNote; 318 Actions m_action; 319 NoteEditMode m_noteEditMode; 320 321 int m_selectStartTick; 322 int m_selectedTick; 323 int m_selectStartKey; 324 int m_selectedKeys; 325 326 // boundary box around all selected notes when dragging 327 int m_moveBoundaryLeft; 328 int m_moveBoundaryTop; 329 int m_moveBoundaryRight; 330 int m_moveBoundaryBottom; 331 332 // remember where the scrolling started when dragging so that 333 // we can handle dragging while scrolling with arrow keys 334 int m_mouseDownKey; 335 int m_mouseDownTick; 336 337 // remember the last x and y of a mouse movement 338 int m_lastMouseX; 339 int m_lastMouseY; 340 341 // x,y of when the user starts a drag 342 int m_moveStartX; 343 int m_moveStartY; 344 345 int m_oldNotesEditHeight; 346 int m_notesEditHeight; 347 int m_ppt; // pixels per tact 348 int m_totalKeysToScroll; 349 350 // remember these values to use them 351 // for the next note that is set 352 MidiTime m_lenOfNewNotes; 353 volume_t m_lastNoteVolume; 354 panning_t m_lastNotePanning; 355 356 int m_startKey; // first key when drawing 357 int m_lastKey; 358 359 EditModes m_editMode; 360 EditModes m_ctrlMode; // mode they were in before they hit ctrl 361 362 bool m_mouseDownRight; //true if right click is being held down 363 364 TimeLineWidget * m_timeLine; 365 bool m_scrollBack; 366 367 void copyToClipboard(const NoteVector & notes ) const; 368 369 void drawDetuningInfo( QPainter & _p, const Note * _n, int _x, int _y ) const; 370 bool mouseOverNote(); 371 Note * noteUnderMouse(); 372 373 // turn a selection rectangle into selected notes 374 void computeSelectedNotes( bool shift ); 375 void clearSelectedNotes(); 376 377 // did we start a mouseclick with shift pressed 378 bool m_startedWithShift; 379 380 friend class PianoRollWindow; 381 382 // qproperty fields 383 QColor m_barLineColor; 384 QColor m_beatLineColor; 385 QColor m_lineColor; 386 QColor m_noteModeColor; 387 QColor m_noteColor; 388 QColor m_barColor; 389 QColor m_selectedNoteColor; 390 QColor m_textColor; 391 QColor m_textColorLight; 392 QColor m_textShadow; 393 QColor m_markedSemitoneColor; 394 int m_noteOpacity; 395 bool m_noteBorders; 396 QColor m_backgroundShade; 397 398 signals: 399 void positionChanged( const MidiTime & ); 400 } ; 401 402 403 404 405 class PianoRollWindow : public Editor, SerializingObject 406 { 407 Q_OBJECT 408 public: 409 PianoRollWindow(); 410 411 const Pattern* currentPattern() const; 412 void setCurrentPattern(Pattern* pattern); 413 414 int quantization() const; 415 416 void play(); 417 void stop(); 418 void record(); 419 void recordAccompany(); 420 void stopRecording(); 421 422 bool isRecording() const; 423 424 /*! \brief Resets settings to default when e.g. creating a new project */ 425 void reset(); 426 427 using SerializingObject::saveState; 428 using SerializingObject::restoreState; 429 virtual void saveSettings(QDomDocument & doc, QDomElement & de ); 430 virtual void loadSettings( const QDomElement & de ); 431 nodeName()432 inline virtual QString nodeName() const 433 { 434 return "pianoroll"; 435 } 436 437 QSize sizeHint() const; 438 439 signals: 440 void currentPatternChanged(); 441 442 443 private slots: 444 void patternRenamed(); 445 446 private: 447 void focusInEvent(QFocusEvent * event); 448 449 PianoRoll* m_editor; 450 451 ComboBox * m_zoomingComboBox; 452 ComboBox * m_quantizeComboBox; 453 ComboBox * m_noteLenComboBox; 454 ComboBox * m_scaleComboBox; 455 ComboBox * m_chordComboBox; 456 457 }; 458 459 460 #endif 461