[gtk+] GtkStyleContext: Add gtk_render_icon_pixbuf()



commit a23863211b098d3db2b04f9dcf4a941645c506ae
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Nov 3 21:14:08 2010 +0100

    GtkStyleContext: Add gtk_render_icon_pixbuf()
    
    This function is similar to gtk_style_render_icon(), which is now
    implemented on top of this one.

 gtk/gtkstyle.c         |  125 +++++++++---------------------------------------
 gtk/gtkstylecontext.c  |   33 +++++++++++++
 gtk/gtkstylecontext.h  |    4 ++
 gtk/gtkthemingengine.c |   92 +++++++++++++++++++++++++++++++++++
 gtk/gtkthemingengine.h |    4 ++
 5 files changed, 156 insertions(+), 102 deletions(-)
---
diff --git a/gtk/gtkstyle.c b/gtk/gtkstyle.c
index 6c45302..9aba0fa 100644
--- a/gtk/gtkstyle.c
+++ b/gtk/gtkstyle.c
@@ -327,6 +327,9 @@ static void hls_to_rgb			(gdouble	 *h,
 
 static void style_unrealize_cursors     (GtkStyle *style);
 
+static void transform_detail_string (const gchar     *detail,
+                                     GtkStyleContext *context);
+
 /*
  * Data for default check and radio buttons
  */
@@ -1608,54 +1611,6 @@ out:
 }
 
 static GdkPixbuf *
