[gnome-documents] all: use the thumbnail frame from Nautilus to frame thumbnails



commit 30bf9b23015b2b4ddacd59c51db1cf4264276c7e
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Tue Aug 30 13:05:11 2011 -0400

    all: use the thumbnail frame from Nautilus to frame thumbnails
    
    Also use symbolic emblems now.

 data/Makefile.am                    |    4 +
 data/gtk-style.css                  |    4 -
 data/thumbnail-frame.png            |  Bin 0 -> 482 bytes
 src/Makefile-lib.am                 |    2 -
 src/documents.js                    |   74 ++++++++++++++++----
 src/iconView.js                     |    4 +-
 src/lib/gd-framed-pixbuf-renderer.c |   85 -----------------------
 src/lib/gd-framed-pixbuf-renderer.h |   75 --------------------
 src/lib/gd-utils.c                  |  128 +++++++++++++++++++++++++++++++++++
 src/lib/gd-utils.h                  |    7 ++
 src/listView.js                     |    4 +-
 src/path.js.in                      |    3 +-
 12 files changed, 204 insertions(+), 186 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index 39500ae..8dcffe9 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -17,6 +17,10 @@ gsettingsschema_in_files = org.gnome.documents.gschema.xml.in
 gsettings_SCHEMAS = $(gsettingsschema_in_files:.xml.in=.xml)
 .PRECIOUS: $(gsettings_SCHEMAS)
 
+iconsdir = $(pkgdatadir)/icons
+dist_icons_DATA = \
+    thumbnail-frame.png
+
 @INTLTOOL_XML_NOMERGE_RULE@
 @GSETTINGS_RULES@
 
diff --git a/data/gtk-style.css b/data/gtk-style.css
index 07fa92d..f04502d 100644
--- a/data/gtk-style.css
+++ b/data/gtk-style.css
@@ -1,9 +1,5 @@
 /* GTK+ custom style here */
 
-.shadowed {
-    icon-shadow: 2 2 shade(@theme_bg_color, 0.80);
-}
-
 #ViewLoadMore {
     border-image-width: 0 2 2 2;
     border-width: 0 1 1 1;
diff --git a/data/thumbnail-frame.png b/data/thumbnail-frame.png
new file mode 100644
index 0000000..674b648
Binary files /dev/null and b/data/thumbnail-frame.png differ
diff --git a/src/Makefile-lib.am b/src/Makefile-lib.am
index 93533d6..cef8f48 100644
--- a/src/Makefile-lib.am
+++ b/src/Makefile-lib.am
@@ -11,14 +11,12 @@ gdprivate_source_h = \
     lib/gd-gdata-goa-authorizer.c \
     lib/gd-gdata-goa-authorizer.h \
     lib/gd-utils.h \
-    lib/gd-framed-pixbuf-renderer.h \
     lib/gd-pdf-loader.h \
     lib/gd-two-lines-renderer.h \
     $(NULL)
 
 gdprivate_source_c = \
     lib/gd-utils.c \
-    lib/gd-framed-pixbuf-renderer.c \
     lib/gd-pdf-loader.c \
     lib/gd-two-lines-renderer.c \
     $(NULL)
diff --git a/src/documents.js b/src/documents.js
index ff446f9..2c11c24 100644
--- a/src/documents.js
+++ b/src/documents.js
@@ -22,6 +22,7 @@
 const GdkPixbuf = imports.gi.GdkPixbuf;
 const Gio = imports.gi.Gio;
 const Gd = imports.gi.Gd;
+const Gdk = imports.gi.Gdk;
 const GData = imports.gi.GData;
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
@@ -32,10 +33,13 @@ const Signals = imports.signals;
 
 const ChangeMonitor = imports.changeMonitor;
 const Global = imports.global;
+const Path = imports.path;
 const Query = imports.query;
 const TrackerUtils = imports.trackerUtils;
 const Utils = imports.utils;
 
+const _THUMBNAIL_FRAME = 3;
+
 function DocCommon(cursor) {
     this._init(cursor);
 }
@@ -56,6 +60,8 @@ DocCommon.prototype = {
         this.favorite = false;
         this.shared = false;
 
+        this._thumbnailed = false;
+
         this.populateFromCursor(cursor);
 
         this._refreshIconId =
@@ -115,16 +121,38 @@ DocCommon.prototype = {
 
     refreshIcon: function() {
         this.pixbuf = Utils.pixbufFromRdfType(this._type);
-        this.checkEmblemsAndUpdateInfo();
+        this.checkEffectsAndUpdateInfo();
+    },
+
+    _createSymbolicEmblem: function(name) {
+        let symbolicName = name + '-symbolic';
+        let icon = new Gio.ThemedIcon({ name: symbolicName });
+
+        let theme = Gtk.IconTheme.get_default();
+        let info = theme.lookup_by_gicon(icon, 64, Gtk.IconLookupFlags.FORCE_SIZE);
+
+        let rgba = new Gdk.RGBA();
+        rgba.parse("#3465a4");
+
+        let pix = null;
+
+        try {
+            pix = info.load_symbolic(rgba, null, null, null, null)[0];
+        } catch (e) {
+            pix = new Gio.ThemedIcon({ name: name });
+        }
+
+        return pix;
     },
 
-    checkEmblemsAndUpdateInfo: function() {
+    checkEffectsAndUpdateInfo: function() {
         let emblemIcons = [];
+        let pixbuf = this.pixbuf;
 
         if (this.favorite)
-            emblemIcons.push(new Gio.ThemedIcon({ name: 'emblem-favorite' }));
+            emblemIcons.push(this._createSymbolicEmblem('emblem-favorite'));
         if (this.shared)
-            emblemIcons.push(new Gio.ThemedIcon({ name: 'emblem-shared' }));
+            emblemIcons.push(this._createSymbolicEmblem('emblem-shared'));
 
         if (emblemIcons.length > 0) {
             let emblemedIcon = new Gio.EmblemedIcon({ gicon: this.pixbuf });
@@ -142,12 +170,21 @@ DocCommon.prototype = {
                                                      Math.max(this.pixbuf.get_width(),
                                                               this.pixbuf.get_height()),
                                                      Gtk.IconLookupFlags.FORCE_SIZE);
-                this.pixbuf = iconInfo.load_icon();
+
+                pixbuf = iconInfo.load_icon();
             } catch (e) {
                 log('Unable to render the emblem: ' + e.toString());
             }
         }
 
+        if (this.thumbnailed)
+            this.pixbuf = Gd.embed_image_in_frame(pixbuf,
+                Global.documentManager.getPixbufFrame(),
+                _THUMBNAIL_FRAME, _THUMBNAIL_FRAME,
+                _THUMBNAIL_FRAME, _THUMBNAIL_FRAME);
+        else
+            this.pixbuf = pixbuf;
+
         this.emit('info-updated');
     },
 
@@ -202,10 +239,10 @@ LocalDocument.prototype = {
 
         let thumbPath = info.get_attribute_byte_string(Gio.FILE_ATTRIBUTE_THUMBNAIL_PATH);
         if (thumbPath) {
-            this.pixbuf =
-                GdkPixbuf.Pixbuf.new_from_file_at_size(thumbPath,
-                                                       Utils.getIconSize(),
-                                                       Utils.getIconSize());
+            this.pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(thumbPath,
+                                                                 Utils.getIconSize(),
+                                                                 Utils.getIconSize());
+            this.thumbnailed = true;
             haveNewIcon = true;
         } else {
             let icon = info.get_icon();
@@ -217,6 +254,7 @@ LocalDocument.prototype = {
                                                      Gtk.IconLookupFlags.GENERIC_FALLBACK);
                 try {
                     this.pixbuf = iconInfo.load_icon();
+                    this.thumbnailed = false;
                     haveNewIcon = true;
                 } catch (e) {
                     log('Unable to load an icon from theme for file at ' + this.uri + ': ' + e.toString());
@@ -229,7 +267,7 @@ LocalDocument.prototype = {
         }
 
         if (haveNewIcon)
-            this.checkEmblemsAndUpdateInfo();
+            this.checkEffectsAndUpdateInfo();
     },
 
     _onQueueThumbnailJob: function(object, res) {
@@ -254,15 +292,15 @@ LocalDocument.prototype = {
             return;
         }
 
-        let thumbPath = info.get_attribute_byte_string(Gio.FILE_ATTRIBUTE_THUMBNAIL_PATH);
-
-        if (thumbPath) {
+        this._thumbPath = info.get_attribute_byte_string(Gio.FILE_ATTRIBUTE_THUMBNAIL_PATH);
+        if (this._thumbPath) {
             this.pixbuf =
-                GdkPixbuf.Pixbuf.new_from_file_at_size(thumbPath,
+                GdkPixbuf.Pixbuf.new_from_file_at_size(this._thumbPath,
                                                        Utils.getIconSize(),
                                                        Utils.getIconSize());
+            this.thumbnailed = true;
 
-            this.checkEmblemsAndUpdateInfo();
+            this.checkEffectsAndUpdateInfo();
         }
     },
 
@@ -401,6 +439,8 @@ function DocumentManager() {
 DocumentManager.prototype = {
     _init: function() {
         this._docs = [];
+
+        this._pixbufFrame = GdkPixbuf.Pixbuf.new_from_file(Path.ICONS_DIR + 'thumbnail-frame.png');
     },
 
     _identifierIsGoogle: function(identifier) {
@@ -408,6 +448,10 @@ DocumentManager.prototype = {
                 (identifier.indexOf('https://docs.google.com') != -1));
     },
 
+    getPixbufFrame: function() {
+        return this._pixbufFrame;
+    },
+
     addDocument: function(cursor) {
         let identifier = cursor.get_string(Query.QueryColumns.IDENTIFIER)[0];
         let doc;
diff --git a/src/iconView.js b/src/iconView.js
index ff18513..5739317 100644
--- a/src/iconView.js
+++ b/src/iconView.js
@@ -75,8 +75,8 @@ IconView.prototype = {
 
     createRenderers: function() {
         let pixbufRenderer =
-            new Gd.FramedPixbufRenderer({ xalign: 0.5,
-                                          yalign: 0.5 });
+            new Gtk.CellRendererPixbuf({ xalign: 0.5,
+                                         yalign: 0.5 });
 
         this.widget.pack_start(pixbufRenderer, false);
         this.widget.add_attribute(pixbufRenderer,
diff --git a/src/lib/gd-utils.c b/src/lib/gd-utils.c
index 0da2141..fcc5322 100644
--- a/src/lib/gd-utils.c
+++ b/src/lib/gd-utils.c
@@ -22,6 +22,7 @@
 #include "gd-utils.h"
 
 #include <gdk-pixbuf/gdk-pixbuf.h>
+#include <string.h>
 
 #define GNOME_DESKTOP_USE_UNSTABLE_API
 #include <libgnome-desktop/gnome-desktop-thumbnail.h>
@@ -254,3 +255,130 @@ gd_gtk_tree_view_set_activate_on_single_click (GtkTreeView *tree_view,
 				   GUINT_TO_POINTER (button_press_id));
 	}
 }
+
+/* utility to stretch a frame to the desired size */
+
+static void
+draw_frame_row (GdkPixbuf *frame_image, int target_width, int source_width, int source_v_position, int dest_v_position, GdkPixbuf *result_pixbuf, int left_offset, int height)
+{
+	int remaining_width, h_offset, slab_width;
+	
+	remaining_width = target_width;
+	h_offset = 0;
+	while (remaining_width > 0) {	
+		slab_width = remaining_width > source_width ? source_width : remaining_width;
+		gdk_pixbuf_copy_area (frame_image, left_offset, source_v_position, slab_width, height, result_pixbuf, left_offset + h_offset, dest_v_position);
+		remaining_width -= slab_width;
+		h_offset += slab_width; 
+	}
+}
+
+/* utility to draw the middle section of the frame in a loop */
+static void
+draw_frame_column (GdkPixbuf *frame_image, int target_height, int source_height, int source_h_position, int dest_h_position, GdkPixbuf *result_pixbuf, int top_offset, int width)
+{
+	int remaining_height, v_offset, slab_height;
+	
+	remaining_height = target_height;
+	v_offset = 0;
+	while (remaining_height > 0) {	
+		slab_height = remaining_height > source_height ? source_height : remaining_height;
+		gdk_pixbuf_copy_area (frame_image, source_h_position, top_offset, width, slab_height, result_pixbuf, dest_h_position, top_offset + v_offset);
+		remaining_height -= slab_height;
+		v_offset += slab_height; 
+	}
+}
+
+static GdkPixbuf *
+gd_stretch_frame_image (GdkPixbuf *frame_image, int left_offset, int top_offset, int right_offset, int bottom_offset,
+			 int dest_width, int dest_height, gboolean fill_flag)
+{
+	GdkPixbuf *result_pixbuf;
+	guchar *pixels_ptr;
+	int frame_width, frame_height;
+	int y, row_stride;
+	int target_width, target_frame_width;
+	int target_height, target_frame_height;
+	
+	frame_width  = gdk_pixbuf_get_width  (frame_image);
+	frame_height = gdk_pixbuf_get_height (frame_image );
+	
+	if (fill_flag) {
+		result_pixbuf = gdk_pixbuf_scale_simple (frame_image, dest_width, dest_height, GDK_INTERP_NEAREST);
+	} else {
+		result_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, dest_width, dest_height);
+	}
+	row_stride = gdk_pixbuf_get_rowstride (result_pixbuf);
+	pixels_ptr = gdk_pixbuf_get_pixels (result_pixbuf);
+	
+	/* clear the new pixbuf */
+	if (!fill_flag) {
+		for (y = 0; y < dest_height; y++) {
+			memset (pixels_ptr, 255, row_stride);
+			pixels_ptr += row_stride; 
+		}
+	}
+	
+	target_width  = dest_width - left_offset - right_offset;
+	target_frame_width = frame_width - left_offset - right_offset;
+	
+	target_height  = dest_height - top_offset - bottom_offset;
+	target_frame_height = frame_height - top_offset - bottom_offset;
+	
+	/* draw the left top corner  and top row */
+	gdk_pixbuf_copy_area (frame_image, 0, 0, left_offset, top_offset, result_pixbuf, 0,  0);
+	draw_frame_row (frame_image, target_width, target_frame_width, 0, 0, result_pixbuf, left_offset, top_offset);
+	
+	/* draw the right top corner and left column */
+	gdk_pixbuf_copy_area (frame_image, frame_width - right_offset, 0, right_offset, top_offset, result_pixbuf, dest_width - right_offset,  0);
+	draw_frame_column (frame_image, target_height, target_frame_height, 0, 0, result_pixbuf, top_offset, left_offset);
+
+	/* draw the bottom right corner and bottom row */
+	gdk_pixbuf_copy_area (frame_image, frame_width - right_offset, frame_height - bottom_offset, right_offset, bottom_offset, result_pixbuf, dest_width - right_offset,  dest_height - bottom_offset);
+	draw_frame_row (frame_image, target_width, target_frame_width, frame_height - bottom_offset, dest_height - bottom_offset, result_pixbuf, left_offset, bottom_offset);
+		
+	/* draw the bottom left corner and the right column */
+	gdk_pixbuf_copy_area (frame_image, 0, frame_height - bottom_offset, left_offset, bottom_offset, result_pixbuf, 0,  dest_height - bottom_offset);
+	draw_frame_column (frame_image, target_height, target_frame_height, frame_width - right_offset, dest_width - right_offset, result_pixbuf, top_offset, right_offset);
+	
+	return result_pixbuf;
+}
+
+/**
+ * gd_embed_image_in_frame: 
+ * @source_image:
+ * @frame_image:
+ * @left_offset:
+ * @top_offset:
+ * @right_offset:
+ * @bottom_offset:
+ *
+ * Returns: (transfer full):
+ */
+/* draw an arbitrary frame around an image, with the result passed back in a newly allocated pixbuf */
+GdkPixbuf *
+gd_embed_image_in_frame (GdkPixbuf *source_image,
+                         GdkPixbuf *frame_image,
+                         int left_offset, 
+                         int top_offset, 
+                         int right_offset, 
+                         int bottom_offset)
+{
+	GdkPixbuf *result_pixbuf;
+	int source_width, source_height;
+	int dest_width, dest_height;
+	
+	source_width  = gdk_pixbuf_get_width  (source_image);
+	source_height = gdk_pixbuf_get_height (source_image);
+
+	dest_width  = source_width  + left_offset + right_offset;
+	dest_height = source_height + top_offset  + bottom_offset;
+	
+	result_pixbuf = gd_stretch_frame_image (frame_image, left_offset, top_offset, right_offset, bottom_offset, 
+                                                dest_width, dest_height, FALSE);
+		
+	/* Finally, copy the source image into the framed area */
+	gdk_pixbuf_copy_area (source_image, 0, 0, source_width, source_height, result_pixbuf, left_offset,  top_offset);
+
+	return result_pixbuf;
+}
diff --git a/src/lib/gd-utils.h b/src/lib/gd-utils.h
index eab4d6e..16edb47 100644
--- a/src/lib/gd-utils.h
+++ b/src/lib/gd-utils.h
@@ -56,5 +56,12 @@ gboolean gd_queue_thumbnail_job_for_file_finish (GAsyncResult *res);
 void gd_gtk_tree_view_set_activate_on_single_click (GtkTreeView *tree_view,
                                                     gboolean should_activate);
 
+GdkPixbuf * gd_embed_image_in_frame (GdkPixbuf *source_image,
+                                     GdkPixbuf *frame_image,
+                                     int left_offset,
+                                     int top_offset,
+                                     int right_offset,
+                                     int bottom_offset);
+
 #endif /* __GD_UTILS_H__ */
                                   
diff --git a/src/listView.js b/src/listView.js
index e4e7af6..741c6fe 100644
--- a/src/listView.js
+++ b/src/listView.js
@@ -76,8 +76,8 @@ ListView.prototype = {
         this.widget.append_column(col);
 
         let pixbufRenderer =
-            new Gd.FramedPixbufRenderer({ xalign: 0.5,
-                                          yalign: 0.5 });
+            new Gtk.CellRendererPixbuf({ xalign: 0.5,
+                                         yalign: 0.5 });
 
         col.pack_start(pixbufRenderer, false);
         col.add_attribute(pixbufRenderer,
diff --git a/src/path.js.in b/src/path.js.in
index 1928af4..9a43427 100644
--- a/src/path.js.in
+++ b/src/path.js.in
@@ -1,2 +1,3 @@
 let LOCALE_DIR = "@localedir@";
-let STYLE_DIR = "@pkgdatadir@/style/";
\ No newline at end of file
+let STYLE_DIR = "@pkgdatadir@/style/";
+let ICONS_DIR = "@pkgdatadir@/icons/";



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