colorscale: Draw a trough
Make sure the color info is actually drawn inside the trough.
This commit is contained in:
		| @ -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)); | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -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__ */ | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -80,6 +80,7 @@ | ||||
|                 <property name="orientation">vertical</property> | ||||
|                 <property name="adjustment">h_adj</property> | ||||
|                 <property name="draw_value">False</property> | ||||
|                 <property name="has_origin">False</property> | ||||
|                 <signal name="popup-menu" handler="popup_edit" swapped="no"/> | ||||
|               </object> | ||||
|               <packing> | ||||
| @ -94,6 +95,7 @@ | ||||
|                 <property name="adjustment">a_adj</property> | ||||
|                 <property name="draw_value">False</property> | ||||
|                 <property name="scale_type">1</property> | ||||
|                 <property name="has_origin">False</property> | ||||
|                 <style> | ||||
|                   <class name="scale-has-marks-above"/> | ||||
|                 </style> | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Benjamin Otte
					Benjamin Otte