mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-05 09:40:02 +00:00
Add option to export sprite sheets in memory only (without a file, fix #865)
We have converted the label "Save As" into a checkbox in the Export Sprite Sheet dialog.
This commit is contained in:
parent
4b21d8d5f4
commit
9c1a8762ab
@ -37,10 +37,10 @@
|
||||
<label text="Frames:" />
|
||||
<combobox id="frames" text="" cell_hspan="3" />
|
||||
|
||||
<label text="Save As:" />
|
||||
<check id="image_enabled" text="Output File" />
|
||||
<button id="image_filename" cell_hspan="3" />
|
||||
|
||||
<check id="data_enabled" text="JSON Data:" />
|
||||
<check id="data_enabled" text="JSON Data" />
|
||||
<button id="data_filename" cell_hspan="3" />
|
||||
|
||||
<check id="open_generated" text="Open generated sprite sheet" cell_hspan="4" />
|
||||
|
@ -46,6 +46,10 @@ namespace {
|
||||
static const char* kSelectedLayers = "**selected-layers**";
|
||||
static const char* kSelectedFrames = "**selected-frames**";
|
||||
|
||||
// Special key value used in default preferences to know if by default
|
||||
// the user wants to generate texture and/or files.
|
||||
static const char* kSpecifiedFilename = "**filename**";
|
||||
|
||||
struct Fit {
|
||||
int width;
|
||||
int height;
|
||||
@ -125,6 +129,7 @@ namespace {
|
||||
bool ask_overwrite(bool askFilename, std::string filename,
|
||||
bool askDataname, std::string dataname) {
|
||||
if ((askFilename &&
|
||||
!filename.empty() &&
|
||||
base::is_file(filename)) ||
|
||||
(askDataname &&
|
||||
!dataname.empty() &&
|
||||
@ -338,19 +343,26 @@ public:
|
||||
}
|
||||
|
||||
m_filename = m_docPref.spriteSheet.textureFilename();
|
||||
imageEnabled()->setSelected(!m_filename.empty());
|
||||
imageFilename()->setVisible(imageEnabled()->isSelected());
|
||||
|
||||
m_dataFilename = m_docPref.spriteSheet.dataFilename();
|
||||
dataEnabled()->setSelected(!m_dataFilename.empty());
|
||||
dataFilename()->setVisible(dataEnabled()->isSelected());
|
||||
|
||||
std::string base = doc->filename();
|
||||
base = base::join_path(base::get_file_path(base), base::get_file_title(base));
|
||||
if (m_filename.empty()) {
|
||||
|
||||
if (m_filename.empty() ||
|
||||
m_filename == kSpecifiedFilename) {
|
||||
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())
|
||||
|
||||
if (m_dataFilename.empty() ||
|
||||
m_dataFilename == kSpecifiedFilename)
|
||||
m_dataFilename = base + ".json";
|
||||
|
||||
exportButton()->Click.connect(Bind<void>(&ExportSpriteSheetWindow::onExport, this));
|
||||
@ -362,14 +374,17 @@ public:
|
||||
borderPadding()->Change.connect(Bind<void>(&ExportSpriteSheetWindow::onPaddingChange, this));
|
||||
shapePadding()->Change.connect(Bind<void>(&ExportSpriteSheetWindow::onPaddingChange, this));
|
||||
innerPadding()->Change.connect(Bind<void>(&ExportSpriteSheetWindow::onPaddingChange, this));
|
||||
imageEnabled()->Click.connect(Bind<void>(&ExportSpriteSheetWindow::onImageEnabledChange, 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));
|
||||
paddingEnabled()->Click.connect(Bind<void>(&ExportSpriteSheetWindow::onPaddingEnabledChange, this));
|
||||
frames()->Change.connect(Bind<void>(&ExportSpriteSheetWindow::onFramesChange, this));
|
||||
openGenerated()->Click.connect(Bind<void>(&ExportSpriteSheetWindow::onOpenGeneratedChange, this));
|
||||
|
||||
onSheetTypeChange();
|
||||
onFileNamesChange();
|
||||
updateExportButton();
|
||||
}
|
||||
|
||||
bool ok() const {
|
||||
@ -397,7 +412,10 @@ public:
|
||||
}
|
||||
|
||||
std::string filenameValue() {
|
||||
return m_filename;
|
||||
if (imageEnabled()->isSelected())
|
||||
return m_filename;
|
||||
else
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string dataFilenameValue() {
|
||||
@ -456,7 +474,7 @@ public:
|
||||
return kAllFrames;
|
||||
}
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
void onExport() {
|
||||
if (!ask_overwrite(m_filenameAskOverwrite, filenameValue(),
|
||||
@ -518,6 +536,14 @@ protected:
|
||||
onFileNamesChange();
|
||||
}
|
||||
|
||||
void onImageEnabledChange() {
|
||||
m_filenameAskOverwrite = true;
|
||||
|
||||
imageFilename()->setVisible(imageEnabled()->isSelected());
|
||||
updateExportButton();
|
||||
resize();
|
||||
}
|
||||
|
||||
void onDataFilename() {
|
||||
// TODO hardcoded "json" extension
|
||||
std::string newFilename = app::show_file_selector(
|
||||
@ -534,6 +560,7 @@ protected:
|
||||
m_dataFilenameAskOverwrite = true;
|
||||
|
||||
dataFilename()->setVisible(dataEnabled()->isSelected());
|
||||
updateExportButton();
|
||||
resize();
|
||||
}
|
||||
|
||||
@ -551,7 +578,9 @@ protected:
|
||||
updateSizeFields();
|
||||
}
|
||||
|
||||
private:
|
||||
void onOpenGeneratedChange() {
|
||||
updateExportButton();
|
||||
}
|
||||
|
||||
void resize() {
|
||||
gfx::Size reqSize = getPreferredSize();
|
||||
@ -559,6 +588,13 @@ private:
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void updateExportButton() {
|
||||
exportButton()->setEnabled(
|
||||
imageEnabled()->isSelected() ||
|
||||
dataEnabled()->isSelected() ||
|
||||
openGenerated()->isSelected());
|
||||
}
|
||||
|
||||
void updateSizeFields() {
|
||||
int nframes = m_sprite->totalFrames();
|
||||
std::string tagName = frameTagValue();
|
||||
@ -671,8 +707,11 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
|
||||
// Default preferences for future sprites
|
||||
DocumentPreferences& defPref(Preferences::instance().document(nullptr));
|
||||
defPref.spriteSheet = docPref.spriteSheet;
|
||||
defPref.spriteSheet.textureFilename("");
|
||||
defPref.spriteSheet.dataFilename("");
|
||||
if (!defPref.spriteSheet.textureFilename().empty())
|
||||
defPref.spriteSheet.textureFilename.setValueAndDefault(kSpecifiedFilename);
|
||||
if (!defPref.spriteSheet.dataFilename().empty())
|
||||
defPref.spriteSheet.dataFilename.setValueAndDefault(kSpecifiedFilename);
|
||||
defPref.save();
|
||||
|
||||
askOverwrite = false; // Already asked in the ExportSpriteSheetWindow
|
||||
}
|
||||
@ -768,7 +807,8 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
|
||||
if (sheet_h == 0) sheet_h = fit.height;
|
||||
|
||||
DocumentExporter exporter;
|
||||
exporter.setTextureFilename(filename);
|
||||
if (!filename.empty())
|
||||
exporter.setTextureFilename(filename);
|
||||
if (!dataFilename.empty())
|
||||
exporter.setDataFilename(dataFilename);
|
||||
exporter.setTextureWidth(sheet_w);
|
||||
@ -797,6 +837,19 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
|
||||
}
|
||||
|
||||
if (docPref.spriteSheet.openGenerated()) {
|
||||
// Setup a filename for the new document in case that user didn't
|
||||
// save the file/specified one output filename.
|
||||
if (filename.empty()) {
|
||||
std::string fn = document->filename();
|
||||
std::string ext = base::get_file_extension(fn);
|
||||
if (!ext.empty())
|
||||
ext.insert(0, 1, '.');
|
||||
|
||||
newDocument->setFilename(
|
||||
base::join_path(base::get_file_path(fn),
|
||||
base::get_file_title(fn) + "-Sheet") + ext);
|
||||
}
|
||||
|
||||
newDocument->setContext(context);
|
||||
newDocument.release();
|
||||
}
|
||||
|
@ -37,11 +37,30 @@ namespace app {
|
||||
, m_dirty(false) {
|
||||
}
|
||||
|
||||
const T& operator()() const {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
const T& operator()(const T& newValue) {
|
||||
setValue(newValue);
|
||||
return m_value;
|
||||
}
|
||||
|
||||
// operator=() changes the value and the default value of the
|
||||
// option. E.g. it's used when we copy two complete Sections,
|
||||
// from default settings to user settings, or viceversa (the
|
||||
// default value is always involved).
|
||||
Option& operator=(const Option& opt) {
|
||||
operator()(opt.m_value);
|
||||
setValueAndDefault(opt.m_value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Changes the default value and the current one.
|
||||
void setValueAndDefault(const T& value) {
|
||||
setDefaultValue(value);
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
const char* section() const { return m_section->name(); }
|
||||
const char* id() const { return m_id; }
|
||||
const T& defaultValue() const { return m_default; }
|
||||
@ -53,13 +72,9 @@ namespace app {
|
||||
void forceDirtyFlag() { m_dirty = true; }
|
||||
void cleanDirtyFlag() { m_dirty = false; }
|
||||
|
||||
const T& operator()() const {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
const T& operator()(const T& newValue) {
|
||||
void setValue(const T& newValue) {
|
||||
if (m_value == newValue)
|
||||
return m_value;
|
||||
return;
|
||||
|
||||
BeforeChange(newValue);
|
||||
if (m_section)
|
||||
@ -71,8 +86,6 @@ namespace app {
|
||||
AfterChange(newValue);
|
||||
if (m_section)
|
||||
m_section->AfterChange();
|
||||
|
||||
return m_value;
|
||||
}
|
||||
|
||||
Signal1<void, const T&> BeforeChange;
|
||||
|
@ -103,7 +103,11 @@ DocumentPreferences& Preferences::document(const app::Document* doc)
|
||||
DocumentPreferences* docPref;
|
||||
if (doc) {
|
||||
docPref = new DocumentPreferences("");
|
||||
*docPref = this->document(nullptr);
|
||||
|
||||
// The default preferences for this document are the current
|
||||
// defaults for (document=nullptr).
|
||||
DocumentPreferences& defPref = this->document(nullptr);
|
||||
*docPref = defPref;
|
||||
|
||||
// Default values for symmetry
|
||||
docPref->symmetry.xAxis.setDefaultValue(doc->sprite()->width()/2);
|
||||
@ -113,7 +117,10 @@ DocumentPreferences& Preferences::document(const app::Document* doc)
|
||||
docPref = new DocumentPreferences("");
|
||||
|
||||
m_docs[doc] = docPref;
|
||||
|
||||
// Load document preferences
|
||||
serializeDocPref(doc, docPref, false);
|
||||
|
||||
return *docPref;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user