Add --all-layers option to export hidden layers (fix #805)

Now Aseprite will export only visible layers by default.

- Added doc::LayersRange to simplify layer iteration
This commit is contained in:
David Capello 2015-11-05 13:01:53 -03:00
parent d05dc56503
commit e525fc10a6
8 changed files with 175 additions and 23 deletions

View File

@ -61,6 +61,7 @@
#include "doc/frame_tag.h"
#include "doc/image.h"
#include "doc/layer.h"
#include "doc/layers_range.h"
#include "doc/palette.h"
#include "doc/site.h"
#include "doc/sprite.h"
@ -223,6 +224,7 @@ void App::initialize(const AppOptions& options)
Console console;
bool splitLayers = false;
bool splitLayersSaveAs = false;
bool allLayers = false;
bool listLayers = false;
bool listTags = false;
std::string importLayer;
@ -283,6 +285,10 @@ void App::initialize(const AppOptions& options)
importLayer = value.value();
importLayerSaveAs = value.value();
}
// --all-layers
else if (opt == &options.allLayers()) {
allLayers = true;
}
// --frame-tag <tag-name>
else if (opt == &options.frameTag()) {
frameTagName = value.value();
@ -344,10 +350,8 @@ void App::initialize(const AppOptions& options)
Command* cropCommand = CommandsModule::instance()->getCommandByName(CommandId::CropSprite);
Command* undoCommand = CommandsModule::instance()->getCommandByName(CommandId::Undo);
// --save-as with --split-layers
if (splitLayersSaveAs) {
std::vector<Layer*> layers;
doc->sprite()->getLayersList(layers);
std::string fn, fmt;
if (format.empty()) {
if (doc->sprite()->totalFrames() > frame_t(1))
@ -356,9 +360,21 @@ void App::initialize(const AppOptions& options)
format = "{path}/{title} ({layer}).{extension}";
}
// Store in "visibility" the original "visible" state of every layer.
std::vector<bool> visibility(doc->sprite()->countLayers());
int i = 0;
for (Layer* layer : doc->sprite()->layers())
visibility[i++] = layer->isVisible();
// For each layer, hide other ones and save the sprite.
for (Layer* show : layers) {
for (Layer* hide : layers)
i = 0;
for (Layer* show : doc->sprite()->layers()) {
// If the user doesn't want all layers and this one is hidden.
if (!visibility[i++])
continue; // Just ignore this layer.
// Make this layer ("show") the only one visible.
for (Layer* hide : doc->sprite()->layers())
hide->setVisible(hide == show);
FilenameInfo fnInfo;
@ -393,14 +409,16 @@ void App::initialize(const AppOptions& options)
doc->undoHistory()->clearRedo();
}
}
// Restore layer visibility
i = 0;
for (Layer* layer : doc->sprite()->layers())
layer->setVisible(visibility[i++]);
}
else {
std::vector<Layer*> layers;
doc->sprite()->getLayersList(layers);
// Show only one layer
if (!importLayerSaveAs.empty()) {
for (Layer* layer : layers)
for (Layer* layer : doc->sprite()->layers())
layer->setVisible(layer->name() == importLayerSaveAs);
}
@ -478,13 +496,20 @@ void App::initialize(const AppOptions& options)
// List layers and/or tags
if (doc) {
// Show all layers
if (allLayers) {
for (Layer* layer : doc->sprite()->layers())
layer->setVisible(true);
}
if (listLayers) {
listLayers = false;
std::vector<Layer*> layers;
doc->sprite()->getLayersList(layers);
for (Layer* layer : layers)
std::cout << layer->name() << "\n";
for (Layer* layer : doc->sprite()->layers()) {
if (layer->isVisible())
std::cout << layer->name() << "\n";
}
}
if (listTags) {
listTags = false;
for (FrameTag* tag : doc->sprite()->frameTags())
@ -497,11 +522,8 @@ void App::initialize(const AppOptions& options)
frameTag = doc->sprite()->frameTags().getByName(frameTagName);
if (!importLayer.empty()) {
std::vector<Layer*> layers;
doc->sprite()->getLayersList(layers);
Layer* foundLayer = NULL;
for (Layer* layer : layers) {
for (Layer* layer : doc->sprite()->layers()) {
if (layer->name() == importLayer) {
foundLayer = layer;
break;
@ -511,13 +533,14 @@ void App::initialize(const AppOptions& options)
m_exporter->addDocument(doc, foundLayer, frameTag);
}
else if (splitLayers) {
std::vector<Layer*> layers;
doc->sprite()->getLayersList(layers);
for (auto layer : layers)
m_exporter->addDocument(doc, layer, frameTag);
for (auto layer : doc->sprite()->layers()) {
if (layer->isVisible())
m_exporter->addDocument(doc, layer, frameTag);
}
}
else
else {
m_exporter->addDocument(doc, nullptr, frameTag);
}
}
}

View File

@ -38,6 +38,7 @@ AppOptions::AppOptions(int argc, const char* argv[])
, m_sheetPack(m_po.add("sheet-pack").description("Use a packing algorithm to avoid waste of space\nin the texture"))
, m_splitLayers(m_po.add("split-layers").description("Import each layer of the next given sprite as\na separated image in the sheet"))
, m_layer(m_po.add("layer").alias("import-layer").requiresValue("<name>").description("Include just the given layer in the sheet"))
, m_allLayers(m_po.add("all-layers").description("Make all layers visible\nBy default hidden layers will be ignored"))
, m_frameTag(m_po.add("frame-tag").requiresValue("<name>").description("Include tagged frames in the sheet"))
, m_ignoreEmpty(m_po.add("ignore-empty").description("Do not export empty frames/cels"))
, m_borderPadding(m_po.add("border-padding").requiresValue("<value>").description("Add padding on the texture borders"))

View File

@ -46,6 +46,7 @@ public:
const Option& sheetPack() const { return m_sheetPack; }
const Option& splitLayers() const { return m_splitLayers; }
const Option& layer() const { return m_layer; }
const Option& allLayers() const { return m_allLayers; }
const Option& frameTag() const { return m_frameTag; }
const Option& ignoreEmpty() const { return m_ignoreEmpty; }
const Option& borderPadding() const { return m_borderPadding; }
@ -84,6 +85,7 @@ private:
Option& m_sheetPack;
Option& m_splitLayers;
Option& m_layer;
Option& m_allLayers;
Option& m_frameTag;
Option& m_ignoreEmpty;
Option& m_borderPadding;

View File

@ -37,6 +37,7 @@ add_library(doc-lib
layer.cpp
layer_index.cpp
layer_io.cpp
layers_range.cpp
mask.cpp
mask_boundaries.cpp
mask_io.cpp

56
src/doc/layers_range.cpp Normal file
View File

@ -0,0 +1,56 @@
// 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

58
src/doc/layers_range.h Normal file
View File

@ -0,0 +1,58 @@
// 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.
#ifndef DOC_LAYERS_RANGE_H_INCLUDED
#define DOC_LAYERS_RANGE_H_INCLUDED
#pragma once
#include "doc/layer_index.h"
#include "doc/object_id.h"
#include <set>
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;
std::set<ObjectId> m_visited;
};
iterator begin() { return m_begin; }
iterator end() { return m_end; }
private:
iterator m_begin, m_end;
};
} // namespace doc
#endif

View File

@ -18,6 +18,7 @@
#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"
@ -532,7 +533,12 @@ void Sprite::pickCels(int x, int y, frame_t frame, int opacityThreshold, CelList
}
//////////////////////////////////////////////////////////////////////
// CelsRange
// Iterators
LayersRange Sprite::layers() const
{
return LayersRange(this, LayerIndex(0), LayerIndex(countLayers()-1));
}
CelsRange Sprite::cels() const
{

View File

@ -31,6 +31,7 @@ namespace doc {
class Layer;
class LayerFolder;
class LayerImage;
class LayersRange;
class Mask;
class Palette;
class Remap;
@ -143,6 +144,10 @@ namespace doc {
void remapImages(frame_t frameFrom, frame_t frameTo, const Remap& remap);
void pickCels(int x, int y, frame_t frame, int opacityThreshold, CelList& cels) const;
////////////////////////////////////////
// Iterators
LayersRange layers() const;
CelsRange cels() const;
CelsRange cels(frame_t frame) const;
CelsRange uniqueCels() const;