1 //============================================================================= 2 // MuseScore 3 // Music Composition & Notation 4 // 5 // Copyright (C) 2009-2011 Werner Schweer 6 // 7 // This program is free software; you can redistribute it and/or modify 8 // it under the terms of the GNU General Public License version 2 9 // as published by the Free Software Foundation and appearing in 10 // the file LICENCE.GPL 11 //============================================================================= 12 13 #ifndef __PIANOVIEW_H__ 14 #define __PIANOVIEW_H__ 15 16 #include "libmscore/pos.h" 17 #include "pianorolledittool.h" 18 19 namespace Ms { 20 21 class Score; 22 class Staff; 23 class Chord; 24 class ChordRest; 25 class Segment; 26 class Note; 27 class NoteEvent; 28 class PianoView; 29 class NoteTweakerDialog; 30 31 enum class NoteSelectType { 32 REPLACE = 0, 33 XOR, 34 ADD, 35 SUBTRACT, 36 FIRST 37 }; 38 39 enum class DragStyle { 40 NONE = 0, 41 CANCELLED, 42 SELECTION_RECT, 43 NOTES 44 }; 45 46 struct BarPattern { 47 QString name; 48 char isWhiteKey[12]; //Set to 1 for white keys, 0 for black 49 }; 50 51 //--------------------------------------------------------- 52 // PianoItem 53 //--------------------------------------------------------- 54 55 class PianoItem { 56 Note* _note; 57 PianoView* _pianoView; 58 59 void paintNoteBlock(QPainter* painter, NoteEvent* evt); 60 QRect boundingRectTicks(NoteEvent* evt); 61 QRect boundingRectPixels(NoteEvent* evt); 62 bool intersectsBlock(int startTick, int endTick, int highPitch, int lowPitch, NoteEvent* evt); 63 64 public: 65 const static int NOTE_BLOCK_CORNER_RADIUS = 3; 66 67 PianoItem(Note*, PianoView*); ~PianoItem()68 ~PianoItem() {} note()69 Note* note() { return _note; } 70 void paint(QPainter* painter); 71 bool intersects(int startTick, int endTick, int highPitch, int lowPitch); 72 73 QRect boundingRect(); 74 75 NoteEvent* getTweakNoteEvent(); 76 }; 77 78 //--------------------------------------------------------- 79 // PianoView 80 //--------------------------------------------------------- 81 82 class PianoView : public QGraphicsView { 83 Q_OBJECT 84 85 public: 86 static const BarPattern barPatterns[]; 87 88 private: 89 Staff* _staff; 90 Chord* _chord; 91 92 Pos trackingPos; //Track mouse position 93 Pos* _locator; 94 int _ticks; 95 TType _timeType; 96 int _noteHeight; 97 qreal _xZoom; 98 int _tuplet; //Tuplet divisions 99 int _subdiv; //Beat subdivisions 100 int _barPattern; 101 102 bool _playEventsView; 103 bool _mouseDown; 104 bool _dragStarted; 105 QString _dragNoteCache; 106 QPointF _mouseDownPos; 107 QPointF _lastMousePos; 108 QPointF _popupMenuPos; 109 DragStyle _dragStyle; 110 int _dragStartPitch; 111 bool _inProgressUndoEvent; 112 113 //The length of the note we are using for editng purposes, expressed as a fraction of the measure. 114 // Note length will be (2^_editNoteLength) of a measure 115 int _editNoteLength = 0; 116 int _editNoteDots = 0; 117 int _editNoteVoice = 0; 118 PianoRollEditTool _editNoteTool = PianoRollEditTool::SELECT; 119 120 QList<PianoItem*> _noteList; 121 quint8 _pitchHighlight[128]; 122 123 virtual void drawBackground(QPainter* painter, const QRectF& rect); 124 125 void addChord(Chord* _chord, int voice); 126 QVector<Note*> getSegmentNotes(Segment* seg, int track); 127 void updateBoundingSize(); 128 void clearNoteData(); 129 void selectNotes(int startTick, int endTick, int lowPitch, int highPitch, NoteSelectType selType); 130 void showPopupMenu(const QPoint& pos); 131 bool cutChordRest(ChordRest* targetCr, int track, Fraction cutTick, ChordRest*& cr0, ChordRest*& cr1); 132 QVector<Note*> addNote(Fraction startTick, Fraction duration, int pitch, int track); 133 void handleSelectionClick(); 134 void insertNote(int modifiers); 135 Fraction roundToStartBeat(int tick) const; 136 Fraction noteEditLength() const; 137 void changeChordLength(const QPointF& pos); 138 void eraseNote(const QPointF& pos); 139 void appendNoteToChord(const QPointF& pos); 140 void cutChord(const QPointF& pos); 141 void toggleTie(const QPointF& pos); 142 void toggleTie(Note*); 143 void dragSelectionNoteGroup(); 144 void finishNoteGroupDrag(); toolCanDragNotes()145 bool toolCanDragNotes() const { 146 return _editNoteTool == PianoRollEditTool::SELECT || _editNoteTool == PianoRollEditTool::INSERT_NOTE || 147 _editNoteTool == PianoRollEditTool::APPEND_NOTE || _editNoteTool == PianoRollEditTool::CUT_CHORD || 148 _editNoteTool == PianoRollEditTool::TIE; 149 } 150 151 QAction* getAction(const char* id); 152 153 protected: 154 virtual void wheelEvent(QWheelEvent* event); 155 virtual void keyReleaseEvent(QKeyEvent* event); 156 virtual void mousePressEvent(QMouseEvent* event); 157 virtual void mouseReleaseEvent(QMouseEvent* event); 158 virtual void mouseMoveEvent(QMouseEvent* event); 159 virtual void leaveEvent(QEvent*); 160 virtual void contextMenuEvent(QContextMenuEvent *event); 161 162 signals: 163 void xZoomChanged(qreal); 164 void tupletChanged(int); 165 void subdivChanged(int); 166 void barPatternChanged(int); 167 void noteHeightChanged(int); 168 void pitchChanged(int); 169 void trackingPosChanged(const Pos&); 170 void selectionChanged(); 171 void showNoteTweakerRequest(); 172 173 public slots: 174 void moveLocator(int); 175 void updateNotes(); 176 void setXZoom(int); 177 void setTuplet(int); 178 void setSubdiv(int); 179 void setBarPattern(int); 180 void togglePitchHighlight(int pitch); 181 void showNoteTweaker(); 182 void setNotesToVoice(int voice); 183 184 QString serializeSelectedNotes(); 185 void pasteNotes(const QString& copiedNotes, Fraction pasteStartTick, int pitchOffset, bool xIsOffset = false); 186 void drawDraggedNotes(QPainter* painter); 187 void drawDraggedNote(QPainter* painter, Fraction startTick, Fraction frac, int pitch, int track, QColor color); 188 189 void cutNotes(); 190 void copyNotes(); 191 void pasteNotesAtCursor(); 192 193 public: 194 PianoView(); 195 ~PianoView(); staff()196 Staff* staff() { return _staff; } 197 void setStaff(Staff*, Pos* locator); 198 void ensureVisible(int tick); noteHeight()199 int noteHeight() { return _noteHeight; } xZoom()200 qreal xZoom() { return _xZoom; } tuplet()201 int tuplet() { return _tuplet; } subdiv()202 int subdiv() { return _subdiv; } barPattern()203 int barPattern() { return _barPattern; } editTool()204 PianoRollEditTool editTool() const { return _editNoteTool; } items()205 QList<QGraphicsItem*> items() { return scene()->selectedItems(); } editNoteDots()206 int editNoteDots() const { return _editNoteDots; } 207 setEditNoteLength(int len)208 void setEditNoteLength(int len) { _editNoteLength = len; } setEditNoteVoice(int voice)209 void setEditNoteVoice(int voice) { _editNoteVoice = voice; } setEditNoteDots(int dot)210 void setEditNoteDots(int dot) { _editNoteDots = dot; } setEditNoteTool(PianoRollEditTool tool)211 void setEditNoteTool(PianoRollEditTool tool) { _editNoteTool = tool; } 212 213 int pixelXToTick(int pixX); 214 int tickToPixelX(int tick); pixelYToPitch(int pixY)215 int pixelYToPitch(int pixY) { return (int)floor(128 - pixY / (qreal)_noteHeight); } pitchToPixelY(int pitch)216 int pitchToPixelY(int pitch) { return (128 - pitch) * _noteHeight; } 217 218 PianoItem* pickNote(int tick, int pitch); 219 220 QList<PianoItem*> getSelectedItems(); 221 QList<PianoItem*> getItems(); 222 223 void zoomView(int step, bool horizontal, int centerX, int centerY); 224 playEventsView()225 bool playEventsView() { return _playEventsView; } 226 }; 227 228 229 } // namespace Ms 230 #endif 231 232