mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-03 21:46:20 +00:00
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:
parent
d05dc56503
commit
e525fc10a6
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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"))
|
||||
|
@ -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;
|
||||
|
@ -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
56
src/doc/layers_range.cpp
Normal 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
58
src/doc/layers_range.h
Normal 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
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user