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 )
103 {
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 }
112 }
114 ColorScales::~ColorScales()
115 {
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 }
124 }
126 void sp_color_scales_init (SPColorScales *cs)
127 {
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 }
134 }
136 void ColorScales::init()
137 {
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);
186 }
188 static void
189 sp_color_scales_destroy (GtkObject *object)
190 {
191 if (((GtkObjectClass *) (parent_class))->destroy)
192 (* ((GtkObjectClass *) (parent_class))->destroy) (object);
193 }
195 static void
196 sp_color_scales_show_all (GtkWidget *widget)
197 {
198 gtk_widget_show (widget);
199 }
201 static void
202 sp_color_scales_hide_all (GtkWidget *widget)
203 {
204 gtk_widget_hide (widget);
205 }
207 GtkWidget *
208 sp_color_scales_new (void)
209 {
210 SPColorScales *csel;
212 csel = (SPColorScales*)gtk_type_new (SP_TYPE_COLOR_SCALES);
214 return GTK_WIDGET (csel);
215 }
217 void ColorScales::_recalcColor( gboolean changing )
218 {
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 }
247 }
249 /* Helpers for setting color value */
250 gfloat ColorScales::getScaled( const GtkAdjustment *a )
251 {
252 gfloat val = a->value / a->upper;
253 return val;
254 }
256 void ColorScales::setScaled( GtkAdjustment *a, gfloat v )
257 {
258 gfloat val = v * a->upper;
259 gtk_adjustment_set_value( a, val );
260 }
262 void ColorScales::_setRangeLimit( gdouble upper )
263 {
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 }
269 }
271 void ColorScales::_colorChanged( const SPColor& color, gfloat alpha )
272 {
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;
306 }
308 void ColorScales::_getRgbaFloatv( gfloat *rgba )
309 {
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 }
331 }
333 void ColorScales::_getCmykaFloatv( gfloat *cmyka )
334 {
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 }
360 }
362 guint32 ColorScales::_getRgba32()
363 {
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;
372 }
374 void ColorScales::setMode(SPColorScalesMode mode)
375 {
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 }
481 }
483 SPColorScalesMode ColorScales::getMode() const
484 {
485 return _mode;
486 }
488 void ColorScales::setSubmode( guint submode )
489 {
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 }
507 }
509 guint ColorScales::getSubmode() const
510 {
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;
527 }
529 void ColorScales::_adjustmentAnyChanged( GtkAdjustment *adjustment, SPColorScales *cs )
530 {
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);
540 }
542 void ColorScales::_sliderAnyGrabbed( SPColorSlider *slider, SPColorScales *cs )
543 {
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 }
550 }
552 void ColorScales::_sliderAnyReleased( SPColorSlider *slider, SPColorScales *cs )
553 {
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 }
560 }
562 void ColorScales::_sliderAnyChanged( SPColorSlider *slider, SPColorScales *cs )
563 {
564 ColorScales* scales = (ColorScales*)(SP_COLOR_SELECTOR(cs)->base);
566 scales->_recalcColor( TRUE );
567 }
569 void ColorScales::_adjustmentChanged( SPColorScales *cs, guint channel )
570 {
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;
581 }
583 void ColorScales::_updateSliders( guint channels )
584 {
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
716 }
718 static const gchar *
719 sp_color_scales_hue_map (void)
720 {
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;
739 }