gnome-shell r143 - in trunk: . js/ui src



Author: marinaz
Date: Fri Jan  9 01:09:35 2009
New Revision: 143
URL: http://svn.gnome.org/viewvc/gnome-shell?rev=143&view=rev

Log:
Display thumbnails of recent files in the overlay mode by using GnomeThumbnailFactory to get them. Fall back to the system icon for the file type provided by GtkRecentInfo when a thumbnail is not available. 



Modified:
   trunk/configure.ac
   trunk/js/ui/appDisplay.js
   trunk/js/ui/docDisplay.js
   trunk/js/ui/genericDisplay.js
   trunk/js/ui/overlay.js
   trunk/src/Makefile.am
   trunk/src/shell-global.c
   trunk/src/shell-global.h

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Fri Jan  9 01:09:35 2009
@@ -20,6 +20,10 @@
 PKG_CHECK_MODULES(TIDY, clutter-0.8)
 PKG_CHECK_MODULES(BIG, clutter-cairo-0.8 gtk+-2.0 librsvg-2.0)
 PKG_CHECK_MODULES(TRAY, gtk+-2.0)
+# We require libgnomeui for generating thumbnails for recent files with GnomeThumbnailFactory.
+# We'll switch to using GnomeDesktopThumbnailFactory once the branch of gnome-desktop that contains
+# it becomes stable.
+PKG_CHECK_MODULES(LIBGNOMEUI, libgnomeui-2.0)
 
 # Sets GLIB_GENMARSHAL and GLIB_MKENUMS
 AM_PATH_GLIB_2_0()

Modified: trunk/js/ui/appDisplay.js
==============================================================================
--- trunk/js/ui/appDisplay.js	(original)
+++ trunk/js/ui/appDisplay.js	Fri Jan  9 01:09:35 2009
@@ -56,11 +56,11 @@
 
         let iconTheme = Gtk.IconTheme.get_default();
 
-        let icon = new Clutter.Texture({ width: 48, height: 48});
+        let icon = new Clutter.Texture({ width: GenericDisplay.ITEM_DISPLAY_ICON_SIZE, height: GenericDisplay.ITEM_DISPLAY_ICON_SIZE});
         let gicon = appInfo.get_icon();
         let path = null;
         if (gicon != null) {
-            let iconinfo = iconTheme.lookup_by_gicon(gicon, 48, Gtk.IconLookupFlags.NO_SVG);
+            let iconinfo = iconTheme.lookup_by_gicon(gicon, GenericDisplay.ITEM_DISPLAY_ICON_SIZE, Gtk.IconLookupFlags.NO_SVG);
             if (iconinfo)
                 path = iconinfo.get_filename();
         }
