diff options
Diffstat (limited to 'e-util/e-icon-factory.c')
-rw-r--r-- | e-util/e-icon-factory.c | 234 |
1 files changed, 17 insertions, 217 deletions
diff --git a/e-util/e-icon-factory.c b/e-util/e-icon-factory.c index cdbf39c788..411deead24 100644 --- a/e-util/e-icon-factory.c +++ b/e-util/e-icon-factory.c @@ -38,200 +38,16 @@ #include "e-icon-factory.h" #include "e-util-private.h" -#include "art/broken-image-16.xpm" -#include "art/broken-image-24.xpm" - #define d(x) -typedef struct { - gchar *name; - GdkPixbuf *pixbuf; -} Icon; - -static GdkPixbuf *broken16_pixbuf = NULL; -static GdkPixbuf *broken24_pixbuf = NULL; - -static GHashTable *name_to_icon = NULL; -static GtkIconTheme *icon_theme = NULL; -static GStaticMutex mutex = G_STATIC_MUTEX_INIT; - -/* Note: takes ownership of the pixbufs (eg. does not ref them) */ -static Icon * -icon_new (const gchar *name, GdkPixbuf *pixbuf) -{ - Icon *icon; - - icon = g_slice_new (Icon); - icon->name = g_strdup (name); - icon->pixbuf = pixbuf; - - return icon; -} - -static void -icon_free (Icon *icon) -{ - g_free (icon->name); - if (icon->pixbuf) - g_object_unref (icon->pixbuf); - g_slice_free (Icon, icon); -} - -static Icon * -load_icon (const gchar *icon_key, const gchar *icon_name, gint size, gint scale) -{ - GdkPixbuf *pixbuf, *unscaled = NULL; - gchar *basename, *filename = NULL; - - if (g_path_is_absolute (icon_name)) - filename = g_strdup (icon_name); - else { - GtkIconInfo *icon_info; - - icon_info = gtk_icon_theme_lookup_icon ( - icon_theme, icon_name, size, 0); - if (icon_info != NULL) { - filename = g_strdup ( - gtk_icon_info_get_filename (icon_info)); - gtk_icon_info_free (icon_info); - } - } - - if (!filename || !(unscaled = gdk_pixbuf_new_from_file (filename, NULL))) { - if (scale) { - const gchar *dent; - gint width; - GDir *dir; - gchar *x; - - if (!(dir = g_dir_open (EVOLUTION_ICONSDIR, 0, NULL))) { - goto done; - } - - /* scan icon directories looking for an icon with a size >= the size we need. */ - while ((dent = g_dir_read_name (dir))) { - if (!(dent[0] >= '1' && dent[0] <= '9')) - continue; - - if (((width = strtol (dent, &x, 10)) < size) || *x != 'x') - continue; - - if (((strtol (x + 1, &x, 10)) != width) || *x != '\0') - continue; - - /* if the icon exists in this directory, we can [use/scale] it */ - g_free (filename); - basename = g_strconcat (icon_name, ".png", NULL); - filename = g_build_filename (EVOLUTION_ICONSDIR, - dent, - basename, - NULL); - g_free (basename); - if ((unscaled = gdk_pixbuf_new_from_file (filename, NULL))) - break; - } - - g_dir_close (dir); - } else { - gchar *size_x_size; - - size_x_size = g_strdup_printf ("%dx%d", size, size); - basename = g_strconcat (icon_name, ".png", NULL); - g_free (filename); - filename = g_build_filename (EVOLUTION_ICONSDIR, - size_x_size, - basename, - NULL); - g_free (basename); - g_free (size_x_size); - unscaled = gdk_pixbuf_new_from_file (filename, NULL); - } - } - - done: - - g_free (filename); - if (unscaled != NULL) { - if (gdk_pixbuf_get_width(unscaled) != size || gdk_pixbuf_get_height(unscaled) != size) - { - pixbuf = e_icon_factory_pixbuf_scale (unscaled, size, size); - g_object_unref (unscaled); - } else - pixbuf = unscaled; - } else { - pixbuf = NULL; - } - - return icon_new (icon_key, pixbuf); -} - -static void -icon_theme_changed_cb (GtkIconTheme *icon_theme, gpointer user_data) -{ - g_hash_table_remove_all (name_to_icon); -} - -/** - * e_icon_factory_init: - * - * Initialises the icon factory. - **/ -void -e_icon_factory_init (void) -{ - gchar *path; - - if (name_to_icon != NULL) - return; - - name_to_icon = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) icon_free); - - icon_theme = gtk_icon_theme_get_default (); - path = g_build_filename (EVOLUTION_DATADIR, - "evolution", - BASE_VERSION, - "icons", - NULL); - gtk_icon_theme_append_search_path (icon_theme, path); - g_free (path); - g_signal_connect ( - icon_theme, "changed", - G_CALLBACK (icon_theme_changed_cb), NULL); - - broken16_pixbuf = gdk_pixbuf_new_from_xpm_data ( - (const gchar **) broken_image_16_xpm); - broken24_pixbuf = gdk_pixbuf_new_from_xpm_data ( - (const gchar **) broken_image_24_xpm); -} - -/** - * e_icon_factory_shutdown: - * - * Shuts down the icon factory (cleans up all cached icons, etc). - **/ -void -e_icon_factory_shutdown (void) -{ - if (name_to_icon == NULL) - return; - - g_hash_table_destroy (name_to_icon); - g_object_unref (broken16_pixbuf); - g_object_unref (broken24_pixbuf); - name_to_icon = NULL; -} - /** * e_icon_factory_get_icon_filename: * @icon_name: name of the icon - * @size: size of the icon + * @icon_size: size of the icon * - * Looks up the icon to use based on name and size. + * Returns the filename of the requested icon in the default icon theme. * - * Returns the requested icon pixbuf. + * Returns: the filename of the requested icon **/ gchar * e_icon_factory_get_icon_filename (const gchar *icon_name, @@ -265,51 +81,35 @@ e_icon_factory_get_icon_filename (const gchar *icon_name, * @icon_name: name of the icon * @icon_size: size of the icon * - * Returns the specified icon of the requested size (may perform - * scaling to achieve this). If @icon_name is a full path, that file - * is used directly. Otherwise it is looked up in the user's current - * icon theme. If the icon cannot be found in the icon theme, it falls - * back to loading the requested icon from Evolution's icon set - * installed from the art/ srcdir. If even that fails to find the - * requested icon, then a "broken-image" icon is returned. + * Loads the requested icon from the default icon theme and renders it + * to a pixbuf. + * + * Returns: the rendered icon **/ GdkPixbuf * e_icon_factory_get_icon (const gchar *icon_name, GtkIconSize icon_size) { + GtkIconTheme *icon_theme; GdkPixbuf *pixbuf; - gchar *icon_key; - Icon *icon; - gint size, width, height; + gint width, height; + GError *error = NULL; g_return_val_if_fail (icon_name != NULL, NULL); + icon_theme = gtk_icon_theme_get_default (); + if (!gtk_icon_size_lookup (icon_size, &width, &height)) return NULL; - size = height; - - icon_key = g_alloca (strlen (icon_name) + 7); - sprintf (icon_key, "%dx%d/%s", size, size, icon_name); - - g_static_mutex_lock (&mutex); + pixbuf = gtk_icon_theme_load_icon ( + icon_theme, icon_name, height, 0, &error); - if (!(icon = g_hash_table_lookup (name_to_icon, icon_key))) { - icon = load_icon (icon_key, icon_name, size, TRUE); - g_hash_table_insert (name_to_icon, icon->name, icon); + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); } - if ((pixbuf = icon->pixbuf)) { - g_object_ref (pixbuf); - } else { - if (size >= 24) - pixbuf = gdk_pixbuf_scale_simple (broken24_pixbuf, size, size, GDK_INTERP_NEAREST); - else - pixbuf = gdk_pixbuf_scale_simple (broken16_pixbuf, size, size, GDK_INTERP_NEAREST); - } - - g_static_mutex_unlock (&mutex); - return pixbuf; } |