Code

Indent support for XSLT extensions output.
[inkscape.git] / src / widgets / sp-color-selector.cpp
1 /*
2  *   bulia byak <buliabyak@users.sf.net>
3  *   Jon A. Cruz <jon@joncruz.org>
4  */
6 #ifdef HAVE_CONFIG_H
7 # include "config.h"
8 #endif
9 #include <math.h>
10 #include <gtk/gtksignal.h>
11 #include <glibmm/i18n.h>
12 #include "sp-color-selector.h"
14 enum {
15     GRABBED,
16     DRAGGED,
17     RELEASED,
18     CHANGED,
19     LAST_SIGNAL
20 };
22 #define noDUMP_CHANGE_INFO
23 #define FOO_NAME(x) g_type_name( G_TYPE_FROM_INSTANCE(x) )
25 static void sp_color_selector_class_init( SPColorSelectorClass *klass );
26 static void sp_color_selector_init( SPColorSelector *csel );
27 static void sp_color_selector_destroy( GtkObject *object );
29 static void sp_color_selector_show_all( GtkWidget *widget );
30 static void sp_color_selector_hide_all( GtkWidget *widget );
32 static GtkVBoxClass *parent_class;
33 static guint csel_signals[LAST_SIGNAL] = {0};
35 double ColorSelector::_epsilon = 1e-4;
37 GType sp_color_selector_get_type( void )
38 {
39     static GType type = 0;
40     if (!type) {
41         static const GTypeInfo info = {
42             sizeof(SPColorSelectorClass),
43             NULL, /* base_init */
44             NULL, /* base_finalize */
45             (GClassInitFunc) sp_color_selector_class_init,
46             NULL, /* class_finalize */
47             NULL, /* class_data */
48             sizeof(SPColorSelector),
49             0,    /* n_preallocs */
50             (GInstanceInitFunc) sp_color_selector_init,
51             NULL
52         };
54         type = g_type_register_static( GTK_TYPE_VBOX,
55                                        "SPColorSelector",
56                                        &info,
57                                        static_cast<GTypeFlags>(0) );
58     }
59     return type;
60 }
62 void sp_color_selector_class_init( SPColorSelectorClass *klass )
63 {
64     static const gchar* nameset[] = {N_("Unnamed"), 0};
65     GtkObjectClass *object_class;
66     GtkWidgetClass *widget_class;
68     object_class = GTK_OBJECT_CLASS(klass);
69     widget_class = GTK_WIDGET_CLASS(klass);
71     parent_class = GTK_VBOX_CLASS( gtk_type_class(GTK_TYPE_VBOX) );
73     csel_signals[GRABBED] = gtk_signal_new( "grabbed",
74                                             (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
75                                             GTK_CLASS_TYPE(object_class),
76                                             GTK_SIGNAL_OFFSET(SPColorSelectorClass, grabbed),
77                                             gtk_marshal_NONE__NONE,
78                                             GTK_TYPE_NONE, 0 );
79     csel_signals[DRAGGED] = gtk_signal_new( "dragged",
80                                             (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
81                                             GTK_CLASS_TYPE(object_class),
82                                             GTK_SIGNAL_OFFSET(SPColorSelectorClass, dragged),
83                                             gtk_marshal_NONE__NONE,
84                                             GTK_TYPE_NONE, 0 );
85     csel_signals[RELEASED] = gtk_signal_new( "released",
86                                              (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
87                                              GTK_CLASS_TYPE(object_class),
88                                              GTK_SIGNAL_OFFSET(SPColorSelectorClass, released),
89                                              gtk_marshal_NONE__NONE,
90                                              GTK_TYPE_NONE, 0 );
91     csel_signals[CHANGED] = gtk_signal_new( "changed",
92                                             (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
93                                             GTK_CLASS_TYPE(object_class),
94                                             GTK_SIGNAL_OFFSET(SPColorSelectorClass, changed),
95                                             gtk_marshal_NONE__NONE,
96                                             GTK_TYPE_NONE, 0 );
98     klass->name = nameset;
99     klass->submode_count = 1;
101     object_class->destroy = sp_color_selector_destroy;
103     widget_class->show_all = sp_color_selector_show_all;
104     widget_class->hide_all = sp_color_selector_hide_all;
108 void sp_color_selector_init( SPColorSelector *csel )
110     if ( csel->base )
111     {
112         csel->base->init();
113     }
114 /*   gtk_signal_connect(GTK_OBJECT(csel->rgbae), "changed", GTK_SIGNAL_FUNC(sp_color_selector_rgba_entry_changed), csel); */
117 void sp_color_selector_destroy( GtkObject *object )
119     SPColorSelector *csel = SP_COLOR_SELECTOR( object );
120     if ( csel->base )
121         {
122             delete csel->base;
123             csel->base = 0;
124         }
126     if ( (GTK_OBJECT_CLASS(parent_class))->destroy ) {
127         (* (GTK_OBJECT_CLASS(parent_class))->destroy)(object);
128     }
131 void sp_color_selector_show_all( GtkWidget *widget )
133     gtk_widget_show( widget );
136 void sp_color_selector_hide_all( GtkWidget *widget )
138     gtk_widget_hide( widget );
141 GtkWidget *sp_color_selector_new( GType selector_type )
143     g_return_val_if_fail( g_type_is_a( selector_type, SP_TYPE_COLOR_SELECTOR ), NULL );
145     SPColorSelector *csel = SP_COLOR_SELECTOR( g_object_new( selector_type, NULL ) );
147     return GTK_WIDGET( csel );
150 void ColorSelector::setSubmode( guint /*submode*/ )
154 guint ColorSelector::getSubmode() const
156     guint mode = 0;
157     return mode;
160 ColorSelector::ColorSelector( SPColorSelector* csel )
161     : _csel(csel),
162       _color( 0 ),
163       _alpha(1.0),
164       _held(FALSE),
165       virgin(true)
167     g_return_if_fail( SP_IS_COLOR_SELECTOR(_csel) );
170 ColorSelector::~ColorSelector()
174 void ColorSelector::init()
176     _csel->base = new ColorSelector( _csel );
179 void ColorSelector::setColor( const SPColor& color )
181     setColorAlpha( color, _alpha );
184 SPColor ColorSelector::getColor() const
186     return _color;
189 void ColorSelector::setAlpha( gfloat alpha )
191     g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) );
192     setColorAlpha( _color, alpha );
195 gfloat ColorSelector::getAlpha() const
197     return _alpha;
200 #include "svg/svg-icc-color.h"
202 /**
203 Called from the outside to set the color; optionally emits signal (only when called from
204 downstream, e.g. the RGBA value field, but not from the rest of the program)
205 */
206 void ColorSelector::setColorAlpha( const SPColor& color, gfloat alpha, bool emit )
208 #ifdef DUMP_CHANGE_INFO
209     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));
210 #endif
211     g_return_if_fail( _csel != NULL );
212     g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) );
214 #ifdef DUMP_CHANGE_INFO
215     g_message("---- ColorSelector::setColorAlpha    virgin:%s   !close:%s    alpha is:%s in %s",
216               (virgin?"YES":"no"),
217               (!color.isClose( _color, _epsilon )?"YES":"no"),
218               ((fabs((_alpha) - (alpha)) >= _epsilon )?"YES":"no"),
219               FOO_NAME(_csel)
220               );
221 #endif
223     if ( virgin || !color.isClose( _color, _epsilon ) ||
224          (fabs((_alpha) - (alpha)) >= _epsilon )) {
226         virgin = false;
228         _color = color;
229         _alpha = alpha;
230         _colorChanged();
232         if (emit) {
233             gtk_signal_emit(GTK_OBJECT(_csel), csel_signals[CHANGED]);
234         }
235 #ifdef DUMP_CHANGE_INFO
236     } else {
237         g_message("++++ ColorSelector::setColorAlpha   color:%08x  ==>  _color:%08X   isClose:%s   in %s", color.toRGBA32(alpha), _color.toRGBA32(_alpha),
238                   (color.isClose( _color, _epsilon )?"YES":"no"), FOO_NAME(_csel));
239 #endif
240     }
243 void ColorSelector::_grabbed()
245     _held = TRUE;
246 #ifdef DUMP_CHANGE_INFO
247     g_message("%s:%d: About to signal %s in %s", __FILE__, __LINE__,
248                "GRABBED",
249                FOO_NAME(_csel));
250 #endif
251     gtk_signal_emit(GTK_OBJECT(_csel), csel_signals[GRABBED]);
254 void ColorSelector::_released()
256     _held = false;
257 #ifdef DUMP_CHANGE_INFO
258     g_message("%s:%d: About to signal %s in %s", __FILE__, __LINE__,
259                "RELEASED",
260                FOO_NAME(_csel));
261 #endif
262     gtk_signal_emit(GTK_OBJECT(_csel), csel_signals[RELEASED]);
263     gtk_signal_emit(GTK_OBJECT(_csel), csel_signals[CHANGED]);
266 // Called from subclasses to update color and broadcast if needed
267 void ColorSelector::_updateInternals( const SPColor& color, gfloat alpha, gboolean held )
269     g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) );
270     gboolean colorDifferent = ( !color.isClose( _color, _epsilon )
271                                 || ( fabs((_alpha) - (alpha)) >= _epsilon ) );
273     gboolean grabbed = held && !_held;
274     gboolean released = !held && _held;
276     // Store these before emmiting any signals
277     _held = held;
278     if ( colorDifferent )
279     {
280         _color = color;
281         _alpha = alpha;
282     }
284     if ( grabbed )
285     {
286 #ifdef DUMP_CHANGE_INFO
287         g_message("%s:%d: About to signal %s to color %08x::%s in %s", __FILE__, __LINE__,
288                    "GRABBED",
289                    color.toRGBA32( alpha ), (color.icc?color.icc->colorProfile.c_str():"<null>"), FOO_NAME(_csel));
290 #endif
291         gtk_signal_emit(GTK_OBJECT(_csel), csel_signals[GRABBED]);
292     }
293     else if ( released )
294     {
295 #ifdef DUMP_CHANGE_INFO
296         g_message("%s:%d: About to signal %s to color %08x::%s in %s", __FILE__, __LINE__,
297                    "RELEASED",
298                    color.toRGBA32( alpha ), (color.icc?color.icc->colorProfile.c_str():"<null>"), FOO_NAME(_csel));
299 #endif
300         gtk_signal_emit(GTK_OBJECT(_csel), csel_signals[RELEASED]);
301     }
303     if ( colorDifferent || released )
304     {
305 #ifdef DUMP_CHANGE_INFO
306         g_message("%s:%d: About to signal %s to color %08x::%s in %s", __FILE__, __LINE__,
307                    (_held ? "CHANGED" : "DRAGGED" ),
308                    color.toRGBA32( alpha ), (color.icc?color.icc->colorProfile.c_str():"<null>"), FOO_NAME(_csel));
309 #endif
310         gtk_signal_emit(GTK_OBJECT(_csel), csel_signals[_held ? CHANGED : DRAGGED]);
311     }
314 /**
315  * Called once the color actually changes. Allows subclasses to react to changes.
316  */
317 void ColorSelector::_colorChanged()
321 void ColorSelector::getColorAlpha( SPColor &color, gfloat &alpha ) const
323     gint i = 0;
325     color = _color;
326     alpha = _alpha;
328     // Try to catch uninitialized value usage
329     if ( color.v.c[0] )
330     {
331         i++;
332     }
333     if ( color.v.c[1] )
334     {
335         i++;
336     }
337     if ( color.v.c[2] )
338     {
339         i++;
340     }
341     if ( alpha )
342     {
343         i++;
344     }
347 /*
348   Local Variables:
349   mode:c++
350   c-file-style:"stroustrup"
351   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
352   indent-tabs-mode:nil
353   fill-column:99
354   End:
355 */
356 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :