From 1ef67cada45b7c5459246d31ce066198972f3abb Mon Sep 17 00:00:00 2001 From: David Capello Date: Thu, 18 Jul 2019 11:44:33 -0300 Subject: [PATCH] lua: Support more filters from scripts (BrightnessContrast, Despeckle, HueSaturation, InvertColor, Outline) --- src/app/CMakeLists.txt | 10 +- src/app/commands/commands_list.h | 10 +- .../filters/cmd_brightness_contrast.cpp | 42 ++++++- src/app/commands/filters/cmd_despeckle.cpp | 67 ++++++++--- .../commands/filters/cmd_hue_saturation.cpp | 56 +++++++-- src/app/commands/filters/cmd_invert_color.cpp | 43 +++++-- src/app/commands/filters/cmd_outline.cpp | 96 ++++++++++----- .../commands/filters/cmd_replace_color.cpp | 10 +- .../commands/filters/filter_manager_impl.cpp | 8 +- src/app/commands/new_params.cpp | 109 +++++++++++++++++- src/app/script/api_version.h | 4 +- src/app/script/engine.cpp | 5 +- src/filters/brightness_contrast_filter.h | 3 + src/filters/outline_filter.cpp | 7 +- src/filters/outline_filter.h | 13 ++- 15 files changed, 383 insertions(+), 100 deletions(-) diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 95ee0f102..2bbcbb8f5 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -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 diff --git a/src/app/commands/commands_list.h b/src/app/commands/commands_list.h index 64fde251b..875a343c3 100644 --- a/src/app/commands/commands_list.h +++ b/src/app/commands/commands_list.h @@ -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) diff --git a/src/app/commands/filters/cmd_brightness_contrast.cpp b/src/app/commands/filters/cmd_brightness_contrast.cpp index eafb15b69..613477160 100644 --- a/src/app/commands/filters/cmd_brightness_contrast.cpp +++ b/src/app/commands/filters/cmd_brightness_contrast.cpp @@ -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 ui { this, true, "ui" }; + Param channels { this, 0, "channels" }; + Param brightness { this, 0.0, "brightness" }; + Param 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 { public: BrightnessContrastCommand(); @@ -74,7 +88,7 @@ protected: }; BrightnessContrastCommand::BrightnessContrastCommand() - : Command(CommandId::BrightnessContrast(), CmdRecordableFlag) + : CommandWithNewParams(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() diff --git a/src/app/commands/filters/cmd_despeckle.cpp b/src/app/commands/filters/cmd_despeckle.cpp index d32e0570a..abe8feea4 100644 --- a/src/app/commands/filters/cmd_despeckle.cpp +++ b/src/app/commands/filters/cmd_despeckle.cpp @@ -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 ui { this, true, "ui" }; + Param channels { this, 0, "channels" }; + Param width { this, 3, "width" }; + Param height { this, 3, "height" }; + Param 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 { public: DespeckleCommand(); @@ -96,7 +107,7 @@ protected: }; DespeckleCommand::DespeckleCommand() - : Command(CommandId::Despeckle(), CmdRecordableFlag) + : CommandWithNewParams(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); } } diff --git a/src/app/commands/filters/cmd_hue_saturation.cpp b/src/app/commands/filters/cmd_hue_saturation.cpp index 56ae0fa1a..bf21a72af 100644 --- a/src/app/commands/filters/cmd_hue_saturation.cpp +++ b/src/app/commands/filters/cmd_hue_saturation.cpp @@ -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 ui { this, true, "ui" }; + Param channels { this, 0, "channels" }; + Param mode { this, filters::HueSaturationFilter::Mode::HSL, "mode" }; + Param hue { this, 0.0, "hue" }; + Param saturation { this, 0.0, "saturation" }; + Param lightness { this, 0.0, { "lightness", "value" } }; + Param 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 { public: HueSaturationCommand(); @@ -127,7 +144,7 @@ protected: }; HueSaturationCommand::HueSaturationCommand() - : Command(CommandId::HueSaturation(), CmdRecordableFlag) + : CommandWithNewParams(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() diff --git a/src/app/commands/filters/cmd_invert_color.cpp b/src/app/commands/filters/cmd_invert_color.cpp index 652e7f131..b6f102527 100644 --- a/src/app/commands/filters/cmd_invert_color.cpp +++ b/src/app/commands/filters/cmd_invert_color.cpp @@ -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 ui { this, true, "ui" }; + Param 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 { public: InvertColorCommand(); @@ -51,7 +62,7 @@ protected: }; InvertColorCommand::InvertColorCommand() - : Command(CommandId::InvertColor(), CmdRecordableFlag) + : CommandWithNewParams(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() diff --git a/src/app/commands/filters/cmd_outline.cpp b/src/app/commands/filters/cmd_outline.cpp index c56fb8ad8..76659548a 100644 --- a/src/app/commands/filters/cmd_outline.cpp +++ b/src/app/commands/filters/cmd_outline.cpp @@ -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 ui { this, true, "ui" }; + Param channels { this, 0, "channels" }; + Param place { this, OutlineFilter::Place::Outside, "place" }; + Param matrix { this, OutlineFilter::Matrix::Circle, "matrix" }; + Param color { this, app::Color(), "color" }; + Param bgColor { this, app::Color(), "bgColor" }; + Param 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 { public: OutlineCommand(); @@ -177,7 +193,7 @@ protected: }; OutlineCommand::OutlineCommand() - : Command(CommandId::Outline(), CmdRecordableFlag) + : CommandWithNewParams(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); } } diff --git a/src/app/commands/filters/cmd_replace_color.cpp b/src/app/commands/filters/cmd_replace_color.cpp index d631f04c4..e4eb73fc7 100644 --- a/src/app/commands/filters/cmd_replace_color.cpp +++ b/src/app/commands/filters/cmd_replace_color.cpp @@ -39,13 +39,9 @@ namespace app { -#ifdef ENABLE_UI -static const char* ConfigSection = "ReplaceColor"; -#endif - struct ReplaceColorParams : public NewParams { Param ui { this, true, "ui" }; - Param target { this, 0, "target" }; + Param channels { this, 0, "channels" }; Param from { this, app::Color(), "from" }; Param to { this, app::Color(), "to" }; Param 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) { diff --git a/src/app/commands/filters/filter_manager_impl.cpp b/src/app/commands/filters/filter_manager_impl.cpp index 6dd1624ec..170e95694 100644 --- a/src/app/commands/filters/filter_manager_impl.cpp +++ b/src/app/commands/filters/filter_manager_impl.cpp @@ -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; } diff --git a/src/app/commands/new_params.cpp b/src/app/commands/new_params.cpp index 251f7577d..60fbb80df 100644 --- a/src/app/commands/new_params.cpp +++ b/src/app/commands/new_params.cpp @@ -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::fromString(const std::string& value) { @@ -36,6 +43,12 @@ void Param::fromString(const std::string& value) setValue(base::convert_to(value)); } +template<> +void Param::fromString(const std::string& value) +{ + setValue(base::convert_to(value)); +} + template<> void Param::fromString(const std::string& value) { @@ -91,6 +104,56 @@ void Param::fromString(const std::string& value) setValue(app::Color::fromString(value)); } +template<> +void Param::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::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::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::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::fromLua(lua_State* L, int index) setValue(lua_tointeger(L, index)); } +template<> +void Param::fromLua(lua_State* L, int index) +{ + setValue(lua_tonumber(L, index)); +} + template<> void Param::fromLua(lua_State* L, int index) { @@ -147,6 +216,42 @@ void Param::fromLua(lua_State* L, int index) setValue(script::convert_args_into_color(L, index)); } +template<> +void Param::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::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::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::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)) diff --git a/src/app/script/api_version.h b/src/app/script/api_version.h index c532342d4..69c378e40 100644 --- a/src/app/script/api_version.h +++ b/src/app/script/api_version.h @@ -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 diff --git a/src/app/script/engine.cpp b/src/app/script/engine.cpp index 9838dab64..c531f1674 100644 --- a/src/app/script/engine.cpp +++ b/src/app/script/engine.cpp @@ -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 diff --git a/src/filters/brightness_contrast_filter.h b/src/filters/brightness_contrast_filter.h index 108cc7734..08dabbd5b 100644 --- a/src/filters/brightness_contrast_filter.h +++ b/src/filters/brightness_contrast_filter.h @@ -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); diff --git a/src/filters/outline_filter.cpp b/src/filters/outline_filter.cpp index c18fe572f..f8c65d2f4 100644 --- a/src/filters/outline_filter.cpp +++ b/src/filters/outline_filter.cpp @@ -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) diff --git a/src/filters/outline_filter.h b/src/filters/outline_filter.h index 1088b4c1b..1e081d0cc 100644 --- a/src/filters/outline_filter.h +++ b/src/filters/outline_filter.h @@ -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();