diff --git a/data/themes/default/step_btn_duplicate.png b/data/themes/default/step_btn_duplicate.png new file mode 100644 index 000000000..af9521fad Binary files /dev/null and b/data/themes/default/step_btn_duplicate.png differ diff --git a/include/BBEditor.h b/include/BBEditor.h index aea2f8763..17ab510ab 100644 --- a/include/BBEditor.h +++ b/include/BBEditor.h @@ -82,6 +82,7 @@ public: public slots: void addSteps(); + void cloneSteps(); void removeSteps(); void addAutomationTrack(); @@ -91,6 +92,7 @@ protected slots: private: BBTrackContainer * m_bbtc; + void makeSteps( bool clone ); }; diff --git a/include/Pattern.h b/include/Pattern.h index 1e3c5db10..ce6702fbb 100644 --- a/include/Pattern.h +++ b/include/Pattern.h @@ -127,6 +127,7 @@ protected: protected slots: void addSteps(); + void cloneSteps(); void removeSteps(); void clear(); void changeTimeSignature(); diff --git a/src/gui/editors/BBEditor.cpp b/src/gui/editors/BBEditor.cpp index db14eecf6..953cefa91 100644 --- a/src/gui/editors/BBEditor.cpp +++ b/src/gui/editors/BBEditor.cpp @@ -102,7 +102,9 @@ BBEditor::BBEditor( BBTrackContainer* tc ) : m_toolBar->addAction(embed::getIconPixmap("step_btn_remove"), tr("Remove steps"), m_trackContainerView, SLOT(removeSteps())); m_toolBar->addAction(embed::getIconPixmap("step_btn_add"), tr("Add steps"), - m_trackContainerView, SLOT(addSteps())); + m_trackContainerView, SLOT( addSteps())); + m_toolBar->addAction( embed::getIconPixmap( "step_btn_duplicate" ), tr( "Clone Steps" ), + m_trackContainerView, SLOT( cloneSteps() ) ); m_toolBar->addSeparator(); connect( &tc->m_bbComboBoxModel, SIGNAL( dataChanged() ), @@ -170,17 +172,12 @@ BBTrackContainerView::BBTrackContainerView(BBTrackContainer* tc) : void BBTrackContainerView::addSteps() { - TrackContainer::TrackList tl = model()->tracks(); + makeSteps( false ); +} - for( TrackContainer::TrackList::iterator it = tl.begin(); - it != tl.end(); ++it ) - { - if( ( *it )->type() == Track::InstrumentTrack ) - { - Pattern* p = static_cast( ( *it )->getTCO( m_bbtc->currentBB() ) ); - p->addSteps(); - } - } +void BBTrackContainerView::cloneSteps() +{ + makeSteps( true ); } @@ -264,3 +261,27 @@ void BBTrackContainerView::updatePosition() //realignTracks(); emit positionChanged( m_currentPosition ); } + + + + +void BBTrackContainerView::makeSteps( bool clone ) +{ + TrackContainer::TrackList tl = model()->tracks(); + + for( TrackContainer::TrackList::iterator it = tl.begin(); + it != tl.end(); ++it ) + { + if( ( *it )->type() == Track::InstrumentTrack ) + { + Pattern* p = static_cast( ( *it )->getTCO( m_bbtc->currentBB() ) ); + if( clone ) + { + p->cloneSteps(); + } else + { + p->addSteps(); + } + } + } +} diff --git a/src/tracks/Pattern.cpp b/src/tracks/Pattern.cpp index cea27895a..e9ba69d9f 100644 --- a/src/tracks/Pattern.cpp +++ b/src/tracks/Pattern.cpp @@ -478,6 +478,29 @@ void Pattern::addSteps() updateBBTrack(); } +void Pattern::cloneSteps() +{ + int oldLength = m_steps; + m_steps += MidiTime::stepsPerTact(); + ensureBeatNotes(); + for(int i = 0; i < MidiTime::stepsPerTact(); ++i ) + { + Note *toCopy = noteAtStep( i ); + if( toCopy ) + { + setStep( oldLength + i, true ); + Note *newNote = noteAtStep( oldLength + i ); + newNote->setKey( toCopy->key() ); + newNote->setLength( toCopy->length() ); + newNote->setPanning( toCopy->getPanning() ); + newNote->setVolume( toCopy->getVolume() ); + } + } + ensureBeatNotes(); + emit dataChanged(); + updateBBTrack(); +} +