Refactor sprite size command params

This commit is contained in:
Gaspar Capello 2019-07-26 09:30:28 -03:00
parent ccef22f187
commit 3e1584e638
5 changed files with 135 additions and 108 deletions

View File

@ -13,7 +13,6 @@
#include "app/cli/app_options.h"
#include "app/cli/cli_delegate.h"
#include "app/commands/cmd_sprite_size.h"
#include "app/commands/commands.h"
#include "app/commands/params.h"
#include "app/console.h"
@ -350,14 +349,14 @@ void CliProcessor::process(Context* ctx)
}
// --scale <factor>
else if (opt == &m_options.scale()) {
Command* command = Commands::instance()->byId(CommandId::SpriteSize());
double scale = strtod(value.value().c_str(), NULL);
static_cast<SpriteSizeCommand*>(command)->setScale(scale, scale);
Params params;
params.set("scale", value.value().c_str());
// Scale all sprites
for (auto doc : ctx->documents()) {
ctx->setActiveDocument(doc);
ctx->executeCommand(command);
ctx->executeCommand(Commands::instance()->byId(CommandId::SpriteSize()),
params);
}
}
// --dithering-algorithm <algorithm>
@ -442,9 +441,10 @@ void CliProcessor::process(Context* ctx)
scaleHeight = (doc->height() > maxHeight ? maxHeight / doc->height() : 1.0);
if (scaleWidth < 1.0 || scaleHeight < 1.0) {
scale = MIN(scaleWidth, scaleHeight);
Command* command = Commands::instance()->byId(CommandId::SpriteSize());
static_cast<SpriteSizeCommand*>(command)->setScale(scale, scale);
ctx->executeCommand(command);
Params params;
params.set("scale", base::convert_to<std::string>(scale).c_str());
ctx->executeCommand(Commands::instance()->byId(CommandId::SpriteSize()),
params);
}
}
}

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2019 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -10,8 +11,8 @@
#include "app/cmd/set_cel_bounds.h"
#include "app/cmd/set_slice_key.h"
#include "app/commands/cmd_sprite_size.h"
#include "app/commands/command.h"
#include "app/commands/new_params.h"
#include "app/commands/params.h"
#include "app/doc_api.h"
#include "app/ini_file.h"
@ -19,6 +20,7 @@
#include "app/modules/palettes.h"
#include "app/sprite_job.h"
#include "base/bind.h"
#include "base/convert_to.h"
#include "doc/algorithm/resize_image.h"
#include "doc/cel.h"
#include "doc/cels_range.h"
@ -39,6 +41,17 @@ namespace app {
using namespace ui;
using doc::algorithm::ResizeMethod;
struct SpriteSizeParams : public NewParams {
Param<bool> ui { this, true, { "ui", "use-ui" } };
Param<int> width { this, 0, "width" };
Param<int> height { this, 0, "height" };
Param<bool> lockRatio { this, false, "lockRatio" };
Param<double> scale { this, 1.0, "scale" };
Param<double> scaleX { this, 1.0, "scaleX" };
Param<double> scaleY { this, 1.0, "scaleY" };
Param<ResizeMethod> method { this, ResizeMethod::RESIZE_METHOD_NEAREST_NEIGHBOR, { "method", "resize-method" } };
};
class SpriteSizeJob : public SpriteJob {
int m_new_width;
int m_new_height;
@ -180,17 +193,21 @@ protected:
};
#ifdef ENABLE_UI
class SpriteSizeWindow : public app::gen::SpriteSize {
public:
SpriteSizeWindow(Context* ctx, int new_width, int new_height) : m_ctx(ctx) {
SpriteSizeWindow(Context* ctx, const SpriteSizeParams& params) : m_ctx(ctx) {
lockRatio()->Click.connect(base::Bind<void>(&SpriteSizeWindow::onLockRatioClick, this));
widthPx()->Change.connect(base::Bind<void>(&SpriteSizeWindow::onWidthPxChange, this));
heightPx()->Change.connect(base::Bind<void>(&SpriteSizeWindow::onHeightPxChange, this));
widthPerc()->Change.connect(base::Bind<void>(&SpriteSizeWindow::onWidthPercChange, this));
heightPerc()->Change.connect(base::Bind<void>(&SpriteSizeWindow::onHeightPercChange, this));
widthPx()->setTextf("%d", new_width);
heightPx()->setTextf("%d", new_height);
widthPx()->setTextf("%d", params.width());
heightPx()->setTextf("%d", params.height());
widthPerc()->setTextf(PERC_FORMAT, params.scaleX() * 100.0);
heightPerc()->setTextf(PERC_FORMAT, params.scaleY() * 100.0);
static_assert(doc::algorithm::RESIZE_METHOD_NEAREST_NEIGHBOR == 0 &&
doc::algorithm::RESIZE_METHOD_BILINEAR == 1 &&
@ -199,9 +216,15 @@ public:
method()->addItem("Nearest-neighbor");
method()->addItem("Bilinear");
method()->addItem("RotSprite");
method()->setSelectedItemIndex(
get_config_int("SpriteSize", "Method",
doc::algorithm::RESIZE_METHOD_NEAREST_NEIGHBOR));
int resize_method;
if (params.method.isSet())
resize_method = (int)params.method();
else
resize_method = get_config_int("SpriteSize", "Method",
doc::algorithm::RESIZE_METHOD_NEAREST_NEIGHBOR);
method()->setSelectedItemIndex(resize_method);
const bool lock = (params.lockRatio.isSet())? params.lockRatio() : get_config_bool("SpriteSize", "LockRatio", false);
lockRatio()->setSelected(lock);
}
private:
@ -267,48 +290,20 @@ private:
Context* m_ctx;
};
#endif // ENABLE_UI
class SpriteSizeCommand : public CommandWithNewParams<SpriteSizeParams> {
public:
SpriteSizeCommand();
protected:
bool onEnabled(Context* context) override;
void onExecute(Context* context) override;
};
SpriteSizeCommand::SpriteSizeCommand()
: Command(CommandId::SpriteSize(), CmdRecordableFlag)
: CommandWithNewParams<SpriteSizeParams>(CommandId::SpriteSize(), CmdRecordableFlag)
{
m_useUI = true;
m_width = 0;
m_height = 0;
m_scaleX = 1.0;
m_scaleY = 1.0;
m_resizeMethod = doc::algorithm::RESIZE_METHOD_NEAREST_NEIGHBOR;
}
void SpriteSizeCommand::onLoadParams(const Params& params)
{
std::string useUI = params.get("use-ui");
m_useUI = (useUI.empty() || (useUI == "true"));
std::string width = params.get("width");
if (!width.empty()) {
m_width = std::strtol(width.c_str(), NULL, 10);
}
else
m_width = 0;
std::string height = params.get("height");
if (!height.empty()) {
m_height = std::strtol(height.c_str(), NULL, 10);
}
else
m_height = 0;
std::string resize_method = params.get("resize-method");
if (!resize_method.empty()) {
if (resize_method == "bilinear")
m_resizeMethod = doc::algorithm::RESIZE_METHOD_BILINEAR;
else if (resize_method == "rotsprite")
m_resizeMethod = doc::algorithm::RESIZE_METHOD_ROTSPRITE;
else
m_resizeMethod = doc::algorithm::RESIZE_METHOD_NEAREST_NEIGHBOR;
}
else
m_resizeMethod = doc::algorithm::RESIZE_METHOD_NEAREST_NEIGHBOR;
}
bool SpriteSizeCommand::onEnabled(Context* context)
@ -319,15 +314,73 @@ bool SpriteSizeCommand::onEnabled(Context* context)
void SpriteSizeCommand::onExecute(Context* context)
{
#ifdef ENABLE_UI
const bool ui = (params().ui() && context->isUIAvailable());
#endif
const ContextReader reader(context);
const Sprite* sprite(reader.sprite());
int new_width = (m_width ? m_width: int(sprite->width()*m_scaleX));
int new_height = (m_height ? m_height: int(sprite->height()*m_scaleY));
ResizeMethod resize_method = m_resizeMethod;
auto& params = this->params();
double ratio = sprite->width() / double(sprite->height());
if (params.scale.isSet()) {
params.width(int(sprite->width() * params.scale()));
params.height(int(sprite->height() * params.scale()));
params.scaleX(params.scale());
params.scaleY(params.scale());
}
else if (params.lockRatio()) {
if (params.width.isSet()) {
params.height(int(params.width() / ratio));
params.scaleX(params.width() / double(sprite->width()));
params.scaleY(params.scaleX());
}
else if (params.height.isSet()) {
params.width(int(params.height() * ratio));
params.scaleY(params.height() / double(sprite->height()));
params.scaleX(params.scaleY());
}
else if (params.scaleX.isSet()) {
params.width(int(params.scaleX() * sprite->width()));
params.height(int(params.scaleX() * sprite->height()));
params.scaleY(params.scaleX());
}
else if (params.scaleY.isSet()) {
params.width(int(params.scaleY() * sprite->width()));
params.height(int(params.scaleY() * sprite->height()));
params.scaleX(params.scaleY());
}
else {
params.width(sprite->width());
params.height(sprite->height());
}
}
else {
if (params.width.isSet()) {
params.scaleX(params.width() / double(sprite->width()));
}
else if (params.scaleX.isSet()) {
params.width(int(params.scaleX() * sprite->width()));
}
else {
params.width(sprite->width());
}
if (params.height.isSet()) {
params.scaleY(params.height() / double(sprite->height()));
}
else if (params.scaleY.isSet()) {
params.height(int(params.scaleY() * sprite->height()));
}
else {
params.height(sprite->height());
}
}
int new_width = params.width();
int new_height = params.height();
ResizeMethod resize_method = params.method();
#ifdef ENABLE_UI
if (m_useUI && context->isUIAvailable()) {
SpriteSizeWindow window(context, new_width, new_height);
if (ui) {
SpriteSizeWindow window(context, params);
window.remapWindow();
window.centerWindow();
@ -344,6 +397,7 @@ void SpriteSizeCommand::onExecute(Context* context)
resize_method = (ResizeMethod)window.method()->getSelectedItemIndex();
set_config_int("SpriteSize", "Method", resize_method);
set_config_bool("SpriteSize", "LockRatio", window.lockRatio()->isSelected());
}
#endif // ENABLE_UI

View File

@ -1,48 +0,0 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifndef APP_COMMANDS_CMD_SPRITE_SIZE_H_INCLUDED
#define APP_COMMANDS_CMD_SPRITE_SIZE_H_INCLUDED
#pragma once
#include "app/commands/command.h"
#include "doc/algorithm/resize_image.h"
#include <string>
namespace ui {
class CheckBox;
class Entry;
}
namespace app {
class SpriteSizeCommand : public Command {
public:
SpriteSizeCommand();
void setScale(double x, double y) {
m_scaleX = x;
m_scaleY = y;
}
protected:
virtual void onLoadParams(const Params& params) override;
virtual bool onEnabled(Context* context) override;
virtual void onExecute(Context* context) override;
private:
bool m_useUI;
int m_width;
int m_height;
double m_scaleX;
double m_scaleY;
doc::algorithm::ResizeMethod m_resizeMethod;
};
} // namespace app
#endif

View File

@ -15,6 +15,7 @@
#include "app/sprite_sheet_type.h"
#include "base/convert_to.h"
#include "base/string.h"
#include "doc/algorithm/resize_image.h"
#include "doc/color_mode.h"
#include "filters/hue_saturation_filter.h"
#include "filters/outline_filter.h"
@ -55,6 +56,17 @@ void Param<std::string>::fromString(const std::string& value)
setValue(value);
}
template<>
void Param<doc::algorithm::ResizeMethod>::fromString(const std::string& value)
{
if (base::utf8_icmp(value, "bilinear") == 0)
setValue(doc::algorithm::RESIZE_METHOD_BILINEAR);
else if (base::utf8_icmp(value, "rotsprite") == 0)
setValue(doc::algorithm::RESIZE_METHOD_ROTSPRITE);
else
setValue(doc::algorithm::ResizeMethod::RESIZE_METHOD_NEAREST_NEIGHBOR);
}
template<>
void Param<app::SpriteSheetType>::fromString(const std::string& value)
{
@ -183,6 +195,15 @@ void Param<std::string>::fromLua(lua_State* L, int index)
setValue(std::string());
}
template<>
void Param<doc::algorithm::ResizeMethod>::fromLua(lua_State* L, int index)
{
if (lua_type(L, index) == LUA_TSTRING)
fromString(lua_tostring(L, index));
else
setValue((doc::algorithm::ResizeMethod)lua_tointeger(L, index));
}
template<>
void Param<app::SpriteSheetType>::fromLua(lua_State* L, int index)
{

View File

@ -73,7 +73,7 @@ namespace app {
params->addParam(id, this);
}
bool isSet() {
bool isSet() const {
return m_isSet;
}