From fc7335bdb4c1bed38b7287354d348af949c20ace Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 9 Mar 2016 17:27:01 +0100 Subject: [PATCH] colorscale: Draw a trough Make sure the color info is actually drawn inside the trough. --- gtk/gtkcolorscale.c | 157 +++++-------------------------------- gtk/gtkcolorscaleprivate.h | 7 ++ gtk/gtkrange.c | 12 +-- gtk/ui/gtkcoloreditor.ui | 2 + 4 files changed, 35 insertions(+), 143 deletions(-) diff --git a/gtk/gtkcolorscale.c b/gtk/gtkcolorscale.c index fd03029c2b..be1123d958 100644 --- a/gtk/gtkcolorscale.c +++ b/gtk/gtkcolorscale.c @@ -34,8 +34,6 @@ struct _GtkColorScalePrivate { - cairo_surface_t *surface; - gint width, height; GdkRGBA color; GtkColorScaleType type; @@ -55,97 +53,35 @@ static void hold_action (GtkGestureLongPress *gesture, G_DEFINE_TYPE_WITH_PRIVATE (GtkColorScale, gtk_color_scale, GTK_TYPE_SCALE) -static void -gtk_color_scale_get_trough_size (GtkColorScale *scale, - gint *x_offset_out, - gint *y_offset_out, - gint *width_out, - gint *height_out) +void +gtk_color_scale_draw_trough (GtkColorScale *scale, + cairo_t *cr, + int x, + int y, + int width, + int height) { - GtkWidget *widget = GTK_WIDGET (scale); - GtkCssGadget *slider_gadget; - gint width, height; - gint x_offset, y_offset; - gint slider_width, slider_height; + GtkWidget *widget; - slider_gadget = gtk_range_get_slider_gadget (GTK_RANGE (scale)); - gtk_css_gadget_get_preferred_size (slider_gadget, - GTK_ORIENTATION_HORIZONTAL, -1, - &slider_width, NULL, - NULL, NULL); - gtk_css_gadget_get_preferred_size (slider_gadget, - GTK_ORIENTATION_VERTICAL, -1, - &slider_height, NULL, - NULL, NULL); - - width = gtk_widget_get_allocated_width (widget); - height = gtk_widget_get_allocated_height (widget); - - x_offset = 0; - y_offset = 0; - - /* if the slider has a vertical shape, draw the trough asymmetric */ - if (slider_width > slider_height) - { - if (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_VERTICAL) - { - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) - x_offset += (gint) floor (slider_width / 2.0); - - width = (gint) floor (slider_width / 2.0); - } - else - { - height = (gint) floor (slider_width / 2.0); - } - } - - if (width_out) - *width_out = width; - if (height_out) - *height_out = height; - if (x_offset_out) - *x_offset_out = x_offset; - if (y_offset_out) - *y_offset_out = y_offset; -} - -static void -create_surface (GtkColorScale *scale) -{ - GtkWidget *widget = GTK_WIDGET (scale); - cairo_surface_t *surface; - gint width, height; - - if (!gtk_widget_get_realized (widget)) + if (width <= 1 || height <= 1) return; - gtk_color_scale_get_trough_size (scale, - NULL, NULL, - &width, &height); + cairo_save (cr); + cairo_translate (cr, x, y); - if (!scale->priv->surface || - width != scale->priv->width || - height != scale->priv->height) + widget = GTK_WIDGET (scale); + cairo_rectangle (cr, 0, 0, width, height); + cairo_clip (cr); + + if (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_HORIZONTAL && + gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) { - surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget), - CAIRO_CONTENT_COLOR, - width, height); - if (scale->priv->surface) - cairo_surface_destroy (scale->priv->surface); - scale->priv->surface = surface; - scale->priv->width = width; - scale->priv->height= height; + cairo_translate (cr, width, 0); + cairo_scale (cr, -1, 1); } - else - surface = scale->priv->surface; - - if (width == 1 || height == 1) - return; if (scale->priv->type == GTK_COLOR_SCALE_HUE) { - cairo_t *cr; gint stride; cairo_surface_t *tmp; guint red, green, blue; @@ -176,24 +112,19 @@ create_surface (GtkColorScale *scale) tmp = cairo_image_surface_create_for_data ((guchar *)data, CAIRO_FORMAT_RGB24, width, height, stride); - cr = cairo_create (surface); cairo_set_source_surface (cr, tmp, 0, 0); cairo_paint (cr); - cairo_destroy (cr); cairo_surface_destroy (tmp); g_free (data); } else if (scale->priv->type == GTK_COLOR_SCALE_ALPHA) { - cairo_t *cr; cairo_pattern_t *pattern; cairo_matrix_t matrix; GdkRGBA *color; - cr = cairo_create (surface); - cairo_set_source_rgb (cr, 0.33, 0.33, 0.33); cairo_paint (cr); cairo_set_source_rgb (cr, 0.66, 0.66, 0.66); @@ -212,51 +143,9 @@ create_surface (GtkColorScale *scale) cairo_set_source (cr, pattern); cairo_paint (cr); cairo_pattern_destroy (pattern); - - cairo_destroy (cr); } -} - -static gboolean -scale_draw (GtkWidget *widget, - cairo_t *cr) -{ - GtkColorScale *scale = GTK_COLOR_SCALE (widget); - gint width, height, x_offset, y_offset; - cairo_pattern_t *pattern; - GtkStyleContext *context; - - create_surface (scale); - gtk_color_scale_get_trough_size (scale, - &x_offset, &y_offset, - &width, &height); - - cairo_save (cr); - cairo_translate (cr, x_offset, y_offset); - - context = gtk_widget_get_style_context (widget); - gtk_render_content_path (context, cr, 0, 0, width, height); - - pattern = cairo_pattern_create_for_surface (scale->priv->surface); - if (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_HORIZONTAL && - gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - { - cairo_matrix_t matrix; - - cairo_matrix_init_scale (&matrix, -1, 1); - cairo_matrix_translate (&matrix, -width, 0); - cairo_pattern_set_matrix (pattern, &matrix); - } - cairo_set_source (cr, pattern); - cairo_fill (cr); - - cairo_pattern_destroy (pattern); cairo_restore (cr); - - GTK_WIDGET_CLASS (gtk_color_scale_parent_class)->draw (widget, cr); - - return FALSE; } static void @@ -283,9 +172,6 @@ scale_finalize (GObject *object) { GtkColorScale *scale = GTK_COLOR_SCALE (object); - if (scale->priv->surface) - cairo_surface_destroy (scale->priv->surface); - g_clear_object (&scale->priv->long_press_gesture); G_OBJECT_CLASS (gtk_color_scale_parent_class)->finalize (object); @@ -363,14 +249,11 @@ static void gtk_color_scale_class_init (GtkColorScaleClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); object_class->finalize = scale_finalize; object_class->get_property = scale_get_property; object_class->set_property = scale_set_property; - widget_class->draw = scale_draw; - g_object_class_install_property (object_class, PROP_SCALE_TYPE, g_param_spec_int ("scale-type", P_("Scale type"), P_("Scale type"), 0, 1, 0, @@ -382,8 +265,6 @@ gtk_color_scale_set_rgba (GtkColorScale *scale, const GdkRGBA *color) { scale->priv->color = *color; - scale->priv->width = -1; /* force surface refresh */ - create_surface (scale); gtk_widget_queue_draw (GTK_WIDGET (scale)); } diff --git a/gtk/gtkcolorscaleprivate.h b/gtk/gtkcolorscaleprivate.h index 9ce776bb37..15b33243e8 100644 --- a/gtk/gtkcolorscaleprivate.h +++ b/gtk/gtkcolorscaleprivate.h @@ -64,6 +64,13 @@ GtkWidget * gtk_color_scale_new (GtkAdjustment *adjustment, void gtk_color_scale_set_rgba (GtkColorScale *scale, const GdkRGBA *color); +void gtk_color_scale_draw_trough (GtkColorScale *scale, + cairo_t *cr, + int x, + int y, + int width, + int height); + G_END_DECLS #endif /* __GTK_COLOR_SCALE_H__ */ diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c index 50357c2cb6..9b78108934 100644 --- a/gtk/gtkrange.c +++ b/gtk/gtkrange.c @@ -2355,6 +2355,12 @@ gtk_range_render_trough (GtkCssGadget *gadget, GtkRange *range = GTK_RANGE (widget); GtkRangePrivate *priv = range->priv; + /* HACK: GtkColorScale wants to draw its own trough + * so we let it... + */ + if (GTK_IS_COLOR_SCALE (widget)) + gtk_color_scale_draw_trough (GTK_COLOR_SCALE (widget), cr, x, y, width, height); + if (priv->show_fill_level && gtk_adjustment_get_upper (priv->adjustment) - gtk_adjustment_get_page_size (priv->adjustment) - gtk_adjustment_get_lower (priv->adjustment) != 0) @@ -2379,11 +2385,7 @@ gtk_range_render (GtkCssGadget *gadget, GtkRange *range = GTK_RANGE (widget); GtkRangePrivate *priv = range->priv; - /* HACK: we can't render the contents box directly because - * GtkColorScale wants to omit the trough but still draw the slider... - */ - if (!GTK_IS_COLOR_SCALE (widget)) - gtk_css_gadget_draw (priv->contents_gadget, cr); + gtk_css_gadget_draw (priv->contents_gadget, cr); /* Draw the slider last, so that e.g. the focus ring stays below it */ gtk_css_gadget_draw (priv->slider_gadget, cr); diff --git a/gtk/ui/gtkcoloreditor.ui b/gtk/ui/gtkcoloreditor.ui index 1c3e971795..664b1b5f29 100644 --- a/gtk/ui/gtkcoloreditor.ui +++ b/gtk/ui/gtkcoloreditor.ui @@ -80,6 +80,7 @@ vertical h_adj False + False @@ -94,6 +95,7 @@ a_adj False 1 + False