From 73c725827e462fe8ecb58e122dcaf79a92516645 Mon Sep 17 00:00:00 2001 From: David Capello Date: Wed, 19 Aug 2015 15:59:30 -0300 Subject: [PATCH] Add "Duplicate Cels" command (fix #746) --- data/gui.xml | 18 ++++++++- src/app/commands/cmd_new_frame.cpp | 60 ++++++++++++++++++++++++++---- src/app/document_api.cpp | 14 ++++++- src/app/document_api.h | 3 ++ 4 files changed, 84 insertions(+), 11 deletions(-) diff --git a/data/gui.xml b/data/gui.xml index 269784fa9..6f57b6104 100644 --- a/data/gui.xml +++ b/data/gui.xml @@ -70,6 +70,12 @@ + + + + + + @@ -598,7 +604,10 @@ - + + + + @@ -752,6 +761,13 @@ + + + + + + + diff --git a/src/app/commands/cmd_new_frame.cpp b/src/app/commands/cmd_new_frame.cpp index c641d9c1b..a9fa3acfe 100644 --- a/src/app/commands/cmd_new_frame.cpp +++ b/src/app/commands/cmd_new_frame.cpp @@ -39,7 +39,8 @@ public: enum class Content { DUPLICATE_FRAME, NEW_EMPTY_FRAME, - DUPLICATE_CEL + DUPLICATE_CELS, + DUPLICATE_CELS_BLOCK, }; NewFrameCommand(); @@ -73,7 +74,9 @@ void NewFrameCommand::onLoadParams(const Params& params) else if (content == "empty") m_content = Content::NEW_EMPTY_FRAME; else if (content == "cel") - m_content = Content::DUPLICATE_CEL; + m_content = Content::DUPLICATE_CELS; + else if (content == "celblock") + m_content = Content::DUPLICATE_CELS_BLOCK; } bool NewFrameCommand::onEnabled(Context* context) @@ -92,26 +95,64 @@ void NewFrameCommand::onExecute(Context* context) DocumentApi api = document->getApi(transaction); switch (m_content) { + case Content::DUPLICATE_FRAME: api.addFrame(sprite, writer.frame()+1); break; + case Content::NEW_EMPTY_FRAME: api.addEmptyFrame(sprite, writer.frame()+1); break; - case Content::DUPLICATE_CEL: { + + case Content::DUPLICATE_CELS: + case Content::DUPLICATE_CELS_BLOCK: { // TODO the range of selected frames should be in doc::Site. Timeline* timeline = App::instance()->getMainWindow()->getTimeline(); Timeline::Range range = timeline->range(); if (range.enabled()) { + std::map relatedCels; timeline->prepareToMoveRange(); - for (LayerIndex layer = range.layerBegin(); layer <= range.layerEnd(); ++layer) { + LayerIndex layerBegin = range.layerBegin(); + LayerIndex layerEnd = range.layerEnd(); + + if (range.type() == DocumentRange::kFrames) { + layerBegin = writer.sprite()->firstLayer(); + layerEnd = writer.sprite()->lastLayer(); + } + + for (LayerIndex layer = layerBegin; layer <= layerEnd; ++layer) { Layer* layerPtr = writer.sprite()->indexToLayer(layer); if (layerPtr->isImage()) { for (frame_t frame = range.frameEnd(); frame >= range.frameBegin(); --frame) { + frame_t srcFrame = frame; + frame_t dstFrame = frame+range.frames(); + bool continuous; + CelData* srcCelData = nullptr; + + if (m_content == Content::DUPLICATE_CELS_BLOCK) { + continuous = false; + + Cel* srcCel = static_cast(layerPtr)->cel(srcFrame); + if (srcCel) { + srcCelData = srcCel->data(); + + auto it = relatedCels.find(srcCelData); + if (it != relatedCels.end()) { + srcFrame = it->second->frame(); + continuous = true; + } + } + } + else + continuous = layerPtr->isContinuous(); + api.copyCel( - static_cast(layerPtr), frame, - static_cast(layerPtr), frame+range.frames()); + static_cast(layerPtr), srcFrame, + static_cast(layerPtr), dstFrame, continuous); + + if (srcCelData && !relatedCels[srcCelData]) + relatedCels[srcCelData] = layerPtr->cel(dstFrame); } } } @@ -157,8 +198,11 @@ std::string NewFrameCommand::onGetFriendlyName() const case Content::NEW_EMPTY_FRAME: text = "New Empty Frame"; break; - case Content::DUPLICATE_CEL: - text = "Copy Cel into Next Frame"; + case Content::DUPLICATE_CELS: + text = "Duplicate Linked Cels"; + break; + case Content::DUPLICATE_CELS_BLOCK: + text = "Duplicate Cels"; break; } diff --git a/src/app/document_api.cpp b/src/app/document_api.cpp index cf373e352..8c210ddd1 100644 --- a/src/app/document_api.cpp +++ b/src/app/document_api.cpp @@ -357,11 +357,21 @@ void DocumentApi::moveCel( void DocumentApi::copyCel( LayerImage* srcLayer, frame_t srcFrame, LayerImage* dstLayer, frame_t dstFrame) +{ + copyCel( + srcLayer, srcFrame, + dstLayer, dstFrame, dstLayer->isContinuous()); +} + +void DocumentApi::copyCel( + LayerImage* srcLayer, frame_t srcFrame, + LayerImage* dstLayer, frame_t dstFrame, bool continuous) { ASSERT(srcLayer != dstLayer || srcFrame != dstFrame); - m_transaction.execute(new cmd::CopyCel( + m_transaction.execute( + new cmd::CopyCel( srcLayer, srcFrame, - dstLayer, dstFrame, dstLayer->isContinuous())); + dstLayer, dstFrame, continuous)); } void DocumentApi::swapCel( diff --git a/src/app/document_api.h b/src/app/document_api.h index 4280a717d..5c983d86b 100644 --- a/src/app/document_api.h +++ b/src/app/document_api.h @@ -73,6 +73,9 @@ namespace app { void copyCel( LayerImage* srcLayer, frame_t srcFrame, LayerImage* dstLayer, frame_t dstFrame); + void copyCel( + LayerImage* srcLayer, frame_t srcFrame, + LayerImage* dstLayer, frame_t dstFrame, bool continuous); void swapCel( LayerImage* layer, frame_t frame1, frame_t frame2);