Code

05299624791ebedbe29bab9618217b0455e1d685
[inkscape.git] / src / widgets / sp-color-selector.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/gtksignal.h>
10 #include <glibmm/i18n.h>
11 #include "sp-color-selector.h"
13 enum {
14         GRABBED,
15         DRAGGED,
16         RELEASED,
17         CHANGED,
18         LAST_SIGNAL
19 };
21 #define noDUMP_CHANGE_INFO
22 #define FOO_NAME(x) g_type_name( G_TYPE_FROM_INSTANCE(x) )
24 static void sp_color_selector_class_init (SPColorSelectorClass *klass);
25 static void sp_color_selector_init (SPColorSelector *csel);
26 static void sp_color_selector_destroy (GtkObject *object);
28 static void sp_color_selector_show_all (GtkWidget *widget);
29 static void sp_color_selector_hide_all (GtkWidget *widget);
31 static GtkVBoxClass *parent_class;
32 static guint csel_signals[LAST_SIGNAL] = {0};
34 GType
35 sp_color_selector_get_type (void)
36 {
37         static GType type = 0;
38         if (!type) {
39                 static const GTypeInfo info = {
40                         sizeof (SPColorSelectorClass),
41                         NULL, /* base_init */
42                         NULL, /* base_finalize */
43                         (GClassInitFunc) sp_color_selector_class_init,
44                         NULL, /* class_finalize */
45                         NULL, /* class_data */
46                         sizeof (SPColorSelector),
47                         0,        /* n_preallocs */
48                         (GInstanceInitFunc) sp_color_selector_init,
49                         NULL
50                 };
52                 type = g_type_register_static (GTK_TYPE_VBOX,
53                                                                            "SPColorSelector",
54                                                                            &info,
55                                                                            static_cast< GTypeFlags > (0) );
56         }
57         return type;
58 }
60 static void
61 sp_color_selector_class_init (SPColorSelectorClass *klass)
62 {
63         static const gchar* nameset[] = {N_("Unnamed"), 0};
64         GtkObjectClass *object_class;
65         GtkWidgetClass *widget_class;
67         object_class = (GtkObjectClass *) klass;
68         widget_class = (GtkWidgetClass *) klass;
70         parent_class = (GtkVBoxClass*)gtk_type_class (GTK_TYPE_VBOX);
72         csel_signals[GRABBED] = gtk_signal_new ("grabbed",
73                                                  (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
74                                                  GTK_CLASS_TYPE(object_class),
75                                                  GTK_SIGNAL_OFFSET (SPColorSelectorClass, grabbed),
76                                                  gtk_marshal_NONE__NONE,
77                                                  GTK_TYPE_NONE, 0);
78         csel_signals[DRAGGED] = gtk_signal_new ("dragged",
79                                                  (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
80                                                  GTK_CLASS_TYPE(object_class),
81                                                  GTK_SIGNAL_OFFSET (SPColorSelectorClass, dragged),
82                                                  gtk_marshal_NONE__NONE,
83                                                  GTK_TYPE_NONE, 0);
84         csel_signals[RELEASED] = gtk_signal_new ("released",
85                                                  (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
86                                                  GTK_CLASS_TYPE(object_class),
87                                                  GTK_SIGNAL_OFFSET (SPColorSelectorClass, released),
88                                                  gtk_marshal_NONE__NONE,
89                                                  GTK_TYPE_NONE, 0);
90         csel_signals[CHANGED] = gtk_signal_new ("changed",
91                                                  (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
92                                                  GTK_CLASS_TYPE(object_class),
93                                                  GTK_SIGNAL_OFFSET (SPColorSelectorClass, changed),
94                                                  gtk_marshal_NONE__NONE,
95                                                  GTK_TYPE_NONE, 0);
97         klass->name = nameset;
98         klass->submode_count = 1;
100         object_class->destroy = sp_color_selector_destroy;
102         widget_class->show_all = sp_color_selector_show_all;
103         widget_class->hide_all = sp_color_selector_hide_all;
107 void sp_color_selector_init (SPColorSelector *csel)
109     if ( csel->base )
110     {
111         csel->base->init();
112     }
113 /*   gtk_signal_connect (GTK_OBJECT (csel->rgbae), "changed", GTK_SIGNAL_FUNC (sp_color_selector_rgba_entry_changed), csel); */
116 static void
117 sp_color_selector_destroy (GtkObject *object)
119         SPColorSelector *csel;
121         csel = SP_COLOR_SELECTOR (object);
122     if ( csel->base )
123     {
124         delete csel->base;
125         csel->base = 0;
126     }
128         if (((GtkObjectClass *) (parent_class))->destroy)
129                 (* ((GtkObjectClass *) (parent_class))->destroy) (object);
132 static void
133 sp_color_selector_show_all (GtkWidget *widget)
135         gtk_widget_show (widget);
138 static void
139 sp_color_selector_hide_all (GtkWidget *widget)
141         gtk_widget_hide (widget);
144 GtkWidget *
145 sp_color_selector_new( GType selector_type )
147         SPColorSelector *csel;
148         g_return_val_if_fail (g_type_is_a (selector_type, SP_TYPE_COLOR_SELECTOR), NULL);
150         csel = SP_COLOR_SELECTOR (g_object_new (selector_type, NULL));
152         return GTK_WIDGET (csel);
155 double ColorSelector::_epsilon = 1e-4;
157 void ColorSelector::setSubmode( guint submode )
159     (void)submode;
162 guint ColorSelector::getSubmode() const
164     guint mode = 0;
165     return mode;
168 ColorSelector::ColorSelector( SPColorSelector* csel )
169     : _csel(csel),
170       _color( 0 ),
171       _alpha(1.0),
172       _held(FALSE),
173       virgin(true)
177 ColorSelector::~ColorSelector()
181 void ColorSelector::init()
183     _csel->base = new ColorSelector( _csel );
186 void ColorSelector::setColor( const SPColor& color )
188     setColorAlpha( color, _alpha );
191 SPColor ColorSelector::getColor() const
193     return _color;
196 void ColorSelector::setAlpha( gfloat alpha )
198     g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) );
199     setColorAlpha( _color, alpha );
202 gfloat ColorSelector::getAlpha() const
204     return _alpha;
207 #include "svg/svg-icc-color.h"
209 /**
210 Called from the outside to set the color; optionally emits signal (only when called from
211 downstream, e.g. the RGBA value field, but not from the rest of the program)
212 */
213 void ColorSelector::setColorAlpha( const SPColor& color, gfloat alpha, bool emit )
215 #ifdef DUMP_CHANGE_INFO
216     g_message("ColorSelector::setColorAlpha( this=%p, %f, %f, %f, %s,   %f,   %s) in %s", this, color.v.c[0], color.v.c[1], color.v.c[2], (color.icc?color.icc->colorProfile.c_str():"<null>"), alpha, (emit?"YES":"no"), FOO_NAME(_csel));
217 #endif
218     g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) );
220 #ifdef DUMP_CHANGE_INFO
221     g_message("---- ColorSelector::setColorAlpha    virgin:%s   !close:%s    alpha is:%s in %s",
222               (virgin?"YES":"no"),
223               (!color.isClose( _color, _epsilon )?"YES":"no"),
224               ((fabs ((_alpha) - (alpha)) >= _epsilon )?"YES":"no"),
225               FOO_NAME(_csel)
226               );
227 #endif
229     if ( virgin || !color.isClose( _color, _epsilon ) ||
230          (fabs ((_alpha) - (alpha)) >= _epsilon )) {
232         virgin = false;
234         _color = color;
235         _alpha = alpha;
236         _colorChanged( color, alpha );
238         if (emit)
239                 gtk_signal_emit (GTK_OBJECT (_csel), csel_signals[CHANGED]);
240 #ifdef DUMP_CHANGE_INFO
241     } else {
242         g_message("++++ ColorSelector::setColorAlpha   color:%08x  ==>  _color:%08X   isClose:%s   in %s", color.toRGBA32(alpha), _color.toRGBA32(_alpha),
243                   (color.isClose( _color, _epsilon )?"YES":"no"), FOO_NAME(_csel));
244 #endif
245     }
248 void ColorSelector::_grabbed()
250     _held = TRUE;
251 #ifdef DUMP_CHANGE_INFO
252     g_message ("%s:%d: About to signal %s in %s", __FILE__, __LINE__,
253                "GRABBED",
254                FOO_NAME(_csel));
255 #endif
256     gtk_signal_emit (GTK_OBJECT (_csel), csel_signals[GRABBED]);
259 void ColorSelector::_released()
261     _held = false;
262 #ifdef DUMP_CHANGE_INFO
263     g_message ("%s:%d: About to signal %s in %s", __FILE__, __LINE__,
264                "RELEASED",
265                FOO_NAME(_csel));
266 #endif
267     gtk_signal_emit (GTK_OBJECT (_csel), csel_signals[RELEASED]);
268     gtk_signal_emit (GTK_OBJECT (_csel), csel_signals[CHANGED]);
271 // Called from subclasses to update color and broadcast if needed
272 void ColorSelector::_updateInternals( const SPColor& color, gfloat alpha, gboolean held )
274     g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) );
275     gboolean colorDifferent = ( !color.isClose( _color, _epsilon )
276                                 || ( fabs((_alpha) - (alpha)) >= _epsilon ) );
278     gboolean grabbed = held && !_held;
279     gboolean released = !held && _held;
281     // Store these before emmiting any signals
282     _held = held;
283     if ( colorDifferent )
284     {
285         _color = color;
286         _alpha = alpha;
287     }
289     if ( grabbed )
290     {
291 #ifdef DUMP_CHANGE_INFO
292         g_message ("%s:%d: About to signal %s to color %08x::%s in %s", __FILE__, __LINE__,
293                    "GRABBED",
294                    color.toRGBA32( alpha ), (color.icc?color.icc->colorProfile.c_str():"<null>"), FOO_NAME(_csel));
295 #endif
296         gtk_signal_emit (GTK_OBJECT (_csel), csel_signals[GRABBED]);
297     }
298     else if ( released )
299     {
300 #ifdef DUMP_CHANGE_INFO
301         g_message ("%s:%d: About to signal %s to color %08x::%s in %s", __FILE__, __LINE__,
302                    "RELEASED",
303                    color.toRGBA32( alpha ), (color.icc?color.icc->colorProfile.c_str():"<null>"), FOO_NAME(_csel));
304 #endif
305         gtk_signal_emit (GTK_OBJECT (_csel), csel_signals[RELEASED]);
306     }
308     if ( colorDifferent || released )
309     {
310 #ifdef DUMP_CHANGE_INFO
311         g_message ("%s:%d: About to signal %s to color %08x::%s in %s", __FILE__, __LINE__,
312                    (_held ? "CHANGED" : "DRAGGED" ),
313                    color.toRGBA32( alpha ), (color.icc?color.icc->colorProfile.c_str():"<null>"), FOO_NAME(_csel));
314 #endif
315         gtk_signal_emit (GTK_OBJECT (_csel), csel_signals[_held ? CHANGED : DRAGGED]);
316     }
319 void ColorSelector::_colorChanged( const SPColor& color, gfloat alpha )
321     (void)color;
322     (void)alpha;
325 void ColorSelector::getColorAlpha( SPColor& color, gfloat* alpha ) const
327     gint i = 0;
329     color = _color;
330     if ( alpha )
331     {
332         *alpha = _alpha;
333     }
335     // Try to catch uninitialized value usage
336     if ( color.v.c[0] )
337     {
338         i++;
339     }
340     if ( color.v.c[1] )
341     {
342         i++;
343     }
344     if ( color.v.c[2] )
345     {
346         i++;
347     }
348     if ( color.v.c[3] )
349     {
350         i++;
351     }
352     if ( alpha && *alpha )
353     {
354         i++;
355     }