color-scales.cpp revision 66aef0bd4f8eae433e11409fffce072a4578577d
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix/*
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix * bulia byak <buliabyak@users.sf.net>
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix */
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#ifdef HAVE_CONFIG_H
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#include "config.h"
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#endif
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#include <math.h>
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#include <gtkmm/adjustment.h>
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#include <glibmm/i18n.h>
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#include <gtk/gtk.h>
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#include "svg/svg-icc-color.h"
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#include "ui/dialog-events.h"
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#include "ui/widget/color-scales.h"
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#include "ui/widget/color-slider.h"
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#define CSC_CHANNEL_R (1 << 0)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#define CSC_CHANNEL_G (1 << 1)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#define CSC_CHANNEL_B (1 << 2)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#define CSC_CHANNEL_A (1 << 3)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#define CSC_CHANNEL_H (1 << 0)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#define CSC_CHANNEL_S (1 << 1)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#define CSC_CHANNEL_V (1 << 2)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#define CSC_CHANNEL_C (1 << 0)
25ad3718fb4b96b39930af8e043c8ee1e624fd10cilix#define CSC_CHANNEL_M (1 << 1)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#define CSC_CHANNEL_Y (1 << 2)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#define CSC_CHANNEL_K (1 << 3)
5b20351508dc029f37f23fb7add6d0b43bf47f20johanengelen#define CSC_CHANNEL_CMYKA (1 << 4)
5b20351508dc029f37f23fb7add6d0b43bf47f20johanengelen
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#define CSC_CHANNELS_ALL 0
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
25ad3718fb4b96b39930af8e043c8ee1e624fd10cilix#define XPAD 4
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#define YPAD 1
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
5b20351508dc029f37f23fb7add6d0b43bf47f20johanengelen#define noDUMP_CHANGE_INFO 1
5b20351508dc029f37f23fb7add6d0b43bf47f20johanengelen
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixnamespace Inkscape {
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixnamespace UI {
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixnamespace Widget {
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic const gchar *sp_color_scales_hue_map();
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
79d46cc367c4181803d9a7a327b163643f23e8a7cilixconst gchar *ColorScales::SUBMODE_NAMES[] = { N_("None"), N_("RGB"), N_("HSL"), N_("CMYK") };
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixColorScales::ColorScales(SelectedColor &color, SPColorScalesMode mode)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#if GTK_CHECK_VERSION(3, 0, 0)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix : Gtk::Grid()
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#else
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix : Gtk::Table(5, 3, false)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#endif
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix , _color(color)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix , _rangeLimit(255.0)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix , _updating(FALSE)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix , _dragging(FALSE)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix{
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix for (gint i = 0; i < 5; i++) {
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _l[i] = 0;
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _a[i] = 0;
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _s[i] = 0;
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _b[i] = 0;
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix }
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _initUI(mode);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _color.signal_changed.connect(sigc::mem_fun(this, &ColorScales::_onColorChanged));
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _color.signal_dragged.connect(sigc::mem_fun(this, &ColorScales::_onColorChanged));
235e8e7977f17c6070b4691837b8a6cb2bd4cc35johanengelen}
235e8e7977f17c6070b4691837b8a6cb2bd4cc35johanengelen
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixColorScales::~ColorScales()
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix{
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix for (gint i = 0; i < 5; i++) {
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _l[i] = 0;
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _a[i] = 0;
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _s[i] = 0;
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _b[i] = 0;
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix }
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix}
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixvoid ColorScales::_initUI(SPColorScalesMode mode)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix{
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gint i;
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _updating = FALSE;
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _dragging = FALSE;
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix GtkWidget *t = GTK_WIDGET(gobj());
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix /* Create components */
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix for (i = 0; i < static_cast<gint>(G_N_ELEMENTS(_a)); i++) {
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix /* Label */
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _l[i] = gtk_label_new("");
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_misc_set_alignment(GTK_MISC(_l[i]), 1.0, 0.5);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_show(_l[i]);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#if GTK_CHECK_VERSION(3, 0, 0)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix #if GTK_CHECK_VERSION(3, 12, 0)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_set_margin_start(_l[i], XPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_set_margin_end(_l[i], XPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix #else
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_set_margin_left(_l[i], XPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_set_margin_right(_l[i], XPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix #endif
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_set_margin_top(_l[i], YPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_set_margin_bottom(_l[i], YPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_grid_attach(GTK_GRID(t), _l[i], 0, i, 1, 1);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#else
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_table_attach(GTK_TABLE(t), _l[i], 0, 1, i, i + 1, GTK_FILL, GTK_FILL, XPAD, YPAD);
5b20351508dc029f37f23fb7add6d0b43bf47f20johanengelen#endif
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix /* Adjustment */
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _a[i] = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, _rangeLimit, 1.0, 10.0, 10.0));
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix /* Slider */
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _s[i] = Gtk::manage(new Inkscape::UI::Widget::ColorSlider(Glib::wrap(_a[i], true)));
5b20351508dc029f37f23fb7add6d0b43bf47f20johanengelen _s[i]->show();
947fb2f89245c19c5bad9dbefb9fd44c2aaed2eccilix
5b20351508dc029f37f23fb7add6d0b43bf47f20johanengelen#if GTK_CHECK_VERSION(3, 0, 0)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix #if GTK_CHECK_VERSION(3, 12, 0)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _s[i]->set_margin_start(XPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _s[i]->set_margin_end(XPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix #else
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _s[i]->set_margin_left(XPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _s[i]->set_margin_right(XPAD);
5b20351508dc029f37f23fb7add6d0b43bf47f20johanengelen #endif
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _s[i]->set_margin_top(YPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _s[i]->set_margin_bottom(YPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _s[i]->set_hexpand(true);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_grid_attach(GTK_GRID(t), _s[i]->gobj(), 1, i, 1, 1);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#else
5b20351508dc029f37f23fb7add6d0b43bf47f20johanengelen gtk_table_attach(GTK_TABLE(t), _s[i]->gobj(), 1, 2, i, i + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
947fb2f89245c19c5bad9dbefb9fd44c2aaed2eccilix GTK_FILL, XPAD, YPAD);
5b20351508dc029f37f23fb7add6d0b43bf47f20johanengelen#endif
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix /* Spinbutton */
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _b[i] = gtk_spin_button_new(GTK_ADJUSTMENT(_a[i]), 1.0, 0);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix sp_dialog_defocus_on_enter(_b[i]);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_label_set_mnemonic_widget(GTK_LABEL(_l[i]), _b[i]);
5b20351508dc029f37f23fb7add6d0b43bf47f20johanengelen gtk_widget_show(_b[i]);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#if GTK_CHECK_VERSION(3, 0, 0)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix #if GTK_CHECK_VERSION(3, 12, 0)
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_set_margin_start(_b[i], XPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_set_margin_end(_b[i], XPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix #else
5b20351508dc029f37f23fb7add6d0b43bf47f20johanengelen gtk_widget_set_margin_left(_b[i], XPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_set_margin_right(_b[i], XPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix #endif
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_set_margin_top(_b[i], YPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_set_margin_bottom(_b[i], YPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_set_halign(_b[i], GTK_ALIGN_CENTER);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_widget_set_valign(_b[i], GTK_ALIGN_CENTER);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_grid_attach(GTK_GRID(t), _b[i], 2, i, 1, 1);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#else
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix gtk_table_attach(GTK_TABLE(t), _b[i], 2, 3, i, i + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix#endif
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix /* Attach channel value to adjustment */
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix g_object_set_data(G_OBJECT(_a[i]), "channel", GINT_TO_POINTER(i));
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix /* Signals */
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix g_signal_connect(G_OBJECT(_a[i]), "value_changed", G_CALLBACK(_adjustmentAnyChanged), this);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _s[i]->signal_grabbed.connect(sigc::mem_fun(this, &ColorScales::_sliderAnyGrabbed));
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _s[i]->signal_released.connect(sigc::mem_fun(this, &ColorScales::_sliderAnyReleased));
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix _s[i]->signal_value_changed.connect(sigc::mem_fun(this, &ColorScales::_sliderAnyChanged));
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix }
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix /* Initial mode is none, so it works */
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix setMode(mode);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix}
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_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];
sp_color_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);
}
/* 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)
{
gfloat val = v * gtk_adjustment_get_upper(a);
gtk_adjustment_set_value(a, val);
}
void ColorScales::_setRangeLimit(gdouble upper)
{
_rangeLimit = upper;
for (gint i = 0; i < static_cast<gint>(G_N_ELEMENTS(_a)); i++) {
gtk_adjustment_set_upper(_a[i], upper);
gtk_adjustment_changed(_a[i]);
}
}
void ColorScales::_onColorChanged()
{
if (!get_visible()) {
return;
}
#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:
sp_color_get_rgb_floatv(&color, c);
c[3] = _color.alpha();
c[4] = 0.0;
break;
case SP_COLOR_SCALES_MODE_HSV:
sp_color_get_rgb_floatv(&color, tmp);
sp_color_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_CMYK:
sp_color_get_cmyk_floatv(&color, 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;
}
void ColorScales::_getRgbaFloatv(gfloat *rgba)
{
g_return_if_fail(rgba != NULL);
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_HSV:
sp_color_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_CMYK:
sp_color_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 != NULL);
switch (_mode) {
case SP_COLOR_SCALES_MODE_RGB:
sp_color_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_HSV:
sp_color_hsl_to_rgb_floatv(rgb, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
sp_color_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_HSV) ||
(_mode == SP_COLOR_SCALES_MODE_CMYK)) {
_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_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(NULL);
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]);
_updating = FALSE;
_updateSliders(CSC_CHANNELS_ALL);
break;
case SP_COLOR_SCALES_MODE_HSV:
_setRangeLimit(255.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_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;
sp_color_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]);
_updating = FALSE;
_updateSliders(CSC_CHANNELS_ALL);
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(NULL);
gtk_widget_show(_l[4]);
_s[4]->show();
gtk_widget_show(_b[4]);
_updating = TRUE;
sp_color_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]);
_updating = FALSE;
_updateSliders(CSC_CHANNELS_ALL);
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_HSV:
/* Hue is never updated */
if ((channels != CSC_CHANNEL_S) && (channels != CSC_CHANNEL_A)) {
/* Update saturation */
sp_color_hsl_to_rgb_floatv(rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]));
sp_color_hsl_to_rgb_floatv(rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]));
sp_color_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 */
sp_color_hsl_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0);
sp_color_hsl_to_rgb_floatv(rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5);
sp_color_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 */
sp_color_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_CMYK:
if ((channels != CSC_CHANNEL_C) && (channels != CSC_CHANNEL_CMYKA)) {
/* Update C */
sp_color_cmyk_to_rgb_floatv(rgb0, 0.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
sp_color_cmyk_to_rgb_floatv(rgbm, 0.5, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
sp_color_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 */
sp_color_cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]), getScaled(_a[3]));
sp_color_cmyk_to_rgb_floatv(rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]), getScaled(_a[3]));
sp_color_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 */
sp_color_cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0, getScaled(_a[3]));
sp_color_cmyk_to_rgb_floatv(rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5, getScaled(_a[3]));
sp_color_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 */
sp_color_cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0);
sp_color_cmyk_to_rgb_floatv(rgbm, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5);
sp_color_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 */
sp_color_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;
}
// Force the internal color to be updated
if (!_updating) {
_recalcColor();
}
#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(void)
{
static gchar *map = NULL;
if (!map) {
gchar *p;
gint h;
map = g_new(gchar, 4 * 1024);
p = map;
for (h = 0; h < 1024; h++) {
gfloat rgb[3];
sp_color_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++ = 255;
}
}
return map;
}
ColorScalesFactory::ColorScalesFactory(SPColorScalesMode submode)
: _submode(submode)
{
}
ColorScalesFactory::~ColorScalesFactory() {}
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]);
}
}
}
}