From 52cba71be7d226b628731ea92c2064bf41f08b54 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 12 Feb 2013 14:04:09 +0100 Subject: [PATCH 62/68] cellrendererpixbuf: Use scaled icons on windows with a scale factor --- gtk/gtkcellrendererpixbuf.c | 115 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 13 deletions(-) diff --git a/gtk/gtkcellrendererpixbuf.c b/gtk/gtkcellrendererpixbuf.c index f689784..7c767b6 100644 --- a/gtk/gtkcellrendererpixbuf.c +++ b/gtk/gtkcellrendererpixbuf.c @@ -63,7 +63,8 @@ enum { PROP_STOCK_DETAIL, PROP_FOLLOW_STATE, PROP_ICON_NAME, - PROP_GICON + PROP_GICON, + PROP_ICON_SET }; @@ -78,6 +79,8 @@ struct _GtkCellRendererPixbufPrivate gboolean follow_state; gchar *icon_name; GIcon *gicon; + GtkIconSet *icon_set; + gdouble render_scale; }; G_DEFINE_TYPE (GtkCellRendererPixbuf, gtk_cell_renderer_pixbuf, GTK_TYPE_CELL_RENDERER) @@ -173,6 +176,14 @@ gtk_cell_renderer_pixbuf_class_init (GtkCellRendererPixbufClass *class) NULL, GTK_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_ICON_SET, + g_param_spec_boxed ("icon-set", + P_("Icon set"), + P_("Icon set to render the image from"), + GTK_TYPE_ICON_SET, + GTK_PARAM_READWRITE)); + /** * GtkCellRendererPixbuf:follow-state: * @@ -277,6 +288,9 @@ gtk_cell_renderer_pixbuf_get_property (GObject *object, case PROP_GICON: g_value_set_object (value, priv->gicon); break; + case PROP_ICON_SET: + g_value_set_boxed (value, priv->icon_set); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -300,6 +314,7 @@ gtk_cell_renderer_pixbuf_set_property (GObject *object, if (cellpixbuf->pixbuf) g_object_unref (cellpixbuf->pixbuf); cellpixbuf->pixbuf = (GdkPixbuf*) g_value_dup_object (value); + priv->render_scale = 1; if (cellpixbuf->pixbuf) { if (priv->stock_id) @@ -422,6 +437,7 @@ gtk_cell_renderer_pixbuf_set_property (GObject *object, g_object_unref (priv->gicon); } priv->gicon = (GIcon *) g_value_dup_object (value); + priv->render_scale = 1; if (priv->gicon) { if (cellpixbuf->pixbuf) @@ -444,6 +460,49 @@ gtk_cell_renderer_pixbuf_set_property (GObject *object, } } break; + case PROP_ICON_SET: + if (priv->icon_set) + { + if (cellpixbuf->pixbuf) + { + g_object_unref (cellpixbuf->pixbuf); + cellpixbuf->pixbuf = NULL; + g_object_notify (object, "pixbuf"); + } + + gtk_icon_set_unref (priv->icon_set); + } + + priv->icon_set = g_value_dup_boxed (value); + + if (priv->icon_set) + { + if (cellpixbuf->pixbuf) + { + g_object_unref (cellpixbuf->pixbuf); + cellpixbuf->pixbuf = NULL; + g_object_notify (object, "pixbuf"); + } + if (priv->stock_id) + { + g_free (priv->stock_id); + priv->stock_id = NULL; + g_object_notify (object, "stock-id"); + } + if (priv->icon_name) + { + g_free (priv->icon_name); + priv->icon_name = NULL; + g_object_notify (object, "icon-name"); + } + if (priv->gicon) + { + g_object_unref (priv->gicon); + priv->gicon = NULL; + g_object_notify (object, "gicon"); + } + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -474,16 +533,19 @@ gtk_cell_renderer_pixbuf_create_stock_pixbuf (GtkCellRendererPixbuf *cellpixbuf, GtkWidget *widget) { GtkCellRendererPixbufPrivate *priv; + GtkIconSet *icon_set; priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (cellpixbuf); if (cellpixbuf->pixbuf) g_object_unref (cellpixbuf->pixbuf); - cellpixbuf->pixbuf = gtk_widget_render_icon (widget, - priv->stock_id, - priv->stock_size, - priv->stock_detail); + priv->render_scale = gtk_widget_get_scale_factor (widget); + cellpixbuf->pixbuf = gtk_widget_render_icon_scaled (widget, + priv->stock_id, + priv->stock_size, + priv->stock_detail, + &priv->render_scale); g_object_notify (G_OBJECT (cellpixbuf), "pixbuf"); } @@ -510,15 +572,24 @@ gtk_cell_renderer_pixbuf_create_themed_pixbuf (GtkCellRendererPixbuf *cellpixbuf icon_theme = gtk_icon_theme_get_for_screen (screen); settings = gtk_settings_get_for_screen (screen); - if (!gtk_icon_size_lookup_for_settings (settings, - priv->stock_size, - &width, &height)) + if (!gtk_icon_size_lookup_scaled (settings, + priv->stock_size, + gdk_window_get_scale_factor (GTK_WIDGET (widget)->window), + &width, &height)) { g_warning ("Invalid icon size %u\n", priv->stock_size); width = height = 24; } - if (priv->icon_name) + if (priv->icon_set) + cellpixbuf->pixbuf = + gtk_icon_set_render_icon_scaled (priv->icon_set, + widget->style, + gtk_widget_get_direction (widget), + gtk_widget_get_state (widget), + priv->stock_size, widget, + NULL, &priv->render_scale); + else if (priv->icon_name) cellpixbuf->pixbuf = gtk_icon_theme_load_icon (icon_theme, priv->icon_name, MIN (width, height), @@ -611,14 +682,28 @@ gtk_cell_renderer_pixbuf_get_size (GtkCellRenderer *cell, { if (priv->stock_id) gtk_cell_renderer_pixbuf_create_stock_pixbuf (cellpixbuf, widget); + else if (priv->icon_set) + { + gdouble scale; + + scale = gtk_widget_get_scale_factor (widget); + cellpixbuf->pixbuf = + gtk_icon_set_render_icon_scaled (priv->icon_set, + widget->style, + gtk_widget_get_direction (widget), + gtk_widget_get_state (widget), + priv->stock_size, + widget, priv->stock_detail, + &scale); + } else if (priv->icon_name || priv->gicon) gtk_cell_renderer_pixbuf_create_themed_pixbuf (cellpixbuf, widget); } if (cellpixbuf->pixbuf) { - pixbuf_width = gdk_pixbuf_get_width (cellpixbuf->pixbuf); - pixbuf_height = gdk_pixbuf_get_height (cellpixbuf->pixbuf); + pixbuf_width = gdk_pixbuf_get_width (cellpixbuf->pixbuf) / priv->render_scale; + pixbuf_height = gdk_pixbuf_get_height (cellpixbuf->pixbuf) / priv->render_scale; } if (cellpixbuf->pixbuf_expander_open) { @@ -761,10 +846,14 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell, pixbuf = colorized; } + draw_rect.x -= pix_rect.x; + draw_rect.y -= pix_rect.y; + cr = gdk_cairo_create (window); - - gdk_cairo_set_source_pixbuf (cr, pixbuf, pix_rect.x, pix_rect.y); + cairo_translate (cr, pix_rect.x, pix_rect.y); gdk_cairo_rectangle (cr, &draw_rect); + cairo_scale (cr, 1 / priv->render_scale, 1 / priv->render_scale); + gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); cairo_fill (cr); cairo_destroy (cr); -- 1.7.10.2 (Apple Git-33)