@@ -68,6 +68,8 @@
         if (path) {
             try {
                 icon.set_from_file(path);
+                icon.x = GenericDisplay.ITEM_DISPLAY_PADDING;
+                icon.y = GenericDisplay.ITEM_DISPLAY_PADDING;
             } catch (e) {
                 // we can get an error here if the file path doesn't exist on the system
                 log('Error loading AppDisplayItem icon ' + e);

Modified: trunk/js/ui/docDisplay.js
==============================================================================
--- trunk/js/ui/docDisplay.js	(original)
+++ trunk/js/ui/docDisplay.js	Fri Jan  9 01:09:35 2009
@@ -9,6 +9,8 @@
 
 const GenericDisplay = imports.ui.genericDisplay;
 
+const ITEM_DISPLAY_ICON_MARGIN = 2;
+
 /* This class represents a single display item containing information about a document.
  *
  * docInfo - GtkRecentInfo object containing information about the document
@@ -30,9 +32,24 @@
         // we can possibly display tags in the space for description in the future
         let description = ""; 
 
-        let icon = new Clutter.Texture({width: 48, height: 48});
-        Shell.clutter_texture_set_from_pixbuf(icon, docInfo.get_icon(48));
-
+        let icon = new Clutter.Texture();
+        let pixbuf = Shell.get_thumbnail_for_recent_info(docInfo);
+        if (pixbuf) {
+            // We calculate the width and height of the texture so as to preserve the aspect ratio of the thumbnail.
+            // Because the images generated based on thumbnails don't have an internal padding like system icons do,
+            // we create a slightly smaller texture and then use extra margin when positioning it. 
+            let scalingFactor = (GenericDisplay.ITEM_DISPLAY_ICON_SIZE - ITEM_DISPLAY_ICON_MARGIN * 2) / Math.max(pixbuf.get_width(), pixbuf.get_height());
+            icon.set_width(Math.ceil(pixbuf.get_width() * scalingFactor));
+            icon.set_height(Math.ceil(pixbuf.get_height() * scalingFactor));
+            Shell.clutter_texture_set_from_pixbuf(icon, pixbuf);
+            icon.x = GenericDisplay.ITEM_DISPLAY_PADDING + ITEM_DISPLAY_ICON_MARGIN;
+            icon.y = GenericDisplay.ITEM_DISPLAY_PADDING + ITEM_DISPLAY_ICON_MARGIN;
+        } else {
+            Shell.clutter_texture_set_from_pixbuf(icon, docInfo.get_icon(GenericDisplay.ITEM_DISPLAY_ICON_SIZE));
+            icon.x = GenericDisplay.ITEM_DISPLAY_PADDING;
+            icon.y = GenericDisplay.ITEM_DISPLAY_PADDING;
+        } 
+  
         this._setItemInfo(name, description, icon); 
     },
 
@@ -124,10 +141,13 @@
         // While this._allItems associative array seems to always be ordered by last added,
         // as the results of this._recentManager.get_items() based on which it is constructed are,
         // we should do the sorting manually because we want the order to be based on last visited.
-        // TODO: would it be better to store an additional array of doc ids as they are 
-        // returned by this._recentManager.get_items() to avoid having to do this sorting?
-        // This function is called each time the search string is set back to '', so we are
-        // doing the sorting over the same items multiple times. 
+        //
+        // This function is called each time the search string is set back to '' or we display
+        // the overlay, so we are doing the sorting over the same items multiple times if the list
+        // of recent items didn't change. We could store an additional array of doc ids and sort
+        // them once when they are returned by this._recentManager.get_items() to avoid having to do 
+        // this sorting each time, but the sorting seems to be very fast anyway, so there is no need
+        // to introduce an additional class variable.
         let docIds = [];
         for (docId in this._allItems) {
             docIds.push(docId);

Modified: trunk/js/ui/genericDisplay.js
==============================================================================
--- trunk/js/ui/genericDisplay.js	(original)
+++ trunk/js/ui/genericDisplay.js	Fri Jan  9 01:09:35 2009
@@ -20,7 +20,9 @@
 ITEM_DISPLAY_SELECTED_BACKGROUND_COLOR.from_pixel(0x00ff0055);
 
 const ITEM_DISPLAY_HEIGHT = 50;
-const ITEM_DISPLAY_PADDING = 4;
+const ITEM_DISPLAY_ICON_SIZE = 48;
+const ITEM_DISPLAY_PADDING = 1;
+const ITEM_DISPLAY_MARGIN = 4;
 
 /* This is a virtual class that represents a single display item containing
  * a name, a description, and an icon. It allows selecting an item and represents 
@@ -106,18 +108,16 @@
         } 
 
         this._icon = iconActor;
-        this._icon.x = 0;
-        this._icon.y = 0;
         this._group.add_actor(this._icon);
 
-        let text_width = this._availableWidth - (this._icon.width + 4);
+        let text_width = this._availableWidth - (ITEM_DISPLAY_ICON_SIZE + 4);
         this._name = new Clutter.Label({ color: ITEM_DISPLAY_NAME_COLOR,
                                      font_name: "Sans 14px",
                                      width: text_width,
                                      ellipsize: Pango.EllipsizeMode.END,
                                      text: nameText,
-                                     x: this._icon.width + 4,
-                                     y: 0});
+                                     x: ITEM_DISPLAY_ICON_SIZE + 4,
+                                     y: ITEM_DISPLAY_PADDING});
         this._group.add_actor(this._name);
         this._description = new Clutter.Label({ color: ITEM_DISPLAY_DESCRIPTION_COLOR,
                                              font_name: "Sans 12px",
@@ -157,7 +157,8 @@
         this._activatedItem = null;
         this._selectedIndex = -1;
         this._keepDisplayCurrent = false;
-        this._maxItems = this._height / (ITEM_DISPLAY_HEIGHT + ITEM_DISPLAY_PADDING);
+        // TODO: this should be Math.floor, but right now we get too few items if we apply it
+        this._maxItems = this._height / (ITEM_DISPLAY_HEIGHT + ITEM_DISPLAY_MARGIN);
         this.actor = this._grid;
     },
 

Modified: trunk/js/ui/overlay.js
==============================================================================
--- trunk/js/ui/overlay.js	(original)
+++ trunk/js/ui/overlay.js	Fri Jan  9 01:09:35 2009
@@ -19,7 +19,7 @@
 OVERLAY_BACKGROUND_COLOR.from_pixel(0x000000ff);
 
 const SIDESHOW_PAD = 6;
-const SIDESHOW_PAD_BOTTOM = 60;
+const SIDESHOW_PAD_BOTTOM = 40;
 const SIDESHOW_MIN_WIDTH = 250;
 const SIDESHOW_SECTION_PAD = 10;
 const SIDESHOW_SECTION_LABEL_PAD_BOTTOM = 6;

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Fri Jan  9 01:09:35 2009
@@ -10,6 +10,7 @@
 
 gnome_shell_cflags =				\
 	$(MUTTER_PLUGIN_CFLAGS)			\
+        $(LIBGNOMEUI_CFLAGS)                    \
 	-Itray					\
 	-DGETTEXT_PACKAGE=gnome-shell		\
 	-DGNOME_SHELL_DATADIR=\"$(pkgdatadir)\"	\
@@ -65,6 +66,7 @@
 libgnome_shell_la_LDFLAGS = -avoid-version -module
 libgnome_shell_la_LIBADD =	\
 	$(MUTTER_PLUGIN_LIBS)	\
+        $(LIBGNOMEUI_LIBS)      \
 	libbig-1.0.la		\
 	libtidy-1.0.la		\
 	libtray.la

Modified: trunk/src/shell-global.c
==============================================================================
--- trunk/src/shell-global.c	(original)
+++ trunk/src/shell-global.c	Fri Jan  9 01:09:35 2009
@@ -8,6 +8,8 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
+#include <math.h>
+#include <libgnomeui-2.0/libgnomeui/gnome-thumbnail.h>
 
 struct _ShellGlobal {
   GObject parent;
@@ -240,6 +242,57 @@
                                               0, NULL);
 }
 
+static GnomeThumbnailFactory *thumbnail_factory;
+
+/**
+ * shell_get_thumbnail_for_recent_info:
+ *
+ * @recent_info: #GtkRecentInfo for which to return a thumbnail
+ *
+ * Return value: #GdkPixbuf containing a thumbnail for the file described by #GtkRecentInfo 
+ *               if the thumbnail exists or can be generated, %NULL otherwise
+ */
+GdkPixbuf *
+shell_get_thumbnail_for_recent_info(GtkRecentInfo  *recent_info)
+{
+    char *existing_thumbnail;
+    GdkPixbuf *pixbuf = NULL;
+    const gchar *uri = gtk_recent_info_get_uri (recent_info);
+    time_t mtime = gtk_recent_info_get_modified (recent_info);
+    const gchar *mime_type = gtk_recent_info_get_mime_type (recent_info);
+    GError *error = NULL;
+    
+    if (thumbnail_factory == NULL)
+       thumbnail_factory = gnome_thumbnail_factory_new (GNOME_THUMBNAIL_SIZE_NORMAL);
+
+    existing_thumbnail = gnome_thumbnail_factory_lookup (thumbnail_factory, uri, mtime);
+
+    if (existing_thumbnail != NULL)
+      {
+        pixbuf = gdk_pixbuf_new_from_file(existing_thumbnail, &error);
+        if (error != NULL) 
+          {
+            g_warning("Could not generate a pixbuf from file %s: %s", existing_thumbnail, error->message);
+            g_clear_error (&error);
+          }
+      }
+    else if (gnome_thumbnail_factory_can_thumbnail (thumbnail_factory, uri, mime_type, mtime)) 
+      {
+        pixbuf = gnome_thumbnail_factory_generate_thumbnail (thumbnail_factory, uri, mime_type);
+        if (pixbuf == NULL) 
+          {
+            g_warning ("Could not generate thumbnail for %s", uri);
+          }          
+        else 
+          {
+            // we need to save the thumbnail so that we don't need to generate it again in the future
+            gnome_thumbnail_factory_save_thumbnail (thumbnail_factory, pixbuf, uri, mtime);
+          }
+      }
+
+    return pixbuf;   
+}
+
 /**
  * shell_global_get:
  *
@@ -402,4 +455,4 @@
   execvp (arr->pdata[0], (char**)arr->pdata);
   g_warning ("failed to reexec: %s", g_strerror (errno));
   g_ptr_array_free (arr, TRUE);
-}
\ No newline at end of file
+}

Modified: trunk/src/shell-global.h
==============================================================================
--- trunk/src/shell-global.h	(original)
+++ trunk/src/shell-global.h	Fri Jan  9 01:09:35 2009
@@ -5,6 +5,7 @@
 #include <clutter/clutter.h>
 #include <glib-object.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gtk/gtk.h>
 
 G_BEGIN_DECLS
 
@@ -30,9 +31,10 @@
 
 GType            shell_global_get_type            (void) G_GNUC_CONST;
 
-gboolean
-shell_clutter_texture_set_from_pixbuf (ClutterTexture *texture,
-                                       GdkPixbuf      *pixbuf);
+gboolean shell_clutter_texture_set_from_pixbuf (ClutterTexture *texture,
+                                                GdkPixbuf      *pixbuf);
+
+GdkPixbuf *shell_get_thumbnail_for_recent_info(GtkRecentInfo  *recent_info);
 
 ShellGlobal *shell_global_get (void);
 



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