diff --git a/src/app/cli/cli_processor.cpp b/src/app/cli/cli_processor.cpp index ae162793a..bb5d97ee7 100644 --- a/src/app/cli/cli_processor.cpp +++ b/src/app/cli/cli_processor.cpp @@ -29,7 +29,6 @@ #include "doc/frame_tag.h" #include "doc/frame_tags.h" #include "doc/layer.h" -#include "doc/layers_range.h" namespace app { @@ -332,7 +331,7 @@ bool CliProcessor::openFile(CliOpenFile& cof) if (doc) { // Show all layers if (cof.allLayers) { - for (doc::Layer* layer : doc->sprite()->layers()) + for (doc::Layer* layer : doc->sprite()->allLayers()) layer->setVisible(true); } @@ -360,7 +359,7 @@ bool CliProcessor::openFile(CliOpenFile& cof) if (!cof.importLayer.empty()) { Layer* foundLayer = nullptr; - for (Layer* layer : doc->sprite()->layers()) { + for (Layer* layer : doc->sprite()->allLayers()) { if (layer->name() == cof.importLayer) { foundLayer = layer; break; @@ -370,10 +369,8 @@ bool CliProcessor::openFile(CliOpenFile& cof) m_exporter->addDocument(doc, foundLayer, frameTag, isTemporalTag); } else if (cof.splitLayers) { - for (auto layer : doc->sprite()->layers()) { - if (layer->isVisible()) - m_exporter->addDocument(doc, layer, frameTag, isTemporalTag); - } + for (auto layer : doc->sprite()->allVisibleLayers()) + m_exporter->addDocument(doc, layer, frameTag, isTemporalTag); } else { m_exporter->addDocument(doc, nullptr, frameTag, isTemporalTag); @@ -407,9 +404,10 @@ void CliProcessor::saveFile(const CliOpenFile& cof) } // Store in "visibility" the original "visible" state of every layer. - std::vector visibility(doc->sprite()->countLayers()); + LayerList allLayers = doc->sprite()->allLayers(); + std::vector visibility(allLayers.size()); int i = 0; - for (doc::Layer* layer : doc->sprite()->layers()) + for (doc::Layer* layer : allLayers) visibility[i++] = layer->isVisible(); std::string fn = cof.filename; @@ -427,13 +425,13 @@ void CliProcessor::saveFile(const CliOpenFile& cof) std::vector layers; // --save-as with --split-layers or --split-tags if (cof.splitLayers) { - for (doc::Layer* layer : doc->sprite()->layers()) + for (doc::Layer* layer : doc->sprite()->allVisibleLayers()) layers.push_back(layer); } else { // Show only one layer if (!cof.importLayer.empty()) { - for (Layer* layer : doc->sprite()->layers()) { + for (Layer* layer : allLayers) { if (layer->name() == cof.importLayer) { layer->setVisible(true); layers.push_back(layer); @@ -481,7 +479,7 @@ void CliProcessor::saveFile(const CliOpenFile& cof) continue; // Just ignore this layer. // Make this layer ("show") the only one visible. - for (doc::Layer* hide : doc->sprite()->layers()) + for (doc::Layer* hide : allLayers) hide->setVisible(hide == layer); } @@ -521,7 +519,7 @@ void CliProcessor::saveFile(const CliOpenFile& cof) // Restore layer visibility i = 0; - for (Layer* layer : doc->sprite()->layers()) + for (Layer* layer : allLayers) layer->setVisible(visibility[i++]); // Undo crop diff --git a/src/app/cli/default_cli_delegate.cpp b/src/app/cli/default_cli_delegate.cpp index 533ddcf5c..1f8b3e292 100644 --- a/src/app/cli/default_cli_delegate.cpp +++ b/src/app/cli/default_cli_delegate.cpp @@ -22,7 +22,6 @@ #include "base/convert_to.h" #include "doc/frame_tag.h" #include "doc/layer.h" -#include "doc/layers_range.h" #include "doc/sprite.h" #include "script/engine_delegate.h" @@ -53,10 +52,8 @@ void DefaultCliDelegate::afterOpenFile(const CliOpenFile& cof) return; if (cof.listLayers) { - for (doc::Layer* layer : cof.document->sprite()->layers()) { - if (layer->isVisible()) - std::cout << layer->name() << "\n"; - } + for (doc::Layer* layer : cof.document->sprite()->allVisibleLayers()) + std::cout << layer->name() << "\n"; } if (cof.listTags) { diff --git a/src/doc/CMakeLists.txt b/src/doc/CMakeLists.txt index 268bf26c0..fb831e96f 100644 --- a/src/doc/CMakeLists.txt +++ b/src/doc/CMakeLists.txt @@ -44,7 +44,6 @@ add_library(doc-lib layer.cpp layer_index.cpp layer_io.cpp - layers_range.cpp mask.cpp mask_boundaries.cpp mask_io.cpp diff --git a/src/doc/layer.cpp b/src/doc/layer.cpp index c4b84cf31..aca2d44eb 100644 --- a/src/doc/layer.cpp +++ b/src/doc/layer.cpp @@ -357,6 +357,39 @@ int LayerGroup::getMemSize() const return size; } +void LayerGroup::allLayers(LayerList& list) const +{ + for (Layer* child : m_layers) { + if (child->isGroup()) + static_cast(child)->allLayers(list); + + list.push_back(child); + } +} + +void LayerGroup::allVisibleLayers(LayerList& list) const +{ + for (Layer* child : m_layers) { + if (!child->isVisible()) + continue; + + if (child->isGroup()) + static_cast(child)->allVisibleLayers(list); + + list.push_back(child); + } +} + +void LayerGroup::allBrowsableLayers(LayerList& list) const +{ + for (Layer* child : m_layers) { + if (child->isBrowsable()) + static_cast(child)->allBrowsableLayers(list); + + list.push_back(child); + } +} + void LayerGroup::getCels(CelList& cels) const { for (const Layer* layer : m_layers) diff --git a/src/doc/layer.h b/src/doc/layer.h index e10966514..38c0bc4da 100644 --- a/src/doc/layer.h +++ b/src/doc/layer.h @@ -186,6 +186,10 @@ namespace doc { Layer* firstLayer() const { return (m_layers.empty() ? nullptr: m_layers.front()); } Layer* lastLayer() const { return (m_layers.empty() ? nullptr: m_layers.back()); } + void allLayers(LayerList& list) const; + void allVisibleLayers(LayerList& list) const; + void allBrowsableLayers(LayerList& list) const; + void getCels(CelList& cels) const override; void displaceFrames(frame_t fromThis, frame_t delta) override; diff --git a/src/doc/layers_range.cpp b/src/doc/layers_range.cpp deleted file mode 100644 index a2f310494..000000000 --- a/src/doc/layers_range.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// Aseprite Document Library -// Copyright (c) 2001-2015 David Capello -// -// This file is released under the terms of the MIT license. -// Read LICENSE.txt for more information. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "doc/layers_range.h" - -#include "doc/cel.h" -#include "doc/layer.h" -#include "doc/sprite.h" - -namespace doc { - -LayersRange::LayersRange(const Sprite* sprite, - LayerIndex first, LayerIndex last) - : m_begin(sprite, first, last) - , m_end() -{ -} - -LayersRange::iterator::iterator() - : m_layer(nullptr) - , m_cur(-1) - , m_last(-1) -{ -} - -LayersRange::iterator::iterator(const Sprite* sprite, - LayerIndex first, LayerIndex last) - : m_layer(nullptr) - , m_cur(first) - , m_last(last) -{ - m_layer = sprite->layer(first); -} - -LayersRange::iterator& LayersRange::iterator::operator++() -{ - if (!m_layer) - return *this; - - ++m_cur; - if (m_cur > m_last) - m_layer = nullptr; - else - m_layer = m_layer->getNext(); - - return *this; -} - -} // namespace doc diff --git a/src/doc/layers_range.h b/src/doc/layers_range.h deleted file mode 100644 index 9f67cb0b8..000000000 --- a/src/doc/layers_range.h +++ /dev/null @@ -1,55 +0,0 @@ -// Aseprite Document Library -// Copyright (c) 2001-2016 David Capello -// -// This file is released under the terms of the MIT license. -// Read LICENSE.txt for more information. - -#ifndef DOC_LAYERS_RANGE_H_INCLUDED -#define DOC_LAYERS_RANGE_H_INCLUDED -#pragma once - -#include "doc/layer_index.h" -#include "doc/object_id.h" - -namespace doc { - class Layer; - class Sprite; - - class LayersRange { - public: - LayersRange(const Sprite* sprite, LayerIndex first, LayerIndex last); - - class iterator { - public: - iterator(); - iterator(const Sprite* sprite, LayerIndex first, LayerIndex last); - - bool operator==(const iterator& other) const { - return m_layer == other.m_layer; - } - - bool operator!=(const iterator& other) const { - return !operator==(other); - } - - Layer* operator*() const { - return m_layer; - } - - iterator& operator++(); - - private: - Layer* m_layer; - LayerIndex m_cur, m_last; - }; - - iterator begin() { return m_begin; } - iterator end() { return m_end; } - - private: - iterator m_begin, m_end; - }; - -} // namespace doc - -#endif diff --git a/src/doc/sprite.cpp b/src/doc/sprite.cpp index 77a8ac196..0d58a79f8 100644 --- a/src/doc/sprite.cpp +++ b/src/doc/sprite.cpp @@ -19,7 +19,6 @@ #include "doc/frame_tag.h" #include "doc/image_impl.h" #include "doc/layer.h" -#include "doc/layers_range.h" #include "doc/palette.h" #include "doc/primitives.h" #include "doc/remap.h" @@ -541,9 +540,25 @@ void Sprite::pickCels(int x, int y, frame_t frame, int opacityThreshold, CelList ////////////////////////////////////////////////////////////////////// // Iterators -LayersRange Sprite::layers() const +LayerList Sprite::allLayers() const { - return LayersRange(this, LayerIndex(0), LayerIndex(countLayers()-1)); + LayerList list; + m_root->allLayers(list); + return list; +} + +LayerList Sprite::allVisibleLayers() const +{ + LayerList list; + m_root->allVisibleLayers(list); + return list; +} + +LayerList Sprite::allBrowsableLayers() const +{ + LayerList list; + m_root->allBrowsableLayers(list); + return list; } CelsRange Sprite::cels() const diff --git a/src/doc/sprite.h b/src/doc/sprite.h index dc0d6dad4..bb5b8efd3 100644 --- a/src/doc/sprite.h +++ b/src/doc/sprite.h @@ -33,7 +33,6 @@ namespace doc { class Layer; class LayerGroup; class LayerImage; - class LayersRange; class Mask; class Palette; class Remap; @@ -155,7 +154,10 @@ namespace doc { //////////////////////////////////////// // Iterators - LayersRange layers() const; + LayerList allLayers() const; + LayerList allVisibleLayers() const; + LayerList allBrowsableLayers() const; + CelsRange cels() const; CelsRange cels(frame_t frame) const; CelsRange uniqueCels() const; diff --git a/src/doc/sprite_tests.cpp b/src/doc/sprite_tests.cpp index 0712a20b3..e741ccf97 100644 --- a/src/doc/sprite_tests.cpp +++ b/src/doc/sprite_tests.cpp @@ -18,6 +18,68 @@ using namespace doc; +TEST(Sprite, Layers) +{ + Sprite* spr = new Sprite(IMAGE_RGB, 32, 32, 256); + + LayerImage* lay1 = new LayerImage(spr); + LayerImage* lay2 = new LayerImage(spr); + LayerImage* lay3 = new LayerImage(spr); + LayerImage* lay4 = new LayerImage(spr); + LayerImage* lay5 = new LayerImage(spr); + LayerImage* lay6 = new LayerImage(spr); + LayerImage* lay7 = new LayerImage(spr); + LayerGroup* grp1 = new LayerGroup(spr); + LayerGroup* grp2 = new LayerGroup(spr); + LayerGroup* grp3 = new LayerGroup(spr); + + grp1->setVisible(false); + lay5->setVisible(false); + grp2->setCollapsed(true); + + ;; grp2->addLayer(lay5); + ;;;; grp3->addLayer(lay7); + ;;;; grp3->addLayer(lay6); + ;; grp2->addLayer(grp3); + spr->root()->addLayer(grp2); + spr->root()->addLayer(lay2); + ;; grp1->addLayer(lay4); + ;; grp1->addLayer(lay3); + spr->root()->addLayer(grp1); + spr->root()->addLayer(lay1); + + auto all = spr->allLayers(); + ASSERT_EQ(10, all.size()); + EXPECT_EQ(lay5, all[0]); + EXPECT_EQ(lay7, all[1]); + EXPECT_EQ(lay6, all[2]); + EXPECT_EQ(grp3, all[3]); + EXPECT_EQ(grp2, all[4]); + EXPECT_EQ(lay2, all[5]); + EXPECT_EQ(lay4, all[6]); + EXPECT_EQ(lay3, all[7]); + EXPECT_EQ(grp1, all[8]); + EXPECT_EQ(lay1, all[9]); + + auto vis = spr->allVisibleLayers(); + ASSERT_EQ(6, vis.size()); + EXPECT_EQ(lay7, vis[0]); + EXPECT_EQ(lay6, vis[1]); + EXPECT_EQ(grp3, vis[2]); + EXPECT_EQ(grp2, vis[3]); + EXPECT_EQ(lay2, vis[4]); + EXPECT_EQ(lay1, vis[5]); + + auto bro = spr->allBrowsableLayers(); + ASSERT_EQ(6, bro.size()); + EXPECT_EQ(grp2, bro[0]); + EXPECT_EQ(lay2, bro[1]); + EXPECT_EQ(lay4, bro[2]); + EXPECT_EQ(lay3, bro[3]); + EXPECT_EQ(grp1, bro[4]); + EXPECT_EQ(lay1, bro[5]); +} + // frames // 0 1 2 // root