[file-roller: 3/26] file selector: added an icon cache for better performances



commit f02000bff21a39a232d6b04d99e547628e1b95ec
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Wed Aug 8 10:00:44 2012 +0200

    file selector: added an icon cache for better performances

 src/Makefile.am               |    2 +
 src/fr-file-selector-dialog.c |   19 +++--
 src/gth-icon-cache.c          |  167 +++++++++++++++++++++++++++++++++++++++++
 src/gth-icon-cache.h          |   41 ++++++++++
 4 files changed, 221 insertions(+), 8 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 508f826..30bf764 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -144,6 +144,8 @@ COMMON_SOURCES = 			\
 	gio-utils.h			\
 	glib-utils.c			\
 	glib-utils.h			\
+	gth-icon-cache.c		\
+	gth-icon-cache.h		\
 	gth-menu-button.c		\
 	gth-menu-button.h		\
 	gtk-utils.c			\
diff --git a/src/fr-file-selector-dialog.c b/src/fr-file-selector-dialog.c
index d430b22..834be42 100644
--- a/src/fr-file-selector-dialog.c
+++ b/src/fr-file-selector-dialog.c
@@ -21,9 +21,10 @@
 
 #include <config.h>
 #include "fr-file-selector-dialog.h"
-#include "gtk-utils.h"
 #include "gio-utils.h"
 #include "glib-utils.h"
+#include "gtk-utils.h"
+#include "gth-icon-cache.h"
 
 
 #define GET_WIDGET(x) (_gtk_builder_get_widget (self->priv->builder, (x)))
@@ -63,10 +64,11 @@ typedef struct {
 
 
 struct _FrFileSelectorDialogPrivate {
-	GtkBuilder *builder;
-	GtkWidget  *extra_widget;
-	GFile      *current_folder;
-	LoadData   *current_operation;
+	GtkBuilder    *builder;
+	GtkWidget     *extra_widget;
+	GFile         *current_folder;
+	LoadData      *current_operation;
+	GthIconCache  *icon_cache;
 };
 
 
@@ -116,6 +118,7 @@ fr_file_selector_dialog_finalize (GObject *object)
 	self = FR_FILE_SELECTOR_DIALOG (object);
 	g_object_unref (self->priv->builder);
 	_g_object_unref (self->priv->current_folder);
+	gth_icon_cache_free (self->priv->icon_cache);
 
 	G_OBJECT_CLASS (fr_file_selector_dialog_parent_class)->finalize (object);
 }
@@ -205,6 +208,8 @@ fr_file_selector_dialog_init (FrFileSelectorDialog *self)
 	self->priv->current_folder = NULL;
 	self->priv->builder = _gtk_builder_new_from_resource ("file-selector.ui");
 
+	self->priv->icon_cache = gth_icon_cache_new_for_widget (GTK_WIDGET (self), GTK_ICON_SIZE_MENU);
+
 	gtk_container_set_border_width (GTK_CONTAINER (self), 5);
 	gtk_window_set_default_size (GTK_WINDOW (self), 830, 510); /* FIXME: find a good size */
 	gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (self))), GET_WIDGET ("content"));