-scale_or_ref (GdkPixbuf *src,
-              gint       width,
-              gint       height)
-{
-  if (width == gdk_pixbuf_get_width (src) &&
-      height == gdk_pixbuf_get_height (src))
-    {
-      return g_object_ref (src);
-    }
-  else
-    {
-      return gdk_pixbuf_scale_simple (src,
-                                      width, height,
-                                      GDK_INTERP_BILINEAR);
-    }
-}
-
-static gboolean
-lookup_icon_size (GtkStyle    *style,
-		  GtkWidget   *widget,
-		  GtkIconSize  size,
-		  gint        *width,
-		  gint        *height)
-{
-  GdkScreen *screen;
-  GtkSettings *settings;
-
-  if (widget && gtk_widget_has_screen (widget))
-    {
-      screen = gtk_widget_get_screen (widget);
-      settings = gtk_settings_get_for_screen (screen);
-    }
-  else if (style && style->visual)
-    {
-      screen = gdk_visual_get_screen (style->visual);
-      settings = gtk_settings_get_for_screen (screen);
-    }
-  else
-    {
-      settings = gtk_settings_get_default ();
-      GTK_NOTE (MULTIHEAD,
-		g_warning ("Using the default screen for gtk_default_render_icon()"));
-    }
-
-  return gtk_icon_size_lookup_for_settings (settings, size, width, height);
-}
-
-static GdkPixbuf *
 gtk_default_render_icon (GtkStyle            *style,
                          const GtkIconSource *source,
                          GtkTextDirection     direction,
@@ -1664,65 +1619,31 @@ gtk_default_render_icon (GtkStyle            *style,
                          GtkWidget           *widget,
                          const gchar         *detail)
 {
-  gint width = 1;
-  gint height = 1;
-  GdkPixbuf *scaled;
-  GdkPixbuf *stated;
-  GdkPixbuf *base_pixbuf;
-
-  /* Oddly, style can be NULL in this function, because
-   * GtkIconSet can be used without a style and if so
-   * it uses this function.
-   */
-
-  base_pixbuf = gtk_icon_source_get_pixbuf (source);
-
-  g_return_val_if_fail (base_pixbuf != NULL, NULL);
+  GtkStyleContext *context;
+  GtkStylePrivate *priv;
+  GdkPixbuf *pixbuf;
 
-  if (size != (GtkIconSize) -1 && !lookup_icon_size(style, widget, size, &width, &height))
+  if (widget)
+    context = gtk_widget_get_style_context (widget);
+  else
     {
-      g_warning (G_STRLOC ": invalid icon size '%d'", size);
-      return NULL;
+      priv = GTK_STYLE_GET_PRIVATE (style);
+      context = priv->context;
     }
 
-  /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
-   * leave it alone.
-   */
-  if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
-    scaled = scale_or_ref (base_pixbuf, width, height);
-  else
-    scaled = g_object_ref (base_pixbuf);
+  if (!context)
+    return NULL;
 
-  /* If the state was wildcarded, then generate a state. */
-  if (gtk_icon_source_get_state_wildcarded (source))
-    {
-      if (state == GTK_STATE_INSENSITIVE)
-        {
-          stated = gdk_pixbuf_copy (scaled);      
-          
-          gdk_pixbuf_saturate_and_pixelate (scaled, stated,
-                                            0.8, TRUE);
-          
-          g_object_unref (scaled);
-        }
-      else if (state == GTK_STATE_PRELIGHT)
-        {
-          stated = gdk_pixbuf_copy (scaled);      
-          
-          gdk_pixbuf_saturate_and_pixelate (scaled, stated,
-                                            1.2, FALSE);
-          
-          g_object_unref (scaled);
-        }
-      else
-        {
-          stated = scaled;
-        }
-    }
-  else
-    stated = scaled;
-  
-  return stated;
+  gtk_style_context_save (context);
+
+  if (detail)
+    transform_detail_string (detail, context);
+
+  pixbuf = gtk_render_icon_pixbuf (context, source, size);
+
+  gtk_style_context_restore (context);
+
+  return pixbuf;
 }
 
 static void
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index fe4084e..aaaf782 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -3270,3 +3270,36 @@ gtk_render_activity (GtkStyleContext *context,
   _gtk_theming_engine_set_context (priv->theming_engine, context);
   engine_class->render_activity (priv->theming_engine, cr, x, y, width, height);
 }
+
+/**
+ * gtk_render_icon_pixbuf:
+ * @context: a #GtkStyleContext
+ * @source: the #GtkIconSource specifying the icon to render
+ * @size: (type int): the size to render the icon at. A size of (GtkIconSize) -1
+ *        means render at the size of the source and don't scale.
+ *
+ * Renders the icon specified by @source at the given @size, returning the result
+ * in a pixbuf.
+ *
+ * Returns: (transfer full): a newly-created #GdkPixbuf containing the rendered icon
+ *
+ * Since: 3.0
+ **/
+GdkPixbuf *
+gtk_render_icon_pixbuf (GtkStyleContext     *context,
+                        const GtkIconSource *source,
+                        GtkIconSize          size)
+{
+  GtkStyleContextPrivate *priv;
+  GtkThemingEngineClass *engine_class;
+
+  g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
+  g_return_val_if_fail (size >= -1, NULL);
+  g_return_val_if_fail (source != NULL, NULL);
+
+  priv = context->priv;
+  engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
+
+  _gtk_theming_engine_set_context (priv->theming_engine, context);
+  return engine_class->render_icon_pixbuf (priv->theming_engine, source, size);
+}
diff --git a/gtk/gtkstylecontext.h b/gtk/gtkstylecontext.h
index c57d914..30c08b8 100644
--- a/gtk/gtkstylecontext.h
+++ b/gtk/gtkstylecontext.h
@@ -404,6 +404,10 @@ void gtk_render_activity  (GtkStyleContext *context,
                            gdouble          width,
                            gdouble          height);
 
+GdkPixbuf * gtk_render_icon_pixbuf (GtkStyleContext     *context,
+                                    const GtkIconSource *source,
+                                    GtkIconSize          size);
+
 G_END_DECLS
 
 #endif /* __GTK_STYLE_CONTEXT_H__ */
diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c
index bd299f3..65a3a55 100644
--- a/gtk/gtkthemingengine.c
+++ b/gtk/gtkthemingengine.c
@@ -168,6 +168,9 @@ static void gtk_theming_engine_render_activity  (GtkThemingEngine *engine,
                                                  gdouble           y,
                                                  gdouble           width,
                                                  gdouble           height);
+static GdkPixbuf * gtk_theming_engine_render_icon_pixbuf (GtkThemingEngine    *engine,
+                                                          const GtkIconSource *source,
+                                                          GtkIconSize          size);
 
 G_DEFINE_TYPE (GtkThemingEngine, gtk_theming_engine, G_TYPE_OBJECT)
 
@@ -220,6 +223,7 @@ gtk_theming_engine_class_init (GtkThemingEngineClass *klass)
   klass->render_extension = gtk_theming_engine_render_extension;
   klass->render_handle = gtk_theming_engine_render_handle;
   klass->render_activity = gtk_theming_engine_render_activity;
+  klass->render_icon_pixbuf = gtk_theming_engine_render_icon_pixbuf;
 
   /**
    * GtkThemingEngine:name:
@@ -2807,3 +2811,91 @@ gtk_theming_engine_render_activity (GtkThemingEngine *engine,
       gtk_theming_engine_render_frame (engine, cr, x, y, width, height);
     }
 }
+
+static GdkPixbuf *
+scale_or_ref (GdkPixbuf *src,
+              gint       width,
+              gint       height)
+{
+  if (width == gdk_pixbuf_get_width (src) &&
+      height == gdk_pixbuf_get_height (src))
+    return g_object_ref (src);
+  else
+    return gdk_pixbuf_scale_simple (src,
+                                    width, height,
+                                    GDK_INTERP_BILINEAR);
+}
+
+static gboolean
+lookup_icon_size (GtkThemingEngine *engine,
+		  GtkIconSize       size,
+		  gint             *width,
+		  gint             *height)
+{
+  GdkScreen *screen;
+  GtkSettings *settings;
+
+  screen = gtk_theming_engine_get_screen (engine);
+  settings = gtk_settings_get_for_screen (screen);
+
+  return gtk_icon_size_lookup_for_settings (settings, size, width, height);
+}
+
+static GdkPixbuf *
+gtk_theming_engine_render_icon_pixbuf (GtkThemingEngine    *engine,
+                                       const GtkIconSource *source,
+                                       GtkIconSize          size)
+{
+  GdkPixbuf *scaled;
+  GdkPixbuf *stated;
+  GdkPixbuf *base_pixbuf;
+  GtkStateFlags state;
+  gint width = 1;
+  gint height = 1;
+
+  base_pixbuf = gtk_icon_source_get_pixbuf (source);
+  state = gtk_theming_engine_get_state (engine);
+
+  g_return_val_if_fail (base_pixbuf != NULL, NULL);
+
+  if (size != (GtkIconSize) -1 &&
+      !lookup_icon_size (engine, size, &width, &height))
+    {
+      g_warning (G_STRLOC ": invalid icon size '%d'", size);
+      return NULL;
+    }
+
+  /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
+   * leave it alone.
+   */
+  if (size != (GtkIconSize) -1 &&
+      gtk_icon_source_get_size_wildcarded (source))
+    scaled = scale_or_ref (base_pixbuf, width, height);
+  else
+    scaled = g_object_ref (base_pixbuf);
+
+  /* If the state was wildcarded, then generate a state. */
+  if (gtk_icon_source_get_state_wildcarded (source))
+    {
+      if (state & GTK_STATE_FLAG_INSENSITIVE)
+        {
+          stated = gdk_pixbuf_copy (scaled);
+          gdk_pixbuf_saturate_and_pixelate (scaled, stated,
+                                            0.8, TRUE);
+          g_object_unref (scaled);
+        }
+      else if (state & GTK_STATE_FLAG_PRELIGHT)
+        {
+          stated = gdk_pixbuf_copy (scaled);
+          gdk_pixbuf_saturate_and_pixelate (scaled, stated,
+                                            1.2, FALSE);
+          g_object_unref (scaled);
+        }
+      else
+        stated = scaled;
+    }
+  else
+    stated = scaled;
+
+  return stated;
+}
diff --git a/gtk/gtkthemingengine.h b/gtk/gtkthemingengine.h
index 78842c6..bc830b3 100644
--- a/gtk/gtkthemingengine.h
+++ b/gtk/gtkthemingengine.h
@@ -157,6 +157,10 @@ struct _GtkThemingEngineClass
                             gdouble           y,
                             gdouble           width,
                             gdouble           height);
+
+  GdkPixbuf * (* render_icon_pixbuf) (GtkThemingEngine    *engine,
+                                      const GtkIconSource *source,
+                                      GtkIconSize          size);
 };
 
 GType gtk_theming_engine_get_type (void) G_GNUC_CONST;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]