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"
13 #include "svg/svg-icc-color.h"
14 #include "svg/svg-device-color.h"
16 #define CSC_CHANNEL_R (1 << 0)
17 #define CSC_CHANNEL_G (1 << 1)
18 #define CSC_CHANNEL_B (1 << 2)
19 #define CSC_CHANNEL_A (1 << 3)
20 #define CSC_CHANNEL_H (1 << 0)
21 #define CSC_CHANNEL_S (1 << 1)
22 #define CSC_CHANNEL_V (1 << 2)
23 #define CSC_CHANNEL_C (1 << 0)
24 #define CSC_CHANNEL_M (1 << 1)
25 #define CSC_CHANNEL_Y (1 << 2)
26 #define CSC_CHANNEL_K (1 << 3)
27 #define CSC_CHANNEL_CMYKA (1 << 4)
29 #define CSC_CHANNELS_ALL 0
32 G_BEGIN_DECLS
34 static void sp_color_scales_class_init (SPColorScalesClass *klass);
35 static void sp_color_scales_init (SPColorScales *cs);
36 static void sp_color_scales_destroy (GtkObject *object);
38 static void sp_color_scales_show_all (GtkWidget *widget);
39 static void sp_color_scales_hide_all (GtkWidget *widget);
41 static const gchar *sp_color_scales_hue_map (void);
43 G_END_DECLS
45 static SPColorSelectorClass *parent_class;
47 #define XPAD 4
48 #define YPAD 1
50 #define noDUMP_CHANGE_INFO 1
52 GType
53 sp_color_scales_get_type (void)
54 {
55 static GType type = 0;
56 if (!type) {
57 static const GTypeInfo info = {
58 sizeof (SPColorScalesClass),
59 NULL, /* base_init */
60 NULL, /* base_finalize */
61 (GClassInitFunc) sp_color_scales_class_init,
62 NULL, /* class_finalize */
63 NULL, /* class_data */
64 sizeof (SPColorScales),
65 0, /* n_preallocs */
66 (GInstanceInitFunc) sp_color_scales_init,
67 NULL
68 };
70 type = g_type_register_static (SP_TYPE_COLOR_SELECTOR,
71 "SPColorScales",
72 &info,
73 static_cast< GTypeFlags > (0) );
74 }
75 return type;
76 }
78 static void
79 sp_color_scales_class_init (SPColorScalesClass *klass)
80 {
81 static const gchar* nameset[] = {N_("RGB"), N_("HSL"), N_("CMYK"), 0};
82 GtkObjectClass *object_class;
83 GtkWidgetClass *widget_class;
84 SPColorSelectorClass *selector_class;
86 object_class = (GtkObjectClass *) klass;
87 widget_class = (GtkWidgetClass *) klass;
88 selector_class = SP_COLOR_SELECTOR_CLASS (klass);
90 parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass));
92 selector_class->name = nameset;
93 selector_class->submode_count = 3;
95 object_class->destroy = sp_color_scales_destroy;
97 widget_class->show_all = sp_color_scales_show_all;
98 widget_class->hide_all = sp_color_scales_hide_all;
99 }
101 ColorScales::ColorScales( SPColorSelector* csel )
102 : ColorSelector( csel ),
103 _mode( SP_COLOR_SCALES_MODE_NONE ),
104 _rangeLimit( 255.0 ),
105 _updating( FALSE ),
106 _dragging( FALSE )
107 {
108 for (gint i = 0; i < 5; i++) {
109 _l[i] = 0;
110 _a[i] = 0;
111 _s[i] = 0;
112 _b[i] = 0;
113 }
114 }
116 ColorScales::~ColorScales()
117 {
118 for (gint 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 color.set( c[0], c[1], c[2] );
230 alpha = c[3];
231 break;
232 case SP_COLOR_SCALES_MODE_CMYK:
233 {
234 _getCmykaFloatv( c );
235 color.device = new SVGDeviceColor();
236 color.device->type=DEVICE_CMYK;
237 color.device->colors.clear();
238 for (int i=0;i<4;i++){
239 color.device->colors.push_back(c[i]);
240 }
242 float rgb[3];
243 sp_color_cmyk_to_rgb_floatv( rgb, c[0], c[1], c[2], c[3] );
244 color.set( rgb[0], rgb[1], rgb[2] );
245 alpha = c[4];
246 break;
247 }
248 default:
249 g_warning ("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode);
250 break;
251 }
253 /* Preserve ICC */
254 color.icc = _color.icc ? new SVGICCColor(*_color.icc) : 0;
256 _updateInternals( color, alpha, _dragging );
257 }
258 else
259 {
260 _updateInternals( _color, _alpha, _dragging );
261 }
262 }
264 /* Helpers for setting color value */
265 gfloat ColorScales::getScaled( const GtkAdjustment *a )
266 {
267 gfloat val = a->value / a->upper;
268 return val;
269 }
271 void ColorScales::setScaled( GtkAdjustment *a, gfloat v )
272 {
273 gfloat val = v * a->upper;
274 gtk_adjustment_set_value( a, val );
275 }
277 void ColorScales::_setRangeLimit( gdouble upper )
278 {
279 _rangeLimit = upper;
280 for ( gint i = 0; i < static_cast<gint>(G_N_ELEMENTS(_a)); i++ ) {
281 _a[i]->upper = upper;
282 gtk_adjustment_changed( _a[i] );
283 }
284 }
286 void ColorScales::_colorChanged()
287 {
288 #ifdef DUMP_CHANGE_INFO
289 g_message("ColorScales::_colorChanged( this=%p, %f, %f, %f, %f)", this, _color.v.c[0], _color.v.c[1], _color.v.c[2], _alpha );
290 #endif
291 gfloat tmp[3];
292 gfloat c[5] = {0.0, 0.0, 0.0, 0.0};
294 switch (_mode) {
295 case SP_COLOR_SCALES_MODE_RGB:
296 sp_color_get_rgb_floatv( &_color, c );
297 c[3] = _alpha;
298 c[4] = 0.0;
299 break;
300 case SP_COLOR_SCALES_MODE_HSV:
301 sp_color_get_rgb_floatv( &_color, tmp );
302 sp_color_rgb_to_hsl_floatv (c, tmp[0], tmp[1], tmp[2]);
303 c[3] = _alpha;
304 c[4] = 0.0;
305 break;
306 case SP_COLOR_SCALES_MODE_CMYK:
307 sp_color_get_cmyk_floatv( &_color, c );
308 c[4] = _alpha;
309 break;
310 default:
311 g_warning ("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode);
312 break;
313 }
315 _updating = TRUE;
316 setScaled( _a[0], c[0] );
317 setScaled( _a[1], c[1] );
318 setScaled( _a[2], c[2] );
319 setScaled( _a[3], c[3] );
320 setScaled( _a[4], c[4] );
321 _updateSliders( CSC_CHANNELS_ALL );
322 _updating = FALSE;
323 }
325 void ColorScales::_getRgbaFloatv( gfloat *rgba )
326 {
327 g_return_if_fail (rgba != NULL);
329 switch (_mode) {
330 case SP_COLOR_SCALES_MODE_RGB:
331 rgba[0] = getScaled(_a[0]);
332 rgba[1] = getScaled(_a[1]);
333 rgba[2] = getScaled(_a[2]);
334 rgba[3] = getScaled(_a[3]);
335 break;
336 case SP_COLOR_SCALES_MODE_HSV:
337 sp_color_hsl_to_rgb_floatv (rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
338 rgba[3] = getScaled(_a[3]);
339 break;
340 case SP_COLOR_SCALES_MODE_CMYK:
341 sp_color_cmyk_to_rgb_floatv (rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
342 rgba[3] = getScaled(_a[4]);
343 break;
344 default:
345 g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
346 break;
347 }
348 }
350 void ColorScales::_getCmykaFloatv( gfloat *cmyka )
351 {
352 gfloat rgb[3];
354 g_return_if_fail (cmyka != NULL);
356 switch (_mode) {
357 case SP_COLOR_SCALES_MODE_RGB:
358 sp_color_rgb_to_cmyk_floatv (cmyka, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
359 cmyka[4] = getScaled(_a[3]);
360 break;
361 case SP_COLOR_SCALES_MODE_HSV:
362 sp_color_hsl_to_rgb_floatv (rgb, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
363 sp_color_rgb_to_cmyk_floatv (cmyka, rgb[0], rgb[1], rgb[2]);
364 cmyka[4] = getScaled(_a[3]);
365 break;
366 case SP_COLOR_SCALES_MODE_CMYK:
367 cmyka[0] = getScaled(_a[0]);
368 cmyka[1] = getScaled(_a[1]);
369 cmyka[2] = getScaled(_a[2]);
370 cmyka[3] = getScaled(_a[3]);
371 cmyka[4] = getScaled(_a[4]);
372 break;
373 default:
374 g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
375 break;
376 }
377 }
379 guint32 ColorScales::_getRgba32()
380 {
381 gfloat c[4];
382 guint32 rgba;
384 _getRgbaFloatv(c);
386 rgba = SP_RGBA32_F_COMPOSE (c[0], c[1], c[2], c[3]);
388 return rgba;
389 }
391 void ColorScales::setMode(SPColorScalesMode mode)
392 {
393 gfloat rgba[4];
394 gfloat c[4];
396 if (_mode == mode) return;
398 if ((_mode == SP_COLOR_SCALES_MODE_RGB) ||
399 (_mode == SP_COLOR_SCALES_MODE_HSV) ||
400 (_mode == SP_COLOR_SCALES_MODE_CMYK)) {
401 _getRgbaFloatv(rgba);
402 } else {
403 rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0;
404 }
406 _mode = mode;
408 switch (mode) {
409 case SP_COLOR_SCALES_MODE_RGB:
410 _setRangeLimit(255.0);
411 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_R"));
412 gtk_tooltips_set_tip (_tt, _s[0], _("Red"), NULL);
413 gtk_tooltips_set_tip (_tt, _b[0], _("Red"), NULL);
414 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_G"));
415 gtk_tooltips_set_tip (_tt, _s[1], _("Green"), NULL);
416 gtk_tooltips_set_tip (_tt, _b[1], _("Green"), NULL);
417 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_B"));
418 gtk_tooltips_set_tip (_tt, _s[2], _("Blue"), NULL);
419 gtk_tooltips_set_tip (_tt, _b[2], _("Blue"), NULL);
420 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_A"));
421 gtk_tooltips_set_tip (_tt, _s[3], _("Alpha (opacity)"), NULL);
422 gtk_tooltips_set_tip (_tt, _b[3], _("Alpha (opacity)"), NULL);
423 sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), NULL);
424 gtk_widget_hide (_l[4]);
425 gtk_widget_hide (_s[4]);
426 gtk_widget_hide (_b[4]);
427 _updating = TRUE;
428 setScaled( _a[0], rgba[0] );
429 setScaled( _a[1], rgba[1] );
430 setScaled( _a[2], rgba[2] );
431 setScaled( _a[3], rgba[3] );
432 _updating = FALSE;
433 _updateSliders( CSC_CHANNELS_ALL );
434 break;
435 case SP_COLOR_SCALES_MODE_HSV:
436 _setRangeLimit(255.0);
437 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_H"));
438 gtk_tooltips_set_tip (_tt, _s[0], _("Hue"), NULL);
439 gtk_tooltips_set_tip (_tt, _b[0], _("Hue"), NULL);
440 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_S"));
441 gtk_tooltips_set_tip (_tt, _s[1], _("Saturation"), NULL);
442 gtk_tooltips_set_tip (_tt, _b[1], _("Saturation"), NULL);
443 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_L"));
444 gtk_tooltips_set_tip (_tt, _s[2], _("Lightness"), NULL);
445 gtk_tooltips_set_tip (_tt, _b[2], _("Lightness"), NULL);
446 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_A"));
447 gtk_tooltips_set_tip (_tt, _s[3], _("Alpha (opacity)"), NULL);
448 gtk_tooltips_set_tip (_tt, _b[3], _("Alpha (opacity)"), NULL);
449 sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), (guchar*)sp_color_scales_hue_map ());
450 gtk_widget_hide (_l[4]);
451 gtk_widget_hide (_s[4]);
452 gtk_widget_hide (_b[4]);
453 _updating = TRUE;
454 c[0] = 0.0;
455 sp_color_rgb_to_hsl_floatv (c, rgba[0], rgba[1], rgba[2]);
456 setScaled( _a[0], c[0] );
457 setScaled( _a[1], c[1] );
458 setScaled( _a[2], c[2] );
459 setScaled( _a[3], rgba[3] );
460 _updating = FALSE;
461 _updateSliders( CSC_CHANNELS_ALL );
462 break;
463 case SP_COLOR_SCALES_MODE_CMYK:
464 _setRangeLimit(100.0);
465 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_C"));
466 gtk_tooltips_set_tip (_tt, _s[0], _("Cyan"), NULL);
467 gtk_tooltips_set_tip (_tt, _b[0], _("Cyan"), NULL);
468 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_M"));
469 gtk_tooltips_set_tip (_tt, _s[1], _("Magenta"), NULL);
470 gtk_tooltips_set_tip (_tt, _b[1], _("Magenta"), NULL);
471 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_Y"));
472 gtk_tooltips_set_tip (_tt, _s[2], _("Yellow"), NULL);
473 gtk_tooltips_set_tip (_tt, _b[2], _("Yellow"), NULL);
474 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_K"));
475 gtk_tooltips_set_tip (_tt, _s[3], _("Black"), NULL);
476 gtk_tooltips_set_tip (_tt, _b[3], _("Black"), NULL);
477 gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[4]), _("_A"));
478 gtk_tooltips_set_tip (_tt, _s[4], _("Alpha (opacity)"), NULL);
479 gtk_tooltips_set_tip (_tt, _b[4], _("Alpha (opacity)"), NULL);
480 sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), NULL);
481 gtk_widget_show (_l[4]);
482 gtk_widget_show (_s[4]);
483 gtk_widget_show (_b[4]);
484 _updating = TRUE;
486 if (_color.device && _color.device->type == DEVICE_CMYK){
487 setScaled( _a[0], _color.device->colors[0] );
488 setScaled( _a[1], _color.device->colors[1] );
489 setScaled( _a[2], _color.device->colors[2] );
490 setScaled( _a[3], _color.device->colors[3] );
491 } else {
492 //If we still dont have a device-color, convert from rbga
493 sp_color_rgb_to_cmyk_floatv (c, rgba[0], rgba[1], rgba[2]);
494 setScaled( _a[0], c[0] );
495 setScaled( _a[1], c[1] );
496 setScaled( _a[2], c[2] );
497 setScaled( _a[3], c[3] );
498 }
499 setScaled( _a[4], rgba[3] );
500 _updating = FALSE;
501 _updateSliders( CSC_CHANNELS_ALL );
502 break;
503 default:
504 g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
505 break;
506 }
507 }
509 SPColorScalesMode ColorScales::getMode() const
510 {
511 return _mode;
512 }
514 void ColorScales::setSubmode( guint submode )
515 {
516 g_return_if_fail (_csel != NULL);
517 g_return_if_fail (SP_IS_COLOR_SCALES (_csel));
518 g_return_if_fail (submode < 3);
520 switch ( submode )
521 {
522 default:
523 case 0:
524 setMode(SP_COLOR_SCALES_MODE_RGB);
525 break;
526 case 1:
527 setMode(SP_COLOR_SCALES_MODE_HSV);
528 break;
529 case 2:
530 setMode(SP_COLOR_SCALES_MODE_CMYK);
531 break;
532 }
533 }
535 guint ColorScales::getSubmode() const
536 {
537 guint submode = 0;
539 switch ( _mode )
540 {
541 case SP_COLOR_SCALES_MODE_HSV:
542 submode = 1;
543 break;
544 case SP_COLOR_SCALES_MODE_CMYK:
545 submode = 2;
546 break;
547 case SP_COLOR_SCALES_MODE_RGB:
548 default:
549 submode = 0;
550 }
552 return submode;
553 }
555 void ColorScales::_adjustmentAnyChanged( GtkAdjustment *adjustment, SPColorScales *cs )
556 {
557 gint channel = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (adjustment), "channel"));
559 _adjustmentChanged(cs, channel);
560 }
562 void ColorScales::_sliderAnyGrabbed( SPColorSlider *slider, SPColorScales *cs )
563 {
564 (void)slider;
565 ColorScales* scales = (ColorScales*)(SP_COLOR_SELECTOR(cs)->base);
566 if (!scales->_dragging) {
567 scales->_dragging = TRUE;
568 scales->_grabbed();
569 scales->_recalcColor( FALSE );
570 }
571 }
573 void ColorScales::_sliderAnyReleased( SPColorSlider *slider, SPColorScales *cs )
574 {
575 (void)slider;
576 ColorScales* scales = (ColorScales*)(SP_COLOR_SELECTOR(cs)->base);
577 if (scales->_dragging) {
578 scales->_dragging = FALSE;
579 scales->_released();
580 scales->_recalcColor( FALSE );
581 }
582 }
584 void ColorScales::_sliderAnyChanged( SPColorSlider *slider, SPColorScales *cs )
585 {
586 (void)slider;
587 ColorScales* scales = (ColorScales*)(SP_COLOR_SELECTOR(cs)->base);
589 scales->_recalcColor( TRUE );
590 }
592 void ColorScales::_adjustmentChanged( SPColorScales *cs, guint channel )
593 {
594 ColorScales* scales = (ColorScales*)(SP_COLOR_SELECTOR(cs)->base);
595 if (scales->_updating) return;
597 scales->_updating = TRUE;
599 scales->_updateSliders( (1 << channel) );
601 scales->_recalcColor (TRUE);
603 scales->_updating = FALSE;
604 }
606 void ColorScales::_updateSliders( guint channels )
607 {
608 gfloat rgb0[3], rgbm[3], rgb1[3];
609 #ifdef SPCS_PREVIEW
610 guint32 rgba;
611 #endif
612 switch (_mode) {
613 case SP_COLOR_SCALES_MODE_RGB:
614 if ((channels != CSC_CHANNEL_R) && (channels != CSC_CHANNEL_A)) {
615 /* Update red */
616 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[0]),
617 SP_RGBA32_F_COMPOSE (0.0, getScaled(_a[1]), getScaled(_a[2]), 1.0),
618 SP_RGBA32_F_COMPOSE (0.5, getScaled(_a[1]), getScaled(_a[2]), 1.0),
619 SP_RGBA32_F_COMPOSE (1.0, getScaled(_a[1]), getScaled(_a[2]), 1.0));
620 }
621 if ((channels != CSC_CHANNEL_G) && (channels != CSC_CHANNEL_A)) {
622 /* Update green */
623 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]),
624 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 0.0, getScaled(_a[2]), 1.0),
625 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 0.5, getScaled(_a[2]), 1.0),
626 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 1.0, getScaled(_a[2]), 1.0));
627 }
628 if ((channels != CSC_CHANNEL_B) && (channels != CSC_CHANNEL_A)) {
629 /* Update blue */
630 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]),
631 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 0.0, 1.0),
632 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 0.5, 1.0),
633 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 1.0, 1.0));
634 }
635 if (channels != CSC_CHANNEL_A) {
636 /* Update alpha */
637 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]),
638 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0),
639 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5),
640 SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0));
641 }
642 break;
643 case SP_COLOR_SCALES_MODE_HSV:
644 /* Hue is never updated */
645 if ((channels != CSC_CHANNEL_S) && (channels != CSC_CHANNEL_A)) {
646 /* Update saturation */
647 sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]));
648 sp_color_hsl_to_rgb_floatv (rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]));
649 sp_color_hsl_to_rgb_floatv (rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]));
650 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]),
651 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
652 SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
653 SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
654 }
655 if ((channels != CSC_CHANNEL_V) && (channels != CSC_CHANNEL_A)) {
656 /* Update value */
657 sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0);
658 sp_color_hsl_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5);
659 sp_color_hsl_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0);
660 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]),
661 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
662 SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
663 SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
664 }
665 if (channels != CSC_CHANNEL_A) {
666 /* Update alpha */
667 sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
668 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]),
669 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.0),
670 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.5),
671 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0));
672 }
673 break;
674 case SP_COLOR_SCALES_MODE_CMYK:
675 if ((channels != CSC_CHANNEL_C) && (channels != CSC_CHANNEL_CMYKA)) {
676 /* Update C */
677 sp_color_cmyk_to_rgb_floatv (rgb0, 0.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
678 sp_color_cmyk_to_rgb_floatv (rgbm, 0.5, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
679 sp_color_cmyk_to_rgb_floatv (rgb1, 1.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
680 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[0]),
681 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
682 SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
683 SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
684 }
685 if ((channels != CSC_CHANNEL_M) && (channels != CSC_CHANNEL_CMYKA)) {
686 /* Update M */
687 sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]), getScaled(_a[3]));
688 sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]), getScaled(_a[3]));
689 sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]), getScaled(_a[3]));
690 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]),
691 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
692 SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
693 SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
694 }
695 if ((channels != CSC_CHANNEL_Y) && (channels != CSC_CHANNEL_CMYKA)) {
696 /* Update Y */
697 sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0, getScaled(_a[3]));
698 sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5, getScaled(_a[3]));
699 sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0, getScaled(_a[3]));
700 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]),
701 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
702 SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
703 SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
704 }
705 if ((channels != CSC_CHANNEL_K) && (channels != CSC_CHANNEL_CMYKA)) {
706 /* Update K */
707 sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0);
708 sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5);
709 sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0);
710 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]),
711 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
712 SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
713 SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
714 }
715 if (channels != CSC_CHANNEL_CMYKA) {
716 /* Update alpha */
717 sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
718 sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[4]),
719 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.0),
720 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.5),
721 SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0));
722 }
723 break;
724 default:
725 g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
726 break;
727 }
729 // Force the internal color to be updated
730 if ( !_updating )
731 {
732 _recalcColor( TRUE );
733 }
735 #ifdef SPCS_PREVIEW
736 rgba = sp_color_scales_get_rgba32 (cs);
737 sp_color_preview_set_rgba32 (SP_COLOR_PREVIEW (_p), rgba);
738 #endif
739 }
741 static const gchar *
742 sp_color_scales_hue_map (void)
743 {
744 static gchar *map = NULL;
746 if (!map) {
747 gchar *p;
748 gint h;
749 map = g_new (gchar, 4 * 1024);
750 p = map;
751 for (h = 0; h < 1024; h++) {
752 gfloat rgb[3];
753 sp_color_hsl_to_rgb_floatv (rgb, h / 1024.0, 1.0, 0.5);
754 *p++ = SP_COLOR_F_TO_U (rgb[0]);
755 *p++ = SP_COLOR_F_TO_U (rgb[1]);
756 *p++ = SP_COLOR_F_TO_U (rgb[2]);
757 *p++ = 255;
758 }
759 }
761 return map;
762 }