Re: GtkImageView for EOG



On 8/16/07, BJörn Lindqvist <bjourne gmail com> wrote:
> > > So, if you like, I can produce a proof of concept patch that
> > > demonstrates how EOG performs with GtkImageView.
> >
> > I personally think it's something worth considering. I'd like to see a
> > proof of concept patch.
>
> Great, I'll post one asap then.

I guess I shouldn't have written "asap" here since it took a month. :)
Have been busy with other things. Anyways, here it is:

This patch adds support for GtkImageView in EOG. It replaces the
EogScrollView widget with GtkImageScrollWin and GtkAnimView which
provides support for GIF animations. It is a "dirty patch" with
commented out code and printf debug messages left in so that if
something goes wrong it is easier to trace. It should apply cleanly to
EOG svn head.

The biggest changes are in the eog-image.c file because it assumes
that the displayed object is a GdkPixbuf. But if it is a
GdkPixbufAnimation, certain operations such as rotations cannot be
carried out. Or they could, but it would require even more changes to
EOG making the patch even bigger.

eog-window.c also had to be changed some, mostly renamings like
"eog_scroll_view_zoom_in" to "gtk_image_view_zoom_in".

The three lost features are AFAICT, EOG:s delayed filtering,
incremental zoom and fullscreen upscaling. If you zoom in on an image,
EOG first displays the image using nearest filtering and triggers a
timer which does the bilinear filtering when it times out.
GtkImageView also uses much larger zoom increments that EogScrollView.
Zooming goes from 100% to 150% to 200% while in EogScrollView you have
to zoom in 15 times to increase the zoom by the same amount.

Personally, I think that GtkImageView does it better and hope that
neither of those issues are showstoppers.

The patch have been tested quite a bit, and I've found no problems
with it yet. Someone more familiar with EOG could probably find more
issues. The patch is in the attachment and also available on

http://trac.bjourne.webfactional.com/browser/patches/use-gtkimageview-in-eog2.patch

raw format here:

http://trac.bjourne.webfactional.com/browser/patches/use-gtkimageview-in-eog2.patch?format=txt

--
mvh Björn
This patch adds support for GtkImageView in EOG. The EogScrollView
widget is replaced with a GtkAnimView. This way, EOG becomes capable
of showing GIF animations.

Patch applies cleanly against EOG r3989.

Copyright (C) 2007 Björn Lindqvist <bjourne gmail com>

Index: src/eog-image.h
===================================================================
--- src/eog-image.h	(revision 3989)
+++ src/eog-image.h	(arbetskopia)
@@ -148,6 +148,8 @@
 
 GdkPixbuf*        eog_image_get_pixbuf               (EogImage   *img);
 
