[gnome-photos] base-item: Implement check_effects_and_update_info
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-photos] base-item: Implement check_effects_and_update_info
- Date: Sun, 15 Jul 2012 20:15:23 +0000 (UTC)
commit fbcd774fb6d27ebfdc9d64d4ca5029cdcedcc1be
Author: Debarshi Ray <debarshir gnome org>
Date: Sun Jul 15 18:34:02 2012 +0200
base-item: Implement check_effects_and_update_info
Added cairo to the list of build requirements.
configure.ac | 1 +
data/Makefile.am | 6 ++
data/thumbnail-frame.png | Bin 0 -> 832 bytes
src/Makefile.am | 3 +
src/photos-base-item.c | 101 ++++++++++++++++++++++++++++
src/photos-utils.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++
src/photos-utils.h | 10 +++
7 files changed, 283 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index a8a4aaf..72b7c14 100644
--- a/configure.ac
+++ b/configure.ac
@@ -41,6 +41,7 @@ AM_GLIB_GNU_GETTEXT
LT_INIT
+PKG_CHECK_MODULES(CAIRO, [cairo])
PKG_CHECK_MODULES(CLUTTER, [clutter-1.0])
PKG_CHECK_MODULES(CLUTTER_GTK, [clutter-gtk-1.0])
PKG_CHECK_MODULES(GDK_PIXBUF, [gdk-pixbuf-2.0])
diff --git a/data/Makefile.am b/data/Makefile.am
index 4a77272..40a41ff 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -8,6 +8,12 @@ desktop_DATA = $(desktop_in_files:.desktop.in.in=.desktop)
gsettings_in_files = org.gnome.photos.gschema.xml.in
gsettings_SCHEMAS = $(gsettings_in_files:.xml.in=.xml)
.PRECIOUS: $(gsettings_SCHEMAS)
+
+iconsdir = $(pkgdatadir)/icons
+dist_icons_DATA = \
+ thumbnail-frame.png \
+ $(NULL)
+
@INTLTOOL_XML_NOMERGE_RULE@
@GSETTINGS_RULES@
diff --git a/data/thumbnail-frame.png b/data/thumbnail-frame.png
new file mode 100644
index 0000000..ba5d721
Binary files /dev/null and b/data/thumbnail-frame.png differ
diff --git a/src/Makefile.am b/src/Makefile.am
index 6dcd2e9..3b57004 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -97,7 +97,9 @@ EXTRA_DIST = \
$(null)
AM_CPPFLAGS = \
+ -DPACKAGE_ICONS_DIR=\""${pkgdatadir}/icons"\" \
-DPACKAGE_LOCALE_DIR=\""${datadir}/locale"\" \
+ $(CAIRO_CFLAGS) \
$(CLUTTER_CFLAGS) \
$(CLUTTER_GTK_CFLAGS) \
$(GDK_PIXBUF_CFLAGS) \
@@ -112,6 +114,7 @@ AM_CPPFLAGS = \
gnome_photos_LDFLAGS =
gnome_photos_LDADD = \
+ $(CAIRO_LIBS) \
$(CLUTTER_LIBS) \
$(CLUTTER_GTK_LIBS) \
$(GDK_PIXBUF_LIBS) \
diff --git a/src/photos-base-item.c b/src/photos-base-item.c
index 9da32d7..fe7e3cc 100644
--- a/src/photos-base-item.c
+++ b/src/photos-base-item.c
@@ -33,6 +33,7 @@
struct _PhotosBaseItemPrivate
{
GdkPixbuf *icon;
+ GdkPixbuf *pristine_icon;
gboolean failed_thumbnailing;
gboolean favorite;
gboolean thumbnailed;
@@ -61,9 +62,108 @@ enum
G_DEFINE_TYPE (PhotosBaseItem, photos_base_item, G_TYPE_OBJECT);
+static GIcon *
+photos_base_item_create_symbolic_emblem (const gchar *name)
+{
+ GIcon *pix;
+ gint size;
+
+ size = photos_utils_get_icon_size ();
+ pix = photos_utils_create_symbolic_icon (name, size);
+ if (pix == NULL)
+ pix = g_themed_icon_new (name);
+
+ return pix;
+}
+
+
static void
photos_base_item_check_effects_and_update_info (PhotosBaseItem *self)
{
+ PhotosBaseItemPrivate *priv = self->priv;
+ GIcon *pix;
+ GList *emblem_icons = NULL;
+ GdkPixbuf *icon;
+
+ icon = g_object_ref (priv->icon);
+ priv->pristine_icon = g_object_ref (icon);
+
+ if (priv->favorite)
+ {
+ pix = photos_base_item_create_symbolic_emblem ("emblem-favorite");
+ emblem_icons = g_list_prepend (emblem_icons, pix);
+ }
+
+ if (g_list_length (emblem_icons) > 0)
+ {
+ GIcon *emblemed_icon;
+ GList *l;
+ GtkIconInfo *icon_info;
+ GtkIconTheme *theme;
+ gint height;
+ gint size;
+ gint width;
+
+ emblem_icons = g_list_reverse (emblem_icons);
+ emblemed_icon = g_emblemed_icon_new (G_ICON (priv->icon), NULL);
+ for (l = g_list_first (emblem_icons); l != NULL; l = g_list_next (l))
+ {
+ GEmblem *emblem;
+ GIcon *emblem_icon = G_ICON (l->data);
+
+ emblem = g_emblem_new (emblem_icon);
+ g_emblemed_icon_add_emblem (G_EMBLEMED_ICON (emblemed_icon), emblem);
+ g_object_unref (emblem);
+ }
+
+ theme = gtk_icon_theme_get_default ();
+
+ width = gdk_pixbuf_get_width (priv->icon);
+ height = gdk_pixbuf_get_height (priv->icon);
+ size = (width > height) ? width : height;
+
+ icon_info = gtk_icon_theme_lookup_by_gicon (theme, emblemed_icon, size, GTK_ICON_LOOKUP_FORCE_SIZE);
+ g_object_unref (theme);
+
+ if (icon_info != NULL)
+ {
+ GError *error = NULL;
+ GdkPixbuf *tmp;
+
+ tmp = gtk_icon_info_load_icon (icon_info, &error);
+ if (error != NULL)
+ {
+ g_warning ("Unable to render the emblem: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ g_object_unref (icon);
+ icon = tmp;
+ }
+
+ gtk_icon_info_free (icon_info);
+ }
+ }
+
+ g_object_unref (priv->icon);
+
+ if (priv->thumbnailed)
+ {
+ GtkBorder *slice;
+
+ slice = photos_utils_get_thumbnail_frame_border ();
+ priv->icon = photos_utils_embed_image_in_frame (icon,
+ PACKAGE_ICONS_DIR "/thumbnail-frame.png",
+ slice,
+ slice);
+ gtk_border_free (slice);
+ }
+ else
+ priv->icon = g_object_ref (icon);
+
+ g_object_unref (icon);
+ g_list_free_full (emblem_icons, g_object_unref);
}
@@ -351,6 +451,7 @@ photos_base_item_dispose (GObject *object)
PhotosBaseItemPrivate *priv = self->priv;
g_clear_object (&priv->icon);
+ g_clear_object (&priv->pristine_icon);
G_OBJECT_CLASS (photos_base_item_parent_class)->dispose (object);
}
diff --git a/src/photos-utils.c b/src/photos-utils.c
index e57ec6f..5a1cb55 100644
--- a/src/photos-utils.c
+++ b/src/photos-utils.c
@@ -26,6 +26,7 @@
#include <string.h>
+#include <cairo.h>
#include <glib.h>
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
@@ -41,6 +42,74 @@ photos_utils_alpha_gtk_widget (GtkWidget *widget)
}
+GIcon *
+photos_utils_create_symbolic_icon (const gchar *name, gint base_size)
+{
+ GIcon *icon;
+ GIcon *ret_val = NULL;
+ GdkPixbuf *pixbuf;
+ GtkIconInfo *info;
+ GtkIconTheme *theme;
+ GtkStyleContext *style;
+ GtkWidgetPath *path;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ gchar *symbolic_name;
+ const gint bg_min_size = 20;
+ const gint emblem_min_size = 8;
+ gint bg_size;
+ gint emblem_size;
+ gint total_size;
+
+ total_size = base_size / 2;
+ bg_size = MAX (total_size / 2, bg_min_size);
+ emblem_size = MAX (bg_size - 8, emblem_min_size);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, total_size, total_size);
+ cr = cairo_create (surface);
+
+ style = gtk_style_context_new ();
+
+ path = gtk_widget_path_new ();
+ gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
+ gtk_style_context_set_path (style, path);
+ gtk_widget_path_unref (path);
+
+ gtk_style_context_add_class (style, "documents-icon-bg");
+
+ gtk_render_background (style, cr, (total_size - bg_size) / 2, (total_size - bg_size) / 2, bg_size, bg_size);
+
+ symbolic_name = g_strconcat (name, "-symbolic", NULL);
+ icon = g_themed_icon_new_with_default_fallbacks (symbolic_name);
+ g_free (symbolic_name);
+
+ theme = gtk_icon_theme_get_default();
+ info = gtk_icon_theme_lookup_by_gicon (theme, icon, emblem_size, GTK_ICON_LOOKUP_FORCE_SIZE);
+ g_object_unref (icon);
+
+ if (info == NULL)
+ goto out;
+
+ pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL);
+ gtk_icon_info_free (info);
+
+ if (pixbuf == NULL)
+ goto out;
+
+ gtk_render_icon (style, cr, pixbuf, (total_size - emblem_size) / 2, (total_size - emblem_size) / 2);
+ g_object_unref (pixbuf);
+
+ ret_val = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, total_size, total_size));
+
+ out:
+ g_object_unref (style);
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+
+ return ret_val;
+}
+
+
static gboolean
photos_utils_create_thumbnail (GIOSchedulerJob *job, GCancellable *cancellable, gpointer user_data)
{
@@ -91,6 +160,84 @@ photos_utils_create_thumbnail (GIOSchedulerJob *job, GCancellable *cancellable,
}
+GdkPixbuf *
+photos_utils_embed_image_in_frame (GdkPixbuf *source_image,
+ const gchar *frame_image_path,
+ GtkBorder *slice_width,
+ GtkBorder *border_width)
+{
+ GError *error = NULL;
+ GdkPixbuf *ret_val;
+ GtkCssProvider *provider;
+ GtkStyleContext *context;
+ GtkWidgetPath *path;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ gchar *css_str;
+ int dest_height;
+ int dest_width;
+ int source_height;
+ int source_width;
+
+ source_width = gdk_pixbuf_get_width (source_image);
+ source_height = gdk_pixbuf_get_height (source_image);
+
+ dest_width = source_width + border_width->left + border_width->right;
+ dest_height = source_height + border_width->top + border_width->bottom;
+
+ css_str = g_strdup_printf (".embedded-image { border-image: url(\"%s\") %d %d %d %d / %dpx %dpx %dpx %dpx }",
+ frame_image_path,
+ slice_width->top, slice_width->right, slice_width->bottom, slice_width->left,
+ border_width->top, border_width->right, border_width->bottom, border_width->left);
+ provider = gtk_css_provider_new ();
+ gtk_css_provider_load_from_data (provider, css_str, -1, &error);
+
+ if (error != NULL)
+ {
+ g_warning ("Unable to create the thumbnail frame image: %s", error->message);
+ g_error_free (error);
+ g_free (css_str);
+
+ return g_object_ref (source_image);
+ }
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, dest_width, dest_height);
+ cr = cairo_create (surface);
+
+ context = gtk_style_context_new ();
+ path = gtk_widget_path_new ();
+ gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
+
+ gtk_style_context_set_path (context, path);
+ gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider), 600);
+
+ gtk_style_context_save (context);
+ gtk_style_context_add_class (context, "embedded-image");
+
+ gtk_render_frame (context, cr,
+ 0, 0,
+ dest_width, dest_height);
+
+ gtk_style_context_restore (context);
+
+ gtk_render_icon (context, cr,
+ source_image,
+ border_width->left, border_width->top);
+
+ ret_val = gdk_pixbuf_get_from_surface (surface, 0, 0, dest_width, dest_height);
+
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+
+ gtk_widget_path_unref (path);
+ g_object_unref (provider);
+ g_object_unref (context);
+ g_free (css_str);
+
+ return ret_val;
+}
+
+
static gchar *
photos_utils_filename_get_extension_offset (const gchar *filename)
{
@@ -144,6 +291,21 @@ photos_utils_get_icon_size (void)
}
+GtkBorder *
+photos_utils_get_thumbnail_frame_border (void)
+{
+ GtkBorder *slice;
+
+ slice = gtk_border_new ();
+ slice->top = 3;
+ slice->right = 3;
+ slice->bottom = 6;
+ slice->left = 4;
+
+ return slice;
+}
+
+
GList *
photos_utils_get_urns_from_paths (GList *paths, GtkTreeModel *model)
{
diff --git a/src/photos-utils.h b/src/photos-utils.h
index a13a479..35e021f 100644
--- a/src/photos-utils.h
+++ b/src/photos-utils.h
@@ -24,6 +24,7 @@
#ifndef PHOTOS_UTILS_H
#define PHOTOS_UTILS_H
+#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gio/gio.h>
#include <glib.h>
#include <gtk/gtk.h>
@@ -32,10 +33,19 @@ G_BEGIN_DECLS
void photos_utils_alpha_gtk_widget (GtkWidget *widget);
+GIcon *photos_utils_create_symbolic_icon (const gchar *name, gint base_size);
+
+GdkPixbuf *photos_utils_embed_image_in_frame (GdkPixbuf *source_image,
+ const gchar *frame_image_path,
+ GtkBorder *slice_width,
+ GtkBorder *border_width);
+
gchar *photos_utils_filename_strip_extension (const gchar *filename_with_extension);
gint photos_utils_get_icon_size (void);
+GtkBorder *photos_utils_get_thumbnail_frame_border (void);
+
GList *photos_utils_get_urns_from_paths (GList *paths, GtkTreeModel *model);
void photos_utils_queue_thumbnail_job_for_file_async (GFile *file,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]