[gnome-shell] StIcon: add support for GIcon



commit 21ac22598101c25f1705fa6dea263a16ffe49be1
Author: Giovanni Campagna <scampa giovanni gmail com>
Date:   Sun Sep 26 17:18:26 2010 +0200

    StIcon: add support for GIcon
    
    Add a "gicon" property so that a GIcon can be used instead of an
    icon name, while still getting icon recoloring from the theme.
    Also include a compatibility wrapper in libshell until GJS has
    support for interface static methods.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=622451

 js/ui/panelMenu.js                     |   19 +++---
 js/ui/placeDisplay.js                  |    8 +-
 src/Makefile.am                        |    4 +-
 src/shell-app-system.c                 |    2 +-
 src/{shell-uri-util.c => shell-util.c} |   18 +++++-
 src/{shell-uri-util.h => shell-util.h} |    7 +-
 src/shell-window-tracker.c             |    2 +-
 src/st/st-icon.c                       |  121 +++++++++++++++++++++++++++----
 src/st/st-icon.h                       |    3 +
 src/st/st-texture-cache.c              |   14 +++--
 src/st/st-texture-cache.h              |    1 +
 11 files changed, 157 insertions(+), 42 deletions(-)
---
diff --git a/js/ui/panelMenu.js b/js/ui/panelMenu.js
index 9888d23..b0dad5e 100644
--- a/js/ui/panelMenu.js
+++ b/js/ui/panelMenu.js
@@ -72,18 +72,19 @@ SystemStatusButton.prototype = {
 
     _init: function(iconName,tooltipText) {
         Button.prototype._init.call(this, St.Align.START);
-        this._iconActor = null;
-        this.setIcon(iconName);
+        this._iconActor = new St.Icon({ icon_name: iconName,
+                                        icon_type: St.IconType.SYMBOLIC,
+                                        style_class: 'system-status-icon' });
+        this.actor.set_child(this._iconActor);
         this.setTooltip(tooltipText);
     },
 
     setIcon: function(iconName) {
-        this._iconName = iconName;
-        if (this._iconActor)
-            this._iconActor.destroy();
-        this._iconActor = new St.Icon({ icon_name: this._iconName,
-                                        style_class: 'system-status-icon' });
-        this.actor.set_child(this._iconActor);
+        this._iconActor.icon_name = iconName;
+    },
+
+    setGIcon: function(gicon) {
+        this._iconActor.gicon = gicon;
     },
 
     setTooltip: function(text) {
@@ -96,4 +97,4 @@ SystemStatusButton.prototype = {
             this.tooltip = null;
         }
     }
-};
\ No newline at end of file
+};
diff --git a/js/ui/placeDisplay.js b/js/ui/placeDisplay.js
index d22f422..88d25da 100644
--- a/js/ui/placeDisplay.js
+++ b/js/ui/placeDisplay.js
@@ -79,7 +79,7 @@ PlaceDeviceInfo.prototype = {
 
     iconFactory: function(size) {
         let icon = this._mount.get_icon();
-        return St.TextureCache.get_default().load_gicon(icon, size);
+        return St.TextureCache.get_default().load_gicon(null, icon, size);
     },
 
     launch: function() {
@@ -137,7 +137,7 @@ PlacesManager.prototype = {
         let homeIcon = Shell.util_get_icon_for_uri (homeUri);
         this._home = new PlaceInfo('special:home', homeLabel,
             function(size) {
-                return St.TextureCache.get_default().load_gicon(homeIcon, size);
+                return St.TextureCache.get_default().load_gicon(null, homeIcon, size);
             },
             function() {
                 Gio.app_info_launch_default_for_uri(homeUri, global.create_app_launch_context());
@@ -150,7 +150,7 @@ PlacesManager.prototype = {
         let desktopIcon = Shell.util_get_icon_for_uri (desktopUri);
         this._desktopMenu = new PlaceInfo('special:desktop', desktopLabel,
             function(size) {
-                return St.TextureCache.get_default().load_gicon(desktopIcon, size);
+                return St.TextureCache.get_default().load_gicon(null, desktopIcon, size);
             },
             function() {
                 Gio.app_info_launch_default_for_uri(desktopUri, global.create_app_launch_context());
@@ -327,7 +327,7 @@ PlacesManager.prototype = {
 
             let item = new PlaceInfo('bookmark:' + bookmark, label,
                 function(size) {
-                    return St.TextureCache.get_default().load_gicon(icon, size);
+                    return St.TextureCache.get_default().load_gicon(null, icon, size);
                 },
                 function() {
                     Gio.app_info_launch_default_for_uri(bookmark, global.create_app_launch_context());
diff --git a/src/Makefile.am b/src/Makefile.am
index 013a884..05b1ded 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -77,7 +77,7 @@ shell_public_headers_h =		\
 	shell-stack.h			\
 	shell-tray-icon.h		\
 	shell-tray-manager.h		\
-	shell-uri-util.h		\
+	shell-util.h			\
 	shell-window-tracker.h		\
 	shell-wm.h			\
 	shell-xfixes-cursor.h
@@ -109,7 +109,7 @@ libgnome_shell_la_SOURCES =		\
 	shell-stack.c			\
 	shell-tray-icon.c		\
 	shell-tray-manager.c		\
-	shell-uri-util.c		\
+	shell-util.c			\
 	shell-window-tracker.c		\
 	shell-wm.c			\
 	shell-xfixes-cursor.c
diff --git a/src/shell-app-system.c b/src/shell-app-system.c
index 7df763f..daf0f14 100644
--- a/src/shell-app-system.c
+++ b/src/shell-app-system.c
@@ -1274,7 +1274,7 @@ shell_app_info_create_icon_texture (ShellAppInfo *info, float size)
     }
   else
     {
-      ret = st_texture_cache_load_gicon (st_texture_cache_get_default (), icon, (int)size);
+      ret = st_texture_cache_load_gicon (st_texture_cache_get_default (), NULL, icon, (int)size);
       g_object_unref (icon);
     }
 
diff --git a/src/shell-uri-util.c b/src/shell-util.c
similarity index 95%
rename from src/shell-uri-util.c
rename to src/shell-util.c
index dcbe58b..1a643c9 100644
--- a/src/shell-uri-util.c
+++ b/src/shell-util.c
@@ -2,7 +2,7 @@
 
 #include "config.h"
 
-#include "shell-uri-util.h"
+#include "shell-util.h"
 #include <glib/gi18n-lib.h>
 #include <gconf/gconf-client.h>
 #include <gtk/gtk.h>
@@ -383,3 +383,19 @@ shell_util_get_icon_for_uri (const char *text_uri)
 
   return g_themed_icon_new ("gtk-file");
 }
+
+/**
+ * shell_util_icon_from_string:
+ * @string: a stringified #GIcon
+ *
+ * A static method equivalent to g_icon_new_for_string, workaround
+ * for GJS not being able to represent Gio.Icon (which is an interface,
+ * not a class).
+ *
+ * Returns: (transfer full): the icon which is represented by @string
+ */
+GIcon *
+shell_util_icon_from_string (const char *string, GError **error)
+{
+  return g_icon_new_for_string (string, error);
+}
diff --git a/src/shell-uri-util.h b/src/shell-util.h
similarity index 60%
rename from src/shell-uri-util.h
rename to src/shell-util.h
index eef415a..f523d44 100644
--- a/src/shell-uri-util.h
+++ b/src/shell-util.h
@@ -1,7 +1,7 @@
 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 
-#ifndef __SHELL_URI_UTIL_H__
-#define __SHELL_URI_UTIL_H__
+#ifndef __SHELL_UTIL_H__
+#define __SHELL_UTIL_H__
 
 #include <gio/gio.h>
 
@@ -9,7 +9,8 @@ G_BEGIN_DECLS
 
 char *shell_util_get_label_for_uri (const char *text_uri);
 GIcon *shell_util_get_icon_for_uri (const char *text_uri);
+GIcon *shell_util_icon_from_string (const char *string, GError **error);
 
 G_END_DECLS
 
-#endif /* __SHELL_URI_UTIL_H__ */
+#endif /* __SHELL_UTIL_H__ */
diff --git a/src/shell-window-tracker.c b/src/shell-window-tracker.c
index ad8bc47..1e61b7c 100644
--- a/src/shell-window-tracker.c
+++ b/src/shell-window-tracker.c
@@ -941,7 +941,7 @@ shell_startup_sequence_create_icon (ShellStartupSequence *sequence, guint size)
 
   themed = g_themed_icon_new (icon_name);
   texture = st_texture_cache_load_gicon (st_texture_cache_get_default (),
-                                         themed, size);
+                                         NULL, themed, size);
   g_object_unref (G_OBJECT (themed));
   return texture;
 }
diff --git a/src/st/st-icon.c b/src/st/st-icon.c
index 94e6842..4b6b14b 100644
--- a/src/st/st-icon.c
+++ b/src/st/st-icon.c
@@ -35,6 +35,7 @@ enum
 {
   PROP_0,
 
+  PROP_GICON,
   PROP_ICON_NAME,
   PROP_ICON_TYPE,
   PROP_ICON_SIZE
@@ -49,6 +50,7 @@ struct _StIconPrivate
 {
   ClutterActor *icon_texture;
 
+  GIcon        *gicon;
   gchar        *icon_name;
   StIconType    icon_type;
   gint          prop_icon_size;  /* icon size set as property */
@@ -72,6 +74,10 @@ st_icon_set_property (GObject      *gobject,
 
   switch (prop_id)
     {
+    case PROP_GICON:
+      st_icon_set_gicon (icon, g_value_get_object (value));
+      break;
+
     case PROP_ICON_NAME:
       st_icon_set_icon_name (icon, g_value_get_string (value));
       break;
@@ -100,6 +106,10 @@ st_icon_get_property (GObject    *gobject,
 
   switch (prop_id)
     {
+    case PROP_GICON:
+      g_value_set_object (value, icon->priv->gicon);
+      break;
+
     case PROP_ICON_NAME:
       g_value_set_string (value, st_icon_get_icon_name (icon));
       break;
@@ -129,6 +139,12 @@ st_icon_dispose (GObject *gobject)
       priv->icon_texture = NULL;
     }
 
+  if (priv->gicon)
+    {
+      g_object_unref (priv->gicon);
+      priv->gicon = NULL;
+    }
+
   G_OBJECT_CLASS (st_icon_parent_class)->dispose (gobject);
 }
 
@@ -272,6 +288,13 @@ st_icon_class_init (StIconClass *klass)
 
   widget_class->style_changed = st_icon_style_changed;
 
+  pspec = g_param_spec_object ("gicon",
+                               "GIcon",
+                               "A GIcon to override :icon-name",
+                               G_TYPE_ICON,
+                               ST_PARAM_READWRITE);
+  g_object_class_install_property (object_class, PROP_GICON, pspec);
+
   pspec = g_param_spec_string ("icon-name",
                                "Icon name",
                                "An icon name",
@@ -299,6 +322,7 @@ st_icon_init (StIcon *self)
 {
   self->priv = ST_ICON_GET_PRIVATE (self);
 
+  self->priv->gicon = NULL;
   self->priv->icon_size = DEFAULT_ICON_SIZE;
   self->priv->prop_icon_size = -1;
   self->priv->icon_type = DEFAULT_ICON_TYPE;
@@ -308,6 +332,8 @@ static void
 st_icon_update (StIcon *icon)
 {
   StIconPrivate *priv = icon->priv;
+  StThemeNode *theme_node;
+  StTextureCache *cache;
 
   /* Get rid of the old one */
   if (priv->icon_texture)
@@ -317,23 +343,30 @@ st_icon_update (StIcon *icon)
     }
 
   /* Try to lookup the new one */
-  if (priv->icon_name)
+  theme_node = st_widget_peek_theme_node (ST_WIDGET (icon));
+  if (theme_node == NULL)
+    return;
+
+  cache = st_texture_cache_get_default ();
+  if (priv->gicon)
+    {
+      priv->icon_texture = st_texture_cache_load_gicon (cache,
+                                                        (priv->icon_type != ST_ICON_APPLICATION &&
+                                                         priv->icon_type != ST_ICON_DOCUMENT) ?
+                                                        theme_node : NULL,
+                                                        priv->gicon,
+                                                        priv->icon_size);
+    }
+ else if (priv->icon_name)
     {
-      StThemeNode *theme_node = st_widget_peek_theme_node (ST_WIDGET (icon));
-
-      if (theme_node)
-        {
-          StTextureCache *cache = st_texture_cache_get_default ();
-          priv->icon_texture = st_texture_cache_load_icon_name (cache,
-                                                                theme_node,
-                                                                priv->icon_name,
-                                                                priv->icon_type,
-                                                                priv->icon_size);
-
-          if (priv->icon_texture)
-            clutter_actor_set_parent (priv->icon_texture, CLUTTER_ACTOR (icon));
-        }
+      priv->icon_texture = st_texture_cache_load_icon_name (cache,
+                                                            theme_node,
+                                                            priv->icon_name,
+                                                            priv->icon_type,
+                                                            priv->icon_size);
     }
+  if (priv->icon_texture)
+    clutter_actor_set_parent (priv->icon_texture, CLUTTER_ACTOR (icon));
 }
 
 static gboolean
@@ -397,9 +430,16 @@ st_icon_set_icon_name (StIcon      *icon,
   g_free (priv->icon_name);
   priv->icon_name = g_strdup (icon_name);
 
-  st_icon_update (icon);
+  if (priv->gicon)
+    {
+      g_object_unref (priv->gicon);
+      priv->gicon = NULL;
+      g_object_notify (G_OBJECT (icon), "gicon");
+    }
 
   g_object_notify (G_OBJECT (icon), "icon-name");
+
+  st_icon_update (icon);
 }
 
 /**
@@ -449,6 +489,55 @@ st_icon_set_icon_type (StIcon     *icon,
 }
 
 /**
+ * st_icon_get_gicon:
+ * @icon: an icon
+ *
+ * Return value: (transfer none): the override GIcon, if set, or NULL
+ */
+GIcon *
+st_icon_get_gicon (StIcon *icon)
+{
+  g_return_val_if_fail (ST_IS_ICON (icon), NULL);
+
+  return icon->priv->gicon;
+}
+
+/**
+ * st_icon_set_gicon:
+ * @icon: an icon
+ * @gicon: (allow-none): a #GIcon to override :icon-name
+ */
+void
+st_icon_set_gicon (StIcon *icon, GIcon *gicon)
+{
+  g_return_if_fail (ST_IS_ICON (icon));
+  g_return_if_fail (G_IS_ICON (gicon));
+
+  if (icon->priv->gicon == gicon) /* do nothing */
+    return;
+
+  if (icon->priv->gicon)
+    {
+      g_object_unref (icon->priv->gicon);
+      icon->priv->gicon = NULL;
+    }
+
+  if (gicon)
+    icon->priv->gicon = g_object_ref (gicon);
+
+  if (icon->priv->icon_name)
+    {
+      g_free (icon->priv->icon_name);
+      icon->priv->icon_name = NULL;
+      g_object_notify (G_OBJECT (icon), "icon-name");
+    }
+
+  g_object_notify (G_OBJECT (icon), "gicon");
+
+  st_icon_update (icon);
+}
+
+/**
  * st_icon_get_icon_size:
  * @icon: an icon
  *
diff --git a/src/st/st-icon.h b/src/st/st-icon.h
index bddb41d..eac4a16 100644
--- a/src/st/st-icon.h
+++ b/src/st/st-icon.h
@@ -29,6 +29,7 @@
 #define _ST_ICON
 
 #include <glib-object.h>
+#include <gio/gio.h>
 #include <st/st-widget.h>
 
 #include <st/st-types.h>
@@ -93,6 +94,8 @@ StIconType   st_icon_get_icon_type (StIcon *icon);
 gint         st_icon_get_icon_size (StIcon *icon);
 void         st_icon_set_icon_size (StIcon *icon, gint size);
 
+void         st_icon_set_gicon (StIcon *icon, GIcon *gicon);
+GIcon       *st_icon_get_gicon (StIcon *icon);
 
 G_END_DECLS
 
diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c
index cd84bdb..35931da 100644
--- a/src/st/st-texture-cache.c
+++ b/src/st/st-texture-cache.c
@@ -1118,6 +1118,8 @@ load_gicon_with_colors (StTextureCache    *cache,
 /**
  * st_texture_cache_load_gicon:
  * @cache: The texture cache instance
+ * @theme_node: (allow-none): The #StThemeNode to use for colors, or NULL
+ *                            if the icon must not be recolored
  * @icon: the #GIcon to load
  * @size: Size of themed
  *
@@ -1132,10 +1134,11 @@ load_gicon_with_colors (StTextureCache    *cache,
  */
 ClutterActor *
 st_texture_cache_load_gicon (StTextureCache    *cache,
+                             StThemeNode       *theme_node,
                              GIcon             *icon,
                              gint               size)
 {
-  return load_gicon_with_colors (cache, icon, size, NULL);
+  return load_gicon_with_colors (cache, icon, size, theme_node ? st_theme_node_get_icon_colors (theme_node) : NULL);
 }
 
 typedef struct {
@@ -1328,7 +1331,7 @@ st_texture_cache_load_icon_name (StTextureCache    *cache,
     case ST_ICON_APPLICATION:
     case ST_ICON_DOCUMENT:
       themed = g_themed_icon_new (name);
-      texture = st_texture_cache_load_gicon (cache, themed, size);
+      texture = load_gicon_with_colors (cache, themed, size, NULL);
       g_object_unref (themed);
 
       return CLUTTER_ACTOR (texture);
@@ -1345,7 +1348,8 @@ st_texture_cache_load_icon_name (StTextureCache    *cache,
       break;
     case ST_ICON_FULLCOLOR:
       themed = g_themed_icon_new_with_default_fallbacks (name);
-      texture = st_texture_cache_load_gicon (cache, themed, size);
+      texture = load_gicon_with_colors (cache, themed, size, NULL);
+      g_object_unref (themed);
 
       return CLUTTER_ACTOR (texture);
       break;
@@ -1693,7 +1697,7 @@ st_texture_cache_load_thumbnail (StTextureCache    *cache,
   if (!g_str_has_prefix (uri, "file://"))
     {
       GIcon *icon = icon_for_mimetype (mimetype);
-      return st_texture_cache_load_gicon (cache, icon, size);
+      return st_texture_cache_load_gicon (cache, NULL, icon, size);
     }
 
   texture = create_default_texture (cache);
@@ -1770,7 +1774,7 @@ st_texture_cache_load_recent_thumbnail (StTextureCache    *cache,
   if (!g_str_has_prefix (uri, "file://"))
     {
       GIcon *icon = icon_for_recent (info);
-      return st_texture_cache_load_gicon (cache, icon, size);
+      return st_texture_cache_load_gicon (cache, NULL, icon, size);
     }
 
   texture = CLUTTER_TEXTURE (clutter_texture_new ());
diff --git a/src/st/st-texture-cache.h b/src/st/st-texture-cache.h
index e8fc586..4f1a482 100644
--- a/src/st/st-texture-cache.h
+++ b/src/st/st-texture-cache.h
@@ -85,6 +85,7 @@ ClutterActor *st_texture_cache_load_icon_name (StTextureCache *cache,
                                                gint            size);
 
 ClutterActor *st_texture_cache_load_gicon (StTextureCache *cache,
+                                           StThemeNode    *theme_node,
                                            GIcon          *icon,
                                            gint            size);
 



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