mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-23 00:40:04 +00:00
Fix export of groups/layers via CLI
We have to propagate show/hide layers/groups visibility properly to export them correctly. We use the same code that in the "Export Sprite Sheet" for this (a new RestoreVisibleLayers class is separated for this).
This commit is contained in:
parent
682e9b8307
commit
f4b5340dfb
@ -327,6 +327,7 @@ add_library(app-lib
|
||||
res/palettes_loader_delegate.cpp
|
||||
res/resources_loader.cpp
|
||||
resource_finder.cpp
|
||||
restore_visible_layers.cpp
|
||||
script/app_object.cpp
|
||||
script/app_scripting.cpp
|
||||
script/console_object.cpp
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "app/document_undo.h"
|
||||
#include "app/file/file.h"
|
||||
#include "app/filename_formatter.h"
|
||||
#include "app/restore_visible_layers.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "base/convert_to.h"
|
||||
#include "base/path.h"
|
||||
@ -29,6 +30,7 @@
|
||||
#include "doc/frame_tags.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/selected_frames.h"
|
||||
#include "doc/selected_layers.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
@ -418,13 +420,6 @@ void CliProcessor::saveFile(const CliOpenFile& cof)
|
||||
ctx->executeCommand(cropCommand, cropParams);
|
||||
}
|
||||
|
||||
// Store in "visibility" the original "visible" state of every layer.
|
||||
LayerList allLayers = doc->sprite()->allLayers();
|
||||
std::vector<bool> visibility(allLayers.size());
|
||||
int i = 0;
|
||||
for (doc::Layer* layer : allLayers)
|
||||
visibility[i++] = layer->isVisible();
|
||||
|
||||
std::string fn = cof.filename;
|
||||
std::string filenameFormat = cof.filenameFormat;
|
||||
if (filenameFormat.empty()) { // Default format
|
||||
@ -437,7 +432,9 @@ void CliProcessor::saveFile(const CliOpenFile& cof)
|
||||
cof.splitTags); // Has frame tag
|
||||
}
|
||||
|
||||
std::vector<doc::Layer*> layers;
|
||||
SelectedLayers filteredLayers;
|
||||
LayerList allLayers = doc->sprite()->allLayers();
|
||||
LayerList layers;
|
||||
// --save-as with --split-layers or --split-tags
|
||||
if (cof.splitLayers) {
|
||||
for (doc::Layer* layer : doc->sprite()->allVisibleLayers())
|
||||
@ -447,17 +444,13 @@ void CliProcessor::saveFile(const CliOpenFile& cof)
|
||||
// Show only one layer
|
||||
if (!cof.importLayer.empty()) {
|
||||
for (Layer* layer : allLayers) {
|
||||
if (layer->name() == cof.importLayer) {
|
||||
layer->setVisible(true);
|
||||
layers.push_back(layer);
|
||||
}
|
||||
else
|
||||
layer->setVisible(false);
|
||||
if (layer->name() == cof.importLayer)
|
||||
filteredLayers.insert(layer);
|
||||
}
|
||||
}
|
||||
|
||||
// All visible layers
|
||||
else
|
||||
layers.push_back(nullptr);
|
||||
layers.push_back(nullptr);
|
||||
}
|
||||
|
||||
std::vector<doc::FrameTag*> frameTags;
|
||||
@ -487,19 +480,21 @@ void CliProcessor::saveFile(const CliOpenFile& cof)
|
||||
|
||||
for (doc::FrameTag* frameTag : frameTags) {
|
||||
// For each layer, hide other ones and save the sprite.
|
||||
i = 0;
|
||||
for (doc::Layer* layer : layers) {
|
||||
RestoreVisibleLayers layersVisibility;
|
||||
|
||||
if (cof.splitLayers) {
|
||||
ASSERT(layer);
|
||||
|
||||
// If the user doesn't want all layers and this one is hidden.
|
||||
if (!visibility[i++])
|
||||
if (!layer->isVisible())
|
||||
continue; // Just ignore this layer.
|
||||
|
||||
// Make this layer ("show") the only one visible.
|
||||
for (doc::Layer* hide : allLayers)
|
||||
hide->setVisible(hide == layer);
|
||||
layersVisibility.showLayer(layer);
|
||||
}
|
||||
else if (!filteredLayers.empty())
|
||||
layersVisibility.showSelectedLayers(doc->sprite(), filteredLayers);
|
||||
|
||||
if (layer) {
|
||||
if ((layerInFormat && layer->isGroup()) ||
|
||||
@ -548,11 +543,6 @@ void CliProcessor::saveFile(const CliOpenFile& cof)
|
||||
}
|
||||
}
|
||||
|
||||
// Restore layer visibility
|
||||
i = 0;
|
||||
for (Layer* layer : allLayers)
|
||||
layer->setVisible(visibility[i++]);
|
||||
|
||||
// Undo crop
|
||||
if (!cof.crop.isEmpty()) {
|
||||
ctx->executeCommand(undoCommand);
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "base/string.h"
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/context.h"
|
||||
@ -19,6 +18,7 @@
|
||||
#include "app/file_selector.h"
|
||||
#include "app/modules/editors.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/restore_visible_layers.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui/timeline.h"
|
||||
@ -26,6 +26,7 @@
|
||||
#include "base/convert_to.h"
|
||||
#include "base/fs.h"
|
||||
#include "base/path.h"
|
||||
#include "base/string.h"
|
||||
#include "doc/frame_tag.h"
|
||||
#include "doc/layer.h"
|
||||
|
||||
@ -188,50 +189,6 @@ namespace {
|
||||
return frameTag;
|
||||
}
|
||||
|
||||
class RestoreSelectedLayers {
|
||||
public:
|
||||
~RestoreSelectedLayers() {
|
||||
for (auto item : m_restore)
|
||||
item.first->setVisible(item.second);
|
||||
}
|
||||
|
||||
void showSelectedLayers(Sprite* sprite) {
|
||||
// TODO the range of selected frames should be in doc::Site.
|
||||
auto range = App::instance()->timeline()->range();
|
||||
if (!range.enabled()) {
|
||||
if (current_editor) {
|
||||
ASSERT(current_editor->sprite() == sprite);
|
||||
range.clearRange();
|
||||
range.startRange(current_editor->layer(),
|
||||
current_editor->frame(), DocumentRange::kCels);
|
||||
range.endRange(current_editor->layer(),
|
||||
current_editor->frame());
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
SelectedLayers selLayers = range.selectedLayers();
|
||||
selLayers.propagateSelection();
|
||||
setLayerVisiblity(sprite->root(), selLayers);
|
||||
}
|
||||
|
||||
private:
|
||||
void setLayerVisiblity(LayerGroup* group, const SelectedLayers& selLayers) {
|
||||
for (Layer* layer : group->layers()) {
|
||||
bool selected = (selLayers.contains(layer));
|
||||
if (selected != layer->isVisible()) {
|
||||
m_restore.push_back(std::make_pair(layer, layer->isVisible()));
|
||||
layer->setVisible(selected);
|
||||
}
|
||||
if (selected && layer->isGroup())
|
||||
setLayerVisiblity(static_cast<LayerGroup*>(layer), selLayers);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::pair<Layer*, bool> > m_restore;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class ExportSpriteSheetWindow : public app::gen::ExportSpriteSheet {
|
||||
@ -822,9 +779,14 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
|
||||
// If the user choose to render selected layers only, we can
|
||||
// temporaly make them visible and hide the other ones.
|
||||
Layer* layer = nullptr;
|
||||
RestoreSelectedLayers layersVisibility;
|
||||
RestoreVisibleLayers layersVisibility;
|
||||
if (layerName == kSelectedLayers) {
|
||||
layersVisibility.showSelectedLayers(sprite);
|
||||
// TODO the range of selected frames should be in doc::Site.
|
||||
auto range = App::instance()->timeline()->range();
|
||||
if (range.enabled())
|
||||
layersVisibility.showSelectedLayers(sprite, range.selectedLayers());
|
||||
else if (current_editor)
|
||||
layersVisibility.showLayer(current_editor->layer());
|
||||
}
|
||||
else {
|
||||
// TODO add a getLayerByName
|
||||
|
54
src/app/restore_visible_layers.cpp
Normal file
54
src/app/restore_visible_layers.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/restore_visible_layers.h"
|
||||
|
||||
#include "doc/layer.h"
|
||||
#include "doc/selected_layers.h"
|
||||
#include "doc/sprite.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace doc;
|
||||
|
||||
RestoreVisibleLayers::~RestoreVisibleLayers()
|
||||
{
|
||||
for (auto item : m_restore)
|
||||
item.first->setVisible(item.second);
|
||||
}
|
||||
|
||||
void RestoreVisibleLayers::showLayer(Layer* layer)
|
||||
{
|
||||
SelectedLayers selLayers;
|
||||
selLayers.insert(layer);
|
||||
showSelectedLayers(layer->sprite(), selLayers);
|
||||
}
|
||||
|
||||
void RestoreVisibleLayers::showSelectedLayers(Sprite* sprite, const SelectedLayers& inSelLayers)
|
||||
{
|
||||
SelectedLayers selLayers = inSelLayers;
|
||||
selLayers.propagateSelection();
|
||||
setLayerVisiblity(sprite->root(), selLayers);
|
||||
}
|
||||
|
||||
void RestoreVisibleLayers::setLayerVisiblity(LayerGroup* group, const SelectedLayers& selLayers)
|
||||
{
|
||||
for (Layer* layer : group->layers()) {
|
||||
bool selected = (selLayers.contains(layer));
|
||||
if (selected != layer->isVisible()) {
|
||||
m_restore.push_back(std::make_pair(layer, layer->isVisible()));
|
||||
layer->setVisible(selected);
|
||||
}
|
||||
if (selected && layer->isGroup())
|
||||
setLayerVisiblity(static_cast<LayerGroup*>(layer), selLayers);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace app
|
37
src/app/restore_visible_layers.h
Normal file
37
src/app/restore_visible_layers.h
Normal file
@ -0,0 +1,37 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifndef APP_RESTORE_VISIBLE_LAYERS_H_INCLUDED
|
||||
#define APP_RESTORE_VISIBLE_LAYERS_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace doc {
|
||||
class Layer;
|
||||
class LayerGroup;
|
||||
class SelectedLayers;
|
||||
class Sprite;
|
||||
}
|
||||
|
||||
namespace app {
|
||||
|
||||
class RestoreVisibleLayers {
|
||||
public:
|
||||
~RestoreVisibleLayers();
|
||||
|
||||
void showLayer(doc::Layer* layer);
|
||||
void showSelectedLayers(doc::Sprite* sprite, const doc::SelectedLayers& selLayers);
|
||||
|
||||
private:
|
||||
void setLayerVisiblity(doc::LayerGroup* group, const doc::SelectedLayers& selLayers);
|
||||
|
||||
std::vector<std::pair<doc::Layer*, bool> > m_restore;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user