Fix CelsRange to iterate over layer groups

This commit is contained in:
David Capello 2016-06-14 12:57:13 -03:00
parent 3931341dee
commit 47eeb4f564
3 changed files with 79 additions and 27 deletions

View File

@ -1,5 +1,5 @@
// Aseprite Document Library
// Copyright (c) 2001-2015 David Capello
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -37,14 +37,18 @@ CelsRange::iterator::iterator(const Sprite* sprite, frame_t first, frame_t last,
// Get first cel
Layer* layer = sprite->layer(sprite->firstLayer());
while (layer && !m_cel) {
for (frame_t f=first; f<=last; ++f) {
m_cel = layer->cel(f);
if (m_cel)
break;
m_cel = nullptr;
if (layer->isImage()) {
for (frame_t f=first; f<=last; ++f) {
m_cel = layer->cel(f);
if (m_cel)
break;
}
}
layer = layer->getNext();
if (!m_cel)
nextLayer(layer);
}
if (m_cel && flags == CelsRange::UNIQUE)
m_visited.insert(m_cel->data()->id());
}
@ -60,25 +64,43 @@ CelsRange::iterator& CelsRange::iterator::operator++()
m_cel = nullptr;
while (layer && !m_cel) {
for (frame_t f=first; f<=m_last; ++f) {
m_cel = layer->cel(f);
if (m_cel) {
if (m_flags == CelsRange::UNIQUE) {
if (m_visited.find(m_cel->data()->id()) == m_visited.end()) {
m_visited.insert(m_cel->data()->id());
break;
if (layer->isImage()) {
for (frame_t f=first; f<=m_last; ++f) {
m_cel = layer->cel(f);
if (m_cel) {
if (m_flags == CelsRange::UNIQUE) {
if (m_visited.find(m_cel->data()->id()) == m_visited.end()) {
m_visited.insert(m_cel->data()->id());
break;
}
else
m_cel = nullptr;
}
else
m_cel = nullptr;
break;
}
else
break;
}
}
layer = layer->getNext();
first = m_first;
if (!m_cel) {
nextLayer(layer);
first = m_first;
}
}
return *this;
}
void CelsRange::iterator::nextLayer(Layer*& layer)
{
// Go to children
if (layer->isGroup()) {
layer = static_cast<LayerGroup*>(layer)->firstLayer();
}
// Go to next layer in the parent
else if (!layer->getNext())
layer = layer->parent()->getNext();
else
layer = layer->getNext();
}
} // namespace doc

View File

@ -1,5 +1,5 @@
// Aseprite Document Library
// Copyright (c) 2001-2015 David Capello
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -15,6 +15,7 @@
namespace doc {
class Cel;
class Layer;
class Sprite;
class CelsRange {
@ -47,6 +48,8 @@ namespace doc {
iterator& operator++();
private:
void nextLayer(Layer*& layer);
Cel* m_cel;
frame_t m_first, m_last;
Flags m_flags;

View File

@ -18,8 +18,13 @@
using namespace doc;
// lay1 = A _ B
// lay2 = C D E
// frames
// 0 1 2
// root
// - lay1: A~~~B
// - lay2: C D~E
// - grp1:
// - lay3: F G~H
TEST(Sprite, CelsRange)
{
Sprite* spr = new Sprite(IMAGE_RGB, 32, 32, 256);
@ -27,8 +32,12 @@ TEST(Sprite, CelsRange)
LayerImage* lay1 = new LayerImage(spr);
LayerImage* lay2 = new LayerImage(spr);
LayerGroup* grp1 = new LayerGroup(spr);
LayerImage* lay3 = new LayerImage(spr);
spr->root()->addLayer(lay1);
spr->root()->addLayer(lay2);
spr->root()->addLayer(grp1);
grp1->addLayer(lay3);
ImageRef imgA(Image::create(IMAGE_RGB, 32, 32));
Cel* celA = new Cel(frame_t(0), imgA);
@ -47,6 +56,16 @@ TEST(Sprite, CelsRange)
lay2->addCel(celD);
lay2->addCel(celE);
ImageRef imgF(Image::create(IMAGE_RGB, 32, 32));
ImageRef imgG(Image::create(IMAGE_RGB, 32, 32));
Cel* celF = new Cel(frame_t(0), imgF);
Cel* celG = new Cel(frame_t(1), imgG);
Cel* celH = Cel::createLink(celG);
celH->setFrame(frame_t(2));
lay3->addCel(celF);
lay3->addCel(celG);
lay3->addCel(celH);
int i = 0;
for (Cel* cel : spr->cels()) {
switch (i) {
@ -55,10 +74,13 @@ TEST(Sprite, CelsRange)
case 2: EXPECT_EQ(cel, celC); break;
case 3: EXPECT_EQ(cel, celD); break;
case 4: EXPECT_EQ(cel, celE); break;
case 5: EXPECT_EQ(cel, celF); break;
case 6: EXPECT_EQ(cel, celG); break;
case 7: EXPECT_EQ(cel, celH); break;
}
++i;
}
EXPECT_EQ(5, i);
EXPECT_EQ(8, i);
i = 0;
for (Cel* cel : spr->uniqueCels()) {
@ -66,39 +88,44 @@ TEST(Sprite, CelsRange)
case 0: EXPECT_EQ(cel, celA); break;
case 1: EXPECT_EQ(cel, celC); break;
case 2: EXPECT_EQ(cel, celD); break;
case 3: EXPECT_EQ(cel, celF); break;
case 4: EXPECT_EQ(cel, celG); break;
}
++i;
}
EXPECT_EQ(3, i);
EXPECT_EQ(5, i);
i = 0;
for (Cel* cel : spr->cels(frame_t(0))) {
switch (i) {
case 0: EXPECT_EQ(cel, celA); break;
case 1: EXPECT_EQ(cel, celC); break;
case 2: EXPECT_EQ(cel, celF); break;
}
++i;
}
EXPECT_EQ(2, i);
EXPECT_EQ(3, i);
i = 0;
for (Cel* cel : spr->cels(frame_t(1))) {
switch (i) {
case 0: EXPECT_EQ(cel, celD); break;
case 1: EXPECT_EQ(cel, celG); break;
}
++i;
}
EXPECT_EQ(1, i);
EXPECT_EQ(2, i);
i = 0;
for (Cel* cel : spr->cels(frame_t(2))) {
switch (i) {
case 0: EXPECT_EQ(cel, celB); break;
case 1: EXPECT_EQ(cel, celE); break;
case 2: EXPECT_EQ(cel, celH); break;
}
++i;
}
EXPECT_EQ(2, i);
EXPECT_EQ(3, i);
}
int main(int argc, char** argv)