]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkcellrendererpixbuf.c
cssprovider: Speed up gtk_widget_style_get() property lookups
[~andy/gtk] / gtk / gtkcellrendererpixbuf.c
index 52b4ec98e5d3a3d6fe5ecc02b5d864665432fb40..8c222ffea12b5e9dee75e9ea21e9445b70d3dffb 100644 (file)
 #include "gtkprivate.h"
 
 
+/**
+ * SECTION:gtkcellrendererpixbuf
+ * @Short_description: Renders a pixbuf in a cell
+ * @Title: GtkCellRendererPixbuf
+ *
+ * A #GtkCellRendererPixbuf can be used to render an image in a cell. It allows
+ * to render either a given #GdkPixbuf (set via the
+ * #GtkCellRendererPixbuf:pixbuf property) or a stock icon (set via the
+ * #GtkCellRendererPixbuf:stock-id property).
+ *
+ * To support the tree view, #GtkCellRendererPixbuf also supports rendering two
+ * alternative pixbufs, when the #GtkCellRenderer:is-expander property is %TRUE.
+ * If the #GtkCellRenderer:is-expanded property is %TRUE and the
+ * #GtkCellRendererPixbuf:pixbuf-expander-open property is set to a pixbuf, it
+ * renders that pixbuf, if the #GtkCellRenderer:is-expanded property is %FALSE
+ * and the #GtkCellRendererPixbuf:pixbuf-expander-closed property is set to a
+ * pixbuf, it renders that one.
+ */
+
+
 static void gtk_cell_renderer_pixbuf_get_property  (GObject                    *object,
                                                    guint                       param_id,
                                                    GValue                     *value,
@@ -68,14 +88,14 @@ enum {
 
 struct _GtkCellRendererPixbufPrivate
 {
-  GtkIconSize stock_size;
-
   GdkPixbuf *pixbuf;
   GdkPixbuf *pixbuf_expander_open;
   GdkPixbuf *pixbuf_expander_closed;
 
   GIcon *gicon;
 
+  GtkIconSize stock_size;
+
   gboolean follow_state;
 
   gchar *stock_id;
@@ -481,10 +501,9 @@ gtk_cell_renderer_pixbuf_create_stock_pixbuf (GtkCellRendererPixbuf *cellpixbuf,
   if (priv->pixbuf)
     g_object_unref (priv->pixbuf);
 
-  priv->pixbuf = gtk_widget_render_icon (widget,
-                                               priv->stock_id,
-                                               priv->stock_size,
-                                               priv->stock_detail);
+  priv->pixbuf = gtk_widget_render_icon_pixbuf (widget,
+                                                priv->stock_id,
+                                                priv->stock_size);
 
   g_object_notify (G_OBJECT (cellpixbuf), "pixbuf");
 }
@@ -533,14 +552,13 @@ gtk_cell_renderer_pixbuf_create_themed_pixbuf (GtkCellRendererPixbuf *cellpixbuf
 
   if (info)
     {
-      GtkStyle *style;
-
-      style = gtk_widget_get_style (GTK_WIDGET (widget));
-      priv->pixbuf = gtk_icon_info_load_symbolic_for_style (info,
-                                                            style,
-                                                            GTK_STATE_NORMAL,
-                                                            NULL,
-                                                            NULL);
+      GtkStyleContext *context;
+
+      context = gtk_widget_get_style_context (GTK_WIDGET (widget));
+      priv->pixbuf = gtk_icon_info_load_symbolic_for_context (info,
+                                                              context,
+                                                              NULL,
+                                                              NULL);
       gtk_icon_info_free (info);
     }
 
@@ -550,7 +568,7 @@ gtk_cell_renderer_pixbuf_create_themed_pixbuf (GtkCellRendererPixbuf *cellpixbuf
 static GdkPixbuf *
 create_symbolic_pixbuf (GtkCellRendererPixbuf *cellpixbuf,
                        GtkWidget             *widget,
-                       GtkStateType           state)
+                        GtkStateFlags          state)
 {
   GtkCellRendererPixbufPrivate *priv = cellpixbuf->priv;
   GdkScreen *screen;
@@ -603,13 +621,20 @@ create_symbolic_pixbuf (GtkCellRendererPixbuf *cellpixbuf,
 
   if (info)
     {
-      GtkStyle *style;
+      GtkStyleContext *context;
+
+      context = gtk_widget_get_style_context (GTK_WIDGET (widget));
 
-      style = gtk_widget_get_style (GTK_WIDGET (widget));
-      pixbuf = gtk_icon_info_load_symbolic_for_style (info,
-                                                      style, state,
-                                                      NULL, NULL);
+      gtk_style_context_save (context);
+      gtk_style_context_set_state (context, state);
+      pixbuf = gtk_icon_info_load_symbolic_for_context (info,
+                                                        context,
+                                                        NULL,
+                                                        NULL);
+
+      gtk_style_context_restore (context);
       gtk_icon_info_free (info);
+
       return pixbuf;
     }
 
@@ -617,8 +642,8 @@ create_symbolic_pixbuf (GtkCellRendererPixbuf *cellpixbuf,
 }
 
 static GdkPixbuf *
-create_colorized_pixbuf (GdkPixbuf *src, 
-                        GdkColor  *new_color)
+create_colorized_pixbuf (GdkPixbuf *src,
+                         GdkRGBA   *new_color)
 {
   gint i, j;
   gint width, height, has_alpha, src_row_stride, dst_row_stride;
@@ -628,11 +653,11 @@ create_colorized_pixbuf (GdkPixbuf *src,
   guchar *pixsrc;
   guchar *pixdest;
   GdkPixbuf *dest;
-  
-  red_value = new_color->red / 255.0;
-  green_value = new_color->green / 255.0;
-  blue_value = new_color->blue / 255.0;
-  
+
+  red_value = (new_color->red * 65535.0) / 255.0;
+  green_value = (new_color->green * 65535.0) / 255.0;
+  blue_value = (new_color->blue * 65535.0) / 255.0;
+
   dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src),
                         gdk_pixbuf_get_has_alpha (src),
                         gdk_pixbuf_get_bits_per_sample (src),
@@ -751,6 +776,7 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer      *cell,
 {
   GtkCellRendererPixbuf *cellpixbuf = (GtkCellRendererPixbuf *) cell;
   GtkCellRendererPixbufPrivate *priv = cellpixbuf->priv;
+  GtkStyleContext *context;
   GdkPixbuf *pixbuf;
   GdkPixbuf *invisible = NULL;
   GdkPixbuf *colorized = NULL;
@@ -795,7 +821,9 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer      *cell,
   if (!pixbuf)
     return;
 
-  if (gtk_widget_get_state (widget) == GTK_STATE_INSENSITIVE ||
+  context = gtk_widget_get_style_context (widget);
+
+  if (!gtk_widget_get_sensitive (widget) ||
       !gtk_cell_renderer_get_sensitive (cell))
     {
       GtkIconSource *source;
@@ -809,43 +837,32 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer      *cell,
       gtk_icon_source_set_size (source, GTK_ICON_SIZE_SMALL_TOOLBAR);
       gtk_icon_source_set_size_wildcarded (source, FALSE);
 
-     invisible = gtk_style_render_icon (gtk_widget_get_style (widget),
-                                       source,
-                                       gtk_widget_get_direction (widget),
-                                       GTK_STATE_INSENSITIVE,
-                                       /* arbitrary */
-                                       (GtkIconSize)-1,
-                                       widget,
-                                       "gtkcellrendererpixbuf");
-     
-     gtk_icon_source_free (source);
-     
-     pixbuf = invisible;
+      gtk_style_context_save (context);
+      gtk_style_context_set_state (context, GTK_STATE_FLAG_INSENSITIVE);
+
+      pixbuf = invisible = gtk_render_icon_pixbuf (context, source,
+                                                   (GtkIconSize) -1);
+
+      gtk_style_context_restore (context);
+      gtk_icon_source_free (source);
     }
   else if (priv->follow_state && 
           (flags & (GTK_CELL_RENDERER_SELECTED|GTK_CELL_RENDERER_PRELIT)) != 0)
     {
-      GtkStateType state;
-
-      if ((flags & GTK_CELL_RENDERER_SELECTED) != 0)
-       {
-         if (gtk_widget_has_focus (widget))
-           state = GTK_STATE_SELECTED;
-         else
-           state = GTK_STATE_ACTIVE;
-       }
-      else
-       state = GTK_STATE_PRELIGHT;
+      GtkStateFlags state;
 
+      state = gtk_cell_renderer_get_state (cell, widget, flags);
       symbolic = create_symbolic_pixbuf (cellpixbuf, widget, state);
-      if (!symbolic) {
-        colorized = create_colorized_pixbuf (pixbuf,
-                                             &gtk_widget_get_style (widget)->base[state]);
 
-       pixbuf = colorized;
-      } else {
+      if (!symbolic)
+        {
+          GdkRGBA color;
+
+          gtk_style_context_get_background_color (context, state, &color);
+          pixbuf = colorized = create_colorized_pixbuf (pixbuf, &color);
+        }
+      else
         pixbuf = symbolic;
-      }
     }
 
   gdk_cairo_set_source_pixbuf (cr, pixbuf, pix_rect.x, pix_rect.y);