[gtk+/gtk-2.90] Load icons on-demand
- From: Christian Dywan <cdywan src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+/gtk-2.90] Load icons on-demand
- Date: Fri, 16 Oct 2009 13:59:05 +0000 (UTC)
commit 7f40495ba09404631ff09ad453267886fbd95ee5
Author: Benjamin Otte <otte gnome org>
Date: Tue Jun 30 23:33:29 2009 +0200
Load icons on-demand
Because loading icons takes a noticable performance, this code loads the
pixbuf on demand and only loads icons for rows that are visible. There
is a few caveats to this:
- The pixbuf cell renderer must report the proer size even if the icon
is not yet loaded. This is achieved by setting a fixed size.
- On theme changes the cahced pixbufs and the cell renderer must be
updated to conform to the new theme.
gtk/gtkfilechooserdefault.c | 102 ++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 100 insertions(+), 2 deletions(-)
---
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index d20c5cf..d98cab1 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -4538,6 +4538,10 @@ create_file_list (GtkFileChooserDefault *impl)
gtk_tree_view_column_set_title (impl->list_name_column, _("Name"));
renderer = gtk_cell_renderer_pixbuf_new ();
+ /* We set a fixed size so that we get an emoty row even if no icons are loaded yet */
+ gtk_cell_renderer_set_fixed_size (renderer,
+ renderer->xpad * 2 + impl->icon_size,
+ renderer->ypad * 2 + impl->icon_size);
gtk_tree_view_column_pack_start (impl->list_name_column, renderer, FALSE);
impl->list_name_renderer = gtk_cell_renderer_text_new ();
@@ -5793,6 +5797,8 @@ change_icon_theme (GtkFileChooserDefault *impl)
{
GtkSettings *settings;
gint width, height;
+ GtkCellRenderer *renderer;
+ GList *cells;
profile_start ("start", NULL);
@@ -5804,6 +5810,16 @@ change_icon_theme (GtkFileChooserDefault *impl)
impl->icon_size = FALLBACK_ICON_SIZE;
shortcuts_reload_icons (impl);
+ /* the first cell in the first column is the icon column, and we have a fixed size there */
+ cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (
+ gtk_tree_view_get_column (GTK_TREE_VIEW (impl->browse_files_tree_view), 0)));
+ renderer = GTK_CELL_RENDERER (cells->data);
+ gtk_cell_renderer_set_fixed_size (renderer,
+ renderer->xpad * 2 + impl->icon_size,
+ renderer->ypad * 2 + impl->icon_size);
+ g_list_free (cells);
+ if (impl->browse_files_model)
+ _gtk_file_system_model_clear_cache (impl->browse_files_model, MODEL_COL_PIXBUF);
gtk_widget_queue_resize (impl->browse_files_tree_view);
profile_end ("end", NULL);
@@ -6770,7 +6786,44 @@ my_g_format_time_for_display (glong secs)
return date_str;
}
-static gboolean
+#define copy_attribute(to, from, attribute) G_STMT_START { \
+ GFileAttributeType type; \
+ gpointer value; \
+\
+ if (g_file_info_get_attribute_data (from, attribute, &type, &value, NULL)) \
+ g_file_info_set_attribute (to, attribute, type, value); \
+}G_STMT_END
+
+static void
+file_system_model_got_thumbnail (GObject *object, GAsyncResult *res, gpointer data)
+{
+ GtkFileSystemModel *model = data; /* might be unreffed if operation was cancelled */
+ GFile *file = G_FILE (object);
+ GFileInfo *queried, *info;
+ GtkTreeIter iter;
+
+ queried = g_file_query_info_finish (file, res, NULL);
+ if (queried == NULL)
+ return;
+
+ /* now we know model is valid */
+
+ /* file was deleted */
+ if (!_gtk_file_system_model_get_iter_for_file (model, &iter, file))
+ return;
+
+ info = g_file_info_dup (_gtk_file_system_model_get_info (model, &iter));
+
+ copy_attribute (info, queried, G_FILE_ATTRIBUTE_THUMBNAIL_PATH);
+ copy_attribute (info, queried, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED);
+ copy_attribute (info, queried, G_FILE_ATTRIBUTE_STANDARD_ICON);
+
+ _gtk_file_system_model_update_file (model, file, info, FALSE);
+
+ g_object_unref (info);
+}
+
+static gboolean
file_system_model_set (GtkFileSystemModel *model,
GFile *file,
GFileInfo *info,
@@ -6802,7 +6855,52 @@ file_system_model_set (GtkFileSystemModel *model,
break;
case MODEL_COL_PIXBUF:
if (info)
- g_value_take_object (value, _gtk_file_info_render_icon (info, GTK_WIDGET (impl), impl->icon_size));
+ {
+ if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_ICON))
+ {
+ g_value_take_object (value, _gtk_file_info_render_icon (info, GTK_WIDGET (impl), impl->icon_size));
+ }
+ else
+ {
+ GtkTreeModel *tree_model;
+ GtkTreePath *path, *start, *end;
+ GtkTreeIter iter;
+
+ if (impl->browse_files_tree_view == NULL ||
+ g_file_info_has_attribute (info, "filechooser::queried"))
+ return FALSE;
+
+ tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (impl->browse_files_tree_view));
+ if (tree_model != GTK_TREE_MODEL (model))
+ return FALSE;
+
+ if (!_gtk_file_system_model_get_iter_for_file (impl->browse_files_model,
+ &iter,
+ file))
+ g_assert_not_reached ();
+ if (!gtk_tree_view_get_visible_range (GTK_TREE_VIEW (impl->browse_files_tree_view), &start, &end))
+ return FALSE;
+ path = gtk_tree_model_get_path (tree_model, &iter);
+ if (gtk_tree_path_compare (start, path) != 1 &&
+ gtk_tree_path_compare (path, end) != 1)
+ {
+ g_file_info_set_attribute_boolean (info, "filechooser::queried", TRUE);
+ g_file_query_info_async (file,
+ G_FILE_ATTRIBUTE_THUMBNAIL_PATH ","
+ G_FILE_ATTRIBUTE_THUMBNAILING_FAILED ","
+ G_FILE_ATTRIBUTE_STANDARD_ICON,
+ 0,
+ G_PRIORITY_DEFAULT,
+ _gtk_file_system_model_get_cancellable (model),
+ file_system_model_got_thumbnail,
+ model);
+ }
+ gtk_tree_path_free (path);
+ gtk_tree_path_free (start);
+ gtk_tree_path_free (end);
+ return FALSE;
+ }
+ }
else
g_value_set_object (value, NULL);
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]