@@ -254,7 +259,6 @@ get_folder_content_done_cb (GError   *error,
 {
 	LoadData             *load_data = user_data;
 	FrFileSelectorDialog *self = load_data->dialog;
-	int                   file_list_icon_size;
 	GtkListStore         *list_store;
 	GList                *scan;
 	GtkTreeIter           iter;
@@ -265,7 +269,6 @@ get_folder_content_done_cb (GError   *error,
 		return;
 	}
 
-	file_list_icon_size = _gtk_widget_lookup_for_size (GTK_WIDGET (self), GTK_ICON_SIZE_MENU);
 	load_data->files = g_list_reverse (load_data->files);
 
 	list_store = GTK_LIST_STORE (GET_WIDGET ("files_liststore"));
@@ -281,7 +284,7 @@ get_folder_content_done_cb (GError   *error,
 
 		gtk_list_store_append (list_store, &iter);
 
-		icon_pixbuf = _g_icon_get_pixbuf (g_file_info_get_icon (file_info->info), file_list_icon_size, gtk_icon_theme_get_default ());
+		icon_pixbuf = gth_icon_cache_get_pixbuf (self->priv->icon_cache, g_file_info_get_icon (file_info->info));
 		size = g_format_size (g_file_info_get_size (file_info->info));
 		g_file_info_get_modification_time (file_info->info, &timeval);
 		datetime = g_date_time_new_from_timeval_local (&timeval);
diff --git a/src/gth-icon-cache.c b/src/gth-icon-cache.c
new file mode 100644
index 0000000..6946cb0
--- /dev/null
+++ b/src/gth-icon-cache.c
@@ -0,0 +1,167 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2008 The Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include "glib-utils.h"
+#include "gth-icon-cache.h"
+#include "gtk-utils.h"
+
+
+#define VOID_PIXBUF_KEY "void-pixbuf"
+
+
+struct _GthIconCache {
+	GtkIconTheme *icon_theme;
+	int           icon_size;
+	GHashTable   *cache;
+};
+
+
+static GdkPixbuf *
+_gdk_pixbuf_new_void (int width,
+                      int height)
+{
+        GdkPixbuf *p;
+
+        p = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+                            TRUE,
+                            8,
+                            width,
+                            height);
+        gdk_pixbuf_fill (p, 0xFFFFFF00);
+
+        return p;
+}
+
+
+GthIconCache *
+gth_icon_cache_new (GtkIconTheme *icon_theme,
+		    int           icon_size)
+{
+	GthIconCache *icon_cache;
+
+	g_return_val_if_fail (icon_theme != NULL, NULL);
+
+	icon_cache = g_new0 (GthIconCache, 1);
+	icon_cache->icon_theme = icon_theme;
+	icon_cache->icon_size = icon_size;
+	icon_cache->cache = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
+
+	g_hash_table_insert (icon_cache->cache, VOID_PIXBUF_KEY, _gdk_pixbuf_new_void (icon_cache->icon_size, icon_cache->icon_size));
+
+	return icon_cache;
+}
+
+
+GthIconCache *
+gth_icon_cache_new_for_widget (GtkWidget   *widget,
+	                       GtkIconSize  icon_size)
+{
+	GtkIconTheme *icon_theme;
+	int           pixel_size;
+
+	icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
+	pixel_size = _gtk_widget_lookup_for_size (widget, icon_size);
+
+	return gth_icon_cache_new (icon_theme, pixel_size);
+}
+
+
+void
+gth_icon_cache_free (GthIconCache *icon_cache)
+{
+	if (icon_cache == NULL)
+		return;
+	g_hash_table_destroy (icon_cache->cache);
+	g_free (icon_cache);
+}
+
+
+static const char *
+_gth_icon_cache_get_icon_key (GIcon *icon)
+{
+	const char *key = NULL;
+
+	if (G_IS_THEMED_ICON (icon)) {
+		char **icon_names;
+		char  *name;
+
+		g_object_get (icon, "names", &icon_names, NULL);
+		name = g_strjoinv (",", icon_names);
+		key = _g_str_get_static (name);
+
+		g_free (name);
+		g_strfreev (icon_names);
+	}
+	else if (G_IS_FILE_ICON (icon)) {
+		GFile *file;
+
+		file = g_file_icon_get_file (G_FILE_ICON (icon));
+		if (file != NULL) {
+			char *uri;
+
+			uri = g_file_get_uri (file);
+			key = _g_str_get_static (uri);
+
+			g_free (uri);
+		}
+	}
+
+	return key;
+}
+
+
+GdkPixbuf *
+gth_icon_cache_get_pixbuf (GthIconCache *icon_cache,
+			   GIcon        *icon)
+{
+	const char *key;
+	GdkPixbuf  *pixbuf;
+
+	key = NULL;
+	if (icon != NULL)
+		key = _gth_icon_cache_get_icon_key (icon);
+
+	if (key == NULL)
+		key = VOID_PIXBUF_KEY;
+
+	pixbuf = g_hash_table_lookup (icon_cache->cache, key);
+	if (pixbuf != NULL) {
+
+		return g_object_ref (pixbuf);
+	}
+
+	if (icon != NULL)
+		pixbuf = _g_icon_get_pixbuf (icon, icon_cache->icon_size, icon_cache->icon_theme);
+
+	if (pixbuf == NULL) {
+		GIcon *unknown_icon;
+
+		unknown_icon = g_themed_icon_new ("missing-image");
+		pixbuf = _g_icon_get_pixbuf (unknown_icon, icon_cache->icon_size, icon_cache->icon_theme);
+
+		g_object_unref (unknown_icon);
+	}
+
+	g_hash_table_insert (icon_cache->cache, (gpointer) key, pixbuf);
+
+	return g_object_ref (pixbuf);
+}
diff --git a/src/gth-icon-cache.h b/src/gth-icon-cache.h
new file mode 100644
index 0000000..8f6819c
--- /dev/null
+++ b/src/gth-icon-cache.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2008 The Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+ 
+#ifndef GTH_ICON_CACHE_H
+#define GTH_ICON_CACHE_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GthIconCache GthIconCache;
+
+GthIconCache * gth_icon_cache_new            (GtkIconTheme *icon_theme,
+			                      int           icon_size);
+GthIconCache * gth_icon_cache_new_for_widget (GtkWidget    *widget,
+			                      GtkIconSize   icon_size);
+void           gth_icon_cache_free           (GthIconCache *icon_cache);	                  
+GdkPixbuf *    gth_icon_cache_get_pixbuf     (GthIconCache *icon_cache,
+				              GIcon        *icon);
+
+G_END_DECLS
+
+#endif /* GTH_ICON_CACHE_H */



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