mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-26 12:35:33 +00:00
Unify "Export Sprite Sheet" command with DocumentExporter
This commit is contained in:
parent
750c7b5414
commit
50e9ed6326
@ -43,6 +43,12 @@
|
||||
<value id="CHECKED_4x4" value="2" />
|
||||
<value id="CHECKED_2x2" value="3" />
|
||||
</enum>
|
||||
<enum id="SpriteSheetType">
|
||||
<value id="NONE" value="0" />
|
||||
<value id="HORIZONTAL_STRIP" value="1" />
|
||||
<value id="VERTICAL_STRIP" value="2" />
|
||||
<value id="MATRIX" value="3" />
|
||||
</enum>
|
||||
</types>
|
||||
|
||||
<global>
|
||||
@ -133,6 +139,15 @@
|
||||
<option id="opacity_step" type="int" default="28" migrate="Onionskin.OpacityStep" />
|
||||
<option id="type" type="OnionskinType" default="OnionskinType::MERGE" migrate="Onionskin.Type" />
|
||||
</section>
|
||||
<section id="sprite_sheet">
|
||||
<option id="type" type="SpriteSheetType" default="SpriteSheetType::NONE" />
|
||||
<option id="columns" type="int" default="0" />
|
||||
<option id="width" type="int" default="0" />
|
||||
<option id="height" type="int" default="0" />
|
||||
<option id="best_fit" type="bool" default="false" />
|
||||
<option id="texture_filename" type="std::string" />
|
||||
<option id="data_filename" type="std::string" />
|
||||
</section>
|
||||
</document>
|
||||
|
||||
</preferences>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!-- ASEPRITE -->
|
||||
<!-- Copyright (C) 2001-2014 by David Capello -->
|
||||
<!-- Copyright (C) 2001-2015 by David Capello -->
|
||||
<gui>
|
||||
<window id="export_sprite_sheet" text="Export Sprite Sheet">
|
||||
<grid columns="4">
|
||||
@ -18,8 +18,11 @@
|
||||
<hbox id="best_fit_filler" />
|
||||
<check cell_hspan="3" id="best_fit" text="Best fit for texture" />
|
||||
|
||||
<label text="Export Action:" />
|
||||
<combobox id="export_action" cell_hspan="3" />
|
||||
<label text="Save As:" />
|
||||
<button id="image_filename" cell_hspan="3" />
|
||||
|
||||
<check id="data_enabled" text="JSON Data:" />
|
||||
<button id="data_filename" cell_hspan="3" />
|
||||
|
||||
<hbox cell_hspan="4">
|
||||
<boxfiller />
|
||||
|
@ -9,32 +9,19 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/commands/cmd_export_sprite_sheet.h"
|
||||
|
||||
#include "app/commands/cmd_save_file.h"
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/commands.h"
|
||||
#include "app/commands/params.h"
|
||||
#include "app/context.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/document.h"
|
||||
#include "app/document_api.h"
|
||||
#include "app/document_undo.h"
|
||||
#include "app/ini_file.h"
|
||||
#include "app/modules/editors.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/modules/palettes.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "app/transaction.h"
|
||||
#include "app/document_exporter.h"
|
||||
#include "app/file/file.h"
|
||||
#include "app/file_selector.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/convert_to.h"
|
||||
#include "doc/cel.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/palette.h"
|
||||
#include "doc/primitives.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "ui/ui.h"
|
||||
#include "base/path.h"
|
||||
|
||||
#include "generated_export_sprite_sheet.h"
|
||||
|
||||
@ -116,24 +103,23 @@ namespace {
|
||||
|
||||
class ExportSpriteSheetWindow : public app::gen::ExportSpriteSheet {
|
||||
public:
|
||||
typedef ExportSpriteSheetCommand::SpriteSheetType SpriteSheetType;
|
||||
typedef ExportSpriteSheetCommand::ExportAction ExportAction;
|
||||
|
||||
ExportSpriteSheetWindow(Document* doc, Sprite* sprite)
|
||||
ExportSpriteSheetWindow(Document* doc, Sprite* sprite,
|
||||
DocumentPreferences& docPref)
|
||||
: m_sprite(sprite)
|
||||
, m_docPref(docPref)
|
||||
{
|
||||
doc::ExportDataPtr data = doc->exportData();
|
||||
static_assert(
|
||||
(int)app::gen::SpriteSheetType::NONE == 0 &&
|
||||
(int)app::gen::SpriteSheetType::HORIZONTAL_STRIP == 1 &&
|
||||
(int)app::gen::SpriteSheetType::VERTICAL_STRIP == 2 &&
|
||||
(int)app::gen::SpriteSheetType::MATRIX == 3,
|
||||
"ExportType enum changed");
|
||||
|
||||
sheetType()->addItem("Horizontal Strip");
|
||||
sheetType()->addItem("Vertical Strip");
|
||||
sheetType()->addItem("Matrix");
|
||||
if (data)
|
||||
sheetType()->setSelectedItemIndex((int)data->type()-1); // TODO harcoded -1
|
||||
|
||||
exportAction()->addItem("Save Copy As...");
|
||||
exportAction()->addItem("Save As...");
|
||||
exportAction()->addItem("Save");
|
||||
exportAction()->addItem("Do Not Save");
|
||||
if (m_docPref.spriteSheet.type() != app::gen::SpriteSheetType::NONE)
|
||||
sheetType()->setSelectedItemIndex((int)m_docPref.spriteSheet.type()-1);
|
||||
|
||||
for (int i=2; i<=8192; i*=2) {
|
||||
std::string value = base::convert_to<std::string>(i);
|
||||
@ -141,44 +127,60 @@ public:
|
||||
if (i >= m_sprite->height()) fitHeight()->addItem(value);
|
||||
}
|
||||
|
||||
if (!data || data->bestFit()) {
|
||||
if (m_docPref.spriteSheet.bestFit()) {
|
||||
bestFit()->setSelected(true);
|
||||
onBestFit();
|
||||
}
|
||||
else if (data) {
|
||||
columns()->setTextf("%d", data->columns());
|
||||
else {
|
||||
columns()->setTextf("%d", m_docPref.spriteSheet.columns());
|
||||
onColumnsChange();
|
||||
|
||||
if (data->width() > 0 || data->height() > 0) {
|
||||
if (data->width() > 0) fitWidth()->getEntryWidget()->setTextf("%d", data->width());
|
||||
if (data->height() > 0) fitHeight()->getEntryWidget()->setTextf("%d", data->height());
|
||||
if (m_docPref.spriteSheet.width() > 0 || m_docPref.spriteSheet.height() > 0) {
|
||||
if (m_docPref.spriteSheet.width() > 0)
|
||||
fitWidth()->getEntryWidget()->setTextf("%d", m_docPref.spriteSheet.width());
|
||||
|
||||
if (m_docPref.spriteSheet.height() > 0)
|
||||
fitHeight()->getEntryWidget()->setTextf("%d", m_docPref.spriteSheet.height());
|
||||
|
||||
onSizeChange();
|
||||
}
|
||||
}
|
||||
else {
|
||||
columns()->setText("4");
|
||||
onColumnsChange();
|
||||
|
||||
m_filename = m_docPref.spriteSheet.textureFilename();
|
||||
m_dataFilename = m_docPref.spriteSheet.dataFilename();
|
||||
dataEnabled()->setSelected(!m_dataFilename.empty());
|
||||
|
||||
std::string base = doc->filename();
|
||||
base = base::join_path(base::get_file_path(base), base::get_file_title(base));
|
||||
if (m_filename.empty()) {
|
||||
if (base::utf8_icmp(base::get_file_extension(doc->filename()), "png") == 0)
|
||||
m_filename = base + "-sheet.png";
|
||||
else
|
||||
m_filename = base + ".png";
|
||||
}
|
||||
if (m_dataFilename.empty())
|
||||
m_dataFilename = base + ".json";
|
||||
|
||||
sheetType()->Change.connect(&ExportSpriteSheetWindow::onSheetTypeChange, this);
|
||||
columns()->EntryChange.connect(Bind<void>(&ExportSpriteSheetWindow::onColumnsChange, this));
|
||||
fitWidth()->Change.connect(Bind<void>(&ExportSpriteSheetWindow::onSizeChange, this));
|
||||
fitHeight()->Change.connect(Bind<void>(&ExportSpriteSheetWindow::onSizeChange, this));
|
||||
bestFit()->Click.connect(Bind<void>(&ExportSpriteSheetWindow::onBestFit, this));
|
||||
imageFilename()->Click.connect(Bind<void>(&ExportSpriteSheetWindow::onImageFilename, this));
|
||||
dataEnabled()->Click.connect(Bind<void>(&ExportSpriteSheetWindow::onDataEnabledChange, this));
|
||||
dataFilename()->Click.connect(Bind<void>(&ExportSpriteSheetWindow::onDataFilename, this));
|
||||
|
||||
onSheetTypeChange();
|
||||
onFileNamesChange();
|
||||
onDataEnabledChange();
|
||||
}
|
||||
|
||||
bool ok() {
|
||||
return getKiller() == exportButton();
|
||||
}
|
||||
|
||||
SpriteSheetType spriteSheetTypeValue() {
|
||||
return (SpriteSheetType)sheetType()->getSelectedItemIndex();
|
||||
}
|
||||
|
||||
ExportAction exportActionValue() {
|
||||
return (ExportAction)exportAction()->getSelectedItemIndex();
|
||||
app::gen::SpriteSheetType spriteSheetTypeValue() {
|
||||
return (app::gen::SpriteSheetType)(sheetType()->getSelectedItemIndex()+1);
|
||||
}
|
||||
|
||||
int columnsValue() {
|
||||
@ -197,12 +199,23 @@ public:
|
||||
return bestFit()->isSelected();
|
||||
}
|
||||
|
||||
std::string filenameValue() {
|
||||
return m_filename;
|
||||
}
|
||||
|
||||
std::string dataFilenameValue() {
|
||||
if (dataEnabled()->isSelected())
|
||||
return m_dataFilename;
|
||||
else
|
||||
return std::string();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void onSheetTypeChange() {
|
||||
bool state = false;
|
||||
switch (sheetType()->getSelectedItemIndex()) {
|
||||
case ExportSpriteSheetCommand::Matrix:
|
||||
switch (spriteSheetTypeValue()) {
|
||||
case app::gen::SpriteSheetType::MATRIX:
|
||||
state = true;
|
||||
break;
|
||||
}
|
||||
@ -215,11 +228,13 @@ protected:
|
||||
fitHeight()->setVisible(state);
|
||||
bestFitFiller()->setVisible(state);
|
||||
bestFit()->setVisible(state);
|
||||
resize();
|
||||
}
|
||||
|
||||
gfx::Size reqSize = getPreferredSize();
|
||||
moveWindow(gfx::Rect(getOrigin(), reqSize));
|
||||
|
||||
invalidate();
|
||||
void onFileNamesChange() {
|
||||
imageFilename()->setText("Select File: " + base::get_file_name(m_filename));
|
||||
dataFilename()->setText("Select File: " + base::get_file_name(m_dataFilename));
|
||||
resize();
|
||||
}
|
||||
|
||||
void onColumnsChange() {
|
||||
@ -249,8 +264,70 @@ protected:
|
||||
fitHeight()->getEntryWidget()->setTextf("%d", fit.height);
|
||||
}
|
||||
|
||||
void onImageFilename() {
|
||||
char exts[4096];
|
||||
get_writable_extensions(exts, sizeof(exts));
|
||||
|
||||
std::string newFilename = app::show_file_selector(
|
||||
"Save Sprite Sheet", m_filename, exts, FileSelectorType::Save);
|
||||
if (newFilename.empty())
|
||||
return;
|
||||
|
||||
m_filename = newFilename;
|
||||
onFileNamesChange();
|
||||
}
|
||||
|
||||
void onDataFilename() {
|
||||
// TODO hardcoded "json" extension
|
||||
std::string newFilename = app::show_file_selector(
|
||||
"Save JSON Data", m_dataFilename, "json", FileSelectorType::Save);
|
||||
if (newFilename.empty())
|
||||
return;
|
||||
|
||||
m_dataFilename = newFilename;
|
||||
onFileNamesChange();
|
||||
}
|
||||
|
||||
void onDataEnabledChange() {
|
||||
dataFilename()->setVisible(dataEnabled()->isSelected());
|
||||
resize();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void resize() {
|
||||
gfx::Size reqSize = getPreferredSize();
|
||||
moveWindow(gfx::Rect(getOrigin(), reqSize));
|
||||
invalidate();
|
||||
}
|
||||
|
||||
Sprite* m_sprite;
|
||||
DocumentPreferences& m_docPref;
|
||||
std::string m_filename;
|
||||
std::string m_dataFilename;
|
||||
};
|
||||
|
||||
class ExportSpriteSheetCommand : public Command {
|
||||
public:
|
||||
ExportSpriteSheetCommand();
|
||||
Command* clone() const override { return new ExportSpriteSheetCommand(*this); }
|
||||
|
||||
void setUseUI(bool useUI) { m_useUI = useUI; }
|
||||
|
||||
protected:
|
||||
void onLoadParams(const Params& params) override;
|
||||
bool onEnabled(Context* context) override;
|
||||
void onExecute(Context* context) override;
|
||||
|
||||
private:
|
||||
bool m_useUI;
|
||||
app::gen::SpriteSheetType m_type;
|
||||
int m_columns;
|
||||
int m_width;
|
||||
int m_height;
|
||||
bool m_bestFit;
|
||||
std::string m_filename;
|
||||
std::string m_dataFilename;
|
||||
};
|
||||
|
||||
ExportSpriteSheetCommand::ExportSpriteSheetCommand()
|
||||
@ -261,6 +338,14 @@ ExportSpriteSheetCommand::ExportSpriteSheetCommand()
|
||||
{
|
||||
}
|
||||
|
||||
void ExportSpriteSheetCommand::onLoadParams(const Params& params)
|
||||
{
|
||||
if (params.has_param("ui"))
|
||||
m_useUI = params.get_as<bool>("ui");
|
||||
else
|
||||
m_useUI = true;
|
||||
}
|
||||
|
||||
bool ExportSpriteSheetCommand::onEnabled(Context* context)
|
||||
{
|
||||
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable);
|
||||
@ -270,21 +355,32 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
|
||||
{
|
||||
Document* document(context->activeDocument());
|
||||
Sprite* sprite = document->sprite();
|
||||
DocumentPreferences& docPref(App::instance()->preferences().document(document));
|
||||
|
||||
if (m_useUI) {
|
||||
ExportSpriteSheetWindow window(document, sprite);
|
||||
if (m_useUI && context->isUiAvailable()) {
|
||||
ExportSpriteSheetWindow window(document, sprite, docPref);
|
||||
window.openWindowInForeground();
|
||||
if (!window.ok())
|
||||
return;
|
||||
|
||||
m_type = window.spriteSheetTypeValue();
|
||||
m_action = window.exportActionValue();
|
||||
m_columns = window.columnsValue();
|
||||
m_width = window.fitWidthValue();
|
||||
m_height= window.fitHeightValue();
|
||||
m_bestFit = window.bestFitValue();
|
||||
docPref.spriteSheet.type(window.spriteSheetTypeValue());
|
||||
docPref.spriteSheet.columns(window.columnsValue());
|
||||
docPref.spriteSheet.width(window.fitWidthValue());
|
||||
docPref.spriteSheet.height(window.fitHeightValue());
|
||||
docPref.spriteSheet.bestFit(window.bestFitValue());
|
||||
docPref.spriteSheet.textureFilename(window.filenameValue());
|
||||
docPref.spriteSheet.dataFilename(window.dataFilenameValue());
|
||||
}
|
||||
else if (m_bestFit) {
|
||||
|
||||
m_type = docPref.spriteSheet.type();
|
||||
m_columns = docPref.spriteSheet.columns();
|
||||
m_width = docPref.spriteSheet.width();
|
||||
m_height = docPref.spriteSheet.height();
|
||||
m_bestFit = docPref.spriteSheet.bestFit();
|
||||
m_filename = docPref.spriteSheet.textureFilename();
|
||||
m_dataFilename = docPref.spriteSheet.dataFilename();
|
||||
|
||||
if (m_bestFit) {
|
||||
Fit fit = best_fit(sprite);
|
||||
m_columns = fit.columns;
|
||||
m_width = fit.width;
|
||||
@ -297,13 +393,13 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
|
||||
int sheet_h = 0;
|
||||
|
||||
switch (m_type) {
|
||||
case HorizontalStrip:
|
||||
case app::gen::SpriteSheetType::HORIZONTAL_STRIP:
|
||||
columns = nframes;
|
||||
break;
|
||||
case VerticalStrip:
|
||||
case app::gen::SpriteSheetType::VERTICAL_STRIP:
|
||||
columns = 1;
|
||||
break;
|
||||
case Matrix:
|
||||
case app::gen::SpriteSheetType::MATRIX:
|
||||
columns = m_columns;
|
||||
if (m_width > 0) sheet_w = m_width;
|
||||
if (m_height > 0) sheet_h = m_height;
|
||||
@ -315,194 +411,19 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
|
||||
if (sheet_h == 0) sheet_h = sprite->height()*((nframes/columns)+((nframes%columns)>0?1:0));
|
||||
columns = sheet_w / sprite->width();
|
||||
|
||||
ImageRef resultImage(Image::create(sprite->pixelFormat(), sheet_w, sheet_h));
|
||||
doc::clear_image(resultImage, 0);
|
||||
DocumentExporter exporter;
|
||||
exporter.setTextureFilename(m_filename);
|
||||
if (!m_dataFilename.empty())
|
||||
exporter.setDataFilename(m_dataFilename);
|
||||
exporter.setTextureWidth(sheet_w);
|
||||
exporter.setTextureHeight(sheet_h);
|
||||
exporter.setTexturePack(true);
|
||||
exporter.addDocument(document);
|
||||
exporter.exportSheet();
|
||||
|
||||
render::Render render;
|
||||
|
||||
int column = 0, row = 0;
|
||||
for (frame_t frame = 0; frame<nframes; ++frame) {
|
||||
render.renderSprite(resultImage, sprite, frame,
|
||||
gfx::Clip(column*sprite->width(), row*sprite->height(),
|
||||
sprite->bounds()));
|
||||
|
||||
if (++column >= columns) {
|
||||
column = 0;
|
||||
++row;
|
||||
}
|
||||
}
|
||||
|
||||
// Store the frame in the current editor so we can restore it
|
||||
// after change and restore the setTotalFrames() number.
|
||||
frame_t oldSelectedFrame = (current_editor ?
|
||||
current_editor->frame():
|
||||
frame_t(0));
|
||||
|
||||
{
|
||||
// The following steps modify the sprite, so we wrap all
|
||||
// operations in a undo-transaction.
|
||||
ContextWriter writer(context);
|
||||
Transaction transaction(writer.context(), "Export Sprite Sheet", ModifyDocument);
|
||||
DocumentApi api = document->getApi(transaction);
|
||||
|
||||
// Add the layer in the sprite.
|
||||
LayerImage* resultLayer = api.newLayer(sprite);
|
||||
|
||||
// Create the cel.
|
||||
base::UniquePtr<Cel> resultCel(new Cel(frame_t(0), resultImage));
|
||||
|
||||
// Add the cel in the layer.
|
||||
api.addCel(resultLayer, resultCel);
|
||||
resultCel.release();
|
||||
|
||||
// Copy the list of layers (because we will modify it in the iteration).
|
||||
LayerList layers = sprite->folder()->getLayersList();
|
||||
|
||||
// Remove all other layers
|
||||
for (LayerIterator it=layers.begin(), end=layers.end(); it!=end; ++it) {
|
||||
if (*it != resultLayer)
|
||||
api.removeLayer(*it);
|
||||
}
|
||||
|
||||
// Change the number of frames (just one, the sprite sheet). As
|
||||
// we are using the observable API, all DocumentView will change
|
||||
// its current frame to frame 1. We'll try to restore the
|
||||
// selected frame for the current_editor later.
|
||||
api.setTotalFrames(sprite, frame_t(1));
|
||||
|
||||
// Set the size of the sprite to the tile size.
|
||||
api.setSpriteSize(sprite, sheet_w, sheet_h);
|
||||
|
||||
transaction.commit();
|
||||
|
||||
// Draw the document with the new dimensions in the screen.
|
||||
update_screen_for_document(document);
|
||||
}
|
||||
|
||||
// This flag indicates if we've to undo the last action (so we
|
||||
// back to the original sprite dimensions).
|
||||
bool undo = false;
|
||||
|
||||
Params params;
|
||||
if (!m_filename.empty())
|
||||
params.set("filename", m_filename.c_str());
|
||||
|
||||
SaveFileBaseCommand* command = NULL;
|
||||
|
||||
// Do the "Export Action"
|
||||
switch (m_action) {
|
||||
|
||||
case SaveCopyAs:
|
||||
command = static_cast<SaveFileBaseCommand*>(CommandsModule::instance()
|
||||
->getCommandByName(CommandId::SaveFileCopyAs));
|
||||
|
||||
context->executeCommand(command, params);
|
||||
|
||||
// Always go back, as we are using "Save Copy As", so the user
|
||||
// wants to continue editing the original sprite.
|
||||
undo = true;
|
||||
break;
|
||||
|
||||
case SaveAs:
|
||||
command = static_cast<SaveFileBaseCommand*>(CommandsModule::instance()
|
||||
->getCommandByName(CommandId::SaveFileAs));
|
||||
|
||||
context->executeCommand(command, params);
|
||||
|
||||
// If the command was cancelled, we go back to the original
|
||||
// state, if the sprite sheet was saved then we don't undo
|
||||
// because the user wants to edit the sprite sheet.
|
||||
undo = (document->isModified());
|
||||
break;
|
||||
|
||||
case Save:
|
||||
command = static_cast<SaveFileBaseCommand*>(CommandsModule::instance()
|
||||
->getCommandByName(CommandId::SaveFile));
|
||||
|
||||
context->executeCommand(command, params);
|
||||
|
||||
// Same case as "Save As"
|
||||
undo = (document->isModified());
|
||||
break;
|
||||
|
||||
case DoNotSave:
|
||||
// Do not undo as the user wants to edit the sprite sheet
|
||||
// before to save the file.
|
||||
undo = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Set export data
|
||||
if (command != NULL) {
|
||||
doc::ExportData::Type type;
|
||||
switch (m_type) {
|
||||
case ExportSpriteSheetCommand::HorizontalStrip:
|
||||
type = doc::ExportData::HorizontalStrip;
|
||||
break;
|
||||
case ExportSpriteSheetCommand::VerticalStrip:
|
||||
type = doc::ExportData::VerticalStrip;
|
||||
break;
|
||||
case ExportSpriteSheetCommand::Matrix:
|
||||
type = doc::ExportData::Matrix;
|
||||
break;
|
||||
}
|
||||
doc::ExportDataPtr data(new doc::ExportData);
|
||||
data->setType(type);
|
||||
data->setColumns(columns);
|
||||
data->setWidth(m_width);
|
||||
data->setHeight(m_height);
|
||||
data->setBestFit(m_bestFit);
|
||||
data->setFilename(command->selectedFilename());
|
||||
document->setExportData(data);
|
||||
}
|
||||
|
||||
// Undo the sprite sheet conversion
|
||||
if (undo) {
|
||||
if (document->undoHistory()->canUndo()) {
|
||||
document->undoHistory()->undo();
|
||||
|
||||
// We've to restore the previously selected frame. As we've
|
||||
// called setTotalFrames(), all document observers
|
||||
// (current_editor included) have changed its current frame to
|
||||
// the first one (to a visible/editable frame). The "undo"
|
||||
// action doesn't restore the previously selected frame in
|
||||
// observers, so at least we can restore the current_editor's
|
||||
// frame.
|
||||
if (current_editor)
|
||||
current_editor->setFrame(oldSelectedFrame);
|
||||
}
|
||||
|
||||
document->generateMaskBoundaries();
|
||||
document->destroyExtraCel(); // Regenerate extras
|
||||
|
||||
// Redraw the sprite.
|
||||
update_screen_for_document(document);
|
||||
}
|
||||
}
|
||||
|
||||
void ExportSpriteSheetCommand::setExportData(doc::ExportDataPtr data)
|
||||
{
|
||||
ExportSpriteSheetCommand::SpriteSheetType type;
|
||||
switch (data->type()) {
|
||||
case doc::ExportData::None: return;
|
||||
case doc::ExportData::HorizontalStrip:
|
||||
type = ExportSpriteSheetCommand::HorizontalStrip;
|
||||
break;
|
||||
case doc::ExportData::VerticalStrip:
|
||||
type = ExportSpriteSheetCommand::VerticalStrip;
|
||||
break;
|
||||
case doc::ExportData::Matrix:
|
||||
type = ExportSpriteSheetCommand::Matrix;
|
||||
break;
|
||||
}
|
||||
|
||||
m_type = type;
|
||||
m_action = ExportSpriteSheetCommand::SaveCopyAs;
|
||||
m_columns = data->columns();
|
||||
m_width = data->width();
|
||||
m_height = data->height();
|
||||
m_bestFit = data->bestFit();
|
||||
m_filename = data->filename();
|
||||
StatusBar* statusbar = StatusBar::instance();
|
||||
if (statusbar)
|
||||
statusbar->showTip(1000, "Sprite Sheet Generated");
|
||||
}
|
||||
|
||||
Command* CommandFactory::createExportSpriteSheetCommand()
|
||||
|
@ -1,51 +0,0 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_COMMANDS_CMD_EXPORT_SPRITE_SHEET_H_INCLUDED
|
||||
#define APP_COMMANDS_CMD_EXPORT_SPRITE_SHEET_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/commands/command.h"
|
||||
#include "doc/export_data.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace app {
|
||||
|
||||
class ExportSpriteSheetCommand : public Command {
|
||||
public:
|
||||
enum SpriteSheetType { HorizontalStrip, VerticalStrip, Matrix };
|
||||
enum ExportAction { SaveCopyAs, SaveAs, Save, DoNotSave };
|
||||
|
||||
ExportSpriteSheetCommand();
|
||||
Command* clone() const override { return new ExportSpriteSheetCommand(*this); }
|
||||
|
||||
SpriteSheetType type() const { return m_type; }
|
||||
ExportAction action() const { return m_action; }
|
||||
|
||||
void setUseUI(bool useUI) { m_useUI = useUI; }
|
||||
void setExportData(doc::ExportDataPtr data);
|
||||
void setAction(ExportAction action) { m_action = action; }
|
||||
|
||||
protected:
|
||||
virtual bool onEnabled(Context* context) override;
|
||||
virtual void onExecute(Context* context) override;
|
||||
|
||||
private:
|
||||
bool m_useUI;
|
||||
SpriteSheetType m_type;
|
||||
ExportAction m_action;
|
||||
int m_columns;
|
||||
int m_width;
|
||||
int m_height;
|
||||
bool m_bestFit;
|
||||
std::string m_filename;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -9,12 +9,13 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/commands/cmd_export_sprite_sheet.h"
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/commands.h"
|
||||
#include "app/commands/params.h"
|
||||
#include "app/context.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/pref/preferences.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
@ -42,25 +43,20 @@ bool RepeatLastExportCommand::onEnabled(Context* context)
|
||||
|
||||
void RepeatLastExportCommand::onExecute(Context* context)
|
||||
{
|
||||
base::UniquePtr<ExportSpriteSheetCommand> command(
|
||||
static_cast<ExportSpriteSheetCommand*>(
|
||||
CommandsModule::instance()->getCommandByName(CommandId::ExportSpriteSheet)->clone()));
|
||||
Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::ExportSpriteSheet);
|
||||
Params params;
|
||||
|
||||
{
|
||||
const ContextReader reader(context);
|
||||
const Document* document(reader.document());
|
||||
doc::ExportDataPtr data = document->exportData();
|
||||
DocumentPreferences& docPref =
|
||||
App::instance()->preferences().document(document);
|
||||
|
||||
if (data != NULL) {
|
||||
if (data->type() == doc::ExportData::None)
|
||||
return; // Do nothing case
|
||||
|
||||
command->setUseUI(false);
|
||||
command->setExportData(data);
|
||||
}
|
||||
params.set("ui",
|
||||
(docPref.spriteSheet.type() == app::gen::SpriteSheetType::NONE ? "1": "0"));
|
||||
}
|
||||
|
||||
context->executeCommand(command);
|
||||
context->executeCommand(cmd, params);
|
||||
}
|
||||
|
||||
Command* CommandFactory::createRepeatLastExportCommand()
|
||||
|
@ -69,7 +69,7 @@ ToolPreferences& Preferences::tool(tools::Tool* tool)
|
||||
}
|
||||
}
|
||||
|
||||
DocumentPreferences& Preferences::document(app::Document* document)
|
||||
DocumentPreferences& Preferences::document(const app::Document* document)
|
||||
{
|
||||
auto it = m_docs.find(document);
|
||||
if (it != m_docs.end()) {
|
||||
@ -102,7 +102,7 @@ void Preferences::onRemoveDocument(doc::Document* doc)
|
||||
}
|
||||
}
|
||||
|
||||
std::string Preferences::docConfigFileName(app::Document* doc)
|
||||
std::string Preferences::docConfigFileName(const app::Document* doc)
|
||||
{
|
||||
if (!doc)
|
||||
return "";
|
||||
@ -118,7 +118,7 @@ std::string Preferences::docConfigFileName(app::Document* doc)
|
||||
return rf.getFirstOrCreateDefault();
|
||||
}
|
||||
|
||||
void Preferences::serializeDocPref(app::Document* doc, app::DocumentPreferences* docPref, bool save)
|
||||
void Preferences::serializeDocPref(const app::Document* doc, app::DocumentPreferences* docPref, bool save)
|
||||
{
|
||||
bool specific_file = false;
|
||||
|
||||
|
@ -42,18 +42,18 @@ namespace app {
|
||||
void save();
|
||||
|
||||
ToolPreferences& tool(tools::Tool* tool);
|
||||
DocumentPreferences& document(app::Document* doc);
|
||||
DocumentPreferences& document(const app::Document* doc);
|
||||
|
||||
protected:
|
||||
void onRemoveDocument(doc::Document* doc) override;
|
||||
|
||||
private:
|
||||
std::string docConfigFileName(app::Document* doc);
|
||||
std::string docConfigFileName(const app::Document* doc);
|
||||
|
||||
void serializeDocPref(app::Document* doc, app::DocumentPreferences* docPref, bool save);
|
||||
void serializeDocPref(const app::Document* doc, app::DocumentPreferences* docPref, bool save);
|
||||
|
||||
std::map<std::string, app::ToolPreferences*> m_tools;
|
||||
std::map<app::Document*, app::DocumentPreferences*> m_docs;
|
||||
std::map<const app::Document*, app::DocumentPreferences*> m_docs;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2001-2014 David Capello
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -12,7 +12,6 @@
|
||||
|
||||
#include "base/path.h"
|
||||
#include "doc/context.h"
|
||||
#include "doc/export_data.h"
|
||||
#include "doc/sprite.h"
|
||||
|
||||
namespace doc {
|
||||
@ -69,11 +68,6 @@ void Document::setFilename(const std::string& filename)
|
||||
notifyObservers(&DocumentObserver::onFileNameChanged, this);
|
||||
}
|
||||
|
||||
void Document::setExportData(const ExportDataPtr& data)
|
||||
{
|
||||
m_exportData = data;
|
||||
}
|
||||
|
||||
void Document::close()
|
||||
{
|
||||
removeFromContext();
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2001-2014 David Capello
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -13,14 +13,12 @@
|
||||
#include "base/observable.h"
|
||||
#include "base/unique_ptr.h"
|
||||
#include "doc/document_observer.h"
|
||||
#include "doc/export_data.h"
|
||||
#include "doc/object.h"
|
||||
#include "doc/sprites.h"
|
||||
|
||||
namespace doc {
|
||||
|
||||
class Context;
|
||||
class ExportData;
|
||||
|
||||
class Document : public Object
|
||||
, public base::Observable<DocumentObserver> {
|
||||
@ -43,10 +41,7 @@ namespace doc {
|
||||
|
||||
std::string name() const;
|
||||
const std::string& filename() const { return m_filename; }
|
||||
ExportDataPtr exportData() const { return m_exportData; }
|
||||
|
||||
void setFilename(const std::string& filename);
|
||||
void setExportData(const ExportDataPtr& data);
|
||||
|
||||
void close();
|
||||
|
||||
@ -61,7 +56,6 @@ namespace doc {
|
||||
std::string m_filename;
|
||||
Sprites m_sprites;
|
||||
Context* m_ctx;
|
||||
ExportDataPtr m_exportData;
|
||||
};
|
||||
|
||||
} // namespace doc
|
||||
|
@ -1,62 +0,0 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2001-2014 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifndef DOC_EXPORT_DATA_H_INCLUDED
|
||||
#define DOC_EXPORT_DATA_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "base/shared_ptr.h"
|
||||
#include "gfx/rect.h"
|
||||
#include <string>
|
||||
|
||||
namespace doc {
|
||||
|
||||
class ExportData {
|
||||
public:
|
||||
enum Type {
|
||||
None,
|
||||
HorizontalStrip,
|
||||
VerticalStrip,
|
||||
Matrix,
|
||||
};
|
||||
|
||||
ExportData() : m_type(None) {
|
||||
m_columns = 0;
|
||||
m_width = 0;
|
||||
m_height = 0;
|
||||
m_bestFit = false;
|
||||
}
|
||||
|
||||
Type type() const { return m_type; }
|
||||
int columns() const { return m_columns; }
|
||||
int width() const { return m_width; }
|
||||
int height() const { return m_height; }
|
||||
bool bestFit() const { return m_bestFit; }
|
||||
const std::string& filename() const { return m_filename; }
|
||||
|
||||
void setType(Type type) { m_type = type; }
|
||||
void setColumns(int columns) { m_columns = columns; }
|
||||
void setWidth(int width) { m_width = width; }
|
||||
void setHeight(int height) { m_height = height; }
|
||||
void setBestFit(bool bestFit) { m_bestFit = bestFit; }
|
||||
void setFilename(const std::string& filename) {
|
||||
m_filename = filename;
|
||||
}
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
int m_columns;
|
||||
int m_width;
|
||||
int m_height;
|
||||
bool m_bestFit;
|
||||
std::string m_filename;
|
||||
};
|
||||
|
||||
typedef SharedPtr<ExportData> ExportDataPtr;
|
||||
|
||||
} // namespace doc
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user