Code

moving trunk for module inkscape
[inkscape.git] / src / widgets / sp-color-scales.cpp
1 /*
2  *   bulia byak <buliabyak@users.sf.net>
3  */
5 #ifdef HAVE_CONFIG_H
6 # include "config.h"
7 #endif
8 #include <math.h>
9 #include <gtk/gtk.h>
10 #include <glibmm/i18n.h>
11 #include "../dialogs/dialog-events.h"
12 #include "sp-color-scales.h"
14 #define CSC_CHANNEL_R (1 << 0)
15 #define CSC_CHANNEL_G (1 << 1)
16 #define CSC_CHANNEL_B (1 << 2)
17 #define CSC_CHANNEL_A (1 << 3)
18 #define CSC_CHANNEL_H (1 << 0)
19 #define CSC_CHANNEL_S (1 << 1)
20 #define CSC_CHANNEL_V (1 << 2)
21 #define CSC_CHANNEL_C (1 << 0)
22 #define CSC_CHANNEL_M (1 << 1)
23 #define CSC_CHANNEL_Y (1 << 2)
24 #define CSC_CHANNEL_K (1 << 3)
25 #define CSC_CHANNEL_CMYKA (1 << 4)
27 #define CSC_CHANNELS_ALL 0
30 G_BEGIN_DECLS
32 static void sp_color_scales_class_init (SPColorScalesClass *klass);
33 static void sp_color_scales_init (SPColorScales *cs);
34 static void sp_color_scales_destroy (GtkObject *object);
36 static void sp_color_scales_show_all (GtkWidget *widget);
37 static void sp_color_scales_hide_all (GtkWidget *widget);
39 static const gchar *sp_color_scales_hue_map (void);
41 G_END_DECLS
43 static SPColorSelectorClass *parent_class;
45 #define XPAD 4
46 #define YPAD 1
48 GType
49 sp_color_scales_get_type (void)
50 {
51         static GType type = 0;
52         if (!type) {
53                 static const GTypeInfo info = {
54                         sizeof (SPColorScalesClass),
55                         NULL, /* base_init */
56                         NULL, /* base_finalize */
57                         (GClassInitFunc) sp_color_scales_class_init,
58                         NULL, /* class_finalize */
59                         NULL, /* class_data */
60                         sizeof (SPColorScales),
61                         0,        /* n_preallocs */
62                         (GInstanceInitFunc) sp_color_scales_init,
63                         NULL
64                 };
66                 type = g_type_register_static (SP_TYPE_COLOR_SELECTOR,
67                                                                            "SPColorScales",
68                                                                            &info,
69                                                                            static_cast< GTypeFlags > (0) );
70         }
71         return type;
72 }
74 static void
75 sp_color_scales_class_init (SPColorScalesClass *klass)
76 {
77         static const gchar* nameset[] = {N_("RGB"), N_("HSL"), N_("CMYK"), 0};
78         GtkObjectClass *object_class;
79         GtkWidgetClass *widget_class;
80         SPColorSelectorClass *selector_class;
82         object_class = (GtkObjectClass *) klass;
83         widget_class = (GtkWidgetClass *) klass;
84         selector_class = SP_COLOR_SELECTOR_CLASS (klass);
86         parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass));
88         selector_class->name = nameset;
89         selector_class->submode_count = 3;
91         object_class->destroy = sp_color_scales_destroy;
93         widget_class->show_all = sp_color_scales_show_all;
94         widget_class->hide_all = sp_color_scales_hide_all;
95 }
97 ColorScales::ColorScales( SPColorSelector* csel )
98     : ColorSelector( csel ),
99       _mode( SP_COLOR_SCALES_MODE_NONE ),
100       _rangeLimit( 255.0 ),
101       _updating( FALSE ),
102       _dragging( FALSE )
104     gint i = 0;
106     for (i = 0; i < 5; i++) {
107         _l[i] = 0;
108         _a[i] = 0;
109         _s[i] = 0;
110         _b[i] = 0;
111     }
114 ColorScales::~ColorScales()
116     gint i = 0;
118     for (i = 0; i < 5; i++) {
119         _l[i] = 0;
120         _a[i] = 0;
121         _s[i] = 0;
122         _b[i] = 0;
123     }
126 void sp_color_scales_init (SPColorScales *cs)
128     SP_COLOR_SELECTOR(cs)->base = new ColorScales( SP_COLOR_SELECTOR(cs) );
130     if ( SP_COLOR_SELECTOR(cs)->base )
131     {
132         SP_COLOR_SELECTOR(cs)->base->init();
133     }
136 void ColorScales::init()
138         GtkWidget *t;
139         gint i;
141         _updating = FALSE;
142         _dragging = FALSE;
144         _tt = gtk_tooltips_new();
146         t = gtk_table_new (5, 3, FALSE);
147         gtk_widget_show (t);
148         gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 0);
150         /* Create components */
151         for (i = 0; i < static_cast< gint > (G_N_ELEMENTS(_a)) ; i++) {
152                 /* Label */
153                 _l[i] = gtk_label_new("");
154                 gtk_misc_set_alignment (GTK_MISC (_l[i]), 1.0, 0.5);
155                 gtk_widget_show (_l[i]);
156                 gtk_table_attach (GTK_TABLE (t), _l[i], 0, 1, i, i + 1, GTK_FILL, GTK_FILL, XPAD, YPAD);
157                 /* Adjustment */
158                 _a[i] = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, _rangeLimit, 1.0, 10.0, 10.0);
159                 /* Slider */
160                 _s[i] = sp_color_slider_new (_a[i]);
161                 gtk_widget_show (_s[i]);
162                 gtk_table_attach (GTK_TABLE (t), _s[i], 1, 2, i, i + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)GTK_FILL, XPAD, YPAD);
164                 /* Spinbutton */
165                 _b[i] = gtk_spin_button_new (GTK_ADJUSTMENT (_a[i]), 1.0, 0);
166                 sp_dialog_defocus_on_enter (_b[i]);
167                 gtk_label_set_mnemonic_widget (GTK_LABEL(_l[i]), _b[i]);
168                 gtk_widget_show (_b[i]);
169                 gtk_table_attach (GTK_TABLE (t), _b[i], 2, 3, i, i + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD);
171                 /* Attach channel value to adjustment */
172                 gtk_object_set_data (GTK_OBJECT (_a[i]), "channel", GINT_TO_POINTER (i));
173                 /* Signals */
174                 gtk_signal_connect (GTK_OBJECT (_a[i]), "value_changed",
175                                         GTK_SIGNAL_FUNC (_adjustmentAnyChanged), _csel);
176                 gtk_signal_connect (GTK_OBJECT (_s[i]), "grabbed",
177                                         GTK_SIGNAL_FUNC (_sliderAnyGrabbed), _csel);
178                 gtk_signal_connect (GTK_OBJECT (_s[i]), "released",
179                                         GTK_SIGNAL_FUNC (_sliderAnyReleased), _csel);
180                 gtk_signal_connect (GTK_OBJECT (_s[i]), "changed",
181                                         GTK_SIGNAL_FUNC (_sliderAnyChanged), _csel);
182         }
184         /* Initial mode is none, so it works */
185         setMode(SP_COLOR_SCALES_MODE_RGB);
188 static void
189 sp_color_scales_destroy (GtkObject *object)
191         if (((GtkObjectClass *) (parent_class))->destroy)
192                 (* ((GtkObjectClass *) (parent_class))->destroy) (object);
195 static void
196 sp_color_scales_show_all (GtkWidget *widget)
198         gtk_widget_show (widget);
201 static void
202 sp_color_scales_hide_all (GtkWidget *widget)
204         gtk_widget_hide (widget);
207 GtkWidget *
208 sp_color_scales_new (void)
210         SPColorScales *csel;
212         csel = (SPColorScales*)gtk_type_new (SP_TYPE_COLOR_SCALES);
214         return GTK_WIDGET (csel);
217 void ColorScales::_recalcColor( gboolean changing )
219     if ( changing )
220     {
221         SPColor color;
222         gfloat alpha = 1.0;
223         gfloat c[5];
225         switch (_mode) {
226         case SP_COLOR_SCALES_MODE_RGB:
227         case SP_COLOR_SCALES_MODE_HSV:
228             _getRgbaFloatv(c);
229             sp_color_set_rgb_float (&color, c[0], c[1], c[2]);
230             alpha = c[3];
231             break;
232         case SP_COLOR_SCALES_MODE_CMYK:
233             _getCmykaFloatv( c );
234             sp_color_set_cmyk_float (&color, c[0], c[1], c[2], c[3]);
235             alpha = c[4];
236             break;
237         default:
238             g_warning ("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode);
239             break;
240         }
241         _updateInternals( color, alpha, _dragging );
242     }
243     else
244     {
245         _updateInternals( _color, _alpha, _dragging );
246     }
249 /* Helpers for setting color value */
250 gfloat ColorScales::getScaled( const GtkAdjustment *a )
252     gfloat val = a->value / a->upper;
253     return val;
256 void ColorScales::setScaled( GtkAdjustment *a, gfloat v )
258     gfloat val = v * a->upper;
259     gtk_adjustment_set_value( a, val );
262 void ColorScales::_setRangeLimit( gdouble upper )
264     _rangeLimit = upper;
265     for ( gint i = 0; i < static_cast<gint>(G_N_ELEMENTS(_a)); i++ ) {
266         _a[i]->upper = upper;
267         gtk_adjustment_changed( _a[i] );
268     }
271 void ColorScales::_colorChanged( const SPColor& color, gfloat alpha )
273         gfloat tmp[3];
274         gfloat c[5] = {0.0, 0.0, 0.0, 0.0};
276         switch (_mode) {
277         case SP_COLOR_SCALES_MODE_RGB:
278                 sp_color_get_rgb_floatv (&color, c);
279                 c[3] = alpha;
280                 c[4] = 0.0;
281                 break;
282         case SP_COLOR_SCALES_MODE_HSV:
283                 sp_color_get_rgb_floatv (&color, tmp);
284                 c[0] = getScaled( _a[0] );
285                 sp_color_rgb_to_hsl_floatv (c, tmp[0], tmp[1], tmp[2]);
286                 c[3] = alpha;
287                 c[4] = 0.0;
288                 break;
289         case SP_COLOR_SCALES_MODE_CMYK:
290                 sp_color_get_cmyk_floatv (&color, c);
291                 c[4] = alpha;
292                 break;
293         default:
294                 g_warning ("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode);
295                 break;
296         }
298         _updating = TRUE;
299         setScaled( _a[0], c[0] );
300         setScaled( _a[1], c[1] );
301         setScaled( _a[2], c[2] );
302         setScaled( _a[3], c[3] );
303         setScaled( _a[4], c[4] );
304         _updateSliders( CSC_CHANNELS_ALL );
305         _updating = FALSE;
308 void ColorScales::_getRgbaFloatv( gfloat *rgba )
310         g_return_if_fail (rgba != NULL);
312         switch (_mode) {
313         case SP_COLOR_SCALES_MODE_RGB:
314                 rgba[0] = getScaled(_a[0]);
315                 rgba[1] = getScaled(_a[1]);
316                 rgba[2] = getScaled(_a[2]);
317                 rgba[3] = getScaled(_a[3]);
318                 break;
319         case SP_COLOR_SCALES_MODE_HSV:
320                 sp_color_hsl_to_rgb_floatv (rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
321                 rgba[3] = getScaled(_a[3]);
322                 break;
323         case SP_COLOR_SCALES_MODE_CMYK:
324                 sp_color_cmyk_to_rgb_floatv (rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
325                 rgba[3] = getScaled(_a[4]);
326                 break;
327         default:
328                 g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
329                 break;
330         }
333 void ColorScales::_getCmykaFloatv( gfloat *cmyka )
335         gfloat rgb[3];
337         g_return_if_fail (cmyka != NULL);
339         switch (_mode) {
340         case SP_COLOR_SCALES_MODE_RGB:
341                 sp_color_rgb_to_cmyk_floatv (cmyka, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
342                 cmyka[4] = getScaled(_a[3]);
343                 break;
344         case SP_COLOR_SCALES_MODE_HSV:
345                 sp_color_hsl_to_rgb_floatv (rgb, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
346                 sp_color_rgb_to_cmyk_floatv (cmyka, rgb[0], rgb[1], rgb[2]);
347                 cmyka[4] = getScaled(_a[3]);
348                 break;
349         case SP_COLOR_SCALES_MODE_CMYK:
350                 cmyka[0] = getScaled(_a[0]);
351                 cmyka[1] = getScaled(_a[1]);
352                 cmyka[2] = getScaled(_a[2]);
353                 cmyka[3] = getScaled(_a[3]);
354                 cmyka[4] = getScaled(_a[4]);
355                 break;
356         default:
357                 g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
358                 break;
359         }
362 guint32 ColorScales::_getRgba32()
364         gfloat c[4];
365         guint32 rgba;
367         _getRgbaFloatv(c);
369         rgba = SP_RGBA32_F_COMPOSE (c[0], c[1], c[2], c[3]);
371         return rgba;
374 void ColorScales::setMode(SPColorScalesMode mode)
376         gfloat rgba[4];
377         gfloat c[4];
379         if (_mode == mode) return;
381         if ((_mode == SP_COLOR_SCALES_MODE_RGB) ||
382                 (_mode == SP_COLOR_SCALES_MODE_HSV) ||
383                 (_mode == SP_COLOR_SCALES_MODE_CMYK)) {
384                 _getRgbaFloatv(rgba);
385         } else {
386                 rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0;
387         }
389         _mode = mode;
391         switch (mode) {
392         case SP_COLOR_SCALES_MODE_RGB:
393                 _setRangeLimit(255.0);
394                 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_R"));
395                 gtk_tooltips_set_tip (_tt, _s[0], _("Red"), NULL);
396                 gtk_tooltips_set_tip (_tt, _b[0], _("Red"), NULL);
397                 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_G"));
398                 gtk_tooltips_set_tip (_tt, _s[1], _("Green"), NULL);
399                 gtk_tooltips_set_tip (_tt, _b[1], _("Green"), NULL);
400                 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_B"));
401                 gtk_tooltips_set_tip (_tt, _s[2], _("Blue"), NULL);
402                 gtk_tooltips_set_tip (_tt, _b[2], _("Blue"), NULL);
403                 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_A"));
404                 gtk_tooltips_set_tip (_tt, _s[3], _("Alpha (opacity)"), NULL);
405                 gtk_tooltips_set_tip (_tt, _b[3], _("Alpha (opacity)"), NULL);
406                 sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), NULL);
407                 gtk_widget_hide (_l[4]);
408                 gtk_widget_hide (_s[4]);
409                 gtk_widget_hide (_b[4]);
410                 _updating = TRUE;
411                 setScaled( _a[0], rgba[0] );
412                 setScaled( _a[1], rgba[1] );
413                 setScaled( _a[2], rgba[2] );
414                 setScaled( _a[3], rgba[3] );
415                 _updating = FALSE;
416                 _updateSliders( CSC_CHANNELS_ALL );
417                 break;
418         case SP_COLOR_SCALES_MODE_HSV:
419                 _setRangeLimit(255.0);
420                 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_H"));
421                 gtk_tooltips_set_tip (_tt, _s[0], _("Hue"), NULL);
422                 gtk_tooltips_set_tip (_tt, _b[0], _("Hue"), NULL);
423                 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_S"));
424                 gtk_tooltips_set_tip (_tt, _s[1], _("Saturation"), NULL);
425                 gtk_tooltips_set_tip (_tt, _b[1], _("Saturation"), NULL);
426                 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_L"));
427                 gtk_tooltips_set_tip (_tt, _s[2], _("Lightness"), NULL);
428                 gtk_tooltips_set_tip (_tt, _b[2], _("Lightness"), NULL);
429                 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_A"));
430                 gtk_tooltips_set_tip (_tt, _s[3], _("Alpha (opacity)"), NULL);
431                 gtk_tooltips_set_tip (_tt, _b[3], _("Alpha (opacity)"), NULL);
432                 sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), (guchar*)sp_color_scales_hue_map ());
433                 gtk_widget_hide (_l[4]);
434                 gtk_widget_hide (_s[4]);
435                 gtk_widget_hide (_b[4]);
436                 _updating = TRUE;
437                 c[0] = 0.0;
438                 sp_color_rgb_to_hsl_floatv (c, rgba[0], rgba[1], rgba[2]);
439                 setScaled( _a[0], c[0] );
440                 setScaled( _a[1], c[1] );
441                 setScaled( _a[2], c[2] );
442                 setScaled( _a[3], rgba[3] );
443                 _updating = FALSE;
444                 _updateSliders( CSC_CHANNELS_ALL );
445                 break;
446         case SP_COLOR_SCALES_MODE_CMYK:
447                 _setRangeLimit(100.0);
448                 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_C"));
449                 gtk_tooltips_set_tip (_tt, _s[0], _("Cyan"), NULL);
450                 gtk_tooltips_set_tip (_tt, _b[0], _("Cyan"), NULL);
451                 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_M"));
452                 gtk_tooltips_set_tip (_tt, _s[1], _("Magenta"), NULL);
453                 gtk_tooltips_set_tip (_tt, _b[1], _("Magenta"), NULL);
454                 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_Y"));
455                 gtk_tooltips_set_tip (_tt, _s[2], _("Yellow"), NULL);
456                 gtk_tooltips_set_tip (_tt, _b[2], _("Yellow"), NULL);
457                 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_K"));
458                 gtk_tooltips_set_tip (_tt, _s[3], _("Black"), NULL);
459                 gtk_tooltips_set_tip (_tt, _b[3], _("Black"), NULL);
460                 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[4]), _("_A"));
461                 gtk_tooltips_set_tip (_tt, _s[4], _("Alpha (opacity)"), NULL);
462                 gtk_tooltips_set_tip (_tt, _b[4], _("Alpha (opacity)"), NULL);
463                 sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), NULL);
464                 gtk_widget_show (_l[4]);
465                 gtk_widget_show (_s[4]);
466                 gtk_widget_show (_b[4]);
467                 _updating = TRUE;
468                 sp_color_rgb_to_cmyk_floatv (c, rgba[0], rgba[1], rgba[2]);
469                 setScaled( _a[0], c[0] );
470                 setScaled( _a[1], c[1] );
471                 setScaled( _a[2], c[2] );
472                 setScaled( _a[3], c[3] );
473                 setScaled( _a[4], rgba[3] );
474                 _updating = FALSE;
475                 _updateSliders( CSC_CHANNELS_ALL );
476                 break;
477         default:
478                 g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
479                 break;
480         }
483 SPColorScalesMode ColorScales::getMode() const
485         return _mode;
488 void ColorScales::setSubmode( guint submode )
490         g_return_if_fail (_csel != NULL);
491         g_return_if_fail (SP_IS_COLOR_SCALES (_csel));
492         g_return_if_fail (submode < 3);
494         switch ( submode )
495         {
496         default:
497         case 0:
498                 setMode(SP_COLOR_SCALES_MODE_RGB);
499                 break;
500         case 1:
501                 setMode(SP_COLOR_SCALES_MODE_HSV);
502                 break;
503         case 2:
504                 setMode(SP_COLOR_SCALES_MODE_CMYK);
505                 break;
506         }
509 guint ColorScales::getSubmode() const
511         guint submode = 0;
513         switch ( _mode )
514         {
515         case SP_COLOR_SCALES_MODE_HSV:
516                 submode = 1;
517                 break;
518         case SP_COLOR_SCALES_MODE_CMYK:
519                 submode = 2;
520                 break;
521         case SP_COLOR_SCALES_MODE_RGB:
522         default:
523                 submode = 0;
524         }
526         return submode;
529 void ColorScales::_adjustmentAnyChanged( GtkAdjustment *adjustment, SPColorScales *cs )
531 // TODO check this. It looks questionable:
532         // if a value is entered between 0 and 1 exclusive, normalize it to (int) 0..255  or 0..100
533         if (adjustment->value > 0.0 && adjustment->value < 1.0) {
534                 gtk_adjustment_set_value( adjustment, floor ((adjustment->value) * adjustment->upper + 0.5) );
535         }
537         gint channel = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (adjustment), "channel"));
539         _adjustmentChanged(cs, channel);
542 void ColorScales::_sliderAnyGrabbed( SPColorSlider *slider, SPColorScales *cs )
544     ColorScales* scales = (ColorScales*)(SP_COLOR_SELECTOR(cs)->base);
545         if (!scales->_dragging) {
546                 scales->_dragging = TRUE;
547         scales->_grabbed();
548         scales->_recalcColor( FALSE );
549         }
552 void ColorScales::_sliderAnyReleased( SPColorSlider *slider, SPColorScales *cs )
554     ColorScales* scales = (ColorScales*)(SP_COLOR_SELECTOR(cs)->base);
555         if (scales->_dragging) {
556                 scales->_dragging = FALSE;
557         scales->_released();
558         scales->_recalcColor( FALSE );
559         }
562 void ColorScales::_sliderAnyChanged( SPColorSlider *slider, SPColorScales *cs )
564     ColorScales* scales = (ColorScales*)(SP_COLOR_SELECTOR(cs)->base);
566     scales->_recalcColor( TRUE );
569 void ColorScales::_adjustmentChanged( SPColorScales *cs, guint channel )
571         ColorScales* scales = (ColorScales*)(SP_COLOR_SELECTOR(cs)->base);
572         if (scales->_updating) return;
574         scales->_updating = TRUE;
576         scales->_updateSliders( (1 << channel) );
578         scales->_recalcColor (TRUE);
580         scales->_updating = FALSE;
583 void ColorScales::_updateSliders( guint channels )
585         gfloat rgb0[3], rgbm[3], rgb1[3];
586 #ifdef SPCS_PREVIEW
587         guint32 rgba;
588 #endif
589         switch (_mode) {
590         case SP_COLOR_SCALES_MODE_RGB:
591                 if ((channels != CSC_CHANNEL_R) && (channels != CSC_CHANNEL_A)) {
592                         /* Update red */
593                         sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[0]),
594                                                         SP_RGBA32_F_COMPOSE (0.0, getScaled(_a[1]), getScaled(_a[2]), 1.0),
595                                                         SP_RGBA32_F_COMPOSE (0.5, getScaled(_a[1]), getScaled(_a[2]), 1.0),
596                                                         SP_RGBA32_F_COMPOSE (1.0, getScaled(_a[1]), getScaled(_a[2]), 1.0));
597                 }
598                 if ((channels != CSC_CHANNEL_G) && (channels != CSC_CHANNEL_A)) {
599                         /* Update green */
600                         sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]),
601                                                         SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 0.0, getScaled(_a[2]), 1.0),
602                                                         SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 0.5, getScaled(_a[2]), 1.0),
603                                                         SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 1.0, getScaled(_a[2]), 1.0));
604                 }
605                 if ((channels != CSC_CHANNEL_B) && (channels != CSC_CHANNEL_A)) {
606                         /* Update blue */
607                         sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]),
608                                                         SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 0.0, 1.0),
609                                                         SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 0.5, 1.0),
610                                                         SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 1.0, 1.0));
611                 }
612                 if (channels != CSC_CHANNEL_A) {
613                         /* Update alpha */
614                         sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]),
615                                                         SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0),
616                                                         SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5),
617                                                         SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0));
618                 }
619                 break;
620         case SP_COLOR_SCALES_MODE_HSV:
621                 /* Hue is never updated */
622                 if ((channels != CSC_CHANNEL_S) && (channels != CSC_CHANNEL_A)) {
623                         /* Update saturation */
624                         sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]));
625                         sp_color_hsl_to_rgb_floatv (rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]));
626                         sp_color_hsl_to_rgb_floatv (rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]));
627                         sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]),
628                                                         SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
629                                                         SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
630                                                         SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
631                 }
632                 if ((channels != CSC_CHANNEL_V) && (channels != CSC_CHANNEL_A)) {
633                         /* Update value */
634                         sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0);
635                         sp_color_hsl_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5);
636                         sp_color_hsl_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0);
637                         sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]),
638                                                         SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
639                                                         SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
640                                                         SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
641                 }
642                 if (channels != CSC_CHANNEL_A) {
643                         /* Update alpha */
644                         sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
645                         sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]),
646                                                         SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.0),
647                                                         SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.5),
648                                                         SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0));
649                 }
650                 break;
651         case SP_COLOR_SCALES_MODE_CMYK:
652                 if ((channels != CSC_CHANNEL_C) && (channels != CSC_CHANNEL_CMYKA)) {
653                         /* Update C */
654                         sp_color_cmyk_to_rgb_floatv (rgb0, 0.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
655                         sp_color_cmyk_to_rgb_floatv (rgbm, 0.5, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
656                         sp_color_cmyk_to_rgb_floatv (rgb1, 1.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
657                         sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[0]),
658                                                         SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
659                                                         SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
660                                                         SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
661                 }
662                 if ((channels != CSC_CHANNEL_M) && (channels != CSC_CHANNEL_CMYKA)) {
663                         /* Update M */
664                         sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]), getScaled(_a[3]));
665                         sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]), getScaled(_a[3]));
666                         sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]), getScaled(_a[3]));
667                         sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]),
668                                                         SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
669                                                         SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
670                                                         SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
671                 }
672                 if ((channels != CSC_CHANNEL_Y) && (channels != CSC_CHANNEL_CMYKA)) {
673                         /* Update Y */
674                         sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0, getScaled(_a[3]));
675                         sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5, getScaled(_a[3]));
676                         sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0, getScaled(_a[3]));
677                         sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]),
678                                                         SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
679                                                         SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
680                                                         SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
681                 }
682                 if ((channels != CSC_CHANNEL_K) && (channels != CSC_CHANNEL_CMYKA)) {
683                         /* Update K */
684                         sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0);
685                         sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5);
686                         sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0);
687                         sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]),
688                                                         SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
689                                                         SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
690                                                         SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
691                 }
692                 if (channels != CSC_CHANNEL_CMYKA) {
693                         /* Update alpha */
694                         sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
695                         sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[4]),
696                                                         SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.0),
697                                                         SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.5),
698                                                         SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0));
699                 }
700                 break;
701         default:
702                 g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
703                 break;
704         }
706         // Force the internal color to be updated
707     if ( !_updating )
708     {
709         _recalcColor( TRUE );
710     }
712 #ifdef SPCS_PREVIEW
713         rgba = sp_color_scales_get_rgba32 (cs);
714         sp_color_preview_set_rgba32 (SP_COLOR_PREVIEW (_p), rgba);
715 #endif
718 static const gchar *
719 sp_color_scales_hue_map (void)
721         static gchar *map = NULL;
723         if (!map) {
724                 gchar *p;
725                 gint h;
726                 map = g_new (gchar, 4 * 1024);
727                 p = map;
728                 for (h = 0; h < 1024; h++) {
729                         gfloat rgb[3];
730                         sp_color_hsl_to_rgb_floatv (rgb, h / 1024.0, 1.0, 0.5);
731                         *p++ = SP_COLOR_F_TO_U (rgb[0]);
732                         *p++ = SP_COLOR_F_TO_U (rgb[1]);
733                         *p++ = SP_COLOR_F_TO_U (rgb[2]);
734                         *p++ = 255;
735                 }
736         }
738         return map;