diff --git a/app/src/actioncommands.cpp b/app/src/actioncommands.cpp index a2523804b8..341e46dc07 100644 --- a/app/src/actioncommands.cpp +++ b/app/src/actioncommands.cpp @@ -616,8 +616,8 @@ void ActionCommands::exposeSelectedFrames(int offset) } currentLayer->setExposureForSelectedFrames(offset); - mEditor->updateTimeLine(); - mEditor->framesModified(); + emit mEditor->updateTimeLine(); + emit mEditor->framesModified(); // Remember to deselect frame again so we don't show it being visually selected. // B: @@ -679,7 +679,7 @@ void ActionCommands::reverseSelectedFrames() if (currentLayer->type() == Layer::CAMERA) { mEditor->view()->forceUpdateViewTransform(); } - mEditor->framesModified(); + emit mEditor->framesModified(); }; void ActionCommands::removeKey() @@ -694,6 +694,30 @@ void ActionCommands::removeKey() } } +void ActionCommands::duplicateLayer() +{ + LayerManager* layerMgr = mEditor->layers(); + Layer* fromLayer = layerMgr->currentLayer(); + int currFrame = mEditor->currentFrame(); + + Layer* toLayer = layerMgr->createLayer(fromLayer->type(), tr("%1 (copy)", "Default duplicate layer name").arg(fromLayer->name())); + toLayer->removeKeyFrame(1); + fromLayer->foreachKeyFrame([&] (KeyFrame* key) { + key = key->clone(); + toLayer->addKeyFrame(key->pos(), key); + if (toLayer->type() == Layer::SOUND) + { + mEditor->sound()->processSound(static_cast(key)); + } + else + { + key->setFileName(""); + key->modification(); + } + }); + mEditor->scrubTo(currFrame); +} + void ActionCommands::duplicateKey() { Layer* layer = mEditor->layers()->currentLayer(); diff --git a/app/src/actioncommands.h b/app/src/actioncommands.h index 53476eb9d8..eb210e88ed 100644 --- a/app/src/actioncommands.h +++ b/app/src/actioncommands.h @@ -67,6 +67,7 @@ class ActionCommands : public QObject /** Will insert a keyframe at the current position and push connected frames to the right */ Status insertKeyFrameAtCurrentPosition(); void removeKey(); + void duplicateLayer(); void duplicateKey(); void moveFrameForward(); void moveFrameBackward(); diff --git a/app/src/mainwindow2.cpp b/app/src/mainwindow2.cpp index 8013771718..663f004d7a 100644 --- a/app/src/mainwindow2.cpp +++ b/app/src/mainwindow2.cpp @@ -1396,6 +1396,7 @@ void MainWindow2::makeConnections(Editor* editor, ScribbleArea* scribbleArea) void MainWindow2::makeConnections(Editor* pEditor, TimeLine* pTimeline) { PlaybackManager* pPlaybackManager = pEditor->playback(); + connect(pTimeline, &TimeLine::duplicateLayerClick, mCommands, &ActionCommands::duplicateLayer); connect(pTimeline, &TimeLine::duplicateKeyClick, mCommands, &ActionCommands::duplicateKey); connect(pTimeline, &TimeLine::soundClick, pPlaybackManager, &PlaybackManager::enableSound); diff --git a/core_lib/src/interface/timeline.cpp b/core_lib/src/interface/timeline.cpp index e32437da4d..c7d35ce176 100644 --- a/core_lib/src/interface/timeline.cpp +++ b/core_lib/src/interface/timeline.cpp @@ -81,9 +81,15 @@ void TimeLine::initUI() removeLayerButton->setToolTip(tr("Remove Layer")); removeLayerButton->setFixedSize(24, 24); + QToolButton* duplicateLayerButton = new QToolButton(this); + duplicateLayerButton->setIcon(QIcon(":icons/controls/duplicate.png")); + duplicateLayerButton->setToolTip(tr("Duplicate Layer")); + duplicateLayerButton->setFixedSize(24, 24); + layerButtons->addWidget(layerLabel); layerButtons->addWidget(addLayerButton); layerButtons->addWidget(removeLayerButton); + layerButtons->addWidget(duplicateLayerButton); layerButtons->setFixedHeight(30); QHBoxLayout* leftToolBarLayout = new QHBoxLayout(); @@ -200,6 +206,7 @@ void TimeLine::initUI() connect(addKeyButton, &QToolButton::clicked, this, &TimeLine::insertKeyClick); connect(removeKeyButton, &QToolButton::clicked, this, &TimeLine::removeKeyClick); + connect(duplicateLayerButton, &QToolButton::clicked, this , &TimeLine::duplicateLayerClick); connect(duplicateKeyButton, &QToolButton::clicked, this, &TimeLine::duplicateKeyClick); connect(zoomSlider, &QSlider::valueChanged, mTracks, &TimeLineCells::setFrameSize); diff --git a/core_lib/src/interface/timeline.h b/core_lib/src/interface/timeline.h index 2db24962e9..8698cc4852 100644 --- a/core_lib/src/interface/timeline.h +++ b/core_lib/src/interface/timeline.h @@ -59,6 +59,7 @@ class TimeLine : public BaseDockWidget void insertKeyClick(); void removeKeyClick(); + void duplicateLayerClick(); void duplicateKeyClick(); void newBitmapLayer(); diff --git a/core_lib/src/managers/layermanager.cpp b/core_lib/src/managers/layermanager.cpp index cca74eb13d..8d082ecabb 100644 --- a/core_lib/src/managers/layermanager.cpp +++ b/core_lib/src/managers/layermanager.cpp @@ -182,6 +182,34 @@ QString LayerManager::nameSuggestLayer(const QString& name) return newName; } +Layer* LayerManager::createLayer(Layer::LAYER_TYPE type, const QString& strLayerName) +{ + Layer* layer = nullptr; + switch (type) { + case Layer::BITMAP: + layer = object()->addNewBitmapLayer(); + break; + case Layer::VECTOR: + layer = object()->addNewVectorLayer(); + break; + case Layer::SOUND: + layer = object()->addNewSoundLayer(); + break; + case Layer::CAMERA: + layer = object()->addNewCameraLayer(); + break; + default: + Q_ASSERT(true); + return nullptr; + } + + layer->setName(strLayerName); + emit layerCountChanged(count()); + setCurrentLayer(getLastLayerIndex()); + + return layer; +} + LayerBitmap* LayerManager::createBitmapLayer(const QString& strLayerName) { LayerBitmap* layer = object()->addNewBitmapLayer(); diff --git a/core_lib/src/managers/layermanager.h b/core_lib/src/managers/layermanager.h index 0fe381ccc9..62c4bad981 100644 --- a/core_lib/src/managers/layermanager.h +++ b/core_lib/src/managers/layermanager.h @@ -56,6 +56,8 @@ class LayerManager : public BaseManager void gotoNextLayer(); void gotoPreviouslayer(); + /** Returns a new Layer with the given LAYER_TYPE */ + Layer* createLayer(Layer::LAYER_TYPE type, const QString& strLayerName); LayerBitmap* createBitmapLayer(const QString& strLayerName); LayerVector* createVectorLayer(const QString& strLayerName); LayerCamera* createCameraLayer(const QString& strLayerName);