Add --crop command line (close #620)

This commit is contained in:
David Capello 2015-04-01 14:59:49 -03:00
parent 20394ceec2
commit 7c3547f147
4 changed files with 50 additions and 6 deletions

View File

@ -59,6 +59,7 @@
#include "base/exception.h"
#include "base/fs.h"
#include "base/path.h"
#include "base/split_string.h"
#include "base/unique_ptr.h"
#include "doc/document_observer.h"
#include "doc/image.h"
@ -204,6 +205,7 @@ void App::initialize(const AppOptions& options)
bool ignoreEmpty = false;
bool trim = false;
Params cropParams;
// Open file specified in the command line
if (!options.values().empty()) {
@ -277,6 +279,17 @@ void App::initialize(const AppOptions& options)
else if (opt == &options.trim()) {
trim = true;
}
// --crop
else if (opt == &options.crop()) {
std::vector<std::string> parts;
base::split_string(value.value(), parts, ",");
if (parts.size() == 4) {
cropParams.set("x", parts[0].c_str());
cropParams.set("y", parts[1].c_str());
cropParams.set("width", parts[2].c_str());
cropParams.set("height", parts[3].c_str());
}
}
// --filename-format
else if (opt == &options.filenameFormat()) {
filenameFormat = value.value();
@ -297,6 +310,7 @@ void App::initialize(const AppOptions& options)
Command* saveAsCommand = CommandsModule::instance()->getCommandByName(CommandId::SaveFileCopyAs);
Command* trimCommand = CommandsModule::instance()->getCommandByName(CommandId::AutocropSprite);
Command* cropCommand = CommandsModule::instance()->getCommandByName(CommandId::CropSprite);
Command* undoCommand = CommandsModule::instance()->getCommandByName(CommandId::Undo);
if (splitLayersSaveAs) {
@ -321,6 +335,9 @@ void App::initialize(const AppOptions& options)
fmt = filename_formatter(format,
value.value(), show->name(), -1, false);
if (!cropParams.empty())
ctx->executeCommand(cropCommand, cropParams);
// TODO --trim command with --save-as doesn't make too
// much sense as we lost the trim rectangle
// information (e.g. we don't have sheet .json) Also,
@ -353,6 +370,9 @@ void App::initialize(const AppOptions& options)
layer->setVisible(layer->name() == importLayerSaveAs);
}
if (!cropParams.empty())
ctx->executeCommand(cropCommand, cropParams);
if (trim)
ctx->executeCommand(trimCommand);

View File

@ -42,6 +42,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_crop(m_po.add("crop").requiresValue("x,y,width,height").description("Crop all the images to the given rectangle"))
, m_filenameFormat(m_po.add("filename-format").requiresValue("<fmt>").description("Special format to generate filenames"))
, m_verbose(m_po.add("verbose").description("Explain what is being done"))
, m_help(m_po.add("help").mnemonic('?').description("Display this help and exits"))

View File

@ -50,6 +50,7 @@ public:
const Option& shapePadding() const { return m_shapePadding; }
const Option& innerPadding() const { return m_innerPadding; }
const Option& trim() const { return m_trim; }
const Option& crop() const { return m_crop; }
const Option& filenameFormat() const { return m_filenameFormat; }
bool hasExporterParams() const;
@ -82,6 +83,7 @@ private:
Option& m_shapePadding;
Option& m_innerPadding;
Option& m_trim;
Option& m_crop;
Option& m_filenameFormat;
Option& m_verbose;

View File

@ -30,8 +30,12 @@ public:
Command* clone() const override { return new CropSpriteCommand(*this); }
protected:
bool onEnabled(Context* context);
void onExecute(Context* context);
void onLoadParams(const Params& params) override;
bool onEnabled(Context* context) override;
void onExecute(Context* context) override;
private:
gfx::Rect m_bounds;
};
CropSpriteCommand::CropSpriteCommand()
@ -41,10 +45,21 @@ CropSpriteCommand::CropSpriteCommand()
{
}
void CropSpriteCommand::onLoadParams(const Params& params)
{
m_bounds = gfx::Rect(0, 0, 0, 0);
if (params.has_param("x")) m_bounds.x = params.get_as<int>("x");
if (params.has_param("y")) m_bounds.y = params.get_as<int>("y");
if (params.has_param("width")) m_bounds.w = params.get_as<int>("width");
if (params.has_param("height")) m_bounds.h = params.get_as<int>("height");
}
bool CropSpriteCommand::onEnabled(Context* context)
{
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
ContextFlags::HasVisibleMask);
return
context->checkFlags(
ContextFlags::ActiveDocumentIsWritable |
(m_bounds.isEmpty() ? ContextFlags::HasVisibleMask: 0));
}
void CropSpriteCommand::onExecute(Context* context)
@ -52,10 +67,16 @@ void CropSpriteCommand::onExecute(Context* context)
ContextWriter writer(context);
Document* document(writer.document());
Sprite* sprite(writer.sprite());
Mask* mask(document->mask());
gfx::Rect bounds;
if (m_bounds.isEmpty())
bounds = document->mask()->bounds();
else
bounds = m_bounds;
{
Transaction transaction(writer.context(), "Sprite Crop");
document->getApi(transaction).cropSprite(sprite, mask->bounds());
document->getApi(transaction).cropSprite(sprite, bounds);
transaction.commit();
}
document->generateMaskBoundaries();