Add Trim by Grid option in Export Sprite Sheet (#1926)

This adds the logic and UI part of Trim by Grid feature, the CLI part
is not yet implemented.
This commit is contained in:
David N Campo 2019-02-07 14:03:11 -03:00 committed by David Capello
parent b8d5e86a8d
commit bdd4202c35
8 changed files with 56 additions and 2 deletions

View File

@ -425,6 +425,7 @@
<option id="shape_padding" type="int" default="0" />
<option id="inner_padding" type="int" default="0" />
<option id="trim" type="bool" default="false" />
<option id="trim_by_grid" type="bool" default="false" />
<option id="extrude" type="bool" default="false" />
<option id="open_generated" type="bool" default="false" />
<option id="layer" type="std::string" />

View File

@ -521,6 +521,7 @@ border = Border:
shape = Shape:
inner = Inner:
trim = Trim
trim_by_grid = by Grid
extrude = Extrude
width = Width:
height = Height:

View File

@ -18,6 +18,10 @@
<vbox>
<check id="padding_enabled" text="@.padding" />
<check id="trim_enabled" text="@.trim" />
<hbox id="trim_container">
<boxfiller />
<check id="grid_trim_enabled" text="@.trim_by_grid" />
</hbox>
<check id="extrude_enabled" text="@.extrude" />
</vbox>
<grid columns="2" id="padding_container" cell_hspan="2">

View File

@ -181,6 +181,7 @@ struct ExportSpriteSheetParams : public NewParams {
Param<int> shapePadding { this, 0, "shapePadding" };
Param<int> innerPadding { this, 0, "innerPadding" };
Param<bool> trim { this, false, "trim" };
Param<bool> trimByGrid { this, false, "trimByGrid" };
Param<bool> extrude { this, false, "extrude" };
Param<bool> openGenerated { this, false, "openGenerated" };
Param<std::string> layer { this, std::string(), "layer" };
@ -221,6 +222,8 @@ public:
openGenerated()->setSelected(params.openGenerated());
trimEnabled()->setSelected(params.trim());
trimContainer()->setVisible(trimEnabled()->isSelected());
gridTrimEnabled()->setSelected(trimEnabled()->isSelected() && params.trimByGrid());
extrudeEnabled()->setSelected(params.extrude());
borderPadding()->setTextf("%d", params.borderPadding());
@ -302,6 +305,7 @@ public:
imageFilename()->Click.connect(base::Bind<void>(&ExportSpriteSheetWindow::onImageFilename, this));
dataEnabled()->Click.connect(base::Bind<void>(&ExportSpriteSheetWindow::onDataEnabledChange, this));
dataFilename()->Click.connect(base::Bind<void>(&ExportSpriteSheetWindow::onDataFilename, this));
trimEnabled()->Click.connect(base::Bind<void>(&ExportSpriteSheetWindow::onTrimEnabledChange, this));
paddingEnabled()->Click.connect(base::Bind<void>(&ExportSpriteSheetWindow::onPaddingEnabledChange, this));
frames()->Change.connect(base::Bind<void>(&ExportSpriteSheetWindow::onFramesChange, this));
openGenerated()->Click.connect(base::Bind<void>(&ExportSpriteSheetWindow::onOpenGeneratedChange, this));
@ -397,6 +401,10 @@ public:
return trimEnabled()->isSelected();
}
bool trimByGridValue() const {
return gridTrimEnabled()->isSelected();
}
bool extrudeValue() const {
return extrudeEnabled()->isSelected();
}
@ -543,6 +551,12 @@ private:
resize();
}
void onTrimEnabledChange() {
trimContainer()->setVisible(trimEnabled()->isSelected());
resize();
updateSizeFields();
}
void onPaddingEnabledChange() {
paddingContainer()->setVisible(paddingEnabled()->isSelected());
resize();
@ -671,6 +685,7 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
if (!params.shapePadding.isSet()) params.shapePadding( docPref.spriteSheet.shapePadding());
if (!params.innerPadding.isSet()) params.innerPadding( docPref.spriteSheet.innerPadding());
if (!params.trim.isSet()) params.trim( docPref.spriteSheet.trim());
if (!params.trimByGrid.isSet()) params.trimByGrid( docPref.spriteSheet.trimByGrid());
if (!params.extrude.isSet()) params.extrude( docPref.spriteSheet.extrude());
if (!params.openGenerated.isSet()) params.openGenerated( docPref.spriteSheet.openGenerated());
if (!params.layer.isSet()) params.layer( docPref.spriteSheet.layer());
@ -699,6 +714,7 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
docPref.spriteSheet.shapePadding (params.shapePadding (window.shapePaddingValue()));
docPref.spriteSheet.innerPadding (params.innerPadding (window.innerPaddingValue()));
docPref.spriteSheet.trim (params.trim (window.trimValue()));
docPref.spriteSheet.trimByGrid (params.trimByGrid (window.trimByGridValue()));
docPref.spriteSheet.extrude (params.extrude (window.extrudeValue()));
docPref.spriteSheet.openGenerated (params.openGenerated (window.openGeneratedValue()));
docPref.spriteSheet.layer (params.layer (window.layerValue()));
@ -736,6 +752,7 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
const int shapePadding = base::clamp(params.shapePadding(), 0, 100);
const int innerPadding = base::clamp(params.innerPadding(), 0, 100);
const bool trimCels = params.trim();
const bool trimByGrid = params.trimByGrid();
const bool extrude = params.extrude();
const int extrudePadding = (extrude ? 1: 0);
const bool listLayers = params.listLayers();
@ -822,6 +839,7 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
exporter.setShapePadding(shapePadding);
exporter.setInnerPadding(innerPadding);
exporter.setTrimCels(trimCels);
exporter.setTrimByGrid(trimByGrid);
exporter.setExtrude(extrude);
if (listLayers) exporter.setListLayers(true);
if (listTags) exporter.setListFrameTags(true);

View File

@ -17,7 +17,9 @@
#include "app/doc.h"
#include "app/file/file.h"
#include "app/filename_formatter.h"
#include "app/pref/preferences.h"
#include "app/restore_visible_layers.h"
#include "app/snap_to_grid.h"
#include "base/convert_to.h"
#include "base/fs.h"
#include "base/fstream_path.h"
@ -396,6 +398,7 @@ DocExporter::DocExporter()
, m_shapePadding(0)
, m_innerPadding(0)
, m_trimCels(false)
, m_trimByGrid(false)
, m_extrude(false)
, m_listFrameTags(false)
, m_listLayers(false)
@ -599,8 +602,21 @@ void DocExporter::captureSamples(Samples& samples)
sample.setTrimmedBounds(frameBounds = gfx::Rect(0, 0, 0, 0));
}
if (m_trimCels)
if (m_trimCels) {
if (m_trimByGrid) {
auto& docPref = Preferences::instance().document(doc);
gfx::Point posTopLeft =
snap_to_grid(docPref.grid.bounds(),
frameBounds.origin(),
PreferSnapTo::FloorGrid);
gfx::Point posBottomRight =
snap_to_grid(docPref.grid.bounds(),
frameBounds.point2(),
PreferSnapTo::CeilGrid);
frameBounds = gfx::Rect(posTopLeft, posBottomRight);
}
sample.setTrimmedBounds(frameBounds);
}
}
samples.addSample(sample);

