Merge pull request #2324 from Wallacoloo/pianoroll-refactor
Refactor PianoRoll code
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user