From 114a18bc4fa85e862fd3b66bc113d216ad98c8da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Capello?= Date: Tue, 15 Oct 2024 16:16:01 -0300 Subject: [PATCH] Move static funcs from Layer class to layer_utils Also refactor the code to make these functions use the current copyLayerContent function in app::Doc and make an actual copy of the specified layer --- src/app/cmd/drop_on_timeline.cpp | 4 ++-- src/app/doc_api.cpp | 5 ++--- src/app/util/layer_utils.cpp | 38 ++++++++++++++++++++++++++++++++ src/app/util/layer_utils.h | 4 ++++ src/doc/layer.cpp | 33 --------------------------- src/doc/layer.h | 3 --- 6 files changed, 46 insertions(+), 41 deletions(-) diff --git a/src/app/cmd/drop_on_timeline.cpp b/src/app/cmd/drop_on_timeline.cpp index f2b67350c..a0be28cbe 100644 --- a/src/app/cmd/drop_on_timeline.cpp +++ b/src/app/cmd/drop_on_timeline.cpp @@ -18,6 +18,7 @@ #include "app/doc.h" #include "app/doc_event.h" #include "app/file/file.h" +#include "app/util/layer_utils.h" #include "app/util/open_file_job.h" #include "app/tx.h" #include "doc/layer_list.h" @@ -160,8 +161,7 @@ void DropOnTimeline::onExecute() auto* layer = *it; // TODO: If we could "relocate" a layer from the source document to the // destination document we could avoid making a copy here. - auto* layerCopy = Layer::MakeCopyWithSprite(layer, destDoc->sprite()); - destDoc->copyLayerContent(layer, destDoc, layerCopy); + auto* layerCopy = copy_layer_with_sprite(layer, destDoc->sprite()); layerCopy->displaceFrames(0, m_frame); if (afterThis) { diff --git a/src/app/doc_api.cpp b/src/app/doc_api.cpp index bee7b71b7..1112372fc 100644 --- a/src/app/doc_api.cpp +++ b/src/app/doc_api.cpp @@ -48,6 +48,7 @@ #include "app/snap_to_grid.h" #include "app/transaction.h" #include "app/util/autocrop.h" +#include "app/util/layer_utils.h" #include "doc/algorithm/flip_image.h" #include "doc/algorithm/shrink_bounds.h" #include "doc/cel.h" @@ -697,9 +698,7 @@ void DocApi::restackLayerBefore(Layer* layer, LayerGroup* parent, Layer* beforeT Layer* DocApi::duplicateLayerAfter(Layer* sourceLayer, LayerGroup* parent, Layer* afterLayer) { ASSERT(parent); - Layer* newLayerPtr = Layer::MakeCopy(sourceLayer); - - m_document->copyLayerContent(sourceLayer, m_document, newLayerPtr); + Layer* newLayerPtr = copy_layer(sourceLayer); newLayerPtr->setName(newLayerPtr->name() + " Copy"); diff --git a/src/app/util/layer_utils.cpp b/src/app/util/layer_utils.cpp index 2a3d9ab42..f1ae997c6 100644 --- a/src/app/util/layer_utils.cpp +++ b/src/app/util/layer_utils.cpp @@ -6,11 +6,14 @@ #include "app/util/layer_utils.h" +#include "app/doc.h" #include "app/i18n/strings.h" #include "app/ui/editor/editor.h" #include "app/ui/status_bar.h" #include "doc/layer.h" +#include "doc/layer_tilemap.h" #include "doc/sprite.h" +#include "doc/tilesets.h" #include "fmt/format.h" namespace app { @@ -80,4 +83,39 @@ std::string get_layer_path(const Layer* layer) return path; } +Layer* copy_layer(doc::Layer* layer) +{ + return copy_layer_with_sprite(layer, layer->sprite()); +} + +Layer* copy_layer_with_sprite(doc::Layer* layer, doc::Sprite* sprite) +{ + std::unique_ptr clone; + if (layer->isTilemap()) { + auto* srcTilemap = static_cast(layer); + tileset_index tilesetIndex = srcTilemap->tilesetIndex(); + // If the caller is trying to make a copy of a tilemap layer specifying a + // different sprite as its owner, then we must copy the tilesets of the + // given tilemap layer into the new owner. + if (sprite != srcTilemap->sprite()) { + auto* srcTilesetCopy = Tileset::MakeCopyCopyingImages(srcTilemap->tileset()); + tilesetIndex = sprite->tilesets()->add(srcTilesetCopy); + } + + clone.reset(new LayerTilemap(sprite, tilesetIndex)); + } + else if (layer->isImage()) + clone.reset(new LayerImage(sprite)); + else if (layer->isGroup()) + clone.reset(new LayerGroup(sprite)); + else + throw std::runtime_error("Invalid layer type"); + + if (auto* doc = dynamic_cast(sprite->document())) { + doc->copyLayerContent(layer, doc, clone.get()); + } + + return clone.release(); +} + } // namespace app diff --git a/src/app/util/layer_utils.h b/src/app/util/layer_utils.h index 996b25804..71eae7469 100644 --- a/src/app/util/layer_utils.h +++ b/src/app/util/layer_utils.h @@ -12,6 +12,7 @@ namespace doc { class Layer; + class Sprite; } namespace app { @@ -31,6 +32,9 @@ namespace app { std::string get_layer_path(const doc::Layer* layer); + doc::Layer* copy_layer(doc::Layer* layer); + doc::Layer* copy_layer_with_sprite(doc::Layer* layer, doc::Sprite* sprite); + } // namespace app #endif diff --git a/src/doc/layer.cpp b/src/doc/layer.cpp index 550231319..d3918964f 100644 --- a/src/doc/layer.cpp +++ b/src/doc/layer.cpp @@ -45,39 +45,6 @@ Layer::~Layer() { } -// static -Layer* Layer::MakeCopy(doc::Layer* layer) -{ - return MakeCopyWithSprite(layer, layer->sprite()); -} - -// static -Layer* Layer::MakeCopyWithSprite(doc::Layer* layer, doc::Sprite* sprite) -{ - std::unique_ptr clone; - if (layer->isTilemap()) { - auto* srcTilemap = static_cast(layer); - tileset_index tilesetIndex = srcTilemap->tilesetIndex(); - // If the caller is trying to make a copy of a tilemap layer specifying a - // different sprite as its owner, then we must copy the tilesets of the - // given tilemap layer into the new owner. - if (sprite != srcTilemap->sprite()) { - auto* srcTilesetCopy = Tileset::MakeCopyCopyingImages(srcTilemap->tileset()); - tilesetIndex = sprite->tilesets()->add(srcTilesetCopy); - } - - clone.reset(new LayerTilemap(sprite, tilesetIndex)); - } - else if (layer->isImage()) - clone.reset(new LayerImage(sprite)); - else if (layer->isGroup()) - clone.reset(new LayerGroup(sprite)); - else - throw std::runtime_error("Invalid layer type"); - - return clone.release(); -} - int Layer::getMemSize() const { return sizeof(Layer); diff --git a/src/doc/layer.h b/src/doc/layer.h index 27867dcfc..130d9c760 100644 --- a/src/doc/layer.h +++ b/src/doc/layer.h @@ -58,9 +58,6 @@ namespace doc { public: virtual ~Layer(); - static Layer* MakeCopy(doc::Layer* layer); - static Layer* MakeCopyWithSprite(doc::Layer* layer, doc::Sprite* sprite); - virtual int getMemSize() const override; const std::string& name() const { return m_name; }