+GdkPixbufAnimation *eog_image_get_anim               (EogImage   *img);
+
 GdkPixbuf*        eog_image_get_thumbnail            (EogImage   *img);
 
 void              eog_image_get_size                 (EogImage   *img, 
Index: src/eog-image-private.h
===================================================================
--- src/eog-image-private.h	(revision 3989)
+++ src/eog-image-private.h	(arbetskopia)
@@ -1,5 +1,7 @@
-/* Eye Of Gnome - Image Private Data 
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*-
  *
+ * Eye Of Gnome - Image Private Data 
+ *
  * Copyright (C) 2007 The Free Software Foundation
  *
  * Author: Lucas Rocha <lucasr gnome org>
@@ -31,7 +33,8 @@
 
 	EogImageStatus    status;
 
-	GdkPixbuf        *image;
+	GdkPixbufAnimation *anim;
+    
 	GdkPixbuf        *thumbnail;
 	
 	gint              width;
Index: src/eog-image-jpeg.c
===================================================================
--- src/eog-image-jpeg.c	(revision 3989)
+++ src/eog-image-jpeg.c	(arbetskopia)
@@ -329,10 +329,10 @@
 	struct error_handler_data jerr;
 	
 	g_return_val_if_fail (EOG_IS_IMAGE (image), FALSE);
-	g_return_val_if_fail (EOG_IMAGE (image)->priv->image != NULL, FALSE);
+	g_return_val_if_fail (EOG_IMAGE (image)->priv->anim != NULL, FALSE);
 	
 	priv = image->priv;
-	pixbuf = priv->image;
+        pixbuf = gdk_pixbuf_animation_get_static_image (priv->anim);
 	
 	outfile = fopen (file, "wb");
 	if (outfile == NULL) {
Index: src/eog-window.c
===================================================================
--- src/eog-window.c	(revision 3989)
+++ src/eog-window.c	(arbetskopia)
@@ -1,5 +1,7 @@
-/* Eye Of Gnome - Main Window 
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*-
  *
+ * Eye Of Gnome - Main Window 
+ *
  * Copyright (C) 2000-2006 The Free Software Foundation
  *
  * Author: Lucas Rocha <lucasr gnome org>
@@ -32,7 +34,6 @@
 #include <math.h>
 
 #include "eog-window.h"
-#include "eog-scroll-view.h"
 #include "eog-debug.h"
 #include "eog-file-chooser.h"
 #include "eog-thumb-view.h"
@@ -62,6 +63,10 @@
 #include <glib-object.h>
 #include <glib/gi18n.h>
 #include <gdk/gdkkeysyms.h>
+#include <gtkimageview/gtkanimview.h>
+#include <gtkimageview/gtkimageview.h>
+#include <gtkimageview/gtkimagescrollwin.h>
+#include <gtkimageview/gtkzooms.h>
 #ifdef GDK_WINDOWING_X11
 #include <gdk/gdkx.h>
 #endif
@@ -135,6 +140,7 @@
         GtkWidget           *box;
         GtkWidget           *layout;
         GtkWidget           *cbox;
+        GtkWidget           *scroll_win;
         GtkWidget           *view;
         GtkWidget           *sidebar;
         GtkWidget           *thumbview;
@@ -220,17 +226,21 @@
 	eog_debug (DEBUG_PREFERENCES);
 
 	g_return_if_fail (EOG_IS_WINDOW (user_data));
-
+        
 	priv = EOG_WINDOW (user_data)->priv;
 
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view));
+	g_return_if_fail (GTK_IMAGE_VIEW (priv->view));
 
 	if (entry->value != NULL && entry->value->type == GCONF_VALUE_BOOL) {
 		interpolate = gconf_value_get_bool (entry->value);
 	}
 
-	eog_scroll_view_set_antialiasing (EOG_SCROLL_VIEW (priv->view), 
-					  interpolate);
+	GdkInterpType interp = GDK_INTERP_NEAREST;
+	if (interpolate) {
+		interp = GDK_INTERP_BILINEAR;
+	}
+	gtk_image_view_set_interpolation (GTK_IMAGE_VIEW (priv->view),
+					  interp);
 }
 
 static void
@@ -239,23 +249,7 @@
 				         GConfEntry  *entry,
 				         gpointer    user_data)
 {
-	EogWindowPrivate *priv;
-	gboolean scroll_wheel_zoom = FALSE;
-
-	eog_debug (DEBUG_PREFERENCES);
-
-	g_return_if_fail (EOG_IS_WINDOW (user_data));
-
-	priv = EOG_WINDOW (user_data)->priv;
-
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view));
-
-	if (entry->value != NULL && entry->value->type == GCONF_VALUE_BOOL) {
-		scroll_wheel_zoom = gconf_value_get_bool (entry->value);
-	}
-
-	eog_scroll_view_set_scroll_wheel_zoom (EOG_SCROLL_VIEW (priv->view), 
-					       scroll_wheel_zoom);
+	printf ("THIS SETTING IS NOT SUPPORTED AT ALL!\n");
 }
 
 static void
@@ -264,23 +258,7 @@
 				       GConfEntry  *entry,
 				       gpointer    user_data)
 {
-	EogWindowPrivate *priv;
-	gdouble multiplier = 0.05;
-
-	eog_debug (DEBUG_PREFERENCES);
-
-	g_return_if_fail (EOG_IS_WINDOW (user_data));
-
-	priv = EOG_WINDOW (user_data)->priv;
-
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view));
-
-	if (entry->value != NULL && entry->value->type == GCONF_VALUE_FLOAT) {
-		multiplier = gconf_value_get_float (entry->value);
-	}
-
-	eog_scroll_view_set_zoom_multiplier (EOG_SCROLL_VIEW (priv->view), 
-					     multiplier);
+	printf ("THIS SETTING IS NOT SUPPORTED AT ALL!\n");
 }
 
 static void
@@ -298,7 +276,7 @@
 
 	priv = EOG_WINDOW (user_data)->priv;
 
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view));
+	g_return_if_fail (GTK_IMAGE_VIEW (priv->view));
 
 	if (entry->value != NULL && entry->value->type == GCONF_VALUE_STRING) {
 		value = gconf_value_get_string (entry->value);
@@ -313,16 +291,21 @@
 		color_str = gconf_client_get_string (priv->client,
 						     EOG_CONF_VIEW_TRANS_COLOR, NULL);
 		if (gdk_color_parse (color_str, &color)) {
-			eog_scroll_view_set_transparency (EOG_SCROLL_VIEW (priv->view),
-							  EOG_TRANSP_COLOR, &color);
+			printf ("FIXME: Color conversion needed.\n");
+			gtk_image_view_set_transp (GTK_IMAGE_VIEW (priv->view),
+						   GTK_IMAGE_TRANSP_COLOR,
+						   (0xff000000
+						    | ((color.red >> 8) << 16)
+						    | ((color.green >> 8) << 8)
+						    | (color.blue >> 8)));
 		}
 		g_free (color_str);
 	} else if (g_ascii_strcasecmp (value, "CHECK_PATTERN") == 0) {
-		eog_scroll_view_set_transparency (EOG_SCROLL_VIEW (priv->view),
-						  EOG_TRANSP_CHECKED, 0);
+		gtk_image_view_set_transp (GTK_IMAGE_VIEW (priv->view),
+					   GTK_IMAGE_TRANSP_GRID, 0);
 	} else {
-		eog_scroll_view_set_transparency (EOG_SCROLL_VIEW (priv->view),
-						  EOG_TRANSP_BACKGROUND, 0);
+		gtk_image_view_set_transp (GTK_IMAGE_VIEW (priv->view),
+					   GTK_IMAGE_TRANSP_BACKGROUND, 0);
 	}
 }
 
@@ -343,7 +326,7 @@
 
 	priv = EOG_WINDOW (user_data)->priv;
 
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view));
+	g_return_if_fail (GTK_IS_IMAGE_VIEW (priv->view));
 
 	value = gconf_client_get_string (priv->client, 
 					 EOG_CONF_VIEW_TRANSPARENCY, 
@@ -358,8 +341,13 @@
 		color_str = gconf_value_get_string (entry->value);
 
 		if (gdk_color_parse (color_str, &color)) {
-			eog_scroll_view_set_transparency (EOG_SCROLL_VIEW (priv->view),
-							  EOG_TRANSP_COLOR, &color);
+			printf ("FIXME: Not sure about this\n");
+			gtk_image_view_set_transp (GTK_IMAGE_VIEW (priv->view),
+						   GTK_IMAGE_TRANSP_COLOR,
+						   (0xff000000
+						    | ((color.red >> 8) << 16)
+						    | ((color.green >> 8) << 8)
+						    | (color.blue >> 8)));
 		}
 	}
 	g_free (value);
@@ -380,7 +368,7 @@
 
 	priv = EOG_WINDOW (user_data)->priv;
 
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view));
+	g_return_if_fail (GTK_IS_IMAGE_VIEW (priv->view));
 
 	if (entry->value != NULL && entry->value->type == GCONF_VALUE_BOOL) {
 		show_buttons = gconf_value_get_bool (entry->value);
@@ -586,6 +574,8 @@
 	EogWindowPrivate *priv;
 	char *str = NULL;
 
+	printf ("update_status_bar\n");
+
 	g_return_if_fail (EOG_IS_WINDOW (window));
 	
 	eog_debug (DEBUG_WINDOW);
@@ -597,7 +587,7 @@
 		int zoom, width, height;
 		GnomeVFSFileSize bytes = 0;
 
-		zoom = floor (100 * eog_scroll_view_get_zoom (EOG_SCROLL_VIEW (priv->view)) + 0.5);
+		zoom = floor (100 * gtk_image_view_get_zoom (GTK_IMAGE_VIEW (priv->view)) + 0.5);
 
 		eog_image_get_size (priv->image, &width, &height);
 
@@ -605,7 +595,7 @@
 		
 		if ((width > 0) && (height > 0)) {
 			char *size_string;
-
+			
 			size_string = gnome_vfs_format_file_size_for_display (bytes);
 
 			/* [image width] x [image height] pixels  [bytes]    [zoom in percent] */
@@ -629,6 +619,7 @@
 			    priv->image_info_message_cid, str ? str : "");
 
 	g_free (str);
