Skip to content

Commit

Permalink
Export slice data in .aseprite-data file (aseprite#721)
Browse files Browse the repository at this point in the history
  • Loading branch information
dacap committed Apr 12, 2017
1 parent 5e1c5af commit 80c61ca
Show file tree
Hide file tree
Showing 5 changed files with 465 additions and 196 deletions.
1 change: 1 addition & 0 deletions src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ add_library(app-lib
document_undo.cpp
extra_cel.cpp
file/file.cpp
file/file_data.cpp
file/file_format.cpp
file/file_formats_manager.cpp
file/palette_file.cpp
Expand Down
207 changes: 13 additions & 194 deletions src/app/file/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,15 @@
#include "app/console.h"
#include "app/context.h"
#include "app/document.h"
#include "app/file/file_data.h"
#include "app/file/file_format.h"
#include "app/file/file_formats_manager.h"
#include "app/file/format_options.h"
#include "app/file/split_filename.h"
#include "app/filename_formatter.h"
#include "app/modules/gui.h"
#include "app/modules/palettes.h"
#include "app/pref/preferences.h"
#include "app/ui/status_bar.h"
#include "app/xml_document.h"
#include "base/fs.h"
#include "base/mutex.h"
#include "base/scoped_lock.h"
Expand All @@ -43,45 +42,6 @@ namespace app {

using namespace base;

namespace {

void updateXmlPartFromSliceKey(const doc::SliceKey* key, TiXmlElement* xmlPart)
{
xmlPart->SetAttribute("x", key->bounds().x);
xmlPart->SetAttribute("y", key->bounds().y);
if (!key->hasCenter()) {
xmlPart->SetAttribute("w", key->bounds().w);
xmlPart->SetAttribute("h", key->bounds().h);
if (xmlPart->Attribute("w1")) xmlPart->RemoveAttribute("w1");
if (xmlPart->Attribute("w2")) xmlPart->RemoveAttribute("w2");
if (xmlPart->Attribute("w3")) xmlPart->RemoveAttribute("w3");
if (xmlPart->Attribute("h1")) xmlPart->RemoveAttribute("h1");
if (xmlPart->Attribute("h2")) xmlPart->RemoveAttribute("h2");
if (xmlPart->Attribute("h3")) xmlPart->RemoveAttribute("h3");
}
else {
xmlPart->SetAttribute("w1", key->center().x);
xmlPart->SetAttribute("w2", key->center().w);
xmlPart->SetAttribute("w3", key->bounds().w - key->center().x2());
xmlPart->SetAttribute("h1", key->center().y);
xmlPart->SetAttribute("h2", key->center().h);
xmlPart->SetAttribute("h3", key->bounds().h - key->center().y2());
if (xmlPart->Attribute("w")) xmlPart->RemoveAttribute("w");
if (xmlPart->Attribute("h")) xmlPart->RemoveAttribute("h");
}

if (key->hasPivot()) {
xmlPart->SetAttribute("focusx", key->pivot().x);
xmlPart->SetAttribute("focusy", key->pivot().y);
}
else {
if (xmlPart->Attribute("focusx")) xmlPart->RemoveAttribute("focusx");
if (xmlPart->Attribute("focusy")) xmlPart->RemoveAttribute("focusy");
}
}

} // anonymous namespace

std::string get_readable_extensions()
{
std::string buf;
Expand Down Expand Up @@ -723,7 +683,12 @@ void FileOp::operate(IFileOpProgress* progress)
if (m_document &&
m_document->sprite() &&
!m_dataFilename.empty()) {
loadData();
try {
load_aseprite_data_file(m_dataFilename, m_document);
}
catch (const std::exception& ex) {
setError("Error loading data file: %s\n", ex.what());
}
}
}
// Save //////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -805,7 +770,12 @@ void FileOp::operate(IFileOpProgress* progress)
m_document->sprite() &&
!hasError() &&
!m_dataFilename.empty()) {
saveData();
try {
save_aseprite_data_file(m_dataFilename, m_document);
}
catch (const std::exception& ex) {
setError("Error loading data file: %s\n", ex.what());
}
}
#else
setError(
Expand Down Expand Up @@ -1091,155 +1061,4 @@ void FileOp::prepareForSequence()
m_formatOptions.reset();
}

void FileOp::loadData()
{
try {
XmlDocumentRef xmlDoc = open_xml(m_dataFilename);
TiXmlHandle handle(xmlDoc.get());

TiXmlElement* xmlSlices = handle
.FirstChild("sprite")
.FirstChild("slices").ToElement();

// Update theme.xml file
if (xmlSlices &&
xmlSlices->Attribute("theme")) {
std::string themeFileName = xmlSlices->Attribute("theme");

// Open theme XML file
XmlDocumentRef xmlThemeDoc = open_xml(
base::join_path(base::get_file_path(m_dataFilename), themeFileName));
TiXmlHandle themeHandle(xmlThemeDoc.get());
for (TiXmlElement* xmlPart = themeHandle
.FirstChild("theme")
.FirstChild("parts")
.FirstChild("part").ToElement();
xmlPart;
xmlPart=xmlPart->NextSiblingElement()) {
const char* partId = xmlPart->Attribute("id");
if (!partId)
continue;

auto slice = new doc::Slice();
slice->setName(partId);

// Default slice color
auto color = Preferences::instance().slices.defaultColor();
slice->userData().setColor(
doc::rgba(color.getRed(),
color.getGreen(),
color.getBlue(),
color.getAlpha()));

doc::SliceKey key;

int x = strtol(xmlPart->Attribute("x"), NULL, 10);
int y = strtol(xmlPart->Attribute("y"), NULL, 10);

if (xmlPart->Attribute("w1")) {
int w1 = xmlPart->Attribute("w1") ? strtol(xmlPart->Attribute("w1"), NULL, 10): 0;
int w2 = xmlPart->Attribute("w2") ? strtol(xmlPart->Attribute("w2"), NULL, 10): 0;
int w3 = xmlPart->Attribute("w3") ? strtol(xmlPart->Attribute("w3"), NULL, 10): 0;
int h1 = xmlPart->Attribute("h1") ? strtol(xmlPart->Attribute("h1"), NULL, 10): 0;
int h2 = xmlPart->Attribute("h2") ? strtol(xmlPart->Attribute("h2"), NULL, 10): 0;
int h3 = xmlPart->Attribute("h3") ? strtol(xmlPart->Attribute("h3"), NULL, 10): 0;

key.setBounds(gfx::Rect(x, y, w1+w2+w3, h1+h2+h3));
key.setCenter(gfx::Rect(w1, h1, w2, h2));
}
else if (xmlPart->Attribute("w")) {
int w = xmlPart->Attribute("w") ? strtol(xmlPart->Attribute("w"), NULL, 10): 0;
int h = xmlPart->Attribute("h") ? strtol(xmlPart->Attribute("h"), NULL, 10): 0;
key.setBounds(gfx::Rect(x, y, w, h));
}

if (xmlPart->Attribute("focusx")) {
int x = xmlPart->Attribute("focusx") ? strtol(xmlPart->Attribute("focusx"), NULL, 10): 0;
int y = xmlPart->Attribute("focusy") ? strtol(xmlPart->Attribute("focusy"), NULL, 10): 0;
key.setPivot(gfx::Point(x, y));
}

slice->insert(0, key);
m_document->sprite()->slices().add(slice);
}
}
}
catch (const std::exception& ex) {
setError("Error loading data file: %s\n", ex.what());
}
}

void FileOp::saveData()
{
try {
XmlDocumentRef xmlDoc = open_xml(m_dataFilename);
TiXmlHandle handle(xmlDoc.get());

TiXmlElement* xmlSlices = handle
.FirstChild("sprite")
.FirstChild("slices").ToElement();

if (xmlSlices &&
xmlSlices->Attribute("theme")) {
// Open theme XML file
std::string themeFileName = base::join_path(
base::get_file_path(m_dataFilename), xmlSlices->Attribute("theme"));
XmlDocumentRef xmlThemeDoc = open_xml(themeFileName);

TiXmlHandle themeHandle(xmlThemeDoc.get());
TiXmlElement* xmlNext = nullptr;
std::set<std::string> existent;

TiXmlElement* xmlParts =
themeHandle
.FirstChild("theme")
.FirstChild("parts").ToElement();

for (TiXmlElement* xmlPart=(TiXmlElement*)xmlParts->FirstChild("part");
xmlPart;
xmlPart=xmlNext) {
xmlNext = xmlPart->NextSiblingElement();

const char* partId = xmlPart->Attribute("id");
if (!partId)
continue;

bool found = false;
for (auto slice : m_document->sprite()->slices()) {
const SliceKey* key;
if ((slice->name() == partId) &&
(key = slice->getByFrame(0))) {
existent.insert(slice->name());
updateXmlPartFromSliceKey(key, xmlPart);
found = true;
break;
}
}

// Delete this <part> element (as the slice was removed)
if (!found)
xmlPart->Parent()->RemoveChild(xmlPart);
}

for (auto slice : m_document->sprite()->slices()) {
const SliceKey* key;
if (existent.find(slice->name()) == existent.end() &&
(key = slice->getByFrame(0))) {

TiXmlElement xmlPart("part");
xmlPart.SetAttribute("id", slice->name().c_str());
updateXmlPartFromSliceKey(key, &xmlPart);

xmlParts->InsertAfterChild(xmlParts->LastChild(), xmlPart);
}
}

save_xml(xmlThemeDoc, themeFileName);
}
}
catch (const std::exception& ex) {
setError("Error loading data file: %s\n", ex.what());
}
}

} // namespace app
2 changes: 0 additions & 2 deletions src/app/file/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,6 @@ namespace app {
} m_seq;

void prepareForSequence();
void loadData();
void saveData();
};

// Available extensions for each load/save operation.
Expand Down
Loading

0 comments on commit 80c61ca

Please sign in to comment.