sp-color-slider.cpp revision 53650c4839343807b95444a86e89225fc71de648
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * A slider with colored background
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * Lauris Kaplinski <lauris@kaplinski.com>
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * bulia byak <buliabyak@users.sf.net>
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelen * Copyright (C) 2001-2002 Lauris Kaplinski
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * This code is in public domain
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrmstatic void sp_color_slider_class_init (SPColorSliderClass *klass);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrmstatic void sp_color_slider_init (SPColorSlider *slider);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrmstatic void sp_color_slider_destroy (GtkObject *object);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrmstatic void sp_color_slider_realize (GtkWidget *widget);
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelenstatic void sp_color_slider_size_request (GtkWidget *widget, GtkRequisition *requisition);
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelenstatic void sp_color_slider_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelen/* static void sp_color_slider_draw (GtkWidget *widget, GdkRectangle *area); */
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelen/* static void sp_color_slider_draw_focus (GtkWidget *widget); */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm/* static void sp_color_slider_draw_default (GtkWidget *widget); */
072916d0ef7dccd696b59381f50bcf776abccefbjohanengelenstatic gint sp_color_slider_expose (GtkWidget *widget, GdkEventExpose *event);
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraudstatic gint sp_color_slider_button_press (GtkWidget *widget, GdkEventButton *event);
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraudstatic gint sp_color_slider_button_release (GtkWidget *widget, GdkEventButton *event);
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraudstatic gint sp_color_slider_motion_notify (GtkWidget *widget, GdkEventMotion *event);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrmstatic void sp_color_slider_adjustment_changed (GtkAdjustment *adjustment, SPColorSlider *slider);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrmstatic void sp_color_slider_adjustment_value_changed (GtkAdjustment *adjustment, SPColorSlider *slider);
70eb1fc448cb08acf3468f80fa2296c03b32afd2cilixstatic void sp_color_slider_paint (SPColorSlider *slider, GdkRectangle *area);
c169f6cddd2da06cfb761339f445bbd8866f72a8buliabyakstatic const guchar *sp_color_slider_render_gradient (gint x0, gint y0, gint width, gint height,
0563fd55cbad59e8a878e6d4cbbdd8e47f74488djohanengelen gint c[], gint dc[], guint b0, guint b1, guint mask);
0cc5b8d2f7b87c4222ee3662071bef1cb1f22b06bgkstatic const guchar *sp_color_slider_render_map (gint x0, gint y0, gint width, gint height,
0563fd55cbad59e8a878e6d4cbbdd8e47f74488djohanengelen guchar *map, gint start, gint step, guint b0, guint b1, guint mask);
61cfd957cd023c4f432ea0c7307784a56bf978e9cilix //TODO: switch to GObject
2f5c0701b333a695eedb1680beb1adf95c0723dacilix // GtkType and such calls were deprecated a while back with the
add2ffae3c4686b50d888775bbdf083a4726a210johanengelen // introduction of GObject as a separate layer, with GType instead. --JonCruz
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrmstatic void
f4db63be4e929f4706410914295deccaceea19cdcilix parent_class = (GtkWidgetClass*)gtk_type_class (GTK_TYPE_WIDGET);
3d0482af18ffb591c1d8ddecf516629e1bcd2ae4cilix (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
add2ffae3c4686b50d888775bbdf083a4726a210johanengelen (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
29f9623ba77fc735b89765ae3a13e0c06aabafcecilix (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraud widget_class->size_request = sp_color_slider_size_request;
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen widget_class->size_allocate = sp_color_slider_size_allocate;
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraud/* widget_class->draw = sp_color_slider_draw; */
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraud/* widget_class->draw_focus = sp_color_slider_draw_focus; */
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen/* widget_class->draw_default = sp_color_slider_draw_default; */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm widget_class->button_press_event = sp_color_slider_button_press;
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen widget_class->button_release_event = sp_color_slider_button_release;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm widget_class->motion_notify_event = sp_color_slider_motion_notify;
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen /* We are widget with window */
044d712d4d03f8354962d54e47cfac2346a69ccccilix gtk_signal_disconnect_by_data (GTK_OBJECT (slider->adjustment), slider);
2f5c0701b333a695eedb1680beb1adf95c0723dacilix (* ((GtkObjectClass *) (parent_class))->destroy) (object);
6656f193fdace606d1b162d6dea0223bc295f0a6cilix attributes.event_mask = gtk_widget_get_events (widget);
6656f193fdace606d1b162d6dea0223bc295f0a6cilix attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
6656f193fdace606d1b162d6dea0223bc295f0a6cilix widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
6656f193fdace606d1b162d6dea0223bc295f0a6cilix widget->style = gtk_style_attach (widget->style, widget->window);
6656f193fdace606d1b162d6dea0223bc295f0a6cilixsp_color_slider_size_request (GtkWidget *widget, GtkRequisition *requisition)
71146abe8aba032d73788a625fee5769a581bd3ccilix requisition->width = SLIDER_WIDTH + widget->style->xthickness * 2;
77a4a003111bd5cfb771d4849801c898aeb889b0cilix requisition->height = SLIDER_HEIGHT + widget->style->ythickness * 2;
9ce14357bb94b9dd92ad40bf43ef435a257b355acilixsp_color_slider_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
eaa9bdc7bf7b73397e536edd47490d84e4420bd8bryce /* Resize GdkWindow */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm gdk_window_move_resize (widget->window, allocation->x, allocation->y, allocation->width, allocation->height);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrmsp_color_slider_expose (GtkWidget *widget, GdkEventExpose *event)
77a4a003111bd5cfb771d4849801c898aeb889b0cilixsp_color_slider_button_press (GtkWidget *widget, GdkEventButton *event)
147c8e03bb214f85cd5906ddc6413c4293c4baa9cilix gtk_signal_emit (GTK_OBJECT (slider), slider_signals[GRABBED]);
77a4a003111bd5cfb771d4849801c898aeb889b0cilix ColorScales::setScaled( slider->adjustment, CLAMP ((gfloat) (event->x - cx) / cw, 0.0, 1.0) );
77a4a003111bd5cfb771d4849801c898aeb889b0cilix gtk_signal_emit (GTK_OBJECT (slider), slider_signals[DRAGGED]);
77a4a003111bd5cfb771d4849801c898aeb889b0cilixsp_color_slider_button_release (GtkWidget *widget, GdkEventButton *event)
97a20864afec63a0b7bb757b628ee2ae596cf648cilix gtk_signal_emit (GTK_OBJECT (slider), slider_signals[RELEASED]);
97a20864afec63a0b7bb757b628ee2ae596cf648cilix if (slider->value != slider->oldvalue) gtk_signal_emit (GTK_OBJECT (slider), slider_signals[CHANGED]);
77a4a003111bd5cfb771d4849801c898aeb889b0cilixsp_color_slider_motion_notify (GtkWidget *widget, GdkEventMotion *event)
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm ColorScales::setScaled( slider->adjustment, CLAMP ((gfloat) (event->x - cx) / cw, 0.0, 1.0) );
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm gtk_signal_emit (GTK_OBJECT (slider), slider_signals[DRAGGED]);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm slider = (SPColorSlider*)gtk_type_new (SP_TYPE_COLOR_SLIDER);
ecda720053ff791e35dae3c5c1177bc225b6cdf1johanengelen sp_color_slider_set_adjustment (slider, adjustment);
46c4893a7458eda6edcd064121bc000634af7a09johanengelensp_color_slider_set_adjustment (SPColorSlider *slider, GtkAdjustment *adjustment)
46c4893a7458eda6edcd064121bc000634af7a09johanengelen g_return_if_fail (SP_IS_COLOR_SLIDER (slider));
46c4893a7458eda6edcd064121bc000634af7a09johanengelen adjustment = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 1.0, 0.01, 0.0, 0.0);
46c4893a7458eda6edcd064121bc000634af7a09johanengelen gtk_adjustment_set_page_increment(adjustment, 0.0);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm gtk_signal_disconnect_by_data (GTK_OBJECT (slider->adjustment), slider);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm GTK_SIGNAL_FUNC (sp_color_slider_adjustment_changed), slider);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm GTK_SIGNAL_FUNC (sp_color_slider_adjustment_value_changed), slider);
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelen sp_color_slider_adjustment_changed (adjustment, slider);
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelensp_color_slider_set_colors (SPColorSlider *slider, guint32 start, guint32 mid, guint32 end)
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelen g_return_if_fail (SP_IS_COLOR_SLIDER (slider));
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelen // Remove any map, if set
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelensp_color_slider_set_map (SPColorSlider *slider, const guchar *map)
5be124ad592f5c71eca838ad2eaac9ffa953605fcilixsp_color_slider_set_background (SPColorSlider *slider, guint dark, guint light, guint size)
5be124ad592f5c71eca838ad2eaac9ffa953605fcilixsp_color_slider_adjustment_changed (GtkAdjustment */*adjustment*/, SPColorSlider *slider)
5be124ad592f5c71eca838ad2eaac9ffa953605fcilixsp_color_slider_adjustment_value_changed (GtkAdjustment *adjustment, SPColorSlider *slider)
1e944d29efb206f5d0b5d1069cb098e22169d548cilix if (slider->value != ColorScales::getScaled( adjustment )) {
1e944d29efb206f5d0b5d1069cb098e22169d548cilix if ((gint) (ColorScales::getScaled( adjustment ) * cw) != (gint) (slider->value * cw)) {
04c99c338ffdc6e10cb6f5c18f6f06b3f555e8ebcilix gtk_widget_queue_draw_area (widget, ax, ay, ARROW_SIZE + 4, ch);
147c8e03bb214f85cd5906ddc6413c4293c4baa9cilix ax = (int)(cx + slider->value * cw - ARROW_SIZE / 2 - 2);
04c99c338ffdc6e10cb6f5c18f6f06b3f555e8ebcilix gtk_widget_queue_draw_area (widget, ax, ay, ARROW_SIZE + 4, ch);
04c99c338ffdc6e10cb6f5c18f6f06b3f555e8ebcilixsp_color_slider_paint (SPColorSlider *slider, GdkRectangle *area)
732fb09f9c502000068a77667c3356cbbd5d39d5cilix gboolean colorsOnTop = Inkscape::Preferences::get()->getBool("/options/workarounds/colorsontop", false);
732fb09f9c502000068a77667c3356cbbd5d39d5cilix /* Widget area */
2d2706a9d621c0da51b7c4178fd5c7c5e4765122joncruz /* Color gradient area */
04c99c338ffdc6e10cb6f5c18f6f06b3f555e8ebcilix carea.height = widget->allocation.height - 2 * carea.y;
c0cd5511d3b975ebe07d019c1f5528108725e438johanengelen /* Arrow area */
73d455c08e8062e257dd052d2d690b9300434351cilix aarea.x = (int)(slider->value * (carea.width - 1) - ARROW_SIZE / 2 + carea.x);
c0cd5511d3b975ebe07d019c1f5528108725e438johanengelen /* Actual paintable area */
c0cd5511d3b975ebe07d019c1f5528108725e438johanengelen if (!gdk_rectangle_intersect (area, &warea, &wpaint)) {
c0cd5511d3b975ebe07d019c1f5528108725e438johanengelen // Draw shadow
c0cd5511d3b975ebe07d019c1f5528108725e438johanengelen gtk_paint_shadow( widget->style, widget->window,
c0cd5511d3b975ebe07d019c1f5528108725e438johanengelen /* Paintable part of color gradient area */
c0cd5511d3b975ebe07d019c1f5528108725e438johanengelen if (gdk_rectangle_intersect (area, &carea, &cpaint)) {
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm /* Render map pixelstore */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm b = sp_color_slider_render_map (cpaint.x - carea.x, cpaint.y - carea.y, cpaint.width, cpaint.height,
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm if (b != NULL) {
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm gdk_draw_rgb_image (widget->window, widget->style->black_gc,
56542e2b97ec8826cc692153b0e2d4f5ac8ef913johanengelen /* Render gradient */
56542e2b97ec8826cc692153b0e2d4f5ac8ef913johanengelen // part 1: from c0 to cm
56542e2b97ec8826cc692153b0e2d4f5ac8ef913johanengelen for (i = 0; i < 4; i++) {
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelen dc[i] = ((slider->cm[i] << 16) - c[i]) / (carea.width/2);
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelen guint wi = MIN(cpaint.x - carea.x + cpaint.width, carea.width/2) - (cpaint.x - carea.x);
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelen b = sp_color_slider_render_gradient (cpaint.x - carea.x, cpaint.y - carea.y, wi, cpaint.height,
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelen /* Draw pixelstore */
56542e2b97ec8826cc692153b0e2d4f5ac8ef913johanengelen gdk_draw_rgb_image (widget->window, widget->style->black_gc,
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen // part 2: from cm to c1
af8d25189f88abf89cdbe0e180e271c94079624fbuliabyak if ((cpaint.x - carea.x + cpaint.width) > carea.width/2) {
a0334366488989ef25fb812d7030d298c0917c96johanengelen for (i = 0; i < 4; i++) {
a0334366488989ef25fb812d7030d298c0917c96johanengelen dc[i] = ((slider->c1[i] << 16) - c[i]) / (carea.width/2);
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen c[i] += (cpaint.x - carea.x - carea.width/2) * dc[i];
a0334366488989ef25fb812d7030d298c0917c96johanengelen guint wi = cpaint.width - MAX(0, (carea.width/2 - (cpaint.x - carea.x)));
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen b = sp_color_slider_render_gradient (MAX(cpaint.x - carea.x, carea.width/2), cpaint.y - carea.y, wi, cpaint.height,
a0334366488989ef25fb812d7030d298c0917c96johanengelen /* Draw pixelstore */
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen gdk_draw_rgb_image (widget->window, widget->style->black_gc,
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen MAX(cpaint.x, carea.width/2 + carea.x), cpaint.y,
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen /* Draw shadow */
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen gtk_paint_shadow( widget->style, widget->window,
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen if (gdk_rectangle_intersect (area, &aarea, &apaint)) {
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen /* Draw arrow */
42e99769805c14a5cc01c805faa3c3b03f9dd1c0johanengelen gdk_gc_set_clip_rectangle (widget->style->white_gc, &apaint);
42e99769805c14a5cc01c805faa3c3b03f9dd1c0johanengelen gdk_gc_set_clip_rectangle (widget->style->black_gc, &apaint);
42e99769805c14a5cc01c805faa3c3b03f9dd1c0johanengelen while ( w > 0 )
56542e2b97ec8826cc692153b0e2d4f5ac8ef913johanengelen gdk_draw_line (widget->window, widget->style->white_gc, x, y1, x + w - 1, y1 );
a797dcb8e284cab19f60b3eff93a53a62abda263johanengelen gdk_draw_line (widget->window, widget->style->white_gc, x, y2, x + w - 1, y2 );
56542e2b97ec8826cc692153b0e2d4f5ac8ef913johanengelen if ( w > 0 )
56542e2b97ec8826cc692153b0e2d4f5ac8ef913johanengelen gdk_draw_line (widget->window, widget->style->black_gc, x, y1, x + w - 1, y1 );
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelen gdk_draw_line (widget->window, widget->style->black_gc, x, y2, x + w - 1, y2 );
bdd7add6c064afee52d2eabeaa18f745430e5a4djohanengelen gdk_gc_set_clip_rectangle (widget->style->white_gc, NULL);
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelen gdk_gc_set_clip_rectangle (widget->style->black_gc, NULL);
42ba1b712b7b430669fc49aa9facb439181081becilix/* Colors are << 16 */
42ba1b712b7b430669fc49aa9facb439181081becilixstatic const guchar *
42ba1b712b7b430669fc49aa9facb439181081becilixsp_color_slider_render_gradient (gint x0, gint y0, gint width, gint height,
42ba1b712b7b430669fc49aa9facb439181081becilix guint r, g, b, a;
d = dp;
r += dc[0];
return buf;
static const guchar *
gint x, y;
if (!buf) {
guchar *d;
d = dp;
return buf;