diff --git a/include/AutomationTrack.h b/include/AutomationTrack.h index 92a50dd04a9..c8a0009e966 100644 --- a/include/AutomationTrack.h +++ b/include/AutomationTrack.h @@ -46,7 +46,7 @@ class AutomationTrack : public Track } TrackView * createView( TrackContainerView* ) override; - TrackContentObject * createTCO( const MidiTime & _pos ) override; + TrackContentObject* createTCO(const MidiTime & pos) override; virtual void saveTrackSpecificSettings( QDomDocument & _doc, QDomElement & _parent ) override; diff --git a/include/BBTrack.h b/include/BBTrack.h index 36a10884547..5f9cfe408f0 100644 --- a/include/BBTrack.h +++ b/include/BBTrack.h @@ -106,7 +106,7 @@ class LMMS_EXPORT BBTrack : public Track virtual bool play( const MidiTime & _start, const fpp_t _frames, const f_cnt_t _frame_base, int _tco_num = -1 ) override; TrackView * createView( TrackContainerView* tcv ) override; - TrackContentObject * createTCO( const MidiTime & _pos ) override; + TrackContentObject* createTCO(const MidiTime & pos) override; virtual void saveTrackSpecificSettings( QDomDocument & _doc, QDomElement & _parent ) override; diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index 29348b98eb6..fa1d1692e63 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -136,7 +136,7 @@ class LMMS_EXPORT InstrumentTrack : public Track, public MidiEventProcessor TrackView * createView( TrackContainerView* tcv ) override; // create new track-content-object = pattern - TrackContentObject * createTCO( const MidiTime & _pos ) override; + TrackContentObject* createTCO(const MidiTime & pos) override; // called by track diff --git a/include/SampleTrack.h b/include/SampleTrack.h index 47cc0df3945..eda1299a538 100644 --- a/include/SampleTrack.h +++ b/include/SampleTrack.h @@ -140,7 +140,7 @@ class SampleTrack : public Track virtual bool play( const MidiTime & _start, const fpp_t _frames, const f_cnt_t _frame_base, int _tco_num = -1 ) override; TrackView * createView( TrackContainerView* tcv ) override; - TrackContentObject * createTCO( const MidiTime & _pos ) override; + TrackContentObject* createTCO(const MidiTime & pos) override; virtual void saveTrackSpecificSettings( QDomDocument & _doc, diff --git a/plugins/HydrogenImport/HydrogenImport.cpp b/plugins/HydrogenImport/HydrogenImport.cpp index 4a69bc4511c..c39c52416fc 100644 --- a/plugins/HydrogenImport/HydrogenImport.cpp +++ b/plugins/HydrogenImport/HydrogenImport.cpp @@ -314,10 +314,8 @@ bool HydrogenImport::readSong() int i = pattern_id[patId]+song_num_tracks; Track *t = ( BBTrack * ) s->tracks().at( i ); - TrackContentObject *tco = t->createTCO( pos ); - tco->movePosition( pos ); + t->createTCO(pos); - if ( pattern_length[patId] > best_length ) { best_length = pattern_length[patId]; diff --git a/plugins/MidiImport/MidiImport.cpp b/plugins/MidiImport/MidiImport.cpp index 8b2aa6117d6..a93e1e41e8d 100644 --- a/plugins/MidiImport/MidiImport.cpp +++ b/plugins/MidiImport/MidiImport.cpp @@ -193,8 +193,7 @@ class smfMidiCC { MidiTime pPos = MidiTime( time.getBar(), 0 ); ap = dynamic_cast( - at->createTCO(0) ); - ap->movePosition( pPos ); + at->createTCO(pPos)); ap->addObject( objModel ); } @@ -287,8 +286,7 @@ class smfMidiChannel if (!newPattern || n->pos() > lastEnd + DefaultTicksPerBar) { MidiTime pPos = MidiTime(n->pos().getBar(), 0); - newPattern = dynamic_cast(it->createTCO(0)); - newPattern->movePosition(pPos); + newPattern = dynamic_cast(it->createTCO(pPos)); } lastEnd = n->pos() + n->length(); diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 70da1e1d73c..d73bdbed7ea 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -151,10 +151,11 @@ TrackContentObject::~TrackContentObject() */ void TrackContentObject::movePosition( const MidiTime & pos ) { - if( m_startPosition != pos ) + MidiTime newPos = qMax(0, pos.getTicks()); + if (m_startPosition != newPos) { Engine::mixer()->requestChangeInModel(); - m_startPosition = pos; + m_startPosition = newPos; Engine::mixer()->doneChangeInModel(); Engine::getSong()->updateLength(); emit positionChanged(); @@ -955,9 +956,8 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) { MidiTime newPos = draggedTCOPos( me ); - // Don't go left of bar zero - newPos = max( 0, newPos.getTicks() ); - m_tco->movePosition( newPos ); + m_tco->movePosition(newPos); + newPos = m_tco->startPosition(); // Get the real position the TCO was dragged to for the label m_trackView->getTrackContentWidget()->changePosition(); s_textFloat->setText( QString( "%1:%2" ). arg( newPos.getBar() + 1 ). @@ -1073,7 +1073,6 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) if( m_tco->length() + ( oldPos - t ) >= 1 ) { m_tco->movePosition( t ); - m_trackView->getTrackContentWidget()->changePosition(); m_tco->changeLength( m_tco->length() + ( oldPos - t ) ); sTco->setStartTimeOffset( sTco->startTimeOffset() + ( oldPos - t ) ); } @@ -1896,6 +1895,20 @@ bool TrackContentWidget::pasteSelection( MidiTime tcoPos, const QMimeData * md, // The offset is quantized (rather than the positions) to preserve fine adjustments offset = offset.quantize(snapSize); + // Get the leftmost TCO and fix the offset if it reaches below bar 0 + MidiTime leftmostPos = grabbedTCOPos; + for(int i = 0; i < tcoNodes.length(); ++i) + { + QDomElement outerTCOElement = tcoNodes.item(i).toElement(); + QDomElement tcoElement = outerTCOElement.firstChildElement(); + + MidiTime pos = tcoElement.attributeNode("pos").value().toInt(); + + if(pos < leftmostPos) { leftmostPos = pos; } + } + // Fix offset if it sets the left most TCO to a negative position + offset = std::max(offset.getTicks(), -leftmostPos.getTicks()); + for( int i = 0; icreateTCO( pos ); tco->restoreState( tcoElement ); - tco->movePosition( pos ); + tco->movePosition(pos); // Because we restored the state, we need to move the TCO again. if( wasSelection ) { tco->selectViewOnCreate( true ); @@ -1967,11 +1980,7 @@ void TrackContentWidget::mousePressEvent( QMouseEvent * me ) getTrack()->addJournalCheckPoint(); const MidiTime pos = getPosition( me->x() ).getBar() * MidiTime::ticksPerBar(); - TrackContentObject * tco = getTrack()->createTCO( pos ); - - tco->saveJournallingState( false ); - tco->movePosition( pos ); - tco->restoreJournallingState(); + getTrack()->createTCO(pos); } } @@ -2697,8 +2706,6 @@ void Track::loadSettings( const QDomElement & element ) TrackContentObject * tco = createTCO( MidiTime( 0 ) ); tco->restoreState( node.toElement() ); - saveJournallingState( false ); - restoreJournallingState(); } } node = node.nextSibling(); @@ -2886,7 +2893,6 @@ void Track::createTCOsForBB( int bb ) { MidiTime position = MidiTime( numOfTCOs(), 0 ); TrackContentObject * tco = createTCO( position ); - tco->movePosition( position ); tco->changeLength( MidiTime( 1, 0 ) ); } } @@ -2932,8 +2938,7 @@ void Track::removeBar( const MidiTime & pos ) { if( ( *it )->startPosition() >= pos ) { - ( *it )->movePosition( qMax( ( *it )->startPosition() - - MidiTime::ticksPerBar(), 0 ) ); + (*it)->movePosition((*it)->startPosition() - MidiTime::ticksPerBar()); } } } diff --git a/src/tracks/AutomationTrack.cpp b/src/tracks/AutomationTrack.cpp index 430f54a5692..fe3622921d9 100644 --- a/src/tracks/AutomationTrack.cpp +++ b/src/tracks/AutomationTrack.cpp @@ -57,9 +57,11 @@ TrackView * AutomationTrack::createView( TrackContainerView* tcv ) -TrackContentObject * AutomationTrack::createTCO( const MidiTime & ) +TrackContentObject* AutomationTrack::createTCO(const MidiTime & pos) { - return new AutomationPattern( this ); + AutomationPattern* p = new AutomationPattern(this); + p->movePosition(pos); + return p; } @@ -133,7 +135,6 @@ void AutomationTrackView::dropEvent( QDropEvent * _de ) TrackContentObject * tco = getTrack()->createTCO( pos ); AutomationPattern * pat = dynamic_cast( tco ); pat->addObject( mod ); - pat->movePosition( pos ); } } diff --git a/src/tracks/BBTrack.cpp b/src/tracks/BBTrack.cpp index 2bd0fdaf546..5ec03db30b4 100644 --- a/src/tracks/BBTrack.cpp +++ b/src/tracks/BBTrack.cpp @@ -382,9 +382,10 @@ TrackView * BBTrack::createView( TrackContainerView* tcv ) -TrackContentObject * BBTrack::createTCO( const MidiTime & _pos ) +TrackContentObject* BBTrack::createTCO(const MidiTime & pos) { - BBTCO * bbtco = new BBTCO( this ); + BBTCO* bbtco = new BBTCO(this); + bbtco->movePosition(pos); return bbtco; } diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 5a51bb8aced..0f3f7b31e96 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -713,9 +713,11 @@ bool InstrumentTrack::play( const MidiTime & _start, const fpp_t _frames, -TrackContentObject * InstrumentTrack::createTCO( const MidiTime & ) +TrackContentObject* InstrumentTrack::createTCO(const MidiTime & pos) { - return new Pattern( this ); + Pattern* p = new Pattern(this); + p->movePosition(pos); + return p; }