Add --list-slices CLI option

This commit is contained in:
David Capello 2017-03-16 10:35:26 -03:00
parent 9f76136876
commit 347ccfbb78
18 changed files with 117 additions and 23 deletions

View File

@ -332,6 +332,7 @@
<option id="frame_tag" type="std::string" />
<option id="list_layers" type="bool" default="true" />
<option id="list_frame_tags" type="bool" default="true" />
<option id="list_slices" type="bool" default="true" />
</section>
<section id="import_sprite_sheet">
<option id="type" type="app::SpriteSheetType" default="app::SpriteSheetType::Rows" />

View File

@ -96,6 +96,7 @@ json_data_array = Array
meta = Meta:
meta_layers = Layers
meta_frame_tags = Frame Tags
meta_slices = Slices
open_sprite_sheet = Open generated sprite sheet
export = &Export
cancel = &Cancel

View File

@ -1,5 +1,5 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<!-- Copyright (C) 2001-2017 by David Capello -->
<gui>
<window id="export_sprite_sheet" text="@.title">
<grid columns="4">
@ -56,6 +56,7 @@
<label text="@.meta" />
<check id="list_layers" text="@.meta_layers" />
<check id="list_tags" text="@.meta_frame_tags" />
<check id="list_slices" text="@.meta_slices" />
</hbox>
<check id="open_generated" text="@.open_sprite_sheet" cell_hspan="4" />

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -60,7 +60,8 @@ AppOptions::AppOptions(int argc, const char* argv[])
, m_script(m_po.add("script").requiresValue("<filename>").description("Execute a specific script"))
#endif
, m_listLayers(m_po.add("list-layers").description("List layers of the next given sprite\nor include layers in JSON data"))
, m_listTags(m_po.add("list-tags").description("List tags of the next given sprite sprite\nor include frame tags in JSON data"))
, m_listTags(m_po.add("list-tags").description("List tags of the next given sprite\nor include frame tags in JSON data"))
, m_listSlices(m_po.add("list-slices").description("List slices of the next given sprite\nor include slices in JSON data"))
, m_oneFrame(m_po.add("oneframe").description("Load just the first frame"))
, m_verbose(m_po.add("verbose").mnemonic('v').description("Explain what is being done"))
, m_debug(m_po.add("debug").description("Extreme verbose mode and\ncopy log to desktop"))

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -75,6 +75,7 @@ public:
#endif
const Option& listLayers() const { return m_listLayers; }
const Option& listTags() const { return m_listTags; }
const Option& listSlices() const { return m_listSlices; }
const Option& oneFrame() const { return m_oneFrame; }
bool hasExporterParams() const;
@ -124,6 +125,7 @@ private:
#endif
Option& m_listLayers;
Option& m_listTags;
Option& m_listSlices;
Option& m_oneFrame;
Option& m_verbose;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2016 David Capello
// Copyright (C) 2016-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -28,6 +28,7 @@ CliOpenFile::CliOpenFile()
allLayers = false;
listLayers = false;
listTags = false;
listSlices = false;
ignoreEmpty = false;
trim = false;
oneFrame = false;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2016 David Capello
// Copyright (C) 2016-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -32,6 +32,7 @@ namespace app {
bool allLayers;
bool listLayers;
bool listTags;
bool listSlices;
bool ignoreEmpty;
bool trim;
bool oneFrame;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -375,6 +375,12 @@ void CliProcessor::process()
if (m_exporter)
m_exporter->setListFrameTags(true);
}
// --list-slices
else if (opt == &m_options.listSlices()) {
cof.listSlices = true;
if (m_exporter)
m_exporter->setListSlices(true);
}
// --oneframe
else if (opt == &m_options.oneFrame()) {
cof.oneFrame = true;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2016 David Capello
// Copyright (C) 2016-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -23,6 +23,7 @@
#include "doc/frame_tag.h"
#include "doc/layer.h"
#include "doc/palette.h"
#include "doc/slice.h"
#include "doc/sprite.h"
#ifdef ENABLE_SCRIPTING
@ -65,6 +66,11 @@ void DefaultCliDelegate::afterOpenFile(const CliOpenFile& cof)
for (doc::FrameTag* tag : cof.document->sprite()->frameTags())
std::cout << tag->name() << "\n";
}
if (cof.listSlices) {
for (doc::Slice* slice : cof.document->sprite()->slices())
std::cout << slice->name() << "\n";
}
}
void DefaultCliDelegate::saveFile(const CliOpenFile& cof)

