diff --git a/app/ui/mainwindow2.ui b/app/ui/mainwindow2.ui index 0d5693f082..b20674c35a 100644 --- a/app/ui/mainwindow2.ui +++ b/app/ui/mainwindow2.ui @@ -986,6 +986,11 @@ Flip Rolling + + + Merge Layers + + Peg bar Alignment diff --git a/core_lib/src/interface/timelinecells.cpp b/core_lib/src/interface/timelinecells.cpp index ccb1d0ed0a..d2b7e7fd34 100644 --- a/core_lib/src/interface/timelinecells.cpp +++ b/core_lib/src/interface/timelinecells.cpp @@ -20,6 +20,8 @@ GNU General Public License for more details. #include #include #include +#include +#include #include "object.h" #include "editor.h" @@ -164,11 +166,95 @@ void TimeLineCells::updateContent() update(); } - bool TimeLineCells::didDetatchLayer() { return abs(getMouseMoveY()) > mLayerDetatchThreshold; } +void TimeLineCells::showContextMenu(QPoint pos) +{ + pos = this->mapToGlobal(pos); + int index = mEditor->layers()->currentLayerIndex(); + bool mergeInMenu = false; + QMenu* menu = new QMenu(); + if (mEditor->layers()->currentLayerIndex() > 0 && + mEditor->layers()->currentLayer()->type() == Layer::BITMAP && + mEditor->layers()->getLayer(index)->type() == mEditor->layers()->getLayer(index-1)->type()) + { + menu->addAction(tr("Merge onto Layer: %1").arg(mEditor->layers()->getLayer(index-1)->name()), this, &TimeLineCells::mergeLayerDown); + mergeInMenu = true; + } + + if (mEditor->layers()->currentLayer()->type() == Layer::BITMAP) + { + menu->addAction(tr("Merge visible bitmap layers"), this, &TimeLineCells::mergeVisibleLayers); + mergeInMenu = true; + } + + if (mergeInMenu) + { + menu->addSeparator(); + } + + if (mEditor->layers()->currentLayer()->type() == Layer::BITMAP) + { + menu->addAction(tr("Duplicate Layer: %1").arg(mEditor->layers()->currentLayer()->name()), this, &TimeLineCells::duplicateLayer); + } + menu->addAction(tr("Delete Layer: %1").arg(mEditor->layers()->currentLayer()->name()), this, &TimeLineCells::deleteLayer); + + menu->exec(pos); +} + +void TimeLineCells::deleteLayer() +{ + mEditor->layers()->deleteLayer(mEditor->layers()->currentLayerIndex()); +} + +void TimeLineCells::duplicateLayer() +{ + QString newLayerName = mEditor->layers()->currentLayer()->name() + "_copy"; + mEditor->layers()->createBitmapLayer(newLayerName); + mEditor->layers()->duplicateLayer(mEditor->layers()->currentLayer(), mEditor->layers()->findLayerByName(newLayerName)); +} + +void TimeLineCells::mergeLayerDown() +{ + int index = mEditor->layers()->currentLayerIndex(); + if (mEditor->layers()->getLayer(index)->type() == mEditor->layers()->getLayer(index-1)->type()) + { + mEditor->layers()->mergeLayers(mEditor->layers()->currentLayer(), mEditor->layers()->getLayer(index-1)); + } + mEditor->layers()->deleteLayer(index); +} + +void TimeLineCells::mergeVisibleLayers() +{ + QList indexes; + for (int i = 0; i < mEditor->layers()->count(); i++) + { + if (mEditor->layers()->getLayer(i)->type() == Layer::BITMAP && + mEditor->layers()->getLayer(i)->visible()) + indexes.append(i); + } + + if (indexes.size() < 2) { return; } + + int count = indexes.size(); + while (count > 1) + { + mEditor->layers()->mergeLayers(mEditor->layers()->getLayer(indexes.at(count - 1)), + mEditor->layers()->getLayer(indexes.at(count - 2))); + count--; + } + + indexes.removeFirst(); + + while (!indexes.empty()) + { + mEditor->layers()->deleteLayer(indexes.last()); + indexes.removeLast(); + } +} + void TimeLineCells::drawContent() { if (mCache == nullptr) @@ -504,6 +590,10 @@ void TimeLineCells::mousePressEvent(QMouseEvent* event) else { mEditor->layers()->setCurrentLayer(layerNumber); + if (event->button() == Qt::RightButton) + { + showContextMenu(event->pos()); + } } } if (layerNumber == -1) diff --git a/core_lib/src/interface/timelinecells.h b/core_lib/src/interface/timelinecells.h index 9f4fca5cf4..3b1f6bef26 100644 --- a/core_lib/src/interface/timelinecells.h +++ b/core_lib/src/interface/timelinecells.h @@ -63,6 +63,12 @@ class TimeLineCells : public QWidget void paintLayerGutter(QPainter& painter); bool didDetatchLayer(); + void showContextMenu(QPoint pos); + void deleteLayer(); + void duplicateLayer(); + void mergeLayerDown(); + void mergeVisibleLayers(); + Q_SIGNALS: void mouseMovedY(int); void lengthChanged(int); diff --git a/core_lib/src/managers/layermanager.cpp b/core_lib/src/managers/layermanager.cpp index 7759e5c2bf..fccf943f32 100644 --- a/core_lib/src/managers/layermanager.cpp +++ b/core_lib/src/managers/layermanager.cpp @@ -305,6 +305,44 @@ Status LayerManager::deleteLayer(int index) return Status::OK; } +void LayerManager::duplicateLayer(Layer *fromLayer, Layer *toLayer) +{ + if (fromLayer == nullptr || toLayer == nullptr) { return; } + + for (int i = fromLayer->firstKeyFramePosition(); i <= fromLayer->getMaxKeyFramePosition(); i++) + { + editor()->scrubTo(i); + if (fromLayer->keyExists(i)) + { + editor()->layers()->setCurrentLayer(fromLayer); + editor()->copy(); + editor()->layers()->setCurrentLayer(toLayer); + if (!toLayer->keyExists(i)) + toLayer->addNewKeyFrameAt(i); + editor()->paste(); + } + } +} + +void LayerManager::mergeLayers(Layer *fromLayer, Layer *toLayer) +{ + if (fromLayer == nullptr || toLayer == nullptr) { return; } + + for (int i = fromLayer->firstKeyFramePosition(); i <= fromLayer->getMaxKeyFramePosition(); i++) + { + editor()->scrubTo(i); + if (fromLayer->keyExists(i)) + { + editor()->layers()->setCurrentLayer(fromLayer); + editor()->copy(); + editor()->layers()->setCurrentLayer(toLayer); + if (!toLayer->keyExists(i)) + toLayer->addNewKeyFrameAt(i); + editor()->paste(); + } + } +} + Status LayerManager::renameLayer(Layer* layer, const QString& newName) { if (newName.isEmpty()) return Status::FAIL; diff --git a/core_lib/src/managers/layermanager.h b/core_lib/src/managers/layermanager.h index 7a58abc01f..7049526f39 100644 --- a/core_lib/src/managers/layermanager.h +++ b/core_lib/src/managers/layermanager.h @@ -50,6 +50,8 @@ class LayerManager : public BaseManager int count(); Status deleteLayer(int index); + void duplicateLayer(Layer* fromLayer, Layer* toLayer); + void mergeLayers(Layer* fromLayer, Layer* toLayer); Status renameLayer(Layer*, const QString& newName); void notifyLayerChanged(Layer*);