summaryrefslogtreecommitdiffstats
path: root/src/ui/widget/color-scales.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/widget/color-scales.cpp')
-rw-r--r--src/ui/widget/color-scales.cpp736
1 files changed, 736 insertions, 0 deletions
diff --git a/src/ui/widget/color-scales.cpp b/src/ui/widget/color-scales.cpp
new file mode 100644
index 0000000..a93ab2a
--- /dev/null
+++ b/src/ui/widget/color-scales.cpp
@@ -0,0 +1,736 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/** @file
+ * TODO: insert short description here
+ *//*
+ * Authors:
+ * see git history
+ * bulia byak <buliabyak@users.sf.net>
+ *
+ * Copyright (C) 2018 Authors
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#include <gtkmm/adjustment.h>
+#include <glibmm/i18n.h>
+
+#include "ui/dialog-events.h"
+#include "ui/widget/color-scales.h"
+#include "ui/widget/color-slider.h"
+
+#define CSC_CHANNEL_R (1 << 0)
+#define CSC_CHANNEL_G (1 << 1)
+#define CSC_CHANNEL_B (1 << 2)
+#define CSC_CHANNEL_A (1 << 3)
+#define CSC_CHANNEL_H (1 << 0)
+#define CSC_CHANNEL_S (1 << 1)
+#define CSC_CHANNEL_V (1 << 2)
+#define CSC_CHANNEL_C (1 << 0)
+#define CSC_CHANNEL_M (1 << 1)
+#define CSC_CHANNEL_Y (1 << 2)
+#define CSC_CHANNEL_K (1 << 3)
+#define CSC_CHANNEL_CMYKA (1 << 4)
+
+#define CSC_CHANNELS_ALL 0
+
+#define XPAD 4
+#define YPAD 1
+
+#define noDUMP_CHANGE_INFO 1
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+
+static const gchar *sp_color_scales_hue_map();
+
+const gchar *ColorScales::SUBMODE_NAMES[] = { N_("None"), N_("RGB"), N_("HSL"), N_("CMYK"), N_("HSV") };
+
+ColorScales::ColorScales(SelectedColor &color, SPColorScalesMode mode)
+ : Gtk::Grid()
+ , _color(color)
+ , _rangeLimit(255.0)
+ , _updating(FALSE)
+ , _dragging(FALSE)
+ , _mode(SP_COLOR_SCALES_MODE_NONE)
+{
+ for (gint i = 0; i < 5; i++) {
+ _l[i] = nullptr;
+ _a[i] = nullptr;
+ _s[i] = nullptr;
+ _b[i] = nullptr;
+ }
+
+ _initUI(mode);
+
+ _color.signal_changed.connect(sigc::mem_fun(this, &ColorScales::_onColorChanged));
+ _color.signal_dragged.connect(sigc::mem_fun(this, &ColorScales::_onColorChanged));
+}
+
+ColorScales::~ColorScales()
+{
+ for (gint i = 0; i < 5; i++) {
+ _l[i] = nullptr;
+ _a[i] = nullptr;
+ _s[i] = nullptr;
+ _b[i] = nullptr;
+ }
+}
+
+void ColorScales::_initUI(SPColorScalesMode mode)
+{
+ gint i;
+
+ _updating = FALSE;
+ _dragging = FALSE;
+
+ GtkWidget *t = GTK_WIDGET(gobj());
+
+ /* Create components */
+ for (i = 0; i < static_cast<gint>(G_N_ELEMENTS(_a)); i++) {
+ /* Label */
+ _l[i] = gtk_label_new("");
+
+ gtk_widget_set_halign(_l[i], GTK_ALIGN_START);
+ gtk_widget_show(_l[i]);
+
+ gtk_widget_set_margin_start(_l[i], XPAD);
+ gtk_widget_set_margin_end(_l[i], XPAD);
+ gtk_widget_set_margin_top(_l[i], YPAD);
+ gtk_widget_set_margin_bottom(_l[i], YPAD);
+ gtk_grid_attach(GTK_GRID(t), _l[i], 0, i, 1, 1);
+
+ /* Adjustment */
+ _a[i] = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, _rangeLimit, 1.0, 10.0, 10.0));
+ /* Slider */
+ _s[i] = Gtk::manage(new Inkscape::UI::Widget::ColorSlider(Glib::wrap(_a[i], true)));
+ _s[i]->show();
+
+ _s[i]->set_margin_start(XPAD);
+ _s[i]->set_margin_end(XPAD);
+ _s[i]->set_margin_top(YPAD);
+ _s[i]->set_margin_bottom(YPAD);
+ _s[i]->set_hexpand(true);
+ gtk_grid_attach(GTK_GRID(t), _s[i]->gobj(), 1, i, 1, 1);
+
+ /* Spinbutton */
+ _b[i] = gtk_spin_button_new(GTK_ADJUSTMENT(_a[i]), 1.0, 0);
+ sp_dialog_defocus_on_enter(_b[i]);
+ gtk_label_set_mnemonic_widget(GTK_LABEL(_l[i]), _b[i]);
+ gtk_widget_show(_b[i]);
+
+ gtk_widget_set_margin_start(_b[i], XPAD);
+ gtk_widget_set_margin_end(_b[i], XPAD);
+ gtk_widget_set_margin_top(_b[i], YPAD);
+ gtk_widget_set_margin_bottom(_b[i], YPAD);
+ gtk_widget_set_halign(_b[i], GTK_ALIGN_END);
+ gtk_widget_set_valign(_b[i], GTK_ALIGN_CENTER);
+ gtk_grid_attach(GTK_GRID(t), _b[i], 2, i, 1, 1);
+
+ /* Attach channel value to adjustment */
+ g_object_set_data(G_OBJECT(_a[i]), "channel", GINT_TO_POINTER(i));
+ /* Signals */
+ g_signal_connect(G_OBJECT(_a[i]), "value_changed", G_CALLBACK(_adjustmentAnyChanged), this);
+ _s[i]->signal_grabbed.connect(sigc::mem_fun(this, &ColorScales::_sliderAnyGrabbed));
+ _s[i]->signal_released.connect(sigc::mem_fun(this, &ColorScales::_sliderAnyReleased));
+ _s[i]->signal_value_changed.connect(sigc::mem_fun(this, &ColorScales::_sliderAnyChanged));
+ }
+
+ //Prevent 5th bar from being shown by PanelDialog::show_all_children
+ gtk_widget_set_no_show_all(_l[4], TRUE);
+ _s[4]->set_no_show_all(true);
+ gtk_widget_set_no_show_all(_b[4], TRUE);
+
+ /* Initial mode is none, so it works */
+ setMode(mode);
+}
+
+void ColorScales::_recalcColor()
+{
+ SPColor color;
+ gfloat alpha = 1.0;
+ gfloat c[5];
+
+ switch (_mode) {
+ case SP_COLOR_SCALES_MODE_RGB:
+ case SP_COLOR_SCALES_MODE_HSL:
+ case SP_COLOR_SCALES_MODE_HSV:
+ _getRgbaFloatv(c);
+ color.set(c[0], c[1], c[2]);
+ alpha = c[3];
+ break;
+ case SP_COLOR_SCALES_MODE_CMYK: {
+ _getCmykaFloatv(c);
+
+ float rgb[3];
+ SPColor::cmyk_to_rgb_floatv(rgb, c[0], c[1], c[2], c[3]);
+ color.set(rgb[0], rgb[1], rgb[2]);
+ alpha = c[4];
+ break;
+ }
+ default:
+ g_warning("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode);
+ break;
+ }
+
+ _color.preserveICC();
+ _color.setColorAlpha(color, alpha);
+}
+
+void ColorScales::_updateDisplay()
+{
+#ifdef DUMP_CHANGE_INFO
+ g_message("ColorScales::_onColorChanged( this=%p, %f, %f, %f, %f)", this, _color.color().v.c[0],
+ _color.color().v.c[1], _color.color().v.c[2], _color.alpha());
+#endif
+ gfloat tmp[3];
+ gfloat c[5] = { 0.0, 0.0, 0.0, 0.0 };
+
+ SPColor color = _color.color();
+
+ switch (_mode) {
+ case SP_COLOR_SCALES_MODE_RGB:
+ color.get_rgb_floatv(c);
+ c[3] = _color.alpha();
+ c[4] = 0.0;
+ break;
+ case SP_COLOR_SCALES_MODE_HSL:
+ color.get_rgb_floatv(tmp);
+ SPColor::rgb_to_hsl_floatv(c, tmp[0], tmp[1], tmp[2]);
+ c[3] = _color.alpha();
+ c[4] = 0.0;
+ break;
+ case SP_COLOR_SCALES_MODE_HSV:
+ color.get_rgb_floatv(tmp);
+ SPColor::rgb_to_hsv_floatv(c, tmp[0], tmp[1], tmp[2]);
+ c[3] = _color.alpha();
+ c[4] = 0.0;
+ break;
+ case SP_COLOR_SCALES_MODE_CMYK:
+ color.get_cmyk_floatv(c);
+ c[4] = _color.alpha();
+ break;
+ default:
+ g_warning("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode);
+ break;
+ }
+
+ _updating = TRUE;
+ setScaled(_a[0], c[0]);
+ setScaled(_a[1], c[1]);
+ setScaled(_a[2], c[2]);
+ setScaled(_a[3], c[3]);
+ setScaled(_a[4], c[4]);
+ _updateSliders(CSC_CHANNELS_ALL);
+ _updating = FALSE;
+}
+
+/* Helpers for setting color value */
+gfloat ColorScales::getScaled(const GtkAdjustment *a)
+{
+ gfloat val = gtk_adjustment_get_value(const_cast<GtkAdjustment *>(a)) /
+ gtk_adjustment_get_upper(const_cast<GtkAdjustment *>(a));
+ return val;
+}
+
+void ColorScales::setScaled(GtkAdjustment *a, gfloat v, bool constrained)
+{
+ gdouble upper = gtk_adjustment_get_upper(a);
+ gfloat val = v * upper;
+ if (constrained) {
+ // TODO: do we want preferences for these?
+ if (upper == 255) {
+ val = round(val/16) * 16;
+ } else {
+ val = round(val/10) * 10;
+ }
+ }
+ gtk_adjustment_set_value(a, val);
+}
+
+void ColorScales::_setRangeLimit(gdouble upper)
+{
+ _rangeLimit = upper;
+ for (auto & i : _a) {
+ gtk_adjustment_set_upper(i, upper);
+ }
+}
+
+void ColorScales::_onColorChanged()
+{
+ if (!get_visible()) {
+ return;
+ }
+ _updateDisplay();
+}
+
+void ColorScales::on_show()
+{
+ Gtk::Grid::on_show();
+ _updateDisplay();
+}
+
+void ColorScales::_getRgbaFloatv(gfloat *rgba)
+{
+ g_return_if_fail(rgba != nullptr);
+
+ switch (_mode) {
+ case SP_COLOR_SCALES_MODE_RGB:
+ rgba[0] = getScaled(_a[0]);
+ rgba[1] = getScaled(_a[1]);
+ rgba[2] = getScaled(_a[2]);
+ rgba[3] = getScaled(_a[3]);
+ break;
+ case SP_COLOR_SCALES_MODE_HSL:
+ SPColor::hsl_to_rgb_floatv(rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
+ rgba[3] = getScaled(_a[3]);
+ break;
+ case SP_COLOR_SCALES_MODE_HSV:
+ SPColor::hsv_to_rgb_floatv(rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
+ rgba[3] = getScaled(_a[3]);
+ break;
+ case SP_COLOR_SCALES_MODE_CMYK:
+ SPColor::cmyk_to_rgb_floatv(rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
+ rgba[3] = getScaled(_a[4]);
+ break;
+ default:
+ g_warning("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
+ break;
+ }
+}
+
+void ColorScales::_getCmykaFloatv(gfloat *cmyka)
+{
+ gfloat rgb[3];
+
+ g_return_if_fail(cmyka != nullptr);
+
+ switch (_mode) {
+ case SP_COLOR_SCALES_MODE_RGB:
+ SPColor::rgb_to_cmyk_floatv(cmyka, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
+ cmyka[4] = getScaled(_a[3]);
+ break;
+ case SP_COLOR_SCALES_MODE_HSL:
+ SPColor::hsl_to_rgb_floatv(rgb, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
+ SPColor::rgb_to_cmyk_floatv(cmyka, rgb[0], rgb[1], rgb[2]);
+ cmyka[4] = getScaled(_a[3]);
+ break;
+ case SP_COLOR_SCALES_MODE_CMYK:
+ cmyka[0] = getScaled(_a[0]);
+ cmyka[1] = getScaled(_a[1]);
+ cmyka[2] = getScaled(_a[2]);
+ cmyka[3] = getScaled(_a[3]);
+ cmyka[4] = getScaled(_a[4]);
+ break;
+ default:
+ g_warning("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
+ break;
+ }
+}
+
+guint32 ColorScales::_getRgba32()
+{
+ gfloat c[4];
+ guint32 rgba;
+
+ _getRgbaFloatv(c);
+
+ rgba = SP_RGBA32_F_COMPOSE(c[0], c[1], c[2], c[3]);
+
+ return rgba;
+}
+
+void ColorScales::setMode(SPColorScalesMode mode)
+{
+ gfloat rgba[4];
+ gfloat c[4];
+
+ if (_mode == mode)
+ return;
+
+ if ((_mode == SP_COLOR_SCALES_MODE_RGB) || (_mode == SP_COLOR_SCALES_MODE_HSL) ||
+ (_mode == SP_COLOR_SCALES_MODE_CMYK) || (_mode == SP_COLOR_SCALES_MODE_HSV)) {
+ _getRgbaFloatv(rgba);
+ }
+ else {
+ rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0;
+ }
+
+ _mode = mode;
+
+ switch (mode) {
+ case SP_COLOR_SCALES_MODE_RGB:
+ _setRangeLimit(255.0);
+ gtk_adjustment_set_upper(_a[3], 100.0);
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[0]), _("_R:"));
+ _s[0]->set_tooltip_text(_("Red"));
+ gtk_widget_set_tooltip_text(_b[0], _("Red"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[1]), _("_G:"));
+ _s[1]->set_tooltip_text(_("Green"));
+ gtk_widget_set_tooltip_text(_b[1], _("Green"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[2]), _("_B:"));
+ _s[2]->set_tooltip_text(_("Blue"));
+ gtk_widget_set_tooltip_text(_b[2], _("Blue"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[3]), _("_A:"));
+ _s[3]->set_tooltip_text(_("Alpha (opacity)"));
+ gtk_widget_set_tooltip_text(_b[3], _("Alpha (opacity)"));
+ _s[0]->setMap(nullptr);
+ gtk_widget_hide(_l[4]);
+ _s[4]->hide();
+ gtk_widget_hide(_b[4]);
+ _updating = TRUE;
+ setScaled(_a[0], rgba[0]);
+ setScaled(_a[1], rgba[1]);
+ setScaled(_a[2], rgba[2]);
+ setScaled(_a[3], rgba[3]);
+ _updateSliders(CSC_CHANNELS_ALL);
+ _updating = FALSE;
+ break;
+ case SP_COLOR_SCALES_MODE_HSL:
+ _setRangeLimit(100.0);
+
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[0]), _("_H:"));
+ _s[0]->set_tooltip_text(_("Hue"));
+ gtk_widget_set_tooltip_text(_b[0], _("Hue"));
+ gtk_adjustment_set_upper(_a[0], 360.0);
+
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[1]), _("_S:"));
+ _s[1]->set_tooltip_text(_("Saturation"));
+ gtk_widget_set_tooltip_text(_b[1], _("Saturation"));
+
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[2]), _("_L:"));
+ _s[2]->set_tooltip_text(_("Lightness"));
+ gtk_widget_set_tooltip_text(_b[2], _("Lightness"));
+
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[3]), _("_A:"));
+ _s[3]->set_tooltip_text(_("Alpha (opacity)"));
+ gtk_widget_set_tooltip_text(_b[3], _("Alpha (opacity)"));
+ _s[0]->setMap((guchar *)(sp_color_scales_hue_map()));
+ gtk_widget_hide(_l[4]);
+ _s[4]->hide();
+ gtk_widget_hide(_b[4]);
+ _updating = TRUE;
+ c[0] = 0.0;
+
+ SPColor::rgb_to_hsl_floatv(c, rgba[0], rgba[1], rgba[2]);
+
+ setScaled(_a[0], c[0]);
+ setScaled(_a[1], c[1]);
+ setScaled(_a[2], c[2]);
+ setScaled(_a[3], rgba[3]);
+
+ _updateSliders(CSC_CHANNELS_ALL);
+ _updating = FALSE;
+ break;
+ case SP_COLOR_SCALES_MODE_HSV:
+ _setRangeLimit(100.0);
+
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[0]), _("_H:"));
+ _s[0]->set_tooltip_text(_("Hue"));
+ gtk_widget_set_tooltip_text(_b[0], _("Hue"));
+ gtk_adjustment_set_upper(_a[0], 360.0);
+
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[1]), _("_S:"));
+ _s[1]->set_tooltip_text(_("Saturation"));
+ gtk_widget_set_tooltip_text(_b[1], _("Saturation"));
+
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[2]), _("_V:"));
+ _s[2]->set_tooltip_text(_("Value"));
+ gtk_widget_set_tooltip_text(_b[2], _("Value"));
+
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[3]), _("_A:"));
+ _s[3]->set_tooltip_text(_("Alpha (opacity)"));
+ gtk_widget_set_tooltip_text(_b[3], _("Alpha (opacity)"));
+ _s[0]->setMap((guchar *)(sp_color_scales_hue_map()));
+ gtk_widget_hide(_l[4]);
+ _s[4]->hide();
+ gtk_widget_hide(_b[4]);
+ _updating = TRUE;
+ c[0] = 0.0;
+
+ SPColor::rgb_to_hsv_floatv(c, rgba[0], rgba[1], rgba[2]);
+
+ setScaled(_a[0], c[0]);
+ setScaled(_a[1], c[1]);
+ setScaled(_a[2], c[2]);
+ setScaled(_a[3], rgba[3]);
+
+ _updateSliders(CSC_CHANNELS_ALL);
+ _updating = FALSE;
+ break;
+ case SP_COLOR_SCALES_MODE_CMYK:
+ _setRangeLimit(100.0);
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[0]), _("_C:"));
+ _s[0]->set_tooltip_text(_("Cyan"));
+ gtk_widget_set_tooltip_text(_b[0], _("Cyan"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[1]), _("_M:"));
+ _s[1]->set_tooltip_text(_("Magenta"));
+ gtk_widget_set_tooltip_text(_b[1], _("Magenta"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[2]), _("_Y:"));
+ _s[2]->set_tooltip_text(_("Yellow"));
+ gtk_widget_set_tooltip_text(_b[2], _("Yellow"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[3]), _("_K:"));
+ _s[3]->set_tooltip_text(_("Black"));
+ gtk_widget_set_tooltip_text(_b[3], _("Black"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[4]), _("_A:"));
+ _s[4]->set_tooltip_text(_("Alpha (opacity)"));
+ gtk_widget_set_tooltip_text(_b[4], _("Alpha (opacity)"));
+ _s[0]->setMap(nullptr);
+ gtk_widget_show(_l[4]);
+ _s[4]->show();
+ gtk_widget_show(_b[4]);
+ _updating = TRUE;
+
+ SPColor::rgb_to_cmyk_floatv(c, rgba[0], rgba[1], rgba[2]);
+ setScaled(_a[0], c[0]);
+ setScaled(_a[1], c[1]);
+ setScaled(_a[2], c[2]);
+ setScaled(_a[3], c[3]);
+
+ setScaled(_a[4], rgba[3]);
+ _updateSliders(CSC_CHANNELS_ALL);
+ _updating = FALSE;
+ break;
+ default:
+ g_warning("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
+ break;
+ }
+}
+
+SPColorScalesMode ColorScales::getMode() const { return _mode; }
+
+void ColorScales::_adjustmentAnyChanged(GtkAdjustment *adjustment, ColorScales *cs)
+{
+ gint channel = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(adjustment), "channel"));
+
+ _adjustmentChanged(cs, channel);
+}
+
+void ColorScales::_sliderAnyGrabbed()
+{
+ if (_updating) {
+ return;
+ }
+ if (!_dragging) {
+ _dragging = TRUE;
+ _color.setHeld(true);
+ }
+}
+
+void ColorScales::_sliderAnyReleased()
+{
+ if (_updating) {
+ return;
+ }
+ if (_dragging) {
+ _dragging = FALSE;
+ _color.setHeld(false);
+ }
+}
+
+void ColorScales::_sliderAnyChanged()
+{
+ if (_updating) {
+ return;
+ }
+ _recalcColor();
+}
+
+void ColorScales::_adjustmentChanged(ColorScales *scales, guint channel)
+{
+ if (scales->_updating) {
+ return;
+ }
+
+ scales->_updateSliders((1 << channel));
+ scales->_recalcColor();
+}
+
+void ColorScales::_updateSliders(guint channels)
+{
+ gfloat rgb0[3], rgbm[3], rgb1[3];
+#ifdef SPCS_PREVIEW
+ guint32 rgba;
+#endif
+ switch (_mode) {
+ case SP_COLOR_SCALES_MODE_RGB:
+ if ((channels != CSC_CHANNEL_R) && (channels != CSC_CHANNEL_A)) {
+ /* Update red */
+ _s[0]->setColors(SP_RGBA32_F_COMPOSE(0.0, getScaled(_a[1]), getScaled(_a[2]), 1.0),
+ SP_RGBA32_F_COMPOSE(0.5, getScaled(_a[1]), getScaled(_a[2]), 1.0),
+ SP_RGBA32_F_COMPOSE(1.0, getScaled(_a[1]), getScaled(_a[2]), 1.0));
+ }
+ if ((channels != CSC_CHANNEL_G) && (channels != CSC_CHANNEL_A)) {
+ /* Update green */
+ _s[1]->setColors(SP_RGBA32_F_COMPOSE(getScaled(_a[0]), 0.0, getScaled(_a[2]), 1.0),
+ SP_RGBA32_F_COMPOSE(getScaled(_a[0]), 0.5, getScaled(_a[2]), 1.0),
+ SP_RGBA32_F_COMPOSE(getScaled(_a[0]), 1.0, getScaled(_a[2]), 1.0));
+ }
+ if ((channels != CSC_CHANNEL_B) && (channels != CSC_CHANNEL_A)) {
+ /* Update blue */
+ _s[2]->setColors(SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), 0.0, 1.0),
+ SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), 0.5, 1.0),
+ SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), 1.0, 1.0));
+ }
+ if (channels != CSC_CHANNEL_A) {
+ /* Update alpha */
+ _s[3]->setColors(SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0),
+ SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5),
+ SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0));
+ }
+ break;
+ case SP_COLOR_SCALES_MODE_HSL:
+ /* Hue is never updated */
+ if ((channels != CSC_CHANNEL_S) && (channels != CSC_CHANNEL_A)) {
+ /* Update saturation */
+ SPColor::hsl_to_rgb_floatv(rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]));
+ SPColor::hsl_to_rgb_floatv(rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]));
+ SPColor::hsl_to_rgb_floatv(rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]));
+ _s[1]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if ((channels != CSC_CHANNEL_V) && (channels != CSC_CHANNEL_A)) {
+ /* Update value */
+ SPColor::hsl_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0);
+ SPColor::hsl_to_rgb_floatv(rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5);
+ SPColor::hsl_to_rgb_floatv(rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0);
+ _s[2]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if (channels != CSC_CHANNEL_A) {
+ /* Update alpha */
+ SPColor::hsl_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
+ _s[3]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.0),
+ SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.5),
+ SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0));
+ }
+ break;
+ case SP_COLOR_SCALES_MODE_HSV:
+ /* Hue is never updated */
+ if ((channels != CSC_CHANNEL_S) && (channels != CSC_CHANNEL_A)) {
+ /* Update saturation */
+ SPColor::hsv_to_rgb_floatv(rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]));
+ SPColor::hsv_to_rgb_floatv(rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]));
+ SPColor::hsv_to_rgb_floatv(rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]));
+ _s[1]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if ((channels != CSC_CHANNEL_V) && (channels != CSC_CHANNEL_A)) {
+ /* Update value */
+ SPColor::hsv_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0);
+ SPColor::hsv_to_rgb_floatv(rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5);
+ SPColor::hsv_to_rgb_floatv(rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0);
+ _s[2]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if (channels != CSC_CHANNEL_A) {
+ /* Update alpha */
+ SPColor::hsv_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
+ _s[3]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.0),
+ SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.5),
+ SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0));
+ }
+ break;
+ case SP_COLOR_SCALES_MODE_CMYK:
+ if ((channels != CSC_CHANNEL_C) && (channels != CSC_CHANNEL_CMYKA)) {
+ /* Update C */
+ SPColor::cmyk_to_rgb_floatv(rgb0, 0.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
+ SPColor::cmyk_to_rgb_floatv(rgbm, 0.5, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
+ SPColor::cmyk_to_rgb_floatv(rgb1, 1.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
+ _s[0]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if ((channels != CSC_CHANNEL_M) && (channels != CSC_CHANNEL_CMYKA)) {
+ /* Update M */
+ SPColor::cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]), getScaled(_a[3]));
+ SPColor::cmyk_to_rgb_floatv(rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]), getScaled(_a[3]));
+ SPColor::cmyk_to_rgb_floatv(rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]), getScaled(_a[3]));
+ _s[1]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if ((channels != CSC_CHANNEL_Y) && (channels != CSC_CHANNEL_CMYKA)) {
+ /* Update Y */
+ SPColor::cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0, getScaled(_a[3]));
+ SPColor::cmyk_to_rgb_floatv(rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5, getScaled(_a[3]));
+ SPColor::cmyk_to_rgb_floatv(rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0, getScaled(_a[3]));
+ _s[2]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if ((channels != CSC_CHANNEL_K) && (channels != CSC_CHANNEL_CMYKA)) {
+ /* Update K */
+ SPColor::cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0);
+ SPColor::cmyk_to_rgb_floatv(rgbm, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5);
+ SPColor::cmyk_to_rgb_floatv(rgb1, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0);
+ _s[3]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if (channels != CSC_CHANNEL_CMYKA) {
+ /* Update alpha */
+ SPColor::cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]),
+ getScaled(_a[3]));
+ _s[4]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.0),
+ SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.5),
+ SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0));
+ }
+ break;
+ default:
+ g_warning("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
+ break;
+ }
+
+#ifdef SPCS_PREVIEW
+ rgba = sp_color_scales_get_rgba32(cs);
+ sp_color_preview_set_rgba32(SP_COLOR_PREVIEW(_p), rgba);
+#endif
+}
+
+static const gchar *sp_color_scales_hue_map()
+{
+ static gchar *map = nullptr;
+
+ if (!map) {
+ gchar *p;
+ gint h;
+ map = g_new(gchar, 4 * 1024);
+ p = map;
+ for (h = 0; h < 1024; h++) {
+ gfloat rgb[3];
+ SPColor::hsl_to_rgb_floatv(rgb, h / 1024.0, 1.0, 0.5);
+ *p++ = SP_COLOR_F_TO_U(rgb[0]);
+ *p++ = SP_COLOR_F_TO_U(rgb[1]);
+ *p++ = SP_COLOR_F_TO_U(rgb[2]);
+ *p++ = 0xFF;
+ }
+ }
+
+ return map;
+}
+
+ColorScalesFactory::ColorScalesFactory(SPColorScalesMode submode)
+ : _submode(submode)
+{
+}
+
+ColorScalesFactory::~ColorScalesFactory() = default;
+
+Gtk::Widget *ColorScalesFactory::createWidget(Inkscape::UI::SelectedColor &color) const
+{
+ Gtk::Widget *w = Gtk::manage(new ColorScales(color, _submode));
+ return w;
+}
+
+Glib::ustring ColorScalesFactory::modeName() const {
+ return gettext(ColorScales::SUBMODE_NAMES[_submode]);
+}
+
+}
+}
+}