View File

@ -54,6 +54,7 @@ namespace app {
int shapePadding() const { return m_shapePadding; }
int innerPadding() const { return m_innerPadding; }
bool trimCels() const { return m_trimCels; }
bool trimByGrid() const { return m_trimByGrid; }
bool extrude() const { return m_extrude; }
const std::string& filenameFormat() const { return m_filenameFormat; }
bool listFrameTags() const { return m_listFrameTags; }
@ -70,6 +71,7 @@ namespace app {
void setShapePadding(int padding) { m_shapePadding = padding; }
void setInnerPadding(int padding) { m_innerPadding = padding; }
void setTrimCels(bool trim) { m_trimCels = trim; }
void setTrimByGrid(bool trimByGrid) { m_trimByGrid = trimByGrid; }
void setExtrude(bool extrude) { m_extrude = extrude; }
void setFilenameFormat(const std::string& format) { m_filenameFormat = format; }
void setListFrameTags(bool value) { m_listFrameTags = value; }
@ -135,6 +137,7 @@ namespace app {
int m_shapePadding;
int m_innerPadding;
bool m_trimCels;
bool m_trimByGrid;
bool m_extrude;
Items m_documents;
std::string m_filenameFormat;

View File

@ -38,12 +38,21 @@ gfx::Point snap_to_grid(const gfx::Rect& grid,
break;
case PreferSnapTo::BoxOrigin:
case PreferSnapTo::FloorGrid:
d = std::div(point.x-dx.rem, grid.w);
newPoint.x = dx.rem + d.quot*grid.w;
d = std::div(point.y-dy.rem, grid.h);
newPoint.y = dy.rem + d.quot*grid.h;
break;
case PreferSnapTo::CeilGrid:
d = std::div(point.x-dx.rem, grid.w);
newPoint.x = d.rem ? dx.rem + (d.quot+1)*grid.w: point.x;
d = std::div(point.y-dy.rem, grid.h);
newPoint.y = d.rem ? dy.rem + (d.quot+1)*grid.h: point.y;
break;
}
return newPoint;

View File

@ -14,7 +14,9 @@ namespace app {
enum class PreferSnapTo {
ClosestGridVertex,
BoxOrigin
BoxOrigin,
FloorGrid,
CeilGrid
};
gfx::Point snap_to_grid(const gfx::Rect& grid,