Skip to content

Commit

Permalink
Add --trim-by-grid CLI option
Browse files Browse the repository at this point in the history
  • Loading branch information
dncampo authored and dacap committed Mar 22, 2019
1 parent 8062c81 commit f24eb75
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 7 deletions.
4 changes: 4 additions & 0 deletions data/gui.xml
Expand Up @@ -480,6 +480,10 @@
<key command="SymmetryMode">
<param name="orientation" value="horizontal" />
</key>
<key command="AutocropSprite" />
<key command="AutocropSprite">
<param name="byGrid" value="true" />
</key>
</commands>

<!-- Keyboard shortcuts to select tools -->
Expand Down
1 change: 1 addition & 0 deletions src/app/cli/app_options.cpp
Expand Up @@ -59,6 +59,7 @@ AppOptions::AppOptions(int argc, const char* argv[])
, m_shapePadding(m_po.add("shape-padding").requiresValue("<value>").description("Add padding between frames"))
, m_innerPadding(m_po.add("inner-padding").requiresValue("<value>").description("Add padding inside each frame"))
, m_trim(m_po.add("trim").description("Trim all images before exporting"))
, m_trimByGrid(m_po.add("trim-by-grid").description("Trim all images by its correspondent grid boundaries before exporting"))
, m_crop(m_po.add("crop").requiresValue("x,y,width,height").description("Crop all the images to the given rectangle"))
, m_slice(m_po.add("slice").requiresValue("<name>").description("Crop the sprite to the given slice area"))
, m_filenameFormat(m_po.add("filename-format").requiresValue("<fmt>").description("Special format to generate filenames"))
Expand Down
2 changes: 2 additions & 0 deletions src/app/cli/app_options.h
Expand Up @@ -73,6 +73,7 @@ class AppOptions {
const Option& shapePadding() const { return m_shapePadding; }
const Option& innerPadding() const { return m_innerPadding; }
const Option& trim() const { return m_trim; }
const Option& trimByGrid() const { return m_trimByGrid; }
const Option& crop() const { return m_crop; }
const Option& slice() const { return m_slice; }
const Option& filenameFormat() const { return m_filenameFormat; }
Expand Down Expand Up @@ -132,6 +133,7 @@ class AppOptions {
Option& m_shapePadding;
Option& m_innerPadding;
Option& m_trim;
Option& m_trimByGrid;
Option& m_crop;
Option& m_slice;
Option& m_filenameFormat;
Expand Down
1 change: 1 addition & 0 deletions src/app/cli/cli_open_file.cpp
Expand Up @@ -32,6 +32,7 @@ CliOpenFile::CliOpenFile()
listSlices = false;
ignoreEmpty = false;
trim = false;
trimByGrid = false;
oneFrame = false;
crop = gfx::Rect();
}
Expand Down
1 change: 1 addition & 0 deletions src/app/cli/cli_open_file.h
Expand Up @@ -37,6 +37,7 @@ namespace app {
bool listSlices;
bool ignoreEmpty;
bool trim;
bool trimByGrid;
bool oneFrame;
gfx::Rect crop;

Expand Down
18 changes: 16 additions & 2 deletions src/app/cli/cli_processor.cpp
Expand Up @@ -271,6 +271,14 @@ void CliProcessor::process(Context* ctx)
if (m_exporter)
m_exporter->setTrimCels(true);
}
// --trim-by-grid
else if (opt == &m_options.trimByGrid()) {
cof.trim = cof.trimByGrid = true;
if (m_exporter) {
m_exporter->setTrimCels(true);
m_exporter->setTrimByGrid(true);
}
}
// --crop x,y,width,height
else if (opt == &m_options.crop()) {
std::vector<std::string> parts;
Expand Down Expand Up @@ -712,8 +720,13 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
// don't have sheet .json) Also, we should trim each frame
// individually (a process that can be done only in
// FileOp::operate()).
if (cof.trim)
ctx->executeCommand(trimCommand);
if (cof.trim) {
Params params;
if (cof.trimByGrid) {
params.set("byGrid", "true");
}
ctx->executeCommand(trimCommand, params);
}

CliOpenFile itemCof = cof;
FilenameInfo fnInfo;
Expand Down Expand Up @@ -744,6 +757,7 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
// Call delegate
m_delegate->saveFile(ctx, itemCof);

// for trim or trimByGrid case
if (cof.trim) {
ctx->executeCommand(undoCommand);
clearUndo = true;
Expand Down
5 changes: 4 additions & 1 deletion src/app/cli/preview_cli_delegate.cpp
Expand Up @@ -96,7 +96,10 @@ void PreviewCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
}

if (cof.trim) {
std::cout << " - Trim\n";
if (cof.trimByGrid)
std::cout << " - Trim by Grid\n";
else
std::cout << " - Trim\n";
}

if (cof.ignoreEmpty) {
Expand Down
28 changes: 26 additions & 2 deletions src/app/commands/cmd_crop.cpp
Expand Up @@ -12,6 +12,7 @@
#include "app/commands/command.h"
#include "app/context_access.h"
#include "app/doc_api.h"
#include "app/i18n/strings.h"
#include "app/modules/gui.h"
#include "app/tx.h"
#include "app/ui/color_bar.h"
Expand Down Expand Up @@ -87,15 +88,30 @@ class AutocropSpriteCommand : public Command {
AutocropSpriteCommand();

protected:
void onLoadParams(const Params& params) override;
bool onEnabled(Context* context) override;
void onExecute(Context* context) override;
std::string onGetFriendlyName() const override;

private:
bool m_byGrid = false;
};

AutocropSpriteCommand::AutocropSpriteCommand()
: Command(CommandId::AutocropSprite(), CmdRecordableFlag)
{
}

void AutocropSpriteCommand::onLoadParams(const app::Params &params)
{
m_byGrid = false;
if (params.has_param("byGrid")) {
std::string isByGrid = params.get("byGrid");
if (isByGrid == "true")
m_byGrid = true;
}
}

bool AutocropSpriteCommand::onEnabled(Context* context)
{
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
Expand All @@ -108,8 +124,8 @@ void AutocropSpriteCommand::onExecute(Context* context)
Doc* document(writer.document());
Sprite* sprite(writer.sprite());
{
Tx tx(writer.context(), "Trim Sprite");
document->getApi(tx).trimSprite(sprite);
Tx tx(writer.context(), onGetFriendlyName());
document->getApi(tx).trimSprite(sprite, m_byGrid);
tx.commit();
}

Expand All @@ -119,6 +135,14 @@ void AutocropSpriteCommand::onExecute(Context* context)
#endif
}

std::string AutocropSpriteCommand::onGetFriendlyName() const
{
if (m_byGrid)
return "Trim Sprite by Grid";
else
return "Trim Sprite";
}

Command* CommandFactory::createCropSpriteCommand()
{
return new CropSpriteCommand;
Expand Down
18 changes: 17 additions & 1 deletion src/app/doc_api.cpp
Expand Up @@ -9,6 +9,7 @@
#endif

#include "app/doc_api.h"
#include "app/snap_to_grid.h"

#include "app/cmd/add_cel.h"
#include "app/cmd/add_frame.h"
Expand Down Expand Up @@ -45,6 +46,7 @@
#include "app/context.h"
#include "app/doc.h"
#include "app/doc_undo.h"
#include "app/pref/preferences.h"
#include "app/transaction.h"
#include "doc/algorithm/flip_image.h"
#include "doc/algorithm/shrink_bounds.h"
Expand Down Expand Up @@ -156,7 +158,7 @@ void DocApi::cropSprite(Sprite* sprite, const gfx::Rect& bounds)
}
}

void DocApi::trimSprite(Sprite* sprite)
void DocApi::trimSprite(Sprite* sprite, bool isByGrid)
{
gfx::Rect bounds;

Expand All @@ -174,6 +176,20 @@ void DocApi::trimSprite(Sprite* sprite)
gfx::Rect frameBounds;
if (doc::algorithm::shrink_bounds(image, frameBounds, get_pixel(image, 0, 0)))
bounds = bounds.createUnion(frameBounds);

if (isByGrid) {
Doc* doc = m_document;
auto& docPref = Preferences::instance().document(doc);
gfx::Point posTopLeft =
snap_to_grid(docPref.grid.bounds(),
bounds.origin(),
PreferSnapTo::FloorGrid);
gfx::Point posBottomRight =
snap_to_grid(docPref.grid.bounds(),
bounds.point2(),
PreferSnapTo::CeilGrid);
bounds = gfx::Rect(posTopLeft, posBottomRight);
}
}

if (!bounds.isEmpty())
Expand Down
2 changes: 1 addition & 1 deletion src/app/doc_api.h
Expand Up @@ -45,7 +45,7 @@ namespace app {
void setSpriteSize(Sprite* sprite, int w, int h);
void setSpriteTransparentColor(Sprite* sprite, color_t maskColor);
void cropSprite(Sprite* sprite, const gfx::Rect& bounds);
void trimSprite(Sprite* sprite);
void trimSprite(Sprite* sprite, bool isByGrid);

// Frames API
void addFrame(Sprite* sprite, frame_t newFrame);
Expand Down

0 comments on commit f24eb75

Please sign in to comment.