Add addition mode back for Hue/Saturation filter (fix #1848)

This commit is contained in:
David Capello 2020-04-23 12:05:09 -03:00
parent d1843fcf55
commit 4cfa5e743e
7 changed files with 70 additions and 48 deletions

View File

@ -101,10 +101,6 @@
<value id="LEFT" value="1" />
<value id="RIGHT" value="2" />
</enum>
<enum id="HueSaturationMode">
<value id="HSV" value="0" />
<value id="HSL" value="1" />
</enum>
<enum id="ColorProfileBehavior">
<value id="DISABLE" value="0" />
<value id="EMBEDDED" value="1" />
@ -352,7 +348,7 @@
<option id="image_preset" type="int" default="0" />
</section>
<section id="hue_saturation">
<option id="mode" type="HueSaturationMode" default="HueSaturationMode::HSL" />
<option id="mode" type="filters::HueSaturationFilter::Mode" default="filters::HueSaturationFilter::Mode::HSL_MUL" />
</section>
<section id="filters">
<option id="cels_target" type="CelsTarget" default="CelsTarget::Selected" />

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2019 Igara Studio S.A.
// Copyright (C) 2019-2020 Igara Studio S.A.
// Copyright (C) 2017-2018 David Capello
//
// This program is distributed under the terms of
@ -35,10 +35,12 @@
namespace app {
using Mode = filters::HueSaturationFilter::Mode;
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<Mode> mode { this, Mode::HSL_MUL, "mode" };
Param<double> hue { this, 0.0, "hue" };
Param<double> saturation { this, 0.0, "saturation" };
Param<double> lightness { this, 0.0, { "lightness", "value" } };
@ -62,13 +64,17 @@ public:
getContainer()->addChild(&m_colorType);
getContainer()->addChild(&m_sliders);
static_assert(int(Mode::HSV_MUL) == 0 &&
int(Mode::HSL_MUL) == 1 &&
int(Mode::HSV_ADD) == 2 &&
int(Mode::HSL_ADD) == 3,
"Adjust widget showing filters::HueSaturationFilter::Mode enum");
auto mode = Preferences::instance().hueSaturation.mode();
m_colorType.addItem("HSV")->setFocusStop(false);
m_colorType.addItem("HSL")->setFocusStop(false);
if (mode == gen::HueSaturationMode::HSV)
m_colorType.setSelectedItem(0);
else
m_colorType.setSelectedItem(1);
m_colorType.addItem("HSV+")->setFocusStop(false);
m_colorType.addItem("HSL+")->setFocusStop(false);
m_colorType.setSelectedItem(int(mode));
m_colorType.ItemChange.connect(base::Bind<void>(&HueSaturationWindow::onChangeMode, this));
m_sliders.setColorType(app::Color::HslType);
@ -78,24 +84,21 @@ public:
onChangeMode();
}
Mode mode() const {
return Mode(m_colorType.selectedItem());
}
private:
bool isHsl() const {
return (m_colorType.selectedItem() == 1);
return (mode() == Mode::HSL_MUL ||
mode() == Mode::HSL_ADD);
}
void onChangeMode() {
const int isHsl = this->isHsl();
Preferences::instance().hueSaturation.mode
(isHsl ? gen::HueSaturationMode::HSL:
gen::HueSaturationMode::HSV);
m_filter.setMode(isHsl ?
HueSaturationFilter::Mode::HSL:
HueSaturationFilter::Mode::HSV);
m_sliders.setColorType(isHsl ?
Preferences::instance().hueSaturation.mode(mode());
m_filter.setMode(mode());
m_sliders.setColorType(isHsl() ?
app::Color::HslType:
app::Color::HsvType);
@ -139,8 +142,8 @@ public:
HueSaturationCommand();
protected:
bool onEnabled(Context* context) override;
void onExecute(Context* context) override;
bool onEnabled(Context* ctx) override;
void onExecute(Context* ctx) override;
};
HueSaturationCommand::HueSaturationCommand()
@ -148,20 +151,20 @@ HueSaturationCommand::HueSaturationCommand()
{
}
bool HueSaturationCommand::onEnabled(Context* context)
bool HueSaturationCommand::onEnabled(Context* ctx)
{
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
ContextFlags::HasActiveSprite);
return ctx->checkFlags(ContextFlags::ActiveDocumentIsWritable |
ContextFlags::HasActiveSprite);
}
void HueSaturationCommand::onExecute(Context* context)
void HueSaturationCommand::onExecute(Context* ctx)
{
#ifdef ENABLE_UI
const bool ui = (params().ui() && context->isUIAvailable());
const bool ui = (params().ui() && ctx->isUIAvailable());
#endif
HueSaturationFilter filter;
FilterManagerImpl filterMgr(context, &filter);
FilterManagerImpl filterMgr(ctx, &filter);
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);

View File

@ -158,10 +158,15 @@ void Param<filters::OutlineFilter::Matrix>::fromString(const std::string& value)
template<>
void Param<filters::HueSaturationFilter::Mode>::fromString(const std::string& value)
{
if (base::utf8_icmp(value, "hsv") == 0)
setValue(filters::HueSaturationFilter::Mode::HSV);
if (base::utf8_icmp(value, "hsv") == 0 ||
base::utf8_icmp(value, "hsv_mul") == 0)
setValue(filters::HueSaturationFilter::Mode::HSV_MUL);
else if (base::utf8_icmp(value, "hsv_add") == 0)
setValue(filters::HueSaturationFilter::Mode::HSV_ADD);
else if (base::utf8_icmp(value, "hsl_add") == 0)
setValue(filters::HueSaturationFilter::Mode::HSL_ADD);
else
setValue(filters::HueSaturationFilter::Mode::HSL);
setValue(filters::HueSaturationFilter::Mode::HSL_MUL);
}
template<>

View File

@ -26,6 +26,7 @@
#include "doc/frame.h"
#include "doc/layer_list.h"
#include "doc/sprite.h"
#include "filters/hue_saturation_filter.h"
#include "filters/tiled_mode.h"
#include "gfx/rect.h"
#include "render/onionskin_position.h"

View File

@ -151,7 +151,6 @@ FOR_ENUM(app::gen::ColorProfileBehavior)
FOR_ENUM(app::gen::EyedropperChannel)
FOR_ENUM(app::gen::EyedropperSample)
FOR_ENUM(app::gen::FillReferTo)
FOR_ENUM(app::gen::HueSaturationMode)
FOR_ENUM(app::gen::OnionskinType)
FOR_ENUM(app::gen::PaintingCursorType)
FOR_ENUM(app::gen::PivotPosition)
@ -169,6 +168,7 @@ FOR_ENUM(app::tools::RotationAlgorithm)
FOR_ENUM(doc::AniDir)
FOR_ENUM(doc::BrushPattern)
FOR_ENUM(doc::ColorMode)
FOR_ENUM(filters::HueSaturationFilter::Mode)
FOR_ENUM(filters::TiledMode)
FOR_ENUM(render::OnionskinPosition)

View File

@ -34,7 +34,7 @@ const char* HueSaturationFilter::getName()
}
HueSaturationFilter::HueSaturationFilter()
: m_mode(Mode::HSL)
: m_mode(Mode::HSL_MUL)
, m_h(0.0)
, m_s(0.0)
, m_l(0.0)
@ -200,7 +200,9 @@ void HueSaturationFilter::onApplyToPalette(FilterManager* filterMgr,
template<class T,
double (T::*get_lightness)() const,
void (T::*set_lightness)(double)>
void HueSaturationFilter::applyFilterToRgbT(const Target target, doc::color_t& c)
void HueSaturationFilter::applyFilterToRgbT(const Target target,
doc::color_t& c,
bool multiply)
{
int r = rgba_getr(c);
int g = rgba_getg(c);
@ -213,10 +215,12 @@ void HueSaturationFilter::applyFilterToRgbT(const Target target, doc::color_t& c
while (h < 0.0) h += 360.0;
h = std::fmod(h, 360.0);
double s = hsl.saturation()*(1.0+m_s);
double s = (multiply ? hsl.saturation()*(1.0+m_s):
hsl.saturation() + m_s);
s = base::clamp(s, 0.0, 1.0);
double l = (hsl.*get_lightness)()*(1.0+m_l);
double l = (multiply ? (hsl.*get_lightness)()*(1.0+m_l):
(hsl.*get_lightness)() + m_l);
l = base::clamp(l, 0.0, 1.0);
hsl.hue(h);
@ -238,15 +242,25 @@ void HueSaturationFilter::applyFilterToRgbT(const Target target, doc::color_t& c
void HueSaturationFilter::applyFilterToRgb(const Target target, doc::color_t& color)
{
switch (m_mode) {
case Mode::HSL:
applyFilterToRgbT<gfx::Hsl,
&gfx::Hsl::lightness,
&gfx::Hsl::lightness>(target, color);
break;
case Mode::HSV:
case Mode::HSV_MUL:
applyFilterToRgbT<gfx::Hsv,
&gfx::Hsv::value,
&gfx::Hsv::value>(target, color);
&gfx::Hsv::value>(target, color, true);
break;
case Mode::HSL_MUL:
applyFilterToRgbT<gfx::Hsl,
&gfx::Hsl::lightness,
&gfx::Hsl::lightness>(target, color, true);
break;
case Mode::HSV_ADD:
applyFilterToRgbT<gfx::Hsv,
&gfx::Hsv::value,
&gfx::Hsv::value>(target, color, false);
break;
case Mode::HSL_ADD:
applyFilterToRgbT<gfx::Hsl,
&gfx::Hsl::lightness,
&gfx::Hsl::lightness>(target, color, false);
break;
}
}

View File

@ -17,7 +17,10 @@ namespace filters {
class HueSaturationFilter : public FilterWithPalette {
public:
enum class Mode { HSL, HSV };
enum class Mode {
HSV_MUL, HSL_MUL,
HSV_ADD, HSL_ADD,
};
HueSaturationFilter();
@ -40,7 +43,7 @@ namespace filters {
template<class T,
double (T::*get_lightness)() const,
void (T::*set_lightness)(double)>
void applyFilterToRgbT(const Target target, doc::color_t& color);
void applyFilterToRgbT(const Target target, doc::color_t& color, bool multiply);
void applyFilterToRgb(const Target target, doc::color_t& color);
Mode m_mode;