Add --ignore-layer CLI option (fix #1264)

This commit is contained in:
David Capello 2016-09-23 10:46:31 -03:00
parent 1cab8c3de4
commit b84d0d843e
6 changed files with 79 additions and 30 deletions

View File

@ -42,8 +42,9 @@ AppOptions::AppOptions(int argc, const char* argv[])
, m_sheetPack(m_po.add("sheet-pack").description("Same as --sheet-type packed"))
, m_splitLayers(m_po.add("split-layers").description("Save each visible layer of sprites\nas separated images in the sheet\n"))
, m_splitTags(m_po.add("split-tags").description("Save each tag as a separated file"))
, m_layer(m_po.add("layer").alias("import-layer").requiresValue("<name>").description("Include just the given layer in the sheet"))
, m_layer(m_po.add("layer").alias("import-layer").requiresValue("<name>").description("Include just the given layer in the sheet\nor save as operation"))
, m_allLayers(m_po.add("all-layers").description("Make all layers visible\nBy default hidden layers will be ignored"))
, m_ignoreLayer(m_po.add("ignore-layer").requiresValue("<name>").description("Exclude the given layer in the sheet\nor save as operation"))
, m_frameTag(m_po.add("frame-tag").requiresValue("<name>").description("Include tagged frames in the sheet"))
, m_frameRange(m_po.add("frame-range").requiresValue("from,to").description("Only export frames in the [from,to] range"))
, m_ignoreEmpty(m_po.add("ignore-empty").description("Do not export empty frames/cels"))

View File

@ -60,6 +60,7 @@ public:
const Option& splitTags() const { return m_splitTags; }
const Option& layer() const { return m_layer; }
const Option& allLayers() const { return m_allLayers; }
const Option& ignoreLayer() const { return m_ignoreLayer; }
const Option& frameTag() const { return m_frameTag; }
const Option& frameRange() const { return m_frameRange; }
const Option& ignoreEmpty() const { return m_ignoreEmpty; }
@ -103,6 +104,7 @@ private:
Option& m_splitTags;
Option& m_layer;
Option& m_allLayers;
Option& m_ignoreLayer;
Option& m_frameTag;
Option& m_frameRange;
Option& m_ignoreEmpty;

View File

@ -24,7 +24,8 @@ namespace app {
std::string filename;
std::string filenameFormat;
std::string frameTag;
std::vector<std::string> importLayers;
std::vector<std::string> includeLayers;
std::vector<std::string> excludeLayers;
doc::frame_t fromFrame, toFrame;
bool splitLayers;
bool splitTags;
@ -45,6 +46,11 @@ namespace app {
return (fromFrame >= 0 && toFrame >= 0);
}
bool hasLayersFilter() const {
return (!includeLayers.empty() ||
!excludeLayers.empty());
}
FileOpROI roi() const;
};

View File

@ -36,7 +36,7 @@ namespace app {
namespace {
std::string get_layer_path(Layer* layer)
std::string get_layer_path(const Layer* layer)
{
std::string path;
for (; layer != layer->sprite()->root(); layer=layer->parent()) {
@ -47,7 +47,9 @@ std::string get_layer_path(Layer* layer)
return path;
}
bool match_path(const std::string& filter, const std::string& layer_path)
bool match_path(const std::string& filter,
const std::string& layer_path,
const bool exclude)
{
if (filter == layer_path)
return true;
@ -61,21 +63,45 @@ bool match_path(const std::string& filter, const std::string& layer_path)
return false;
}
// Exclude group itself when all children are excluded. This special
// case is only for exclusion because if we leave the group
// selected, the propagation of the selection will include all
// visible children too (see SelectedLayers::propagateSelection()).
if (exclude &&
a.size() > 1 &&
a.size() == b.size()+1 &&
a[a.size()-1] == "*")
return true;
return (a.size() <= b.size());
}
bool filter_layer(const Layer* layer,
const std::string& layer_path,
const std::vector<std::string>& filters,
const bool result)
{
if (filters.empty())
return true;
for (const auto& filter : filters) {
if (layer->name() == filter ||
match_path(filter, layer_path, !result))
return result;
}
return !result;
}
void filter_layers(const LayerList& layers,
const std::vector<std::string>& filters,
const CliOpenFile& cof,
SelectedLayers& filteredLayers)
{
for (const auto& filter : filters) {
bool filterWithGroup = (filter.find('/') != std::string::npos);
for (Layer* layer : layers) {
auto layer_path = get_layer_path(layer);
for (Layer* layer : layers) {
if (layer->name() == filter ||
(filterWithGroup && match_path(filter, get_layer_path(layer))))
filteredLayers.insert(layer);
}
if (filter_layer(layer, layer_path, cof.includeLayers, true) &&
filter_layer(layer, layer_path, cof.excludeLayers, false))
filteredLayers.insert(layer);
}
}
@ -174,7 +200,11 @@ void CliProcessor::process()
}
// --layer <layer-name>
else if (opt == &m_options.layer()) {
cof.importLayers.push_back(value.value());
cof.includeLayers.push_back(value.value());
}
// --ignore-layer <layer-name>
else if (opt == &m_options.ignoreLayer()) {
cof.excludeLayers.push_back(value.value());
}
// --all-layers
else if (opt == &m_options.allLayers()) {
@ -418,9 +448,9 @@ bool CliProcessor::openFile(CliOpenFile& cof)
}
}
if (!cof.importLayers.empty()) {
if (cof.hasLayersFilter()) {
SelectedLayers filteredLayers;
filter_layers(doc->sprite()->allLayers(), cof.importLayers, filteredLayers);
filter_layers(doc->sprite()->allLayers(), cof, filteredLayers);
if (cof.splitLayers) {
for (Layer* layer : filteredLayers) {
@ -499,8 +529,8 @@ void CliProcessor::saveFile(const CliOpenFile& cof)
}
else {
// Filter layers
if (!cof.importLayers.empty())
filter_layers(allLayers, cof.importLayers, filteredLayers);
if (cof.hasLayersFilter())
filter_layers(allLayers, cof, filteredLayers);
// All visible layers
layers.push_back(nullptr);
@ -575,7 +605,7 @@ void CliProcessor::saveFile(const CliOpenFile& cof)
else if (layer->parent() != layer->sprite()->root())
fnInfo.groupName(layer->parent()->name());
itemCof.importLayers.push_back(layer->name());
itemCof.includeLayers.push_back(layer->name());
}
if (frameTag) {
fnInfo

View File

@ -69,12 +69,7 @@ void PreviewCliDelegate::afterOpenFile(const CliOpenFile& cof)
if (cof.allLayers)
std::cout << " - Make all layers visible\n";
if (!cof.importLayers.empty()) {
std::cout << " - Filter layers:";
for (const auto& filter : cof.importLayers)
std::cout << ' ' << filter;
std::cout << "\n";
}
showLayersFilter(cof);
}
void PreviewCliDelegate::saveFile(const CliOpenFile& cof)
@ -101,12 +96,7 @@ void PreviewCliDelegate::saveFile(const CliOpenFile& cof)
<< cof.document->sprite()->width() << "x"
<< cof.document->sprite()->height() << "\n";
if (!cof.importLayers.empty()) {
std::cout << " - Filter layers:";
for (const auto& filter : cof.importLayers)
std::cout << ' ' << filter;
std::cout << "\n";
}
showLayersFilter(cof);
if (cof.hasFrameTag()) {
std::cout << " - Frame tag: '" << cof.frameTag << "'\n";
@ -205,4 +195,21 @@ void PreviewCliDelegate::execScript(const std::string& filename)
std::cout << "- Run script: '" << filename << "'\n";
}
void PreviewCliDelegate::showLayersFilter(const CliOpenFile& cof)
{
if (!cof.includeLayers.empty()) {
std::cout << " - Include layers:";
for (const auto& filter : cof.includeLayers)
std::cout << ' ' << filter;
std::cout << "\n";
}
if (!cof.excludeLayers.empty()) {
std::cout << " - Exclude layers:";
for (const auto& filter : cof.excludeLayers)
std::cout << ' ' << filter;
std::cout << "\n";
}
}
} // namespace app

View File

@ -26,6 +26,9 @@ namespace app {
const std::string& filename) override;
void exportFiles(DocumentExporter& exporter) override;
void execScript(const std::string& filename) override;
private:
void showLayersFilter(const CliOpenFile& cof);
};
} // namespace app