Merge pull request #2324 from Wallacoloo/pianoroll-refactor

Refactor PianoRoll code
This commit is contained in:
Dave French
2015-09-11 08:35:11 +01:00
2 changed files with 225 additions and 363 deletions

View File

@@ -69,6 +69,11 @@ public:
/*! \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()
@@ -120,11 +125,11 @@ protected:
virtual void focusOutEvent( QFocusEvent * );
int getKey( int y ) const;
static inline void drawNoteRect( QPainter & p, int x, int y,
int width, Note * n, const QColor & noteCol );
static void drawNoteRect( QPainter & p, int x, int y,
int width, const Note * n, const QColor & noteCol );
void removeSelection();
void selectAll();
void getSelectedNotes( NoteVector & selected_notes );
NoteVector getSelectedNotes();
// for entering values with dblclick in the vol/pan bars
void enterValue( NoteVector* nv );
@@ -225,12 +230,12 @@ private:
void testPlayKey( int _key, int _vol, int _pan );
void pauseTestNotes(bool pause = true );
inline int noteEditTop() const;
inline int keyAreaBottom() const;
inline int noteEditBottom() const;
inline int keyAreaTop() const;
inline int noteEditRight() const;
inline int noteEditLeft() 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 );
@@ -319,9 +324,9 @@ private:
TimeLineWidget * m_timeLine;
bool m_scrollBack;
void copy_to_clipboard(const NoteVector & notes ) const;
void copyToClipboard(const NoteVector & notes ) const;
void drawDetuningInfo( QPainter & _p, Note * _n, int _x, int _y );
void drawDetuningInfo( QPainter & _p, const Note * _n, int _x, int _y ) const;
bool mouseOverNote();
Note * noteUnderMouse();

View File

@@ -431,6 +431,48 @@ void PianoRoll::reset()
m_lastNotePanning = DefaultPanning;
}
void PianoRoll::showTextFloat(const QString &text, const QPoint &pos, int timeout)
{
s_textFloat->setText( text );
// show the float, offset slightly so as to not obscure anything
s_textFloat->moveGlobal( this, pos + QPoint(4, 16) );
if (timeout == -1)
{
s_textFloat->show();
}
else
{
s_textFloat->setVisibilityTimeOut( timeout );
}
}
void PianoRoll::showVolTextFloat(volume_t vol, const QPoint &pos, int timeout)
{
//! \todo display velocity for MIDI-based instruments
// possibly dBV values too? not sure if it makes sense for note volumes...
showTextFloat( tr("Volume: %1%").arg( vol ), pos, timeout );
}
void PianoRoll::showPanTextFloat(panning_t pan, const QPoint &pos, int timeout)
{
QString text;
if( pan < 0 )
{
text = tr("Panning: %1% left").arg( qAbs( pan ) );
}
else if( pan > 0 )
{
text = tr("Panning: %1% right").arg( qAbs( pan ) );
}
else
{
text = tr("Panning: center");
}
showTextFloat( text, pos, timeout );
}
void PianoRoll::changeNoteEditMode( int i )
@@ -542,27 +584,23 @@ void PianoRoll::setCurrentPattern( Pattern* newPattern )
m_leftRightScroll->setValue( 0 );
const NoteVector & notes = m_pattern->notes();
// determine the central key so that we can scroll to it
int central_key = 0;
if( ! notes.empty() )
int total_notes = 0;
for( const Note *note : m_pattern->notes() )
{
// determine the central key so that we can scroll to it
int total_notes = 0;
for( const Note* const& note : notes )
if( note->length() > 0 )
{
if( note->length() > 0 )
{
central_key += note->key();
++total_notes;
}
central_key += note->key();
++total_notes;
}
}
if( total_notes > 0 )
{
central_key = central_key / total_notes -
( KeysPerOctave * NumOctaves - m_totalKeysToScroll ) / 2;
m_startKey = tLimit( central_key, 0, NumOctaves * KeysPerOctave );
}
if( total_notes > 0 )
{
central_key = central_key / total_notes -
( KeysPerOctave * NumOctaves - m_totalKeysToScroll ) / 2;
m_startKey = tLimit( central_key, 0, NumOctaves * KeysPerOctave );
}
// resizeEvent() does the rest for us (scrolling, range-checking
@@ -659,8 +697,8 @@ void PianoRoll::setBarColor( const QColor & c )
inline void PianoRoll::drawNoteRect(QPainter & p, int x, int y,
int width, Note * n, const QColor & noteCol )
void PianoRoll::drawNoteRect(QPainter & p, int x, int y,
int width, const Note * n, const QColor & noteCol )
{
++x;
++y;
@@ -728,8 +766,8 @@ inline void PianoRoll::drawNoteRect(QPainter & p, int x, int y,
inline void PianoRoll::drawDetuningInfo( QPainter & _p, Note * _n, int _x,
int _y )
void PianoRoll::drawDetuningInfo( QPainter & _p, const Note * _n, int _x,
int _y ) const
{
int middle_y = _y + KEY_LINE_HEIGHT / 2;
_p.setPen( noteColor() );
@@ -792,13 +830,8 @@ void PianoRoll::clearSelectedNotes()
{
if( m_pattern != NULL )
{
// get note-vector of current pattern
const NoteVector & notes = m_pattern->notes();
// will be our iterator in the following loop
NoteVector::ConstIterator it;
for( it = notes.begin(); it != notes.end(); ++it ) {
Note *note = *it;
for( Note *note : m_pattern->notes() )
{
note->setSelected( false );
}
}
@@ -810,11 +843,8 @@ void PianoRoll::clearSelectedNotes()
void PianoRoll::shiftSemiTone( int amount ) // shift notes by amount semitones
{
bool useAllNotes = ! isSelection();
const NoteVector & notes = m_pattern->notes();
NoteVector::ConstIterator it;
for( it = notes.begin(); it != notes.end(); ++it )
for( Note *note : m_pattern->notes() )
{
Note *note = *it;
// if none are selected, move all notes, otherwise
// only move selected notes
if( useAllNotes || note->selected() )
@@ -834,13 +864,10 @@ void PianoRoll::shiftSemiTone( int amount ) // shift notes by amount semitones
void PianoRoll::shiftPos( int amount ) //shift notes pos by amount
{
bool useAllNotes = ! isSelection();
const NoteVector & notes = m_pattern->notes();
NoteVector::ConstIterator it;
bool first = true;
for( it = notes.begin(); it != notes.end(); ++it )
for( Note *note : m_pattern->notes() )
{
Note *note = *it;
// if none are selected, move all notes, otherwise
// only move selected notes
if( note->selected() || (useAllNotes && note->length() > 0) )
@@ -872,11 +899,8 @@ void PianoRoll::shiftPos( int amount ) //shift notes pos by amount
bool PianoRoll::isSelection() const // are any notes selected?
{
const NoteVector & notes = m_pattern->notes();
NoteVector::ConstIterator it;
for( it = notes.begin(); it != notes.end(); ++it )
for( const Note *note : m_pattern->notes() )
{
Note *note = *it;
if( note->selected() )
{
return true;
@@ -892,11 +916,8 @@ int PianoRoll::selectionCount() const // how many notes are selected?
{
int sum = 0;
const NoteVector & notes = m_pattern->notes();
NoteVector::ConstIterator it;
for( it = notes.begin(); it != notes.end(); ++it )
for( const Note *note : m_pattern->notes() )
{
Note *note = *it;
if( note->selected() )
{
++sum;
@@ -924,155 +945,86 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke )
switch( ke->key() )
{
case Qt::Key_Up:
if( ( ke->modifiers() & Qt::ControlModifier ) && m_action == ActionNone )
{
// shift selection up an octave
// if nothing selected, shift _everything_
shiftSemiTone( +12 );
}
else if((ke->modifiers() & Qt::ShiftModifier) && m_action == ActionNone)
{
// Move selected notes up by one semitone
shiftSemiTone( 1 );
}
else
{
// scroll
m_topBottomScroll->setValue(
m_topBottomScroll->value() -
cm_scrollAmtVert );
// if they are moving notes around or resizing,
// recalculate the note/resize position
if( m_action == ActionMoveNote ||
m_action == ActionResizeNote )
{
dragNotes( m_lastMouseX, m_lastMouseY,
ke->modifiers() & Qt::AltModifier,
ke->modifiers() & Qt::ShiftModifier,
ke->modifiers() & Qt::ControlModifier );
}
}
ke->accept();
break;
case Qt::Key_Down:
if( ke->modifiers() & Qt::ControlModifier && m_action == ActionNone )
{
// shift selection down an octave
// if nothing selected, shift _everything_
shiftSemiTone( -12 );
}
else if((ke->modifiers() & Qt::ShiftModifier) && m_action == ActionNone)
{
// Move selected notes down by one semitone
shiftSemiTone( -1 );
}
else
{
// scroll
m_topBottomScroll->setValue(
m_topBottomScroll->value() +
cm_scrollAmtVert );
// if they are moving notes around or resizing,
// recalculate the note/resize position
if( m_action == ActionMoveNote ||
m_action == ActionResizeNote )
int direction = (ke->key() == Qt::Key_Up ? +1 : -1);
if( ( ke->modifiers() & Qt::ControlModifier ) && m_action == ActionNone )
{
dragNotes( m_lastMouseX, m_lastMouseY,
ke->modifiers() & Qt::AltModifier,
ke->modifiers() & Qt::ShiftModifier,
ke->modifiers() & Qt::ControlModifier );
// shift selection up an octave
// if nothing selected, shift _everything_
shiftSemiTone( 12 * direction );
}
}
ke->accept();
break;
case Qt::Key_Left:
if( ke->modifiers() & Qt::ControlModifier && m_action == ActionNone )
{
// Move selected notes by one bar to the left
shiftPos( - MidiTime::ticksPerTact() );
}
else if( ke->modifiers() & Qt::ShiftModifier && m_action == ActionNone)
{
// move notes
bool quantized = ! ( ke->modifiers() & Qt::AltModifier );
int amt = quantized ? quantization() : 1;
shiftPos( -amt );
}
else if( ke->modifiers() & Qt::AltModifier)
{
Pattern * p = m_pattern->previousPattern();
if(p != NULL)
else if((ke->modifiers() & Qt::ShiftModifier) && m_action == ActionNone)
{
setCurrentPattern(p);
// Move selected notes up by one semitone
shiftSemiTone( 1 * direction );
}
}
else
{
// scroll
m_leftRightScroll->setValue(
m_leftRightScroll->value() -
cm_scrollAmtHoriz );
// if they are moving notes around or resizing,
// recalculate the note/resize position
if( m_action == ActionMoveNote ||
m_action == ActionResizeNote )
else
{
dragNotes( m_lastMouseX, m_lastMouseY,
ke->modifiers() & Qt::AltModifier,
ke->modifiers() & Qt::ShiftModifier,
ke->modifiers() & Qt::ControlModifier );
}
// scroll
m_topBottomScroll->setValue( m_topBottomScroll->value() -
cm_scrollAmtVert * direction );
// if they are moving notes around or resizing,
// recalculate the note/resize position
if( m_action == ActionMoveNote ||
m_action == ActionResizeNote )
{
dragNotes( m_lastMouseX, m_lastMouseY,
ke->modifiers() & Qt::AltModifier,
ke->modifiers() & Qt::ShiftModifier,
ke->modifiers() & Qt::ControlModifier );
}
}
ke->accept();
break;
}
ke->accept();
break;
case Qt::Key_Right:
if( ke->modifiers() & Qt::ControlModifier && m_action == ActionNone)
case Qt::Key_Left:
{
// Move selected notes by one bar to the right
shiftPos( MidiTime::ticksPerTact() );
}
else if( ke->modifiers() & Qt::ShiftModifier && m_action == ActionNone)
{
// move notes
bool quantized = !( ke->modifiers() & Qt::AltModifier );
int amt = quantized ? quantization() : 1;
shiftPos( +amt );
}
else if( ke->modifiers() & Qt::AltModifier) {
Pattern * p = m_pattern->nextPattern();
if(p != NULL)
int direction = (ke->key() == Qt::Key_Right ? +1 : -1);
if( ke->modifiers() & Qt::ControlModifier && m_action == ActionNone )
{
setCurrentPattern(p);
// Move selected notes by one bar to the left
shiftPos( direction * MidiTime::ticksPerTact() );
}
}
else
{
// scroll
m_leftRightScroll->setValue(
m_leftRightScroll->value() +
cm_scrollAmtHoriz );
// if they are moving notes around or resizing,
// recalculate the note/resize position
if( m_action == ActionMoveNote ||
m_action == ActionResizeNote )
else if( ke->modifiers() & Qt::ShiftModifier && m_action == ActionNone)
{
dragNotes( m_lastMouseX, m_lastMouseY,
ke->modifiers() & Qt::AltModifier,
ke->modifiers() & Qt::ShiftModifier,
ke->modifiers() & Qt::ControlModifier );
// move notes
bool quantized = ! ( ke->modifiers() & Qt::AltModifier );
int amt = quantized ? quantization() : 1;
shiftPos( direction * amt );
}
else if( ke->modifiers() & Qt::AltModifier)
{
Pattern * p = m_pattern->previousPattern();
if(p != NULL)
{
setCurrentPattern(p);
}
}
else
{
// scroll
m_leftRightScroll->setValue( m_leftRightScroll->value() +
direction * cm_scrollAmtHoriz );
// if they are moving notes around or resizing,
// recalculate the note/resize position
if( m_action == ActionMoveNote ||
m_action == ActionResizeNote )
{
dragNotes( m_lastMouseX, m_lastMouseY,
ke->modifiers() & Qt::AltModifier,
ke->modifiers() & Qt::ShiftModifier,
ke->modifiers() & Qt::ControlModifier );
}
}
ke->accept();
break;
}
ke->accept();
break;
case Qt::Key_A:
if( ke->modifiers() & Qt::ControlModifier )
@@ -1206,7 +1158,7 @@ void PianoRoll::leaveEvent(QEvent * e )
inline int PianoRoll::noteEditTop() const
int PianoRoll::noteEditTop() const
{
return height() - PR_BOTTOM_MARGIN -
m_notesEditHeight + NOTE_EDIT_RESIZE_BAR;
@@ -1215,7 +1167,7 @@ inline int PianoRoll::noteEditTop() const
inline int PianoRoll::noteEditBottom() const
int PianoRoll::noteEditBottom() const
{
return height() - PR_BOTTOM_MARGIN;
}
@@ -1223,7 +1175,7 @@ inline int PianoRoll::noteEditBottom() const
inline int PianoRoll::noteEditRight() const
int PianoRoll::noteEditRight() const
{
return width() - PR_RIGHT_MARGIN;
}
@@ -1231,7 +1183,7 @@ inline int PianoRoll::noteEditRight() const
inline int PianoRoll::noteEditLeft() const
int PianoRoll::noteEditLeft() const
{
return WHITE_KEY_WIDTH;
}
@@ -1239,7 +1191,7 @@ inline int PianoRoll::noteEditLeft() const
inline int PianoRoll::keyAreaTop() const
int PianoRoll::keyAreaTop() const
{
return PR_TOP_MARGIN;
}
@@ -1247,7 +1199,7 @@ inline int PianoRoll::keyAreaTop() const
inline int PianoRoll::keyAreaBottom() const
int PianoRoll::keyAreaBottom() const
{
return height() - PR_BOTTOM_MARGIN - m_notesEditHeight;
}
@@ -1661,14 +1613,10 @@ void PianoRoll::mouseDoubleClickEvent(QMouseEvent * me )
MidiTime::ticksPerTact() / m_ppt + m_currentPosition;
const int ticks_middle = x * MidiTime::ticksPerTact() / m_ppt + m_currentPosition;
// get note-vector of current pattern
NoteVector notes;
notes += m_pattern->notes();
// go through notes to figure out which one we want to change
bool altPressed = me->modifiers() & Qt::AltModifier;
NoteVector nv;
foreach( Note * i, notes )
for ( Note * i : m_pattern->notes() )
{
if( i->withinRange( ticks_start, ticks_end ) || ( i->selected() && !altPressed ) )
{
@@ -1678,12 +1626,12 @@ void PianoRoll::mouseDoubleClickEvent(QMouseEvent * me )
// make sure we're on a note
if( nv.size() > 0 )
{
Note * closest = NULL;
const Note * closest = NULL;
int closest_dist = 9999999;
// if we caught multiple notes, find the closest...
if( nv.size() > 1 )
{
foreach( Note * i, nv )
for ( const Note * i : nv )
{
const int dist = qAbs( i->pos().getTicks() - ticks_middle );
if( dist < closest_dist ) { closest = i; closest_dist = dist; }
@@ -1692,7 +1640,7 @@ void PianoRoll::mouseDoubleClickEvent(QMouseEvent * me )
NoteVector::Iterator it = nv.begin();
while( it != nv.end() )
{
Note *note = *it;
const Note *note = *it;
if( note->pos().getTicks() != closest->pos().getTicks() )
{
it = nv.erase( it );
@@ -1736,11 +1684,8 @@ void PianoRoll::testPlayNote( Note * n )
void PianoRoll::pauseTestNotes( bool pause )
{
const NoteVector & notes = m_pattern->notes();
NoteVector::ConstIterator it = notes.begin();
while( it != notes.end() )
for (Note *note : m_pattern->notes())
{
Note *note = *it;
if( note->isPlaying() )
{
if( pause )
@@ -1755,8 +1700,6 @@ void PianoRoll::pauseTestNotes( bool pause )
testPlayNote( note );
}
}
++it;
}
}
@@ -1807,12 +1750,8 @@ void PianoRoll::computeSelectedNotes(bool shift)
//int y_base = noteEditTop() - 1;
if( hasValidPattern() )
{
const NoteVector & notes = m_pattern->notes();
NoteVector::ConstIterator it;
for( it = notes.begin(); it != notes.end(); ++it )
for( Note *note : m_pattern->notes() )
{
Note *note = *it;
// make a new selection unless they're holding shift
if( ! shift )
{
@@ -1901,20 +1840,14 @@ void PianoRoll::mouseReleaseEvent( QMouseEvent * me )
if( hasValidPattern() )
{
// turn off all notes that are playing
const NoteVector & notes = m_pattern->notes();
NoteVector::ConstIterator it = notes.begin();
while( it != notes.end() )
for ( Note *note : m_pattern->notes() )
{
Note *note = *it;
if( note->isPlaying() )
{
m_pattern->instrumentTrack()->pianoModel()->
handleKeyRelease( note->key() );
note->setIsPlaying( false );
}
++it;
}
// stop playing keys that we let go of
@@ -2035,8 +1968,8 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
// determine what volume/panning to set note to
// if middle-click, set to defaults
volume_t vol;
panning_t pan;
volume_t vol = DefaultVolume;
panning_t pan = DefaultPanning;
if( me->buttons() & Qt::LeftButton )
{
@@ -2051,34 +1984,16 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
( (float)( PanningRight - PanningLeft ) ),
PanningLeft, PanningRight);
}
else
{
vol = DefaultVolume;
pan = DefaultPanning;
}
if( m_noteEditMode == NoteEditVolume )
{
m_lastNoteVolume = vol;
//! \todo display velocity for MIDI-based instruments
// possibly dBV values too? not sure if it makes sense for note volumes...
s_textFloat->setText( tr("Volume: %1%").arg( vol ) );
showVolTextFloat( vol, me->pos() );
}
else if( m_noteEditMode == NoteEditPanning )
{
m_lastNotePanning = pan;
if( pan < 0 )
{
s_textFloat->setText( tr("Panning: %1% left").arg( qAbs( pan ) ) );
}
else if( pan > 0 )
{
s_textFloat->setText( tr("Panning: %1% right").arg( qAbs( pan ) ) );
}
else
{
s_textFloat->setText( tr("Panning: center") );
}
showPanTextFloat( pan, me->pos() );
}
// When alt is pressed we only edit the note under the cursor
@@ -2127,9 +2042,6 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
// Emit pattern has changed
m_pattern->dataChanged();
// Show the new volume value
s_textFloat->moveGlobal( this, QPoint( me->x() + 4, me->y() + 16 ) );
s_textFloat->show();
}
else if( me->buttons() == Qt::NoButton && m_editMode == ModeDraw )
@@ -2168,57 +2080,28 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
if( it != notes.begin()-1 )
{
Note *note = *it;
// x coordinate of the right edge of the note
int noteRightX = ( note->pos() + note->length() -
m_currentPosition) * m_ppt/MidiTime::ticksPerTact();
// cursor at the "tail" of the note?
if( note->length() > 0 &&
pos_ticks*m_ppt /
MidiTime::ticksPerTact() >
( note->pos() +
note->length() )*m_ppt/
MidiTime::ticksPerTact()-
RESIZE_AREA_WIDTH )
bool atTail = note->length() > 0 && x > noteRightX -
RESIZE_AREA_WIDTH;
Qt::CursorShape cursorShape = atTail ? Qt::SizeHorCursor :
Qt::SizeAllCursor;
if( QApplication::overrideCursor() )
{
if( QApplication::overrideCursor() )
if( QApplication::overrideCursor()->shape() != cursorShape )
{
if( QApplication::overrideCursor()->shape() != Qt::SizeHorCursor )
while( QApplication::overrideCursor() != NULL )
{
while( QApplication::overrideCursor() != NULL )
{
QApplication::restoreOverrideCursor();
}
QCursor c( Qt::SizeHorCursor );
QApplication::setOverrideCursor( c );
QApplication::restoreOverrideCursor();
}
}
else
{
QCursor c( Qt::SizeHorCursor );
QApplication::setOverrideCursor(
c );
QApplication::setOverrideCursor(QCursor(cursorShape));
}
}
else
{
if( QApplication::overrideCursor() )
{
if( QApplication::overrideCursor()->shape() != Qt::SizeAllCursor )
{
while( QApplication::overrideCursor() != NULL )
{
QApplication::restoreOverrideCursor();
}
QCursor c( Qt::SizeAllCursor );
QApplication::setOverrideCursor(
c );
}
}
else
{
QCursor c( Qt::SizeAllCursor );
QApplication::setOverrideCursor(
c );
}
QApplication::setOverrideCursor(QCursor(cursorShape));
}
}
else
@@ -2449,9 +2332,8 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
if (m_action == ActionMoveNote)
{
for (NoteVector::ConstIterator it = notes.begin(); it != notes.end(); ++it )
for (Note *note : notes)
{
Note *note = *it;
if( note->selected() )
{
if( ! ( shift && ! m_startedWithShift ) )
@@ -2499,19 +2381,17 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
// This factor is such that the endpoint of the note whose handle is being dragged should lie under the cursor.
// first, determine the start-point of the left-most selected note:
int stretchStartTick = -1;
for (NoteVector::ConstIterator it = notes.begin(); it != notes.end(); ++it )
for (const Note *note : notes)
{
Note *note = *it;
if (note->selected() && (stretchStartTick < 0 || note->oldPos().getTicks() < stretchStartTick))
{
stretchStartTick = note->oldPos().getTicks();
}
}
// determine the ending tick of the right-most selected note
Note *posteriorNote = nullptr;
for (NoteVector::ConstIterator it = notes.begin(); it != notes.end(); ++it )
const Note *posteriorNote = nullptr;
for (const Note *note : notes)
{
Note *note = *it;
if (note->selected() && (posteriorNote == nullptr ||
note->oldPos().getTicks() + note->oldLength().getTicks() >
posteriorNote->oldPos().getTicks() + posteriorNote->oldLength().getTicks()))
@@ -2528,9 +2408,8 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
// process all selected notes & determine how much the endpoint of the right-most note was shifted
int posteriorDeltaThisFrame = 0;
for (NoteVector::ConstIterator it = notes.begin(); it != notes.end(); ++it )
for (Note *note : notes)
{
Note *note = *it;
if(note->selected())
{
// scale relative start and end positions by scaleFactor
@@ -2567,9 +2446,8 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
if (ctrl || selectionCount() == 1)
{
// if holding ctrl or only one note is selected, reposition posterior notes
for (NoteVector::ConstIterator it = notes.begin(); it != notes.end(); ++it )
for (Note *note : notes)
{
Note *note = *it;
if (!note->selected() && note->pos().getTicks() >= posteriorEndTick)
{
int newStart = note->pos().getTicks() + posteriorDeltaThisFrame;
@@ -2581,9 +2459,8 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
else
{
// shift is not pressed; stretch length of selected notes but not their position
for (NoteVector::ConstIterator it = notes.begin(); it != notes.end(); ++it )
for (Note *note : notes)
{
Note *note = *it;
if (note->selected())
{
int newLength = note->oldLength() + off_ticks;
@@ -2981,17 +2858,13 @@ void PianoRoll::paintEvent(QPaintEvent * pe )
width() - WHITE_KEY_WIDTH,
height() - PR_TOP_MARGIN );
const NoteVector & notes = m_pattern->notes();
const int visible_keys = ( keyAreaBottom()-keyAreaTop() ) /
KEY_LINE_HEIGHT + 2;
QPolygon editHandles;
NoteVector::ConstIterator it;
for( it = notes.begin(); it != notes.end(); ++it )
for( const Note *note : m_pattern->notes() )
{
Note *note = *it;
int len_ticks = note->length();
if( len_ticks == 0 )
@@ -3071,7 +2944,7 @@ void PianoRoll::paintEvent(QPaintEvent * pe )
if( note->hasDetuningInfo() )
{
drawDetuningInfo( p, *it,
drawDetuningInfo( p, note,
x + WHITE_KEY_WIDTH,
y_base - key * KEY_LINE_HEIGHT );
}
@@ -3221,15 +3094,11 @@ void PianoRoll::wheelEvent(QWheelEvent * we )
int ticks_end = ( x + pixel_range / 2 ) *
MidiTime::ticksPerTact() / m_ppt + m_currentPosition;
// get note-vector of current pattern
NoteVector notes;
notes += m_pattern->notes();
// When alt is pressed we only edit the note under the cursor
bool altPressed = we->modifiers() & Qt::AltModifier;
// go through notes to figure out which one we want to change
NoteVector nv;
foreach( Note * i, notes )
for ( Note * i : m_pattern->notes() )
{
if( i->withinRange( ticks_start, ticks_end ) || ( i->selected() && !altPressed ) )
{
@@ -3241,38 +3110,41 @@ void PianoRoll::wheelEvent(QWheelEvent * we )
const int step = we->delta() > 0 ? 1.0 : -1.0;
if( m_noteEditMode == NoteEditVolume )
{
foreach( Note * n, nv )
for ( Note * n : nv )
{
volume_t vol = tLimit<int>( n->getVolume() + step, MinVolume, MaxVolume );
n->setVolume( vol );
}
s_textFloat->setText( tr("Volume: %1%").arg( nv[0]->getVolume() ) );
bool allVolumesEqual = std::all_of( nv.begin(), nv.end(),
[nv](const Note *note)
{
return note->getVolume() == nv[0]->getVolume();
});
if ( allVolumesEqual )
{
// show the volume hover-text only if all notes have the
// same volume
showVolTextFloat( nv[0]->getVolume(), we->pos(), 1000 );
}
}
else if( m_noteEditMode == NoteEditPanning )
{
foreach( Note * n, nv )
for ( Note * n : nv )
{
panning_t pan = tLimit<int>( n->getPanning() + step, PanningLeft, PanningRight );
n->setPanning( pan );
}
panning_t pan = nv[0]->getPanning();
if( pan < 0 )
bool allPansEqual = std::all_of( nv.begin(), nv.end(),
[nv](const Note *note)
{
return note->getPanning() == nv[0]->getPanning();
});
if ( allPansEqual )
{
s_textFloat->setText( tr("Panning: %1% left").arg( qAbs( pan ) ) );
// show the pan hover-text only if all notes have the same
// panning
showPanTextFloat( nv[0]->getPanning(), we->pos(), 1000 );
}
else if( pan > 0 )
{
s_textFloat->setText( tr("Panning: %1% right").arg( qAbs( pan ) ) );
}
else
{
s_textFloat->setText( tr("Panning: center") );
}
}
if( nv.size() == 1 )
{
s_textFloat->moveGlobal( this, QPoint( we->x() + 4, we->y() + 16 ) );
s_textFloat->setVisibilityTimeOut( 1000 );
}
update();
}
@@ -3559,15 +3431,11 @@ void PianoRoll::selectAll()
return;
}
const NoteVector & notes = m_pattern->notes();
// if first_time = true, we HAVE to set the vars for select
bool first_time = true;
NoteVector::ConstIterator it;
for( it = notes.begin(); it != notes.end(); ++it )
for( const Note *note : m_pattern->notes() )
{
Note *note = *it;
int len_ticks = note->length();
if( len_ticks > 0 )
@@ -3612,24 +3480,21 @@ void PianoRoll::selectAll()
// returns vector with pointers to all selected notes
void PianoRoll::getSelectedNotes(NoteVector & selected_notes )
NoteVector PianoRoll::getSelectedNotes()
{
if( ! hasValidPattern() )
{
return;
}
NoteVector selectedNotes;
const NoteVector & notes = m_pattern->notes();
NoteVector::ConstIterator it;
for( it = notes.begin(); it != notes.end(); ++it )
if (hasValidPattern())
{
Note *note = *it;
if( note->selected() )
for( Note *note : m_pattern->notes() )
{
selected_notes.push_back( note );
if( note->selected() )
{
selectedNotes.push_back( note );
}
}
}
return selectedNotes;
}
@@ -3648,7 +3513,7 @@ void PianoRoll::enterValue( NoteVector* nv )
if( ok )
{
foreach( Note * n, *nv )
for ( Note * n : *nv )
{
n->setVolume( new_val );
}
@@ -3667,7 +3532,7 @@ void PianoRoll::enterValue( NoteVector* nv )
if( ok )
{
foreach( Note * n, *nv )
for ( Note * n : *nv )
{
n->setPanning( new_val );
}
@@ -3678,17 +3543,16 @@ void PianoRoll::enterValue( NoteVector* nv )
}
void PianoRoll::copy_to_clipboard( const NoteVector & notes ) const
void PianoRoll::copyToClipboard( const NoteVector & notes ) const
{
DataFile dataFile( DataFile::ClipboardData );
QDomElement note_list = dataFile.createElement( "note-list" );
dataFile.content().appendChild( note_list );
MidiTime start_pos( notes.front()->pos().getTact(), 0 );
for( NoteVector::ConstIterator it = notes.begin(); it != notes.end();
++it )
for( const Note *note : notes )
{
Note clip_note( **it );
Note clip_note( *note );
clip_note.setPos( clip_note.pos( start_pos ) );
clip_note.saveState( dataFile, note_list );
}
@@ -3704,12 +3568,11 @@ void PianoRoll::copy_to_clipboard( const NoteVector & notes ) const
void PianoRoll::copySelectedNotes()
{
NoteVector selected_notes;
getSelectedNotes( selected_notes );
NoteVector selected_notes = getSelectedNotes();
if( ! selected_notes.empty() )
{
copy_to_clipboard( selected_notes );
copyToClipboard( selected_notes );
}
}
@@ -3723,19 +3586,16 @@ void PianoRoll::cutSelectedNotes()
return;
}
NoteVector selected_notes;
getSelectedNotes( selected_notes );
NoteVector selected_notes = getSelectedNotes();
if( ! selected_notes.empty() )
{
copy_to_clipboard( selected_notes );
copyToClipboard( selected_notes );
Engine::getSong()->setModified();
NoteVector::Iterator it;
for( it = selected_notes.begin(); it != selected_notes.end(); ++it )
for( const Note *note : selected_notes )
{
Note *note = *it;
// note (the memory of it) is also deleted by
// pattern::removeNote(...) so we don't have to do that
m_pattern->removeNote( note );
@@ -3984,9 +3844,6 @@ Note * PianoRoll::noteUnderMouse()
{
QPoint pos = mapFromGlobal( QCursor::pos() );
// get note-vector of current pattern
const NoteVector & notes = m_pattern->notes();
if( pos.x() <= WHITE_KEY_WIDTH
|| pos.x() > width() - SCROLLBAR_SIZE
|| pos.y() < PR_TOP_MARGIN
@@ -4000,7 +3857,7 @@ Note * PianoRoll::noteUnderMouse()
MidiTime::ticksPerTact() / m_ppt + m_currentPosition;
// loop through whole note-vector...
for( Note* const& note : notes )
for( Note* const& note : m_pattern->notes() )
{
// and check whether the cursor is over an
// existing note