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 for (gint i = 0; i < 5; i++) {
105 _l[i] = 0;
106 _a[i] = 0;
107 _s[i] = 0;
108 _b[i] = 0;
109 }
110 }
112 ColorScales::~ColorScales()
113 {
114 for (gint i = 0; i < 5; i++) {
115 _l[i] = 0;
116 _a[i] = 0;
117 _s[i] = 0;
118 _b[i] = 0;
119 }
120 }
122 void sp_color_scales_init (SPColorScales *cs)
123 {
124 SP_COLOR_SELECTOR(cs)->base = new ColorScales( SP_COLOR_SELECTOR(cs) );
126 if ( SP_COLOR_SELECTOR(cs)->base )
127 {
128 SP_COLOR_SELECTOR(cs)->base->init();
129 }
130 }
132 void ColorScales::init()
133 {
134 GtkWidget *t;
135 gint i;
137 _updating = FALSE;
138 _dragging = FALSE;
140 _tt = gtk_tooltips_new();
142 t = gtk_table_new (5, 3, FALSE);
143 gtk_widget_show (t);
144 gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 0);
146 /* Create components */
147 for (i = 0; i < static_cast< gint > (G_N_ELEMENTS(_a)) ; i++) {
148 /* Label */
149 _l[i] = gtk_label_new("");
150 gtk_misc_set_alignment (GTK_MISC (_l[i]), 1.0, 0.5);
151 gtk_widget_show (_l[i]);
152 gtk_table_attach (GTK_TABLE (t), _l[i], 0, 1, i, i + 1, GTK_FILL, GTK_FILL, XPAD, YPAD);
153 /* Adjustment */
154 _a[i] = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, _rangeLimit, 1.0, 10.0, 10.0);
155 /* Slider */
156 _s[i] = sp_color_slider_new (_a[i]);
157 gtk_widget_show (_s[i]);
158 gtk_table_attach (GTK_TABLE (t), _s[i], 1, 2, i, i + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)GTK_FILL, XPAD, YPAD);
160 /* Spinbutton */
161 _b[i] = gtk_spin_button_new (GTK_ADJUSTMENT (_a[i]), 1.0, 0);
162 sp_dialog_defocus_on_enter (_b[i]);
163 gtk_label_set_mnemonic_widget (GTK_LABEL(_l[i]), _b[i]);
164 gtk_widget_show (_b[i]);
165 gtk_table_attach (GTK_TABLE (t), _b[i], 2, 3, i, i + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD);
167 /* Attach channel value to adjustment */
168 gtk_object_set_data (GTK_OBJECT (_a[i]), "channel", GINT_TO_POINTER (i));
169 /* Signals */
170 gtk_signal_connect (GTK_OBJECT (_a[i]), "value_changed",
171 GTK_SIGNAL_FUNC (_adjustmentAnyChanged), _csel);
172 gtk_signal_connect (GTK_OBJECT (_s[i]), "grabbed",
173 GTK_SIGNAL_FUNC (_sliderAnyGrabbed), _csel);
174 gtk_signal_connect (GTK_OBJECT (_s[i]), "released",
175 GTK_SIGNAL_FUNC (_sliderAnyReleased), _csel);
176 gtk_signal_connect (GTK_OBJECT (_s[i]), "changed",
177 GTK_SIGNAL_FUNC (_sliderAnyChanged), _csel);
178 }
180 /* Initial mode is none, so it works */
181 setMode(SP_COLOR_SCALES_MODE_RGB);
182 }
184 static void
185 sp_color_scales_destroy (GtkObject *object)
186 {
187 if (((GtkObjectClass *) (parent_class))->destroy)
188 (* ((GtkObjectClass *) (parent_class))->destroy) (object);
189 }
191 static void
192 sp_color_scales_show_all (GtkWidget *widget)
193 {
194 gtk_widget_show (widget);
195 }
197 static void
198 sp_color_scales_hide_all (GtkWidget *widget)
199 {
200 gtk_widget_hide (widget);
201 }
203 GtkWidget *
204 sp_color_scales_new (void)
205 {
206 SPColorScales *csel;
208 csel = (SPColorScales*)gtk_type_new (SP_TYPE_COLOR_SCALES);
210 return GTK_WIDGET (csel);
211 }
213 void ColorScales::_recalcColor( gboolean changing )
214 {
215 if ( changing )
216 {
217 SPColor color;
218 gfloat alpha = 1.0;
219 gfloat c[5];
221 switch (_mode) {
222 case SP_COLOR_SCALES_MODE_RGB:
223 case SP_COLOR_SCALES_MODE_HSV:
224 _getRgbaFloatv(c);
225 color.set( c[0], c[1], c[2] );
226 alpha = c[3];
227 break;
228 case SP_COLOR_SCALES_MODE_CMYK:
229 {
230 _getCmykaFloatv( c );
232 float rgb[3];
233 sp_color_cmyk_to_rgb_floatv( rgb, c[0], c[1], c[2], c[3] );
234 color.set( rgb[0], rgb[1], rgb[2] );
235 alpha = c[4];
236 break;
237 }
238 default:
239 g_warning ("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode);
240 break;
241 }
242 _updateInternals( color, alpha, _dragging );
243 }
244 else
245 {
246 _updateInternals( _color, _alpha, _dragging );
247 }
248 }
250 /* Helpers for setting color value */
251 gfloat ColorScales::getScaled( const GtkAdjustment *a )
252 {
253 gfloat val = a->value / a->upper;
254 return val;
255 }
257 void ColorScales::setScaled( GtkAdjustment *a, gfloat v )
258 {
259 gfloat val = v * a->upper;
260 gtk_adjustment_set_value( a, val );
261 }
263 void ColorScales::_setRangeLimit( gdouble upper )
264 {
265 _rangeLimit = upper;
266 for ( gint i = 0; i < static_cast<gint>(G_N_ELEMENTS(_a)); i++ ) {
267 _a[i]->upper = upper;
268 gtk_adjustment_changed( _a[i] );
269 }
270 }
272 void ColorScales::_colorChanged()
273 {
274 #ifdef DUMP_CHANGE_INFO
275 g_message("ColorScales::_colorChanged( this=%p, %f, %f, %f, %f)", this, color.v.c[0], color.v.c[1], color.v.c[2], alpha );
276 #endif
277 gfloat tmp[3];
278 gfloat c[5] = {0.0, 0.0, 0.0, 0.0};
280 switch (_mode) {
281 case SP_COLOR_SCALES_MODE_RGB:
282 sp_color_get_rgb_floatv( &_color, c );
283 c[3] = _alpha;
284 c[4] = 0.0;
285 break;
286 case SP_COLOR_SCALES_MODE_HSV:
287 sp_color_get_rgb_floatv( &_color, tmp );
288 c[0] = getScaled( _a[0] );
289 sp_color_rgb_to_hsl_floatv (c, tmp[0], tmp[1], tmp[2]);
290 c[3] = _alpha;
291 c[4] = 0.0;
292 break;
293 case SP_COLOR_SCALES_MODE_CMYK:
294 sp_color_get_cmyk_floatv( &_color, c );
295 c[4] = _alpha;
296 break;
297 default:
298 g_warning ("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode);
299 break;
300 }
302 _updating = TRUE;
303 setScaled( _a[0], c[0] );
304 setScaled( _a[1], c[1] );
305 setScaled( _a[2], c[2] );
306 setScaled( _a[3], c[3] );
307 setScaled( _a[4], c[4] );
308 _updateSliders( CSC_CHANNELS_ALL );
309 _updating = FALSE;
310 }
312 void ColorScales::_getRgbaFloatv( gfloat *rgba )
313 {
314 g_return_if_fail (rgba != NULL);
316 switch (_mode) {
317 case SP_COLOR_SCALES_MODE_RGB:
318 rgba[0] = getScaled(_a[0]);
319 rgba[1] = getScaled(_a[1]);
320 rgba[2] = getScaled(_a[2]);
321 rgba[3] = getScaled(_a[3]);
322 break;
323 case SP_COLOR_SCALES_MODE_HSV:
324 sp_color_hsl_to_rgb_floatv (rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
325 rgba[3] = getScaled(_a[3]);
326 break;
327 case SP_COLOR_SCALES_MODE_CMYK:
328 sp_color_cmyk_to_rgb_floatv (rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
329 rgba[3] = getScaled(_a[4]);
330 break;
331 default:
332 g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
333 break;
334 }
335 }
337 void ColorScales::_getCmykaFloatv( gfloat *cmyka )
338 {
339 gfloat rgb[3];
341 g_return_if_fail (cmyka != NULL);
343 switch (_mode) {
344 case SP_COLOR_SCALES_MODE_RGB:
345 sp_color_rgb_to_cmyk_floatv (cmyka, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
346 cmyka[4] = getScaled(_a[3]);
347 break;
348 case SP_COLOR_SCALES_MODE_HSV:
349 sp_color_hsl_to_rgb_floatv (rgb, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
350 sp_color_rgb_to_cmyk_floatv (cmyka, rgb[0], rgb[1], rgb[2]);
351 cmyka[4] = getScaled(_a[3]);
352 break;
353 case SP_COLOR_SCALES_MODE_CMYK:
354 cmyka[0] = getScaled(_a[0]);
355 cmyka[1] = getScaled(_a[1]);
356 cmyka[2] = getScaled(_a[2]);
357 cmyka[3] = getScaled(_a[3]);
358 cmyka[4] = getScaled(_a[4]);
359 break;
360 default:
361 g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
362 break;
363 }
364 }
366 guint32 ColorScales::_getRgba32()
367 {
368 gfloat c[4];
369 guint32 rgba;
371 _getRgbaFloatv(c);
373 rgba = SP_RGBA32_F_COMPOSE (c[0], c[1], c[2], c[3]);
375 return rgba;
376 }
378 void ColorScales::setMode(SPColorScalesMode mode)
379 {
380 gfloat rgba[4];
381 gfloat c[4];
383 if (_mode == mode) return;
385 if ((_mode == SP_COLOR_SCALES_MODE_RGB) ||
386 (_mode == SP_COLOR_SCALES_MODE_HSV) ||
387 (_mode == SP_COLOR_SCALES_MODE_CMYK)) {
388 _getRgbaFloatv(rgba);
389 } else {
390 rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0;
391 }
393 _mode = mode;
395 switch (mode) {
396 case SP_COLOR_SCALES_MODE_RGB:
397 _setRangeLimit(255.0);
398 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_R"));
399 gtk_tooltips_set_tip (_tt, _s[0], _("Red"), NULL);
400 gtk_tooltips_set_tip (_tt, _b[0], _("Red"), NULL);
401 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_G"));
402 gtk_tooltips_set_tip (_tt, _s[1], _("Green"), NULL);
403 gtk_tooltips_set_tip (_tt, _b[1], _("Green"), NULL);
404 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_B"));
405 gtk_tooltips_set_tip (_tt, _s[2], _("Blue"), NULL);
406 gtk_tooltips_set_tip (_tt, _b[2], _("Blue"), NULL);
407 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_A"));
408 gtk_tooltips_set_tip (_tt, _s[3], _("Alpha (opacity)"), NULL);
409 gtk_tooltips_set_tip (_tt, _b[3], _("Alpha (opacity)"), NULL);
410 sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), NULL);
411 gtk_widget_hide (_l[4]);
412 gtk_widget_hide (_s[4]);
413 gtk_widget_hide (_b[4]);
414 _updating = TRUE;
415 setScaled( _a[0], rgba[0] );
416 setScaled( _a[1], rgba[1] );
417 setScaled( _a[2], rgba[2] );
418 setScaled( _a[3], rgba[3] );
419 _updating = FALSE;
420 _updateSliders( CSC_CHANNELS_ALL );
421 break;
422 case SP_COLOR_SCALES_MODE_HSV:
423 _setRangeLimit(255.0);
424 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_H"));
425 gtk_tooltips_set_tip (_tt, _s[0], _("Hue"), NULL);
426 gtk_tooltips_set_tip (_tt, _b[0], _("Hue"), NULL);
427 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_S"));
428 gtk_tooltips_set_tip (_tt, _s[1], _("Saturation"), NULL);
429 gtk_tooltips_set_tip (_tt, _b[1], _("Saturation"), NULL);
430 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_L"));
431 gtk_tooltips_set_tip (_tt, _s[2], _("Lightness"), NULL);
432 gtk_tooltips_set_tip (_tt, _b[2], _("Lightness"), NULL);
433 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_A"));
434 gtk_tooltips_set_tip (_tt, _s[3], _("Alpha (opacity)"), NULL);
435 gtk_tooltips_set_tip (_tt, _b[3], _("Alpha (opacity)"), NULL);
436 sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), (guchar*)sp_color_scales_hue_map ());
437 gtk_widget_hide (_l[4]);
438 gtk_widget_hide (_s[4]);
439 gtk_widget_hide (_b[4]);
440 _updating = TRUE;
441 c[0] = 0.0;
442 sp_color_rgb_to_hsl_floatv (c, rgba[0], rgba[1], rgba[2]);
443 setScaled( _a[0], c[0] );
444 setScaled( _a[1], c[1] );
445 setScaled( _a[2], c[2] );
446 setScaled( _a[3], rgba[3] );
447 _updating = FALSE;
448 _updateSliders( CSC_CHANNELS_ALL );
449 break;
450 case SP_COLOR_SCALES_MODE_CMYK:
451 _setRangeLimit(100.0);
452 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_C"));
453 gtk_tooltips_set_tip (_tt, _s[0], _("Cyan"), NULL);
454 gtk_tooltips_set_tip (_tt, _b[0], _("Cyan"), NULL);
455 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_M"));
456 gtk_tooltips_set_tip (_tt, _s[1], _("Magenta"), NULL);
457 gtk_tooltips_set_tip (_tt, _b[1], _("Magenta"), NULL);
458 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_Y"));
459 gtk_tooltips_set_tip (_tt, _s[2], _("Yellow"), NULL);
460 gtk_tooltips_set_tip (_tt, _b[2], _("Yellow"), NULL);
461 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_K"));
462 gtk_tooltips_set_tip (_tt, _s[3], _("Black"), NULL);
463 gtk_tooltips_set_tip (_tt, _b[3], _("Black"), NULL);
464 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[4]), _("_A"));
465 gtk_tooltips_set_tip (_tt, _s[4], _("Alpha (opacity)"), NULL);
466 gtk_tooltips_set_tip (_tt, _b[4], _("Alpha (opacity)"), NULL);
467 sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), NULL);
468 gtk_widget_show (_l[4]);
469 gtk_widget_show (_s[4]);
470 gtk_widget_show (_b[4]);
471 _updating = TRUE;
472 sp_color_rgb_to_cmyk_floatv (c, rgba[0], rgba[1], rgba[2]);
473 setScaled( _a[0], c[0] );
474 setScaled( _a[1], c[1] );
475 setScaled( _a[2], c[2] );
476 setScaled( _a[3], c[3] );
477 setScaled( _a[4], rgba[3] );
478 _updating = FALSE;
479 _updateSliders( CSC_CHANNELS_ALL );
480 break;
481 default:
482 g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
483 break;
484 }
485 }
487 SPColorScalesMode ColorScales::getMode() const
488 {
489 return _mode;
490 }
492 void ColorScales::setSubmode( guint submode )
493 {
494 g_return_if_fail (_csel != NULL);
495 g_return_if_fail (SP_IS_COLOR_SCALES (_csel));
496 g_return_if_fail (submode < 3);
498 switch ( submode )
499 {
500 default:
501 case 0:
502 setMode(SP_COLOR_SCALES_MODE_RGB);
503 break;
504 case 1:
505 setMode(SP_COLOR_SCALES_MODE_HSV);
506 break;
507 case 2:
508 setMode(SP_COLOR_SCALES_MODE_CMYK);
509 break;
510 }
511 }
513 guint ColorScales::getSubmode() const
514 {
515 guint submode = 0;
517 switch ( _mode )
518 {
519 case SP_COLOR_SCALES_MODE_HSV:
520 submode = 1;
521 break;
522 case SP_COLOR_SCALES_MODE_CMYK:
523 submode = 2;
524 break;
525 case SP_COLOR_SCALES_MODE_RGB:
526 default:
527 submode = 0;
528 }
530 return submode;
531 }
533 void ColorScales::_adjustmentAnyChanged( GtkAdjustment *adjustment, SPColorScales *cs )
534 {
535 // TODO check this. It looks questionable:
536 // if a value is entered between 0 and 1 exclusive, normalize it to (int) 0..255 or 0..100
537 if (adjustment->value > 0.0 && adjustment->value < 1.0) {
538 gtk_adjustment_set_value( adjustment, floor ((adjustment->value) * adjustment->upper + 0.5) );
539 }
541 gint channel = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (adjustment), "channel"));
543 _adjustmentChanged(cs, channel);
544 }
546 void ColorScales::_sliderAnyGrabbed( SPColorSlider *slider, SPColorScales *cs )
547 {
548 (void)slider;
549 ColorScales* scales = (ColorScales*)(SP_COLOR_SELECTOR(cs)->base);
550 if (!scales->_dragging) {
551 scales->_dragging = TRUE;
552 scales->_grabbed();
553 scales->_recalcColor( FALSE );
554 }
555 }
557 void ColorScales::_sliderAnyReleased( SPColorSlider *slider, SPColorScales *cs )
558 {
559 (void)slider;
560 ColorScales* scales = (ColorScales*)(SP_COLOR_SELECTOR(cs)->base);
561 if (scales->_dragging) {
562 scales->_dragging = FALSE;
563 scales->_released();
564 scales->_recalcColor( FALSE );
565 }
566 }
568 void ColorScales::_sliderAnyChanged( SPColorSlider *slider, SPColorScales *cs )
569 {
570 (void)slider;
571 ColorScales* scales = (ColorScales*)(SP_COLOR_SELECTOR(cs)->base);
573 scales->_recalcColor( TRUE );
574 }
576 void ColorScales::_adjustmentChanged( SPColorScales *cs, guint channel )
577 {
578 ColorScales* scales = (ColorScales*)(SP_COLOR_SELECTOR(cs)->base);
579 if (scales->_updating) return;
581 scales->_updating = TRUE;
583 scales->_updateSliders( (1 << channel) );
585 scales->_recalcColor (TRUE);
587 scales->_updating = FALSE;
588 }
590 void ColorScales::_updateSliders( guint channels )
591 {
592 gfloat rgb0[3], rgbm[3], rgb1[3];
593 #ifdef SPCS_PREVIEW
594 guint32 rgba;
595 #endif
596 switch (_mode) {
597 case SP_COLOR_SCALES_MODE_RGB:
598 if ((channels != CSC_CHANNEL_R) && (channels != CSC_CHANNEL_A)) {
599 /* Update red */
600 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[0]),
601 SP_RGBA32_F_COMPOSE (0.0, getScaled(_a[1]), getScaled(_a[2]), 1.0),
602 SP_RGBA32_F_COMPOSE (0.5, getScaled(_a[1]), getScaled(_a[2]), 1.0),
603 SP_RGBA32_F_COMPOSE (1.0, getScaled(_a[1]), getScaled(_a[2]), 1.0));
604 }
605 if ((channels != CSC_CHANNEL_G) && (channels != CSC_CHANNEL_A)) {
606 /* Update green */
607 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]),
608 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 0.0, getScaled(_a[2]), 1.0),
609 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 0.5, getScaled(_a[2]), 1.0),
610 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 1.0, getScaled(_a[2]), 1.0));
611 }
612 if ((channels != CSC_CHANNEL_B) && (channels != CSC_CHANNEL_A)) {
613 /* Update blue */
614 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]),
615 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 0.0, 1.0),
616 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 0.5, 1.0),
617 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 1.0, 1.0));
618 }
619 if (channels != CSC_CHANNEL_A) {
620 /* Update alpha */
621 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]),
622 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0),
623 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5),
624 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0));
625 }
626 break;
627 case SP_COLOR_SCALES_MODE_HSV:
628 /* Hue is never updated */
629 if ((channels != CSC_CHANNEL_S) && (channels != CSC_CHANNEL_A)) {
630 /* Update saturation */
631 sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]));
632 sp_color_hsl_to_rgb_floatv (rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]));
633 sp_color_hsl_to_rgb_floatv (rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]));
634 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]),
635 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
636 SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
637 SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
638 }
639 if ((channels != CSC_CHANNEL_V) && (channels != CSC_CHANNEL_A)) {
640 /* Update value */
641 sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0);
642 sp_color_hsl_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5);
643 sp_color_hsl_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0);
644 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]),
645 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
646 SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
647 SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
648 }
649 if (channels != CSC_CHANNEL_A) {
650 /* Update alpha */
651 sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
652 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]),
653 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.0),
654 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.5),
655 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0));
656 }
657 break;
658 case SP_COLOR_SCALES_MODE_CMYK:
659 if ((channels != CSC_CHANNEL_C) && (channels != CSC_CHANNEL_CMYKA)) {
660 /* Update C */
661 sp_color_cmyk_to_rgb_floatv (rgb0, 0.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
662 sp_color_cmyk_to_rgb_floatv (rgbm, 0.5, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
663 sp_color_cmyk_to_rgb_floatv (rgb1, 1.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
664 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[0]),
665 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
666 SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
667 SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
668 }
669 if ((channels != CSC_CHANNEL_M) && (channels != CSC_CHANNEL_CMYKA)) {
670 /* Update M */
671 sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]), getScaled(_a[3]));
672 sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]), getScaled(_a[3]));
673 sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]), getScaled(_a[3]));
674 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]),
675 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
676 SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
677 SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
678 }
679 if ((channels != CSC_CHANNEL_Y) && (channels != CSC_CHANNEL_CMYKA)) {
680 /* Update Y */
681 sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0, getScaled(_a[3]));
682 sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5, getScaled(_a[3]));
683 sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0, getScaled(_a[3]));
684 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]),
685 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
686 SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
687 SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
688 }
689 if ((channels != CSC_CHANNEL_K) && (channels != CSC_CHANNEL_CMYKA)) {
690 /* Update K */
691 sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0);
692 sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5);
693 sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0);
694 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]),
695 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
696 SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
697 SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
698 }
699 if (channels != CSC_CHANNEL_CMYKA) {
700 /* Update alpha */
701 sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
702 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[4]),
703 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.0),
704 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.5),
705 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0));
706 }
707 break;
708 default:
709 g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
710 break;
711 }
713 // Force the internal color to be updated
714 if ( !_updating )
715 {
716 _recalcColor( TRUE );
717 }
719 #ifdef SPCS_PREVIEW
720 rgba = sp_color_scales_get_rgba32 (cs);
721 sp_color_preview_set_rgba32 (SP_COLOR_PREVIEW (_p), rgba);
722 #endif
723 }
725 static const gchar *
726 sp_color_scales_hue_map (void)
727 {
728 static gchar *map = NULL;
730 if (!map) {
731 gchar *p;
732 gint h;
733 map = g_new (gchar, 4 * 1024);
734 p = map;
735 for (h = 0; h < 1024; h++) {
736 gfloat rgb[3];
737 sp_color_hsl_to_rgb_floatv (rgb, h / 1024.0, 1.0, 0.5);
738 *p++ = SP_COLOR_F_TO_U (rgb[0]);
739 *p++ = SP_COLOR_F_TO_U (rgb[1]);
740 *p++ = SP_COLOR_F_TO_U (rgb[2]);
741 *p++ = 255;
742 }
743 }
745 return map;
746 }