View File

@ -66,6 +66,9 @@ void PreviewCliDelegate::afterOpenFile(const CliOpenFile& cof)
if (cof.listTags)
std::cout << " - List tags\n";
if (cof.listSlices)
std::cout << " - List slices\n";
if (cof.oneFrame)
std::cout << " - One frame\n";

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -231,6 +231,7 @@ public:
dataFormat()->setSelectedItemIndex(int(m_docPref.spriteSheet.dataFormat()));
listLayers()->setSelected(m_docPref.spriteSheet.listLayers());
listTags()->setSelected(m_docPref.spriteSheet.listFrameTags());
listSlices()->setSelected(m_docPref.spriteSheet.listSlices());
updateDataFields();
std::string base = site.document()->filename();
@ -373,6 +374,10 @@ public:
return listTags()->isSelected();
}
bool listSlicesValue() const {
return listSlices()->isSelected();
}
private:
void onExport() {
@ -633,6 +638,7 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
docPref.spriteSheet.frameTag(window.frameTagValue());
docPref.spriteSheet.listLayers(window.listLayersValue());
docPref.spriteSheet.listFrameTags(window.listFrameTagsValue());
docPref.spriteSheet.listSlices(window.listSlicesValue());
// Default preferences for future sprites
DocumentPreferences& defPref(Preferences::instance().document(nullptr));

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -34,6 +34,7 @@
#include "doc/primitives.h"
#include "doc/selected_frames.h"
#include "doc/selected_layers.h"
#include "doc/slice.h"
#include "doc/sprite.h"
#include "gfx/packing_rects.h"
#include "gfx/size.h"
@ -403,6 +404,7 @@ DocumentExporter::DocumentExporter()
, m_trimCels(false)
, m_listFrameTags(false)
, m_listLayers(false)
, m_listSlices(false)
{
}
@ -889,6 +891,70 @@ void DocumentExporter::createDataFile(const Samples& samples, std::ostream& os,
os << "\n ]";
}
// meta.slices
if (m_listSlices) {
os << ",\n"
<< " \"slices\": [";
bool firstSlice = true;
for (auto& item : m_documents) {
Document* doc = item.doc;
Sprite* sprite = doc->sprite();
// TODO add possibility to export some slices
for (Slice* slice : sprite->slices()) {
if (firstSlice)
firstSlice = false;
else
os << ",";
os << "\n { \"name\": \"" << escape_for_json(slice->name()) << "\""
<< slice->userData();
// Keys
if (!slice->empty()) {
bool firstKey = true;
os << ", \"keys\": [";
for (const auto& key : *slice) {
if (firstKey)
firstKey = false;
else
os << ", ";
const SliceKey* sliceKey = key.value();
os << "{ \"frame\": " << key.frame() << ", "
<< "\"bounds\": {"
<< "\"x\": " << sliceKey->bounds().x << ", "
<< "\"y\": " << sliceKey->bounds().y << ", "
<< "\"w\": " << sliceKey->bounds().w << ", "
<< "\"h\": " << sliceKey->bounds().h << " }";
if (!sliceKey->center().isEmpty()) {
os << ", \"center\": {"
<< "\"x\": " << sliceKey->center().x << ", "
<< "\"y\": " << sliceKey->center().y << ", "
<< "\"w\": " << sliceKey->center().w << ", "
<< "\"h\": " << sliceKey->center().h << " }";
}
if (sliceKey->hasPivot()) {
os << ", \"pivot\": {"
<< "\"x\": " << sliceKey->pivot().x << ", "
<< "\"y\": " << sliceKey->pivot().y << " }";
}
os << " }";
}
os << "]";
}
os << " }";
}
}
os << "\n ]";
}
os << "\n }\n"
<< "}\n";
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -70,6 +70,7 @@ namespace app {
void setFilenameFormat(const std::string& format) { m_filenameFormat = format; }
void setListFrameTags(bool value) { m_listFrameTags = value; }
void setListLayers(bool value) { m_listLayers = value; }
void setListSlices(bool value) { m_listSlices = value; }
void addDocument(Document* document,
doc::FrameTag* tag,
@ -136,6 +137,7 @@ namespace app {
doc::ImageBufferPtr m_sampleRenderBuf;
bool m_listFrameTags;
bool m_listLayers;
bool m_listSlices;
// Displacement for each tag from/to frames in case we export
// them. It's used in case we trim frames outside tags and they

View File

@ -1760,12 +1760,8 @@ static void ase_file_write_slices_chunk(FILE* f, ASE_FrameHeader* frame_header,
int flags = 0;
for (auto key : range) {
if (key) {
if (!key->center().isEmpty()) {
flags |= ASE_SLICE_FLAG_HAS_CENTER_BOUNDS;
}
if (key->hasPivot()) {
flags |= ASE_SLICE_FLAG_HAS_PIVOT_POINT;
}
if (key->hasCenter()) flags |= ASE_SLICE_FLAG_HAS_CENTER_BOUNDS;
if (key->hasPivot()) flags |= ASE_SLICE_FLAG_HAS_PIVOT_POINT;
}
}
@ -1785,7 +1781,7 @@ static void ase_file_write_slices_chunk(FILE* f, ASE_FrameHeader* frame_header,
fputl(key ? key->bounds().h: 0, f);
if (flags & ASE_SLICE_FLAG_HAS_CENTER_BOUNDS) {
if (key && !key->center().isEmpty()) {
if (key && key->hasCenter()) {
fputl(key->center().x, f);
fputl(key->center().y, f);
fputl(key->center().w, f);
@ -1794,8 +1790,8 @@ static void ase_file_write_slices_chunk(FILE* f, ASE_FrameHeader* frame_header,
else {
fputl(0, f);
fputl(0, f);
fputl(key ? key->bounds().w: 0, f);
fputl(key ? key->bounds().h: 0, f);
fputl(0, f);
fputl(0, f);
}
}

View File

@ -49,7 +49,7 @@ void updateXmlPartFromSliceKey(const SliceKey* key, TiXmlElement* xmlPart)
{
xmlPart->SetAttribute("x", key->bounds().x);
xmlPart->SetAttribute("y", key->bounds().y);
if (key->center().isEmpty()) {
if (!key->hasCenter()) {
xmlPart->SetAttribute("w", key->bounds().w);
xmlPart->SetAttribute("h", key->bounds().h);
if (xmlPart->Attribute("w1")) xmlPart->RemoveAttribute("w1");

View File

@ -982,7 +982,7 @@ void Editor::drawSlices(ui::Graphics* g)
.offset(-bounds().origin());
// Center slices
if (!key->center().isEmpty()) {
if (key->hasCenter()) {
gfx::Rect in =
editorToScreen(gfx::Rect(key->center()).offset(key->bounds().origin()))
.offset(-bounds().origin());

View File

@ -42,7 +42,7 @@ SliceWindow::SliceWindow(const doc::Sprite* sprite,
center()->Click.connect(base::Bind<void>(&SliceWindow::onCenterChange, this));
pivot()->Click.connect(base::Bind<void>(&SliceWindow::onPivotChange, this));
if (!key->center().isEmpty()) {
if (key->hasCenter()) {
center()->setSelected(true);
centerX()->setTextf("%d", key->center().x);
centerY()->setTextf("%d", key->center().y);

View File

@ -29,6 +29,7 @@ namespace doc {
const gfx::Point& pivot = SliceKey::NoPivot);
bool isEmpty() const { return m_bounds.isEmpty(); }
bool hasCenter() const { return !m_center.isEmpty(); }
bool hasPivot() const { return m_pivot != NoPivot; }
const gfx::Rect& bounds() const { return m_bounds; }