Code

Fix version check for wheel selector.
[inkscape.git] / src / widgets / sp-color-wheel-selector.cpp
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4 #include <math.h>
5 #include <gtk/gtksignal.h>
6 #include <gtk/gtklabel.h>
7 #include <gtk/gtktable.h>
8 #include <gtk/gtkspinbutton.h>
9 #include <glibmm/i18n.h>
10 #include "../dialogs/dialog-events.h"
11 #include "sp-color-wheel-selector.h"
12 #include "sp-color-scales.h"
13 #include "sp-color-icc-selector.h"
14 #include "../svg/svg-icc-color.h"
16 G_BEGIN_DECLS
18 static void sp_color_wheel_selector_class_init (SPColorWheelSelectorClass *klass);
19 static void sp_color_wheel_selector_init (SPColorWheelSelector *cs);
20 static void sp_color_wheel_selector_destroy (GtkObject *object);
22 static void sp_color_wheel_selector_show_all (GtkWidget *widget);
23 static void sp_color_wheel_selector_hide_all (GtkWidget *widget);
26 G_END_DECLS
28 static SPColorSelectorClass *parent_class;
30 #define XPAD 4
31 #define YPAD 1
33 GType
34 sp_color_wheel_selector_get_type (void)
35 {
36     static GType type = 0;
37     if (!type) {
38         static const GTypeInfo info = {
39             sizeof (SPColorWheelSelectorClass),
40             NULL, /* base_init */
41             NULL, /* base_finalize */
42             (GClassInitFunc) sp_color_wheel_selector_class_init,
43             NULL, /* class_finalize */
44             NULL, /* class_data */
45             sizeof (SPColorWheelSelector),
46             0,    /* n_preallocs */
47             (GInstanceInitFunc) sp_color_wheel_selector_init,
48             0,    /* value_table */
49         };
51         type = g_type_register_static (SP_TYPE_COLOR_SELECTOR,
52                                        "SPColorWheelSelector",
53                                        &info,
54                                        static_cast< GTypeFlags > (0) );
55     }
56     return type;
57 }
59 static void
60 sp_color_wheel_selector_class_init (SPColorWheelSelectorClass *klass)
61 {
62     static const gchar* nameset[] = {N_("Wheel"), 0};
63     GtkObjectClass *object_class;
64     GtkWidgetClass *widget_class;
65     SPColorSelectorClass *selector_class;
67     object_class = (GtkObjectClass *) klass;
68     widget_class = (GtkWidgetClass *) klass;
69     selector_class = SP_COLOR_SELECTOR_CLASS (klass);
71     parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass));
73     selector_class->name = nameset;
74     selector_class->submode_count = 1;
76     object_class->destroy = sp_color_wheel_selector_destroy;
78     widget_class->show_all = sp_color_wheel_selector_show_all;
79     widget_class->hide_all = sp_color_wheel_selector_hide_all;
80 }
82 ColorWheelSelector::ColorWheelSelector( SPColorSelector* csel )
83     : ColorSelector( csel ),
84       _updating( FALSE ),
85       _dragging( FALSE ),
86       _adj(0),
87       _wheel(0),
88       _sbtn(0),
89       _label(0)
90 {
91 }
93 ColorWheelSelector::~ColorWheelSelector()
94 {
95     _adj = 0;
96     _wheel = 0;
97     _sbtn = 0;
98     _label = 0;
99 }
101 void sp_color_wheel_selector_init (SPColorWheelSelector *cs)
103     SP_COLOR_SELECTOR(cs)->base = new ColorWheelSelector( SP_COLOR_SELECTOR(cs) );
105     if ( SP_COLOR_SELECTOR(cs)->base )
106     {
107         SP_COLOR_SELECTOR(cs)->base->init();
108     }
111 static void resizeHSVWheel( GtkHSV *hsv, GtkAllocation *allocation )
113     gint diam = std::min(allocation->width, allocation->height);
115     // drop a little for resizing
116     diam -= 4;
118     GtkStyle *style = gtk_widget_get_style( GTK_WIDGET(hsv) );
119     if ( style ) {
120         gint thick = std::max(style->xthickness, style->ythickness);
121         if (thick > 0) {
122             diam -= thick * 2;
123         }
124     }
125     gint padding = -1;
126     gtk_widget_style_get( GTK_WIDGET(hsv), 
127                           "focus-padding", &padding,
128                           NULL );
129     if (padding > 0) {
130         diam -= padding * 2;
131     }
132      
133     diam = std::max(20, diam);
134     gint ring = static_cast<gint>( static_cast<gdouble>(diam) / (4.0 * 1.618) );
135     gtk_hsv_set_metrics( hsv, diam, ring );
138 #if GTK_CHECK_VERSION(2,18,0)
139 static void handleWheelStyleSet(GtkHSV *hsv, GtkStyle* /*previous*/, gpointer /*userData*/)
141     GtkAllocation allocation = {0, 0, 0, 0};
142     gtk_widget_get_allocation( GTK_WIDGET(hsv), &allocation );
143     resizeHSVWheel( hsv, &allocation );
145 #endif // GTK_CHECK_VERSION(2,18,0)
147 static void handleWheelAllocation(GtkHSV *hsv, GtkAllocation *allocation, gpointer /*userData*/)
149     resizeHSVWheel( hsv, allocation );
152 void ColorWheelSelector::init()
154     GtkWidget *t;
155     gint row = 0;
157     _updating = FALSE;
158     _dragging = FALSE;
160     _tt = gtk_tooltips_new();
162     t = gtk_table_new (5, 3, FALSE);
163     gtk_widget_show (t);
164     gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 0);
166     /* Create components */
167     row = 0;
169     _wheel = gtk_hsv_new();
170     gtk_hsv_set_metrics( GTK_HSV(_wheel), 48, 8 );
171     gtk_widget_show( _wheel );
172     gtk_table_attach( GTK_TABLE(t), _wheel, 0, 3, row, row + 1,  (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), XPAD, YPAD);
174     row++;
176     /* Label */
177     _label = gtk_label_new_with_mnemonic (_("_A:"));
178     gtk_misc_set_alignment (GTK_MISC (_label), 1.0, 0.5);
179     gtk_widget_show (_label);
180     gtk_table_attach (GTK_TABLE (t), _label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD);
182     /* Adjustment */
183     _adj = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 10.0, 10.0);
185     /* Slider */
186     _slider = sp_color_slider_new (_adj);
187     gtk_tooltips_set_tip (_tt, _slider, _("Alpha (opacity)"), NULL);
188     gtk_widget_show (_slider);
189     gtk_table_attach (GTK_TABLE (t), _slider, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)GTK_FILL, XPAD, YPAD);
191     sp_color_slider_set_colors (SP_COLOR_SLIDER (_slider),
192                                 SP_RGBA32_F_COMPOSE (1.0, 1.0, 1.0, 0.0),
193                                 SP_RGBA32_F_COMPOSE (1.0, 1.0, 1.0, 0.5),
194                                 SP_RGBA32_F_COMPOSE (1.0, 1.0, 1.0, 1.0));
197     /* Spinbutton */
198     _sbtn = gtk_spin_button_new (GTK_ADJUSTMENT (_adj), 1.0, 0);
199     gtk_tooltips_set_tip (_tt, _sbtn, _("Alpha (opacity)"), NULL);
200     sp_dialog_defocus_on_enter (_sbtn);
201     gtk_label_set_mnemonic_widget (GTK_LABEL(_label), _sbtn);
202     gtk_widget_show (_sbtn);
203     gtk_table_attach (GTK_TABLE (t), _sbtn, 2, 3, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD);
205     /* Signals */
206     gtk_signal_connect (GTK_OBJECT (_adj), "value_changed",
207                         GTK_SIGNAL_FUNC (_adjustmentChanged), _csel);
209     gtk_signal_connect (GTK_OBJECT (_slider), "grabbed",
210                         GTK_SIGNAL_FUNC (_sliderGrabbed), _csel);
211     gtk_signal_connect (GTK_OBJECT (_slider), "released",
212                         GTK_SIGNAL_FUNC (_sliderReleased), _csel);
213     gtk_signal_connect (GTK_OBJECT (_slider), "changed",
214                         GTK_SIGNAL_FUNC (_sliderChanged), _csel);
216     gtk_signal_connect( GTK_OBJECT(_wheel), "changed",
217                         GTK_SIGNAL_FUNC(_wheelChanged), _csel );
220     // GTK does not automatically scale the color wheel, so we have to add that in:
221     gtk_signal_connect( GTK_OBJECT(_wheel), "size-allocate",
222                         GTK_SIGNAL_FUNC(handleWheelAllocation), _csel );
223 #if GTK_CHECK_VERSION(2,18,0)
224     gtk_signal_connect( GTK_OBJECT(_wheel), "style-set",
225                         GTK_SIGNAL_FUNC(handleWheelStyleSet), _csel );
226 #endif // GTK_CHECK_VERSION(2,18,0)
229 static void
230 sp_color_wheel_selector_destroy (GtkObject *object)
232     if (((GtkObjectClass *) (parent_class))->destroy)
233         (* ((GtkObjectClass *) (parent_class))->destroy) (object);
236 static void
237 sp_color_wheel_selector_show_all (GtkWidget *widget)
239     gtk_widget_show (widget);
242 static void
243 sp_color_wheel_selector_hide_all (GtkWidget *widget)
245     gtk_widget_hide (widget);
248 GtkWidget *
249 sp_color_wheel_selector_new (void)
251     SPColorWheelSelector *csel;
253     csel = (SPColorWheelSelector*)gtk_type_new (SP_TYPE_COLOR_WHEEL_SELECTOR);
255     return GTK_WIDGET (csel);
258 /* Helpers for setting color value */
260 static void preserve_icc(SPColor *color, SPColorWheelSelector *cs){
261     ColorSelector* selector = (ColorSelector*)(SP_COLOR_SELECTOR(cs)->base);
262     color->icc = selector->getColor().icc ? new SVGICCColor(*selector->getColor().icc) : 0;
265 void ColorWheelSelector::_colorChanged()
267 #ifdef DUMP_CHANGE_INFO
268     g_message("ColorWheelSelector::_colorChanged( this=%p, %f, %f, %f,   %f)", this, color.v.c[0], color.v.c[1], color.v.c[2], alpha );
269 #endif
270     _updating = TRUE;
271     {
272         gdouble h = 0;
273         gdouble s = 0;
274         gdouble v = 0;
275         gtk_rgb_to_hsv( _color.v.c[0], _color.v.c[1], _color.v.c[2], &h, &s, &v  );
276         gtk_hsv_set_color( GTK_HSV(_wheel), h, s, v );
277     }
279     guint32 start = _color.toRGBA32( 0x00 );
280     guint32 mid = _color.toRGBA32( 0x7f );
281     guint32 end = _color.toRGBA32( 0xff );
283     sp_color_slider_set_colors(SP_COLOR_SLIDER(_slider), start, mid, end);
285     ColorScales::setScaled(_adj, _alpha);
287     _updating = FALSE;
290 void ColorWheelSelector::_adjustmentChanged( GtkAdjustment *adjustment, SPColorWheelSelector *cs )
292 // TODO check this. It looks questionable:
293     // if a value is entered between 0 and 1 exclusive, normalize it to (int) 0..255  or 0..100
294     if (adjustment->value > 0.0 && adjustment->value < 1.0) {
295         gtk_adjustment_set_value( adjustment, floor ((adjustment->value) * adjustment->upper + 0.5) );
296     }
298     ColorWheelSelector* wheelSelector = (ColorWheelSelector*)(SP_COLOR_SELECTOR(cs)->base);
299     if (wheelSelector->_updating) return;
301     wheelSelector->_updating = TRUE;
303     preserve_icc(&wheelSelector->_color, cs);
304     wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging );
306     wheelSelector->_updating = FALSE;
309 void ColorWheelSelector::_sliderGrabbed( SPColorSlider *slider, SPColorWheelSelector *cs )
311     (void)slider;
312     ColorWheelSelector* wheelSelector = (ColorWheelSelector*)(SP_COLOR_SELECTOR(cs)->base);
313     if (!wheelSelector->_dragging) {
314         wheelSelector->_dragging = TRUE;
315         wheelSelector->_grabbed();
317         preserve_icc(&wheelSelector->_color, cs);
318         wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging );
319     }
322 void ColorWheelSelector::_sliderReleased( SPColorSlider *slider, SPColorWheelSelector *cs )
324     (void)slider;
325     ColorWheelSelector* wheelSelector = (ColorWheelSelector*)(SP_COLOR_SELECTOR(cs)->base);
326     if (wheelSelector->_dragging) {
327         wheelSelector->_dragging = FALSE;
328         wheelSelector->_released();
330         preserve_icc(&wheelSelector->_color, cs);
331         wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging );
332     }
335 void ColorWheelSelector::_sliderChanged( SPColorSlider *slider, SPColorWheelSelector *cs )
337     (void)slider;
338     ColorWheelSelector* wheelSelector = (ColorWheelSelector*)(SP_COLOR_SELECTOR(cs)->base);
340     preserve_icc(&wheelSelector->_color, cs);
341     wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging );
344 void ColorWheelSelector::_wheelChanged( GtkHSV *hsv, SPColorWheelSelector *cs )
346     ColorWheelSelector* wheelSelector = static_cast<ColorWheelSelector*>(SP_COLOR_SELECTOR(cs)->base);
348     gdouble h = 0;
349     gdouble s = 0;
350     gdouble v = 0;
351     gtk_hsv_get_color( hsv, &h, &s, &v );
352     
353     gdouble r = 0;
354     gdouble g = 0;
355     gdouble b = 0;
356     gtk_hsv_to_rgb(h, s, v, &r, &g, &b);
358     SPColor color(r, g, b);
360     guint32 start = color.toRGBA32( 0x00 );
361     guint32 mid = color.toRGBA32( 0x7f );
362     guint32 end = color.toRGBA32( 0xff );
364     sp_color_slider_set_colors (SP_COLOR_SLIDER(wheelSelector->_slider), start, mid, end);
366     preserve_icc(&color, cs);
367     wheelSelector->_updateInternals( color, wheelSelector->_alpha, gtk_hsv_is_adjusting( hsv ) );
371 /*
372   Local Variables:
373   mode:c++
374   c-file-style:"stroustrup"
375   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
376   indent-tabs-mode:nil
377   fill-column:99
378   End:
379 */
380 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :