diff --git a/data/gui.xml b/data/gui.xml index 19d5de131..bd0b977a6 100644 --- a/data/gui.xml +++ b/data/gui.xml @@ -925,6 +925,9 @@ + + + diff --git a/src/app/commands/cmd_set_color_selector.cpp b/src/app/commands/cmd_set_color_selector.cpp index 1638c592d..a97912c60 100644 --- a/src/app/commands/cmd_set_color_selector.cpp +++ b/src/app/commands/cmd_set_color_selector.cpp @@ -55,6 +55,9 @@ void SetColorSelectorCommand::onLoadParams(const Params& params) else if (type == "ryb-wheel") { m_type = ColorBar::ColorSelector::RYB_WHEEL; } + else if (type == "normal-map-wheel") { + m_type = ColorBar::ColorSelector::NORMAL_MAP_WHEEL; + } } bool SetColorSelectorCommand::onChecked(Context* context) @@ -84,6 +87,9 @@ std::string SetColorSelectorCommand::onGetFriendlyName() const case ColorBar::ColorSelector::RYB_WHEEL: result += "RYB Color Wheel"; break; + case ColorBar::ColorSelector::NORMAL_MAP_WHEEL: + result += "Normal Map Color Wheel"; + break; default: result += "Unknown"; break; diff --git a/src/app/ui/color_bar.cpp b/src/app/ui/color_bar.cpp index 422d02fb9..a53ea4c7e 100644 --- a/src/app/ui/color_bar.cpp +++ b/src/app/ui/color_bar.cpp @@ -341,6 +341,7 @@ void ColorBar::setColorSelector(ColorSelector selector) case ColorSelector::RGB_WHEEL: case ColorSelector::RYB_WHEEL: + case ColorSelector::NORMAL_MAP_WHEEL: if (!m_wheel) { m_wheel = new ColorWheel; m_wheel->setExpansive(true); @@ -348,10 +349,15 @@ void ColorBar::setColorSelector(ColorSelector selector) m_wheel->ColorChange.connect(&ColorBar::onPickSpectrum, this); m_selectorPlaceholder.addChild(m_wheel); } - m_wheel->setColorModel( - (m_selector == ColorSelector::RGB_WHEEL ? - ColorWheel::ColorModel::RGB: - ColorWheel::ColorModel::RYB)); + if (m_selector == ColorSelector::RGB_WHEEL) { + m_wheel->setColorModel(ColorWheel::ColorModel::RGB); + } + else if (m_selector == ColorSelector::RYB_WHEEL) { + m_wheel->setColorModel(ColorWheel::ColorModel::RYB); + } + else if (m_selector == ColorSelector::NORMAL_MAP_WHEEL) { + m_wheel->setColorModel(ColorWheel::ColorModel::NORMAL_MAP); + } m_wheel->setVisible(true); break; diff --git a/src/app/ui/color_bar.h b/src/app/ui/color_bar.h index 2b439107a..5c68bdf5f 100644 --- a/src/app/ui/color_bar.h +++ b/src/app/ui/color_bar.h @@ -50,6 +50,7 @@ namespace app { SPECTRUM, RGB_WHEEL, RYB_WHEEL, + NORMAL_MAP_WHEEL, TINT_SHADE_TONE, }; diff --git a/src/app/ui/color_wheel.cpp b/src/app/ui/color_wheel.cpp index bde5ab16c..d37c28965 100644 --- a/src/app/ui/color_wheel.cpp +++ b/src/app/ui/color_wheel.cpp @@ -84,6 +84,22 @@ app::Color ColorWheel::getColorInClientPos(const gfx::Point& pos) int v = (pos.y - (m_wheelBounds.y+m_wheelBounds.h/2)); double d = std::sqrt(u*u + v*v); + if (m_colorModel == ColorModel::NORMAL_MAP) { + float x = float(u) / float(m_wheelBounds.w / 2); + float y = -float(v) / float(m_wheelBounds.h / 2); + float z = std::sqrt(1 - x*x - y*y); + if (z <= 1.f) { + return app::Color::fromRgb( + int(std::round((x + 1) * 127.5)), + int(std::round((y + 1) * 127.5)), + int(std::round((z + 1) * 127.5)) + ); + } + else { + return app::Color::fromRgb(128, 128, 255); + } + } + // Pick from the wheel if (d < m_wheelRadius+2*guiscale()) { double a = std::atan2(-v, u); @@ -231,7 +247,7 @@ void ColorWheel::onPaint(ui::PaintEvent& ev) } } - if (m_color.getAlpha() > 0) { + if (m_color.getAlpha() > 0 && m_colorModel != ColorModel::NORMAL_MAP) { int n = getHarmonies(); int boxsize = MIN(rc.w/10, rc.h/10); @@ -336,16 +352,32 @@ void ColorWheel::onOptions() menu.addChild(&tetradic); menu.addChild(&square); - if (isDiscrete()) discrete.setSelected(true); - switch (m_harmony) { - case Harmony::NONE: none.setSelected(true); break; - case Harmony::COMPLEMENTARY: complementary.setSelected(true); break; - case Harmony::MONOCHROMATIC: monochromatic.setSelected(true); break; - case Harmony::ANALOGOUS: analogous.setSelected(true); break; - case Harmony::SPLIT: split.setSelected(true); break; - case Harmony::TRIADIC: triadic.setSelected(true); break; - case Harmony::TETRADIC: tetradic.setSelected(true); break; - case Harmony::SQUARE: square.setSelected(true); break; + if (m_colorModel == ColorModel::NORMAL_MAP) { + discrete.setSelected(false); + discrete.setEnabled(false); + + none.setSelected(true); + none.setEnabled(false); + complementary.setEnabled(false); + monochromatic.setEnabled(false); + analogous.setEnabled(false); + split.setEnabled(false); + triadic.setEnabled(false); + tetradic.setEnabled(false); + square.setEnabled(false); + } + else { + if (isDiscrete()) discrete.setSelected(true); + switch (m_harmony) { + case Harmony::NONE: none.setSelected(true); break; + case Harmony::COMPLEMENTARY: complementary.setSelected(true); break; + case Harmony::MONOCHROMATIC: monochromatic.setSelected(true); break; + case Harmony::ANALOGOUS: analogous.setSelected(true); break; + case Harmony::SPLIT: split.setSelected(true); break; + case Harmony::TRIADIC: triadic.setSelected(true); break; + case Harmony::TETRADIC: tetradic.setSelected(true); break; + case Harmony::SQUARE: square.setSelected(true); break; + } } discrete.Click.connect(base::Bind(&ColorWheel::setDiscrete, this, !isDiscrete())); diff --git a/src/app/ui/color_wheel.h b/src/app/ui/color_wheel.h index 5f586b78c..9b157af6c 100644 --- a/src/app/ui/color_wheel.h +++ b/src/app/ui/color_wheel.h @@ -18,6 +18,7 @@ namespace app { enum class ColorModel { RGB, RYB, + NORMAL_MAP, }; enum class Harmony {