+	printf ("update_status_bar:done\n");
 }
 
 static void
@@ -759,7 +750,7 @@
 					priv->mode != EOG_WINDOW_MODE_SLIDESHOW;
 
 		gtk_widget_show (priv->layout);
-		gtk_widget_show_all (priv->view->parent);
+		gtk_widget_show_all (priv->scroll_win->parent);
 
 		if (show_image_collection) 
 			gtk_widget_show (priv->nav);
@@ -917,6 +908,8 @@
 	EogWindowPrivate *priv;
 	GnomeVFSURI *uri;
 
+	printf ("eog_window_display_image\n");
+
 	g_return_if_fail (EOG_IS_WINDOW (window));
 	g_return_if_fail (EOG_IS_IMAGE (image));
 
@@ -935,7 +928,8 @@
 		image_thumb_changed_cb (image, window);
 	}
 
-	eog_scroll_view_set_image (EOG_SCROLL_VIEW (priv->view), image);
+	gtk_anim_view_set_anim (GTK_ANIM_VIEW (priv->view),
+				eog_image_get_anim (image));
 
 	gtk_window_set_title (GTK_WINDOW (window), eog_image_get_caption (image));
 
@@ -1247,6 +1241,8 @@
 	EogWindow *window;
 	EogWindowPrivate *priv;
 
+	printf ("eog_job_load_cb:start\n");
+
         g_return_if_fail (EOG_IS_WINDOW (data));
 	
 	eog_debug (DEBUG_WINDOW);
@@ -1303,7 +1299,7 @@
 
 		update_status_bar (window);
 
-		eog_scroll_view_set_image (EOG_SCROLL_VIEW (priv->view), NULL);
+		gtk_anim_view_set_anim (GTK_ANIM_VIEW (priv->view), NULL);
 
         	if (window->priv->status == EOG_WINDOW_STATUS_INIT) {
 			update_action_groups_state (window);
@@ -1326,6 +1322,7 @@
 	}
 
 	g_object_unref (job->image);
+	printf ("eog_job_load_cb:end\n");
 }
 
 static void
@@ -1349,12 +1346,17 @@
 eog_job_transform_cb (EogJobTransform *job, gpointer data)
 {
 	EogWindow *window;
+
+	printf ("eog_job_transform_cb\n");
 	
         g_return_if_fail (EOG_IS_WINDOW (data));
 	
 	window = EOG_WINDOW (data);
 
 	eog_window_clear_transform_job (window);
+
+	gtk_anim_view_set_anim (GTK_ANIM_VIEW (window->priv->view),
+				eog_image_get_anim (window->priv->image));
 }
 
 static void 
@@ -1449,14 +1451,15 @@
 }
 	
 static void
-view_zoom_changed_cb (GtkWidget *widget, double zoom, gpointer user_data)
+view_zoom_changed_cb (GtkWidget *widget, gpointer user_data)
 {
 	EogWindow *window;
 	GtkAction *action_zoom_in;
 	GtkAction *action_zoom_out;
+	gdouble zoom;
 
 	g_return_if_fail (EOG_IS_WINDOW (user_data));
-	
+
 	window = EOG_WINDOW (user_data);
 
 	update_status_bar (window);
@@ -1469,10 +1472,11 @@
 		gtk_action_group_get_action (window->priv->actions_image, 
 					     "ViewZoomOut");
 
+	zoom = gtk_image_view_get_zoom (GTK_IMAGE_VIEW (window->priv->view));
 	gtk_action_set_sensitive (action_zoom_in,
-			!eog_scroll_view_get_zoom_is_max (EOG_SCROLL_VIEW (window->priv->view)));
+				  zoom < gtk_zooms_get_max_zoom ());
 	gtk_action_set_sensitive (action_zoom_out,
-			!eog_scroll_view_get_zoom_is_min (EOG_SCROLL_VIEW (window->priv->view)));
+				  zoom > gtk_zooms_get_min_zoom ());
 }
 
 static void
@@ -1604,7 +1608,8 @@
 
 	gtk_widget_hide_all (window->priv->fullscreen_popup);
 
-	eog_scroll_view_hide_cursor (EOG_SCROLL_VIEW (window->priv->view));
+	gtk_image_view_set_show_cursor (GTK_IMAGE_VIEW (window->priv->view),
+					FALSE);
 
 	fullscreen_clear_timeout (window);
 
@@ -1673,7 +1678,8 @@
 
 	window->priv->fullscreen_timeout_source = source;
 
-	eog_scroll_view_show_cursor (EOG_SCROLL_VIEW (window->priv->view));
+	gtk_image_view_set_show_cursor (GTK_IMAGE_VIEW (window->priv->view),
+					TRUE);
 }
 
 static void
@@ -1900,7 +1906,6 @@
 {
 	EogWindowPrivate *priv;
 	GtkWidget *menubar;
-	gboolean upscale;
 
 	eog_debug (DEBUG_WINDOW);
 	
@@ -1922,7 +1927,7 @@
 	g_assert (GTK_IS_WIDGET (menubar));
 	gtk_widget_hide (menubar);
 
-	g_object_set (G_OBJECT (gtk_widget_get_parent (priv->view)),
+	g_object_set (G_OBJECT (gtk_widget_get_parent (priv->scroll_win)),
 		      "shadow-type", GTK_SHADOW_NONE,
 		      NULL);
 
@@ -1962,28 +1967,27 @@
 		slideshow_set_timeout (window);
 	}
 
-	upscale = gconf_client_get_bool (priv->client, 
-					 EOG_CONF_FULLSCREEN_UPSCALE, 
-					 NULL);
+	gtk_widget_grab_focus (priv->view);
 
-	eog_scroll_view_set_zoom_upscale (EOG_SCROLL_VIEW (priv->view), 
-					  upscale);
+	
 
-	gtk_widget_grab_focus (priv->view);
-
-	gtk_widget_modify_bg (window->priv->view, GTK_STATE_NORMAL, 
+	gtk_widget_modify_bg (window->priv->view, GTK_STATE_NORMAL,
 			      &(GTK_WIDGET (window)->style->black));
+	gtk_image_view_set_show_frame (GTK_IMAGE_VIEW (priv->view), FALSE);
 
 	{
+		/* Make the border of the frame the scroll_win is
+		   added to invisible. */
 		GtkStyle *style;
+		GtkWidget *frame;
 
-		style = gtk_style_copy (gtk_widget_get_style (priv->view->parent));
+		frame = priv->scroll_win->parent;
 
+		style = gtk_style_copy (gtk_widget_get_style (frame));
 		style->xthickness = 0;
 		style->ythickness = 0;
 
-		gtk_widget_set_style (priv->view->parent, style);
-
+		gtk_widget_set_style (frame, style);
 		g_object_unref (style);
 	}
 
@@ -2019,10 +2023,10 @@
 	if (slideshow) {
 		slideshow_clear_timeout (window);
 	}
-	
-	g_object_set (G_OBJECT (gtk_widget_get_parent (priv->view)),
+
+	g_object_set (G_OBJECT (gtk_widget_get_parent (priv->scroll_win)),
 		      "shadow-type", GTK_SHADOW_IN,
-		      NULL);
+		      NULL);	
 
 	g_signal_handlers_disconnect_by_func (priv->view,
 					      (gpointer) fullscreen_motion_notify_cb,
@@ -2045,21 +2049,18 @@
 	menubar = gtk_ui_manager_get_widget (priv->ui_mgr, "/MainMenu");
 	g_assert (GTK_IS_WIDGET (menubar));
 	gtk_widget_show (menubar);
-	
-	eog_scroll_view_set_zoom_upscale (EOG_SCROLL_VIEW (priv->view), FALSE);
 
-	gtk_widget_modify_bg (window->priv->view, GTK_STATE_NORMAL, NULL);
-	gtk_widget_set_style (window->priv->view->parent, NULL);
 	gtk_window_unfullscreen (GTK_WINDOW (window));
 
+	gtk_widget_modify_bg (window->priv->view, GTK_STATE_NORMAL, NULL);
+	gtk_image_view_set_show_frame (GTK_IMAGE_VIEW (priv->view), TRUE);
+	gtk_image_view_set_show_cursor (GTK_IMAGE_VIEW (priv->view), TRUE);
+
 	if (slideshow) {
 		eog_window_update_slideshow_action (window);
 	} else {
 		eog_window_update_fullscreen_action (window);
 	}
-
-	eog_scroll_view_show_cursor (EOG_SCROLL_VIEW (priv->view));
-
 	eog_application_screensaver_enable (EOG_APP);
 }
 
@@ -3072,7 +3073,7 @@
 	priv = EOG_WINDOW (user_data)->priv;
 
 	if (priv->view) {
-		eog_scroll_view_zoom_in (EOG_SCROLL_VIEW (priv->view), FALSE);
+		gtk_image_view_zoom_in (GTK_IMAGE_VIEW (priv->view));
 	}
 }
 
@@ -3088,7 +3089,7 @@
 	priv = EOG_WINDOW (user_data)->priv;
 
 	if (priv->view) {
-		eog_scroll_view_zoom_out (EOG_SCROLL_VIEW (priv->view), FALSE);
+		gtk_image_view_zoom_out (GTK_IMAGE_VIEW (priv->view));
 	}
 }
 
@@ -3104,7 +3105,7 @@
 	priv = EOG_WINDOW (user_data)->priv;
 
 	if (priv->view) {
-		eog_scroll_view_set_zoom (EOG_SCROLL_VIEW (priv->view), 1.0);
+		gtk_image_view_set_zoom (GTK_IMAGE_VIEW (priv->view), 1.0);
 	}
 }
 
@@ -3120,7 +3121,7 @@
 	priv = EOG_WINDOW (user_data)->priv;
 
 	if (priv->view) {
-		eog_scroll_view_zoom_fit (EOG_SCROLL_VIEW (priv->view));
+		gtk_image_view_set_fitting (GTK_IMAGE_VIEW (priv->view), TRUE);
 	}
 }
 
@@ -3807,8 +3808,10 @@
 				G_CALLBACK (eog_window_sidebar_page_removed),
 				window);
 
- 	priv->view = eog_scroll_view_new ();
-	gtk_widget_set_size_request (GTK_WIDGET (priv->view), 100, 100);
+ 	priv->view = gtk_anim_view_new ();
+	priv->scroll_win =
+		gtk_image_scroll_win_new (GTK_IMAGE_VIEW (priv->view));
+	gtk_widget_set_size_request (priv->view, 100, 100);
 	g_signal_connect (G_OBJECT (priv->view),
 			  "zoom_changed",
 			  G_CALLBACK (view_zoom_changed_cb), 
@@ -3818,7 +3821,7 @@
 				"shadow-type", GTK_SHADOW_IN, 
 				NULL);
 
-	gtk_container_add (GTK_CONTAINER (frame), priv->view);
+	gtk_container_add (GTK_CONTAINER (frame), priv->scroll_win);
 
 	gtk_paned_pack1 (GTK_PANED (hpaned),
 			 priv->sidebar,
@@ -4195,15 +4198,16 @@
 		if (tbcontainer->focus_child != NULL)
 			break;
 	case GDK_Page_Up:
-		if (!eog_scroll_view_scrollbars_visible (EOG_SCROLL_VIEW (EOG_WINDOW (widget)->priv->view))) {
-			eog_thumb_view_select_single (EOG_THUMB_VIEW (EOG_WINDOW (widget)->priv->thumbview), 
-						      EOG_THUMB_VIEW_SELECT_LEFT);
-			result = TRUE;		
-		}
+		printf ("FIXME: Not sure about this\n");
+/* 		if (!eog_scroll_view_scrollbars_visible (EOG_SCROLL_VIEW (EOG_WINDOW (widget)->priv->view))) { */
+/* 			eog_thumb_view_select_single (EOG_THUMB_VIEW (EOG_WINDOW (widget)->priv->thumbview),  */
+/* 						      EOG_THUMB_VIEW_SELECT_LEFT); */
+/* 			result = TRUE;		 */
+/* 		} */
 
-		if (EOG_WINDOW (widget)->priv->mode == EOG_WINDOW_MODE_SLIDESHOW) {
-			slideshow_set_timeout (EOG_WINDOW (widget));
-		}
+/* 		if (EOG_WINDOW (widget)->priv->mode == EOG_WINDOW_MODE_SLIDESHOW) { */
+/* 			slideshow_set_timeout (EOG_WINDOW (widget)); */
+/* 		} */
 		
 		break;
 	case GDK_Down:
@@ -4211,15 +4215,16 @@
 		if (tbcontainer->focus_child != NULL)
 			break;
 	case GDK_Page_Down:
-		if (!eog_scroll_view_scrollbars_visible (EOG_SCROLL_VIEW (EOG_WINDOW (widget)->priv->view))) {
-			eog_thumb_view_select_single (EOG_THUMB_VIEW (EOG_WINDOW (widget)->priv->thumbview), 
-						      EOG_THUMB_VIEW_SELECT_RIGHT);
-			result = TRUE;
-		}
+		printf ("FIXME: Not sure about this\n");
+/* 		if (!eog_scroll_view_scrollbars_visible (EOG_SCROLL_VIEW (EOG_WINDOW (widget)->priv->view))) { */
+/* 			eog_thumb_view_select_single (EOG_THUMB_VIEW (EOG_WINDOW (widget)->priv->thumbview),  */
+/* 						      EOG_THUMB_VIEW_SELECT_RIGHT); */
+/* 			result = TRUE; */
+/* 		} */
 
-		if (EOG_WINDOW (widget)->priv->mode == EOG_WINDOW_MODE_SLIDESHOW) {
-			slideshow_set_timeout (EOG_WINDOW (widget));
-		}
+/* 		if (EOG_WINDOW (widget)->priv->mode == EOG_WINDOW_MODE_SLIDESHOW) { */
+/* 			slideshow_set_timeout (EOG_WINDOW (widget)); */
+/* 		} */
 
 		break;
 	}
Index: src/eog-image.c
===================================================================
--- src/eog-image.c	(revision 3989)
+++ src/eog-image.c	(arbetskopia)
@@ -1,5 +1,7 @@
-/* Eye Of Gnome - Image 
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*-
  *
+ * Eye Of Gnome - Image 
+ *
  * Copyright (C) 2006 The Free Software Foundation
  *
  * Author: Lucas Rocha <lucasr gnome org>
@@ -23,6 +25,9 @@
 #include "config.h"
 #endif
 
+/* Define needed to get the gdk_pixbuf_non_anim_new() function. */
+#define GDK_PIXBUF_ENABLE_BACKEND
+
 #include "eog-image.h"
 #include "eog-image-private.h"
 #include "eog-debug.h"
@@ -41,11 +46,14 @@
 
 #include <unistd.h>
 
+
+
 #include <glib.h>
 #include <glib-object.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixbuf-animation.h>
 #include <libgnomevfs/gnome-vfs.h>
 #include <libgnomeui/gnome-thumbnail.h>
 
@@ -91,9 +99,9 @@
 	if (priv->status == EOG_IMAGE_STATUS_LOADING) {
 		eog_image_cancel_load (image);
 	} else {
-		if (priv->image != NULL) {
-			g_object_unref (priv->image);
-			priv->image = NULL;
+		if (priv->anim != NULL) {
+			g_object_unref (priv->anim);
+			priv->anim = NULL;
 		}
 		
 #ifdef HAVE_EXIF
@@ -231,7 +239,7 @@
 	img->priv = EOG_IMAGE_GET_PRIVATE (img);
 
 	img->priv->uri = NULL;
-	img->priv->image = NULL;
+	img->priv->anim = NULL;
 	img->priv->thumbnail = NULL;
 	img->priv->width = -1;
 	img->priv->height = -1;
@@ -342,20 +350,30 @@
 	GdkPixbuf *transformed;
 	gboolean modified = FALSE;
 
+	printf ("eog_image_real_transform\n");
+
 	g_return_if_fail (EOG_IS_IMAGE (img));
 	g_return_if_fail (EOG_IS_TRANSFORM (trans));
 
 	priv = img->priv;
 
-	if (priv->image != NULL) {
-		transformed = eog_transform_apply (trans, priv->image, job);
+	/* Transformations cannot be applied to animations. */
+	if (priv->anim != NULL &&
+	    gdk_pixbuf_animation_is_static_image (priv->anim) == TRUE) {
+
+		printf ("Making transform!\n");
 		
-		g_object_unref (priv->image);
-		priv->image = transformed;
+		/* Take the static frame, transform it, and then
+		   repackage it in the animation. */
+		GdkPixbuf *pixbuf;
 
+		pixbuf = gdk_pixbuf_animation_get_static_image (priv->anim);
+		transformed = eog_transform_apply (trans, pixbuf, job);
+		g_object_unref (priv->anim);
+
+		priv->anim = gdk_pixbuf_non_anim_new (transformed);
 		priv->width = gdk_pixbuf_get_width (transformed);
 		priv->height = gdk_pixbuf_get_height (transformed);
-       
 		modified = TRUE;
 	}
 
@@ -459,7 +477,7 @@
 		return TRUE;
 	}
 
-	if (priv->image == NULL) {
+	if (priv->anim == NULL) {
 		g_set_error (error, 
 			     EOG_IMAGE_ERROR, 
 			     EOG_IMAGE_ERROR_NOT_LOADED,
@@ -468,17 +486,24 @@
 		return FALSE;
 	}
 
-	if (priv->trans != NULL) {
-		transformed = eog_transform_apply (priv->trans, priv->image, NULL);
+	/* Transformations can only be applied to images, not
+	   animations. */
+	if (gdk_pixbuf_animation_is_static_image (priv->anim) &&
+	    priv->trans != NULL) {
+		/* Take the static frame, transform it, and then
+		   repackage it in the animation. */
+		GdkPixbuf *pixbuf;
+
+		pixbuf = gdk_pixbuf_animation_get_static_image (priv->anim);
+		transformed = eog_transform_apply (priv->trans, pixbuf, NULL);
+		g_object_unref (priv->anim);
+		
+		priv->anim = gdk_pixbuf_non_anim_new (transformed);
+		priv->width = gdk_pixbuf_get_width (transformed);
+		priv->height = gdk_pixbuf_get_height (transformed);
 	}
 
-	g_object_unref (priv->image);
-	priv->image = transformed;
-
-	if (transformed != NULL) {
-		priv->width = gdk_pixbuf_get_width (priv->image);
-		priv->height = gdk_pixbuf_get_height (priv->image);
-	} else {
+	if (transformed == NULL) {
 		g_set_error (error, 
 			     EOG_IMAGE_ERROR, 
 			     EOG_IMAGE_ERROR_GENERIC,
@@ -529,12 +554,16 @@
 	cmsHTRANSFORM transform;
 	gint row, width, rows, stride;
 	guchar *p;
+	GdkPixbuf *pixbuf;
 	
 	g_return_if_fail (img != NULL);
 
 	priv = img->priv;
 
-	if (screen == NULL || priv->profile == NULL) return;
+	if (screen == NULL ||
+	    priv->profile == NULL ||
+	    gdk_pixbuf_animation_is_static_image (priv->anim) == FALSE)
+		return;
 
 	transform = cmsCreateTransform (priv->profile, 
 				        TYPE_RGB_8, 
@@ -542,11 +571,13 @@
 				        TYPE_RGB_8, 
 				        INTENT_PERCEPTUAL, 
 				        0);
+
+	pixbuf = gdk_pixbuf_animation_get_static_image (priv->anim);
 	
-	rows = gdk_pixbuf_get_height(priv->image);
-	width = gdk_pixbuf_get_width (priv->image);
-	stride = gdk_pixbuf_get_rowstride (priv->image);
-	p = gdk_pixbuf_get_pixels (priv->image);
+	rows = gdk_pixbuf_get_height(pixbuf);
+	width = gdk_pixbuf_get_width (pixbuf);
+	stride = gdk_pixbuf_get_rowstride (pixbuf);
+	p = gdk_pixbuf_get_pixels (pixbuf);
 
 	for (row = 0; row < rows; ++row) {
 		cmsDoTransform(transform, p, p, width);
@@ -870,7 +901,7 @@
 
 	priv = img->priv;
 
- 	g_assert (!read_image_data || priv->image == NULL);
+ 	g_assert (!read_image_data || priv->anim == NULL);
 
 	if (read_image_data && priv->file_type != NULL) {
 		g_free (priv->file_type);
@@ -1031,18 +1062,20 @@
 		}
 	} else {
 		if (read_image_data) {
-			if (priv->image != NULL) {
-				g_object_unref (priv->image);
+			if (priv->anim != NULL) {
+				g_object_unref (priv->anim);
 			}
 
-			priv->image = gdk_pixbuf_loader_get_pixbuf (loader);
+			priv->anim = gdk_pixbuf_loader_get_animation (loader);
 
-			g_assert (priv->image != NULL);
+			g_assert (priv->anim != NULL);
 
-			g_object_ref (priv->image);
+			g_object_ref (priv->anim);
 
-			priv->width = gdk_pixbuf_get_width (priv->image);
-			priv->height = gdk_pixbuf_get_height (priv->image);
+			priv->width =
+				gdk_pixbuf_animation_get_width (priv->anim);
+			priv->height =
+				gdk_pixbuf_animation_get_height (priv->anim);
 
 			format = gdk_pixbuf_loader_get_format (loader);
 
@@ -1084,7 +1117,7 @@
 	
 	if ((req_data & EOG_IMAGE_DATA_IMAGE) > 0) {
 		req_data = (req_data & !EOG_IMAGE_DATA_IMAGE);
-		has_data = has_data && (priv->image != NULL);
+		has_data = has_data && (priv->anim != NULL);
 	}
 
 	if ((req_data & EOG_IMAGE_DATA_DIMENSION) > 0 ) {
@@ -1198,7 +1231,7 @@
 	g_return_val_if_fail (EOG_IS_IMAGE (img), NULL);
 
 	g_mutex_lock (img->priv->status_mutex);
-	image = img->priv->image;
+	image = gdk_pixbuf_animation_get_static_image (img->priv->anim);
 	g_mutex_unlock (img->priv->status_mutex);
 
 	if (image != NULL) {
@@ -1208,6 +1241,24 @@
 	return image;
 }
 
+GdkPixbufAnimation *
+eog_image_get_anim (EogImage *img)
+{
+	GdkPixbufAnimation *anim;
+	
+	g_return_val_if_fail (EOG_IS_IMAGE (img), NULL);
+
+	g_mutex_lock (img->priv->status_mutex);
+	anim = img->priv->anim;
+	g_mutex_unlock (img->priv->status_mutex);
+
+	if (anim != NULL) {
+		g_object_ref (anim);
+	}
+
+	return anim;
+}
+
 #ifdef HAVE_LCMS
 cmsHPROFILE
 eog_image_get_profile (EogImage *img)
@@ -1481,7 +1532,7 @@
 	}
 
 	/* fail if there is no image to save */
-	if (priv->image == NULL) {
+	if (priv->anim == NULL) {
 		g_set_error (error, EOG_IMAGE_ERROR,
 			     EOG_IMAGE_ERROR_NOT_LOADED,
 			     _("No image loaded."));
@@ -1507,7 +1558,12 @@
 #endif
 
 	if (!success && (*error == NULL)) {
-		success = gdk_pixbuf_save (priv->image, tmpfile, source->format, error, NULL);
+		success = gdk_pixbuf_save
+			(gdk_pixbuf_animation_get_static_image (priv->anim),
+			 tmpfile,
+			 source->format,
+			 error,
+			 NULL);
 	}
 
 	if (success) {
@@ -1609,7 +1665,7 @@
 	priv = img->priv;
 
 	/* fail if there is no image to save */
-	if (priv->image == NULL) {
+	if (priv->anim == NULL) {
 		g_set_error (error, 
 			     EOG_IMAGE_ERROR,
 			     EOG_IMAGE_ERROR_NOT_LOADED,
@@ -1645,7 +1701,12 @@
 #endif
 
 	if (!success && (*error == NULL)) {
-		success = gdk_pixbuf_save (priv->image, tmpfile, target->format, error, NULL);
+		success = gdk_pixbuf_save
+			(gdk_pixbuf_animation_get_static_image (priv->anim),
+			 tmpfile,
+			 target->format,
+			 error,
+			 NULL);
 	}
 
 	if (success && !direct_copy) { /* not required if we alredy copied the file directly */
Index: configure.ac
===================================================================
--- configure.ac	(revision 3989)
+++ configure.ac	(arbetskopia)
@@ -76,6 +76,7 @@
 GNOME_ICON_THEME_REQUIRED=2.19.1
 SHARED_MIME_INFO_REQUIRED=0.20
 EXEMPI_REQUIRED=1.99.2
+GTKIMAGEVIEW_REQUIRED=1.4.0
 
 
 EOG_MODULES="gtk+-2.0 >= $GTK_REQUIRED \
@@ -89,7 +90,8 @@
              gnome-desktop-2.0 >= $GNOME_DESKTOP_REQUIRED \
              gtk+-unix-print-2.0 >= $GTK_PRINT_REQUIRED \
 	     gnome-icon-theme >= $GNOME_ICON_THEME_REQUIRED \
-	     shared-mime-info >= $SHARED_MIME_INFO_REQUIRED"
+	     shared-mime-info >= $SHARED_MIME_INFO_REQUIRED \
+             gtkimageview >= $GTKIMAGEVIEW_REQUIRED"
 
 # ***************
 # EXIF (optional)


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