lua: Support more filters from scripts (BrightnessContrast, Despeckle, HueSaturation, InvertColor, Outline)

This commit is contained in:
David Capello 2019-07-18 11:44:33 -03:00
parent 814250e325
commit 1ef67cada4
15 changed files with 383 additions and 100 deletions

View File

@ -293,13 +293,8 @@ if(ENABLE_UI)
commands/cmd_undo_history.cpp
commands/cmd_unlink_cel.cpp
commands/cmd_zoom.cpp
commands/filters/cmd_brightness_contrast.cpp
commands/filters/cmd_color_curve.cpp
commands/filters/cmd_convolution_matrix.cpp
commands/filters/cmd_despeckle.cpp
commands/filters/cmd_hue_saturation.cpp
commands/filters/cmd_invert_color.cpp
commands/filters/cmd_outline.cpp
commands/filters/color_curve_editor.cpp
commands/filters/convolution_matrix_stock.cpp
commands/filters/filter_preview.cpp
@ -520,6 +515,11 @@ add_library(app-lib
commands/cmd_undo.cpp
commands/command.cpp
commands/commands.cpp
commands/filters/cmd_brightness_contrast.cpp
commands/filters/cmd_despeckle.cpp
commands/filters/cmd_hue_saturation.cpp
commands/filters/cmd_invert_color.cpp
commands/filters/cmd_outline.cpp
commands/filters/cmd_replace_color.cpp
commands/filters/filter_manager_impl.cpp
commands/filters/filter_worker.cpp

View File

@ -7,12 +7,16 @@
FOR_EACH_COMMAND(AutocropSprite)
FOR_EACH_COMMAND(BackgroundFromLayer)
FOR_EACH_COMMAND(BrightnessContrast)
FOR_EACH_COMMAND(CanvasSize)
FOR_EACH_COMMAND(CelOpacity)
FOR_EACH_COMMAND(ChangePixelFormat)
FOR_EACH_COMMAND(CropSprite)
FOR_EACH_COMMAND(Despeckle)
FOR_EACH_COMMAND(ExportSpriteSheet)
FOR_EACH_COMMAND(FlattenLayers)
FOR_EACH_COMMAND(HueSaturation)
FOR_EACH_COMMAND(InvertColor)
FOR_EACH_COMMAND(LayerFromBackground)
FOR_EACH_COMMAND(LoadPalette)
FOR_EACH_COMMAND(MergeDownLayer)
@ -20,6 +24,7 @@ FOR_EACH_COMMAND(NewFile)
FOR_EACH_COMMAND(NewFrame)
FOR_EACH_COMMAND(NewLayer)
FOR_EACH_COMMAND(OpenFile)
FOR_EACH_COMMAND(Outline)
FOR_EACH_COMMAND(PaletteSize)
FOR_EACH_COMMAND(Redo)
FOR_EACH_COMMAND(RemoveLayer)
@ -34,7 +39,6 @@ FOR_EACH_COMMAND(Undo)
FOR_EACH_COMMAND(About)
FOR_EACH_COMMAND(AddColor)
FOR_EACH_COMMAND(AdvancedMode)
FOR_EACH_COMMAND(BrightnessContrast)
FOR_EACH_COMMAND(Cancel)
FOR_EACH_COMMAND(CelProperties)
FOR_EACH_COMMAND(ChangeBrush)
@ -53,7 +57,6 @@ FOR_EACH_COMMAND(CopyCel)
FOR_EACH_COMMAND(CopyMerged)
FOR_EACH_COMMAND(Cut)
FOR_EACH_COMMAND(DeselectMask)
FOR_EACH_COMMAND(Despeckle)
FOR_EACH_COMMAND(DiscardBrush)
FOR_EACH_COMMAND(DuplicateLayer)
FOR_EACH_COMMAND(DuplicateSprite)
@ -81,9 +84,7 @@ FOR_EACH_COMMAND(GotoPreviousLayer)
FOR_EACH_COMMAND(GotoPreviousTab)
FOR_EACH_COMMAND(GridSettings)
FOR_EACH_COMMAND(Home)
FOR_EACH_COMMAND(HueSaturation)
FOR_EACH_COMMAND(ImportSpriteSheet)
FOR_EACH_COMMAND(InvertColor)
FOR_EACH_COMMAND(InvertMask)
FOR_EACH_COMMAND(KeyboardShortcuts)
FOR_EACH_COMMAND(Launch)
@ -107,7 +108,6 @@ FOR_EACH_COMMAND(OpenGroup)
FOR_EACH_COMMAND(OpenInFolder)
FOR_EACH_COMMAND(OpenWithApp)
FOR_EACH_COMMAND(Options)
FOR_EACH_COMMAND(Outline)
FOR_EACH_COMMAND(PaletteEditor)
FOR_EACH_COMMAND(Paste)
FOR_EACH_COMMAND(PasteText)

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2019 Igara Studio S.A.
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
@ -12,6 +13,8 @@
#include "app/commands/command.h"
#include "app/commands/filters/filter_manager_impl.h"
#include "app/commands/filters/filter_window.h"
#include "app/commands/filters/filter_worker.h"
#include "app/commands/new_params.h"
#include "app/context.h"
#include "app/ini_file.h"
#include "app/modules/gui.h"
@ -30,6 +33,15 @@
namespace app {
struct BrightnessContrastParams : public NewParams {
Param<bool> ui { this, true, "ui" };
Param<filters::Target> channels { this, 0, "channels" };
Param<double> brightness { this, 0.0, "brightness" };
Param<double> contrast { this, 0.0, "contrast" };
};
#ifdef ENABLE_UI
static const char* ConfigSection = "BrightnessContrast";
class BrightnessContrastWindow : public FilterWindow {
@ -39,8 +51,8 @@ public:
: FilterWindow("Brightness/Contrast", ConfigSection, &filterMgr,
WithChannelsSelector,
WithoutTiledCheckBox)
, m_brightness(-100, 100, 0)
, m_contrast(-100, 100, 0)
, m_brightness(-100, 100, int(100.0 * filter.brightness()))
, m_contrast(-100, 100, int(100.0 * filter.contrast()))
, m_filter(filter)
{
getContainer()->addChild(new ui::Label("Brightness:"));
@ -64,7 +76,9 @@ private:
BrightnessContrastFilter& m_filter;
};
class BrightnessContrastCommand : public Command {
#endif // ENABLE_UI
class BrightnessContrastCommand : public CommandWithNewParams<BrightnessContrastParams> {
public:
BrightnessContrastCommand();
@ -74,7 +88,7 @@ protected:
};
BrightnessContrastCommand::BrightnessContrastCommand()
: Command(CommandId::BrightnessContrast(), CmdRecordableFlag)
: CommandWithNewParams<BrightnessContrastParams>(CommandId::BrightnessContrast(), CmdRecordableFlag)
{
}
@ -86,6 +100,10 @@ bool BrightnessContrastCommand::onEnabled(Context* context)
void BrightnessContrastCommand::onExecute(Context* context)
{
#ifdef ENABLE_UI
const bool ui = (params().ui() && context->isUIAvailable());
#endif
BrightnessContrastFilter filter;
FilterManagerImpl filterMgr(context, &filter);
filterMgr.setTarget(TARGET_RED_CHANNEL |
@ -94,8 +112,20 @@ void BrightnessContrastCommand::onExecute(Context* context)
TARGET_GRAY_CHANNEL |
TARGET_ALPHA_CHANNEL);
BrightnessContrastWindow window(filter, filterMgr);
window.doModal();
if (params().channels.isSet()) filterMgr.setTarget(params().channels());
if (params().brightness.isSet()) filter.setBrightness(params().brightness() / 100.0);
if (params().contrast.isSet()) filter.setContrast(params().contrast() / 100.0);
#ifdef ENABLE_UI
if (ui) {
BrightnessContrastWindow window(filter, filterMgr);
window.doModal();
}
else
#endif // ENABLE_UI
{
start_filter_worker(&filterMgr);
}
}
Command* CommandFactory::createBrightnessContrastCommand()

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
@ -12,13 +13,15 @@
#include "app/commands/command.h"
#include "app/commands/filters/filter_manager_impl.h"
#include "app/commands/filters/filter_window.h"
#include "app/commands/filters/filter_worker.h"
#include "app/commands/new_params.h"
#include "app/context.h"
#include "app/doc.h"
#include "app/find_widget.h"
#include "app/ini_file.h"
#include "app/load_widget.h"
#include "app/pref/preferences.h"
#include "base/bind.h"
#include "base/clamp.h"
#include "doc/mask.h"
#include "doc/sprite.h"
#include "filters/median_filter.h"
@ -36,6 +39,16 @@ namespace app {
using namespace filters;
struct DespeckleParams : public NewParams {
Param<bool> ui { this, true, "ui" };
Param<filters::Target> channels { this, 0, "channels" };
Param<int> width { this, 3, "width" };
Param<int> height { this, 3, "height" };
Param<filters::TiledMode> tiledMode { this, filters::TiledMode::NONE, "tiledMode" };
};
#ifdef ENABLE_UI
static const char* ConfigSection = "Despeckle";
class DespeckleWindow : public FilterWindow {
@ -65,8 +78,8 @@ private:
m_heightEntry->textInt());
// Avoid negative numbers
newSize.w = MID(1, newSize.w, 100);
newSize.h = MID(1, newSize.h, 100);
newSize.w = base::clamp(newSize.w, 1, 100);
newSize.h = base::clamp(newSize.h, 1, 100);
m_filter.setSize(newSize.w, newSize.h);
restartPreview();
@ -82,11 +95,9 @@ private:
ExprEntry* m_heightEntry;
};
//////////////////////////////////////////////////////////////////////
// Despeckle command
#endif // ENABLE_UI
class DespeckleCommand : public Command
{
class DespeckleCommand : public CommandWithNewParams<DespeckleParams> {
public:
DespeckleCommand();
@ -96,7 +107,7 @@ protected:
};
DespeckleCommand::DespeckleCommand()
: Command(CommandId::Despeckle(), CmdRecordableFlag)
: CommandWithNewParams<DespeckleParams>(CommandId::Despeckle(), CmdRecordableFlag)
{
}
@ -108,13 +119,12 @@ bool DespeckleCommand::onEnabled(Context* context)
void DespeckleCommand::onExecute(Context* context)
{
DocumentPreferences& docPref = Preferences::instance()
.document(context->activeDocument());
#ifdef ENABLE_UI
const bool ui = (params().ui() && context->isUIAvailable());
#endif
MedianFilter filter;
filter.setTiledMode((filters::TiledMode)docPref.tiled.mode());
filter.setSize(get_config_int(ConfigSection, "Width", 3),
get_config_int(ConfigSection, "Height", 3));
filter.setSize(3, 3); // Default size
FilterManagerImpl filterMgr(context, &filter);
filterMgr.setTarget(TARGET_RED_CHANNEL |
@ -122,10 +132,33 @@ void DespeckleCommand::onExecute(Context* context)
TARGET_BLUE_CHANNEL |
TARGET_GRAY_CHANNEL);
DespeckleWindow window(filter, filterMgr);
if (window.doModal()) {
set_config_int(ConfigSection, "Width", filter.getWidth());
set_config_int(ConfigSection, "Height", filter.getHeight());
#ifdef ENABLE_UI
if (ui) {
DocumentPreferences& docPref = Preferences::instance()
.document(context->activeDocument());
filter.setTiledMode((filters::TiledMode)docPref.tiled.mode());
filter.setSize(get_config_int(ConfigSection, "Width", 3),
get_config_int(ConfigSection, "Height", 3));
}
#endif
if (params().width.isSet()) filter.setSize(params().width(), filter.getHeight());
if (params().height.isSet()) filter.setSize(filter.getWidth(), params().height());
if (params().channels.isSet()) filterMgr.setTarget(params().channels());
if (params().tiledMode.isSet()) filter.setTiledMode(params().tiledMode());
#ifdef ENABLE_UI
if (ui) {
DespeckleWindow window(filter, filterMgr);
if (window.doModal()) {
set_config_int(ConfigSection, "Width", filter.getWidth());
set_config_int(ConfigSection, "Height", filter.getHeight());
}
}
else
#endif // ENABLE_UI
{
start_filter_worker(&filterMgr);
}
}

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2019 Igara Studio S.A.
// Copyright (C) 2017-2018 David Capello
//
// This program is distributed under the terms of
@ -12,6 +13,8 @@
#include "app/commands/command.h"
#include "app/commands/filters/filter_manager_impl.h"
#include "app/commands/filters/filter_window.h"
#include "app/commands/filters/filter_worker.h"
#include "app/commands/new_params.h"
#include "app/context.h"
#include "app/ini_file.h"
#include "app/modules/gui.h"
@ -32,6 +35,18 @@
namespace app {
struct HueSaturationParams : public NewParams {
Param<bool> ui { this, true, "ui" };
Param<filters::Target> channels { this, 0, "channels" };
Param<filters::HueSaturationFilter::Mode> mode { this, filters::HueSaturationFilter::Mode::HSL, "mode" };
Param<double> hue { this, 0.0, "hue" };
Param<double> saturation { this, 0.0, "saturation" };
Param<double> lightness { this, 0.0, { "lightness", "value" } };
Param<double> alpha { this, 0.0, "alpha" };
};
#ifdef ENABLE_UI
static const char* ConfigSection = "HueSaturation";
class HueSaturationWindow : public FilterWindow {
@ -117,7 +132,9 @@ private:
ColorSliders m_sliders;
};
class HueSaturationCommand : public Command {
#endif // ENABLE_UI
class HueSaturationCommand : public CommandWithNewParams<HueSaturationParams> {
public:
HueSaturationCommand();
@ -127,7 +144,7 @@ protected:
};
HueSaturationCommand::HueSaturationCommand()
: Command(CommandId::HueSaturation(), CmdRecordableFlag)
: CommandWithNewParams<HueSaturationParams>(CommandId::HueSaturation(), CmdRecordableFlag)
{
}
@ -139,16 +156,37 @@ bool HueSaturationCommand::onEnabled(Context* context)
void HueSaturationCommand::onExecute(Context* context)
{
#ifdef ENABLE_UI
const bool ui = (params().ui() && context->isUIAvailable());
#endif
HueSaturationFilter filter;
FilterManagerImpl filterMgr(context, &filter);
filterMgr.setTarget(TARGET_RED_CHANNEL |
TARGET_GREEN_CHANNEL |
TARGET_BLUE_CHANNEL |
TARGET_GRAY_CHANNEL |
TARGET_ALPHA_CHANNEL);
if (params().mode.isSet()) filter.setMode(params().mode());
if (params().hue.isSet()) filter.setHue(params().hue());
if (params().saturation.isSet()) filter.setSaturation(params().saturation() / 100.0);
if (params().lightness.isSet()) filter.setLightness(params().lightness() / 100.0);
if (params().alpha.isSet()) filter.setAlpha(params().alpha() / 100.0);
HueSaturationWindow window(filter, filterMgr);
window.doModal();
filters::Target channels =
TARGET_RED_CHANNEL |
TARGET_GREEN_CHANNEL |
TARGET_BLUE_CHANNEL |
TARGET_GRAY_CHANNEL |
TARGET_ALPHA_CHANNEL;
if (params().channels.isSet()) channels = params().channels();
filterMgr.setTarget(channels);
#ifdef ENABLE_UI
if (ui) {
HueSaturationWindow window(filter, filterMgr);
window.doModal();
}
else
#endif // ENABLE_UI
{
start_filter_worker(&filterMgr);
}
}
Command* CommandFactory::createHueSaturationCommand()

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2019 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
@ -9,18 +10,20 @@
#endif
#include "app/color.h"
#include "app/ui/color_button.h"
#include "base/bind.h"
#include "app/commands/command.h"
#include "app/commands/filters/filter_manager_impl.h"
#include "app/commands/filters/filter_window.h"
#include "app/commands/filters/filter_worker.h"
#include "app/commands/new_params.h"
#include "app/context.h"
#include "filters/invert_color_filter.h"
#include "app/ini_file.h"
#include "app/modules/gui.h"
#include "app/ui/color_button.h"
#include "base/bind.h"
#include "doc/image.h"
#include "doc/mask.h"
#include "doc/sprite.h"
#include "filters/invert_color_filter.h"
#include "ui/button.h"
#include "ui/label.h"
#include "ui/slider.h"
@ -29,6 +32,13 @@
namespace app {
struct InvertColorParams : public NewParams {
Param<bool> ui { this, true, "ui" };
Param<filters::Target> channels { this, 0, "channels" };
};
#ifdef ENABLE_UI
static const char* ConfigSection = "InvertColor";
class InvertColorWindow : public FilterWindow {
@ -36,12 +46,13 @@ public:
InvertColorWindow(FilterManagerImpl& filterMgr)
: FilterWindow("Invert Color", ConfigSection, &filterMgr,
WithChannelsSelector,
WithoutTiledCheckBox)
{
WithoutTiledCheckBox) {
}
};
class InvertColorCommand : public Command {
#endif // ENABLE_UI
class InvertColorCommand : public CommandWithNewParams<InvertColorParams> {
public:
InvertColorCommand();
@ -51,7 +62,7 @@ protected:
};
InvertColorCommand::InvertColorCommand()
: Command(CommandId::InvertColor(), CmdRecordableFlag)
: CommandWithNewParams<InvertColorParams>(CommandId::InvertColor(), CmdRecordableFlag)
{
}
@ -63,6 +74,10 @@ bool InvertColorCommand::onEnabled(Context* context)
void InvertColorCommand::onExecute(Context* context)
{
#ifdef ENABLE_UI
const bool ui = (params().ui() && context->isUIAvailable());
#endif
InvertColorFilter filter;
FilterManagerImpl filterMgr(context, &filter);
filterMgr.setTarget(TARGET_RED_CHANNEL |
@ -70,8 +85,18 @@ void InvertColorCommand::onExecute(Context* context)
TARGET_BLUE_CHANNEL |
TARGET_GRAY_CHANNEL);
InvertColorWindow window(filterMgr);
window.doModal();
if (params().channels.isSet()) filterMgr.setTarget(params().channels());
#ifdef ENABLE_UI
if (ui) {
InvertColorWindow window(filterMgr);
window.doModal();
}
else
#endif // ENABLE_UI
{
start_filter_worker(&filterMgr);
}
}
Command* CommandFactory::createInvertColorCommand()

View File

@ -13,6 +13,8 @@
#include "app/commands/command.h"
#include "app/commands/filters/filter_manager_impl.h"
#include "app/commands/filters/filter_window.h"
#include "app/commands/filters/filter_worker.h"
#include "app/commands/new_params.h"
#include "app/context.h"
#include "app/ini_file.h"
#include "app/modules/gui.h"
@ -39,7 +41,15 @@ using namespace app::skin;
enum { CIRCLE, SQUARE, HORZ, VERT };
static const char* ConfigSection = "Outline";
struct OutlineParams : public NewParams {
Param<bool> ui { this, true, "ui" };
Param<filters::Target> channels { this, 0, "channels" };
Param<filters::OutlineFilter::Place> place { this, OutlineFilter::Place::Outside, "place" };
Param<filters::OutlineFilter::Matrix> matrix { this, OutlineFilter::Matrix::Circle, "matrix" };
Param<app::Color> color { this, app::Color(), "color" };
Param<app::Color> bgColor { this, app::Color(), "bgColor" };
Param<filters::TiledMode> tiledMode { this, filters::TiledMode::NONE, "tiledMode" };
};
// Wrapper for ReplaceColorFilter to handle colors in an easy way
class OutlineFilterWrapper : public OutlineFilter {
@ -67,6 +77,10 @@ private:
app::Color m_bgColor;
};
#ifdef ENABLE_UI
static const char* ConfigSection = "Outline";
class OutlineWindow : public FilterWindow {
public:
OutlineWindow(OutlineFilterWrapper& filter,
@ -105,10 +119,10 @@ private:
int commonMatrix = -1;
switch (matrix) {
case OutlineFilter::kCircleMatrix: commonMatrix = CIRCLE; break;
case OutlineFilter::kSquareMatrix: commonMatrix = SQUARE; break;
case OutlineFilter::kHorizontalMatrix: commonMatrix = HORZ; break;
case OutlineFilter::kVerticalMatrix: commonMatrix = VERT; break;
case OutlineFilter::Matrix::Circle: commonMatrix = CIRCLE; break;
case OutlineFilter::Matrix::Square: commonMatrix = SQUARE; break;
case OutlineFilter::Matrix::Horizontal: commonMatrix = HORZ; break;
case OutlineFilter::Matrix::Vertical: commonMatrix = VERT; break;
}
m_panel.outlineType()->setSelectedItem(commonMatrix, false);
@ -119,7 +133,7 @@ private:
for (int i=0; i<9; ++i) {
m_panel.outlineMatrix()
->getItem(i)->setIcon(
(matrix & (1 << (8-i))) ? pixelIcon: emptyIcon);
(((int)matrix) & (1 << (8-i))) ? pixelIcon: emptyIcon);
}
}
@ -139,12 +153,12 @@ private:
}
void onMatrixTypeChange() {
OutlineFilter::Matrix matrix = 0;
OutlineFilter::Matrix matrix = OutlineFilter::Matrix::None;
switch (m_panel.outlineType()->selectedItem()) {
case CIRCLE: matrix = OutlineFilter::kCircleMatrix; break;
case SQUARE: matrix = OutlineFilter::kSquareMatrix; break;
case HORZ: matrix = OutlineFilter::kHorizontalMatrix; break;
case VERT: matrix = OutlineFilter::kVerticalMatrix; break;
case CIRCLE: matrix = OutlineFilter::Matrix::Circle; break;
case SQUARE: matrix = OutlineFilter::Matrix::Square; break;
case HORZ: matrix = OutlineFilter::Matrix::Horizontal; break;
case VERT: matrix = OutlineFilter::Matrix::Vertical; break;
}
m_filter.matrix(matrix);
updateButtonsFromMatrix();
@ -152,9 +166,9 @@ private:
}
void onMatrixPixelChange(const int index) {
OutlineFilter::Matrix matrix = m_filter.matrix();
int matrix = (int)m_filter.matrix();
matrix ^= (1 << (8-index));
m_filter.matrix(matrix);
m_filter.matrix((OutlineFilter::Matrix)matrix);
updateButtonsFromMatrix();
restartPreview();
}
@ -167,7 +181,9 @@ private:
gen::Outline m_panel;
};
class OutlineCommand : public Command {
#endif // ENABLE_UI
class OutlineCommand : public CommandWithNewParams<OutlineParams> {
public:
OutlineCommand();
@ -177,7 +193,7 @@ protected:
};
OutlineCommand::OutlineCommand()
: Command(CommandId::Outline(), CmdRecordableFlag)
: CommandWithNewParams<OutlineParams>(CommandId::Outline(), CmdRecordableFlag)
{
}
@ -189,21 +205,39 @@ bool OutlineCommand::onEnabled(Context* context)
void OutlineCommand::onExecute(Context* context)
{
#ifdef ENABLE_UI
const bool ui = (params().ui() && context->isUIAvailable());
#endif
Site site = context->activeSite();
DocumentPreferences& docPref = Preferences::instance()
.document(site.document());
OutlineFilterWrapper filter(site.layer());
filter.place((OutlineFilter::Place)get_config_int(ConfigSection, "Place", int(OutlineFilter::Place::Outside)));
filter.matrix((OutlineFilter::Matrix)get_config_int(ConfigSection, "Matrix", int(OutlineFilter::kCircleMatrix)));
filter.color(ColorBar::instance()->getFgColor());
filter.tiledMode(docPref.tiled.mode());
filter.bgColor(app::Color::fromMask());
if (site.layer() && site.layer()->isBackground() && site.image()) {
// TODO configure default pixel (same as Autocrop/Trim refpixel)
filter.bgColor(app::Color::fromImage(site.image()->pixelFormat(),
site.image()->getPixel(0, 0)));
}
else {
filter.bgColor(app::Color::fromMask());
}
#ifdef ENABLE_UI
if (ui) {
filter.place((OutlineFilter::Place)get_config_int(ConfigSection, "Place", int(OutlineFilter::Place::Outside)));
filter.matrix((OutlineFilter::Matrix)get_config_int(ConfigSection, "Matrix", int(OutlineFilter::Matrix::Circle)));
filter.color(ColorBar::instance()->getFgColor());
DocumentPreferences& docPref = Preferences::instance()
.document(site.document());
filter.tiledMode(docPref.tiled.mode());
}
#endif // ENABLE_UI
if (params().place.isSet()) filter.place(params().place());
if (params().matrix.isSet()) filter.matrix(params().matrix());
if (params().color.isSet()) filter.color(params().color());
if (params().bgColor.isSet()) filter.bgColor(params().bgColor());
if (params().tiledMode.isSet()) filter.tiledMode(params().tiledMode());
FilterManagerImpl filterMgr(context, &filter);
filterMgr.setTarget(
@ -215,10 +249,20 @@ void OutlineCommand::onExecute(Context* context)
TARGET_GRAY_CHANNEL |
TARGET_ALPHA_CHANNEL);
OutlineWindow window(filter, filterMgr);
if (window.doModal()) {
set_config_int(ConfigSection, "Place", int(filter.place()));
set_config_int(ConfigSection, "Matrix", int(filter.matrix()));
if (params().channels.isSet()) filterMgr.setTarget(params().channels());
#ifdef ENABLE_UI
if (ui) {
OutlineWindow window(filter, filterMgr);
if (window.doModal()) {
set_config_int(ConfigSection, "Place", int(filter.place()));
set_config_int(ConfigSection, "Matrix", int(filter.matrix()));
}
}
else
#endif // ENABLE_UI
{
start_filter_worker(&filterMgr);
}
}

View File

@ -39,13 +39,9 @@
namespace app {
#ifdef ENABLE_UI
static const char* ConfigSection = "ReplaceColor";
#endif
struct ReplaceColorParams : public NewParams {
Param<bool> ui { this, true, "ui" };
Param<filters::Target> target { this, 0, "target" };
Param<filters::Target> channels { this, 0, "channels" };
Param<app::Color> from { this, app::Color(), "from" };
Param<app::Color> to { this, app::Color(), "to" };
Param<int> tolerance { this, 0, "tolerance" };
@ -78,6 +74,8 @@ private:
#ifdef ENABLE_UI
static const char* ConfigSection = "ReplaceColor";
class ReplaceColorWindow : public FilterWindow {
public:
ReplaceColorWindow(ReplaceColorFilterWrapper& filter, FilterManagerImpl& filterMgr)
@ -200,7 +198,7 @@ void ReplaceColorCommand::onExecute(Context* context)
if (params().from.isSet()) filter.setFrom(params().from());
if (params().to.isSet()) filter.setTo(params().to());
if (params().tolerance.isSet()) filter.setTolerance(params().tolerance());
if (params().target.isSet()) filterMgr.setTarget(params().target());
if (params().channels.isSet()) filterMgr.setTarget(params().channels());
#ifdef ENABLE_UI
if (ui) {

View File

@ -438,9 +438,11 @@ doc::PalettePicks FilterManagerImpl::getPalettePicks()
{
doc::PalettePicks picks;
#ifdef ENABLE_UI // TODO add palette entries in Site and use activeSite here
ColorBar::instance()
->getPaletteView()
->getSelectedEntries(picks);
if (auto colorBar = ColorBar::instance()) {
colorBar
->getPaletteView()
->getSelectedEntries(picks);
}
#endif
return picks;
}

View File

@ -16,6 +16,9 @@
#include "base/convert_to.h"
#include "base/string.h"
#include "doc/color_mode.h"
#include "filters/hue_saturation_filter.h"
#include "filters/outline_filter.h"
#include "filters/tiled_mode.h"
#ifdef ENABLE_SCRIPTING
#include "app/script/engine.h"
@ -24,6 +27,10 @@
namespace app {
//////////////////////////////////////////////////////////////////////
// Convert values from strings (e.g. useful for values from gui.xml)
//////////////////////////////////////////////////////////////////////
template<>
void Param<bool>::fromString(const std::string& value)
{
@ -36,6 +43,12 @@ void Param<int>::fromString(const std::string& value)
setValue(base::convert_to<int>(value));
}
template<>
void Param<double>::fromString(const std::string& value)
{
setValue(base::convert_to<double>(value));
}
template<>
void Param<std::string>::fromString(const std::string& value)
{
@ -91,6 +104,56 @@ void Param<app::Color>::fromString(const std::string& value)
setValue(app::Color::fromString(value));
}
template<>
void Param<filters::TiledMode>::fromString(const std::string& value)
{
if (base::utf8_icmp(value, "both") == 0)
setValue(filters::TiledMode::BOTH);
else if (base::utf8_icmp(value, "x") == 0)
setValue(filters::TiledMode::X_AXIS);
else if (base::utf8_icmp(value, "y") == 0)
setValue(filters::TiledMode::Y_AXIS);
else
setValue(filters::TiledMode::NONE);
}
template<>
void Param<filters::OutlineFilter::Place>::fromString(const std::string& value)
{
if (base::utf8_icmp(value, "inside") == 0)
setValue(filters::OutlineFilter::Place::Inside);
else
setValue(filters::OutlineFilter::Place::Outside);
}
template<>
void Param<filters::OutlineFilter::Matrix>::fromString(const std::string& value)
{
if (base::utf8_icmp(value, "circle") == 0)
setValue(filters::OutlineFilter::Matrix::Circle);
else if (base::utf8_icmp(value, "square") == 0)
setValue(filters::OutlineFilter::Matrix::Square);
else if (base::utf8_icmp(value, "horizontal") == 0)
setValue(filters::OutlineFilter::Matrix::Horizontal);
else if (base::utf8_icmp(value, "vertical") == 0)
setValue(filters::OutlineFilter::Matrix::Vertical);
else
setValue((filters::OutlineFilter::Matrix)0);
}
template<>
void Param<filters::HueSaturationFilter::Mode>::fromString(const std::string& value)
{
if (base::utf8_icmp(value, "hsv") == 0)
setValue(filters::HueSaturationFilter::Mode::HSV);
else
setValue(filters::HueSaturationFilter::Mode::HSL);
}
//////////////////////////////////////////////////////////////////////
// Convert values from Lua
//////////////////////////////////////////////////////////////////////
#ifdef ENABLE_SCRIPTING
template<>
@ -105,6 +168,12 @@ void Param<int>::fromLua(lua_State* L, int index)
setValue(lua_tointeger(L, index));
}
template<>
void Param<double>::fromLua(lua_State* L, int index)
{
setValue(lua_tonumber(L, index));
}
template<>
void Param<std::string>::fromLua(lua_State* L, int index)
{
@ -147,6 +216,42 @@ void Param<app::Color>::fromLua(lua_State* L, int index)
setValue(script::convert_args_into_color(L, index));
}
template<>
void Param<filters::TiledMode>::fromLua(lua_State* L, int index)
{
if (lua_type(L, index) == LUA_TSTRING)
fromString(lua_tostring(L, index));
else
setValue((filters::TiledMode)lua_tointeger(L, index));
}
template<>
void Param<filters::OutlineFilter::Place>::fromLua(lua_State* L, int index)
{
if (lua_type(L, index) == LUA_TSTRING)
fromString(lua_tostring(L, index));
else
setValue((filters::OutlineFilter::Place)lua_tointeger(L, index));
}
template<>
void Param<filters::OutlineFilter::Matrix>::fromLua(lua_State* L, int index)
{
if (lua_type(L, index) == LUA_TSTRING)
fromString(lua_tostring(L, index));
else
setValue((filters::OutlineFilter::Matrix)lua_tointeger(L, index));
}
template<>
void Param<filters::HueSaturationFilter::Mode>::fromLua(lua_State* L, int index)
{
if (lua_type(L, index) == LUA_TSTRING)
fromString(lua_tostring(L, index));
else
setValue((filters::HueSaturationFilter::Mode)lua_tointeger(L, index));
}
void CommandWithNewParamsBase::loadParamsFromLuaTable(lua_State* L, int index)
{
onResetValues();
@ -163,7 +268,7 @@ void CommandWithNewParamsBase::loadParamsFromLuaTable(lua_State* L, int index)
m_skipLoadParams = true;
}
#endif
#endif // ENABLE_SCRIPTING
void CommandWithNewParamsBase::onLoadParams(const Params& params)
{
@ -172,7 +277,7 @@ void CommandWithNewParamsBase::onLoadParams(const Params& params)
m_skipLoadParams = false;
return;
}
#endif
#endif // ENABLE_SCRIPTING
onResetValues();
for (const auto& pair : params) {
if (ParamBase* p = onGetParam(pair.first))

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2018-2019 Igara Studio S.A.
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -10,6 +10,6 @@
// Increment this value if the scripting API is modified between two
// released Aseprite versions.
#define API_VERSION 4
#define API_VERSION 5
#endif

View File

@ -322,13 +322,16 @@ Engine::Engine()
lua_newtable(L);
lua_pushvalue(L, -1);
lua_setglobal(L, "FilterTarget");
lua_setglobal(L, "FilterChannels");
setfield_integer(L, "RED", TARGET_RED_CHANNEL);
setfield_integer(L, "GREEN", TARGET_GREEN_CHANNEL);
setfield_integer(L, "BLUE", TARGET_BLUE_CHANNEL);
setfield_integer(L, "ALPHA", TARGET_ALPHA_CHANNEL);
setfield_integer(L, "GRAY", TARGET_GRAY_CHANNEL);
setfield_integer(L, "INDEX", TARGET_INDEX_CHANNEL);
setfield_integer(L, "RGB", TARGET_RED_CHANNEL | TARGET_GREEN_CHANNEL | TARGET_BLUE_CHANNEL);
setfield_integer(L, "RGBA", TARGET_RED_CHANNEL | TARGET_GREEN_CHANNEL | TARGET_BLUE_CHANNEL | TARGET_ALPHA_CHANNEL);
setfield_integer(L, "GRAYA", TARGET_GRAY_CHANNEL | TARGET_ALPHA_CHANNEL);
lua_pop(L, 1);
// Register classes/prototypes

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2019 Igara Studio S.A.
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
@ -21,6 +22,8 @@ namespace filters {
public:
BrightnessContrastFilter();
double brightness() const { return m_brightness; }
double contrast() const { return m_contrast; }
void setBrightness(double brightness);
void setContrast(double contrast);

View File

@ -32,9 +32,10 @@ namespace {
int matrix;
int bit;
void init(color_t bgColor, OutlineFilter::Matrix matrix) {
void init(const color_t bgColor,
const OutlineFilter::Matrix matrix) {
this->bgColor = bgColor;
this->matrix = matrix;
this->matrix = (int)matrix;
}
void reset() {
@ -82,7 +83,7 @@ namespace {
OutlineFilter::OutlineFilter()
: m_place(Place::Outside)
, m_matrix(kCircleMatrix)
, m_matrix(Matrix::Circle)
, m_tiledMode(TiledMode::NONE)
, m_color(0)
, m_bgColor(0)

View File

@ -17,12 +17,13 @@ namespace filters {
class OutlineFilter : public Filter {
public:
enum class Place { Outside, Inside };
typedef int Matrix;
static const Matrix kCircleMatrix = 0252;
static const Matrix kSquareMatrix = 0757;
static const Matrix kHorizontalMatrix = 0050;
static const Matrix kVerticalMatrix = 0202;
enum class Matrix : int {
None = 0,
Circle = 0252,
Square = 0757,
Horizontal = 0050,
Vertical = 0202
};
OutlineFilter();