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*);