[evolution-patches] animation changes



These patches add the ability to stop and start image animations in
gtkhtml and also add logic to stop animations whenever the widget is
fully offscreen/hidden.  The htmlimage patch can stand alone so I left
it separate, the gtkhtml patch contains external api for starting and
stopping and the logic to figure out if the widget is hidden.  I'll be
sending more patches that build off this but I thought the sooner I got
this out the more time people might have to look at it.

--Larry

Index: htmlimage.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlimage.c,v
retrieving revision 1.184
diff -u -p -r1.184 htmlimage.c
--- htmlimage.c	6 May 2003 11:03:19 -0000	1.184
+++ htmlimage.c	18 May 2003 20:06:35 -0000
@@ -56,11 +56,14 @@ struct _HTMLImageFactory {
 	HTMLEngine *engine;
 	GHashTable *loaded_images;
 	GdkPixbuf  *missing;
+	gboolean    animate;
 };
 
 
 #define DEFAULT_SIZE 48
 #define STRDUP_HELPER(i,j) if (i != j) {char *tmp = g_strdup (j); g_free(i); i = tmp;}
+
+#define DA(x)
 
 HTMLImageClass html_image_class;
 static HTMLObjectClass *parent_class = NULL;
@@ -1079,7 +1082,7 @@ html_image_pointer_queue_animation (HTML
 {
 	gint delay = gdk_pixbuf_animation_iter_get_delay_time (ip->iter);
 
-	if (delay >= 0 && !ip->animation_timeout) {
+	if (delay >= 0 && !ip->animation_timeout && ip->factory && ip->factory->animate) {
 		ip->animation_timeout = g_timeout_add (delay, 
 						       (GtkFunction) html_image_pointer_run_animation, 
 						       (gpointer) ip);
@@ -1151,6 +1154,7 @@ html_image_factory_new (HTMLEngine *e)
 	retval->engine = e;
 	retval->loaded_images = g_hash_table_new (g_str_hash, g_str_equal);
 	retval->missing = NULL;
+	retval->animate = TRUE;
 
 	return retval;
 }
@@ -1402,7 +1406,41 @@ stop_anim (gpointer key, gpointer value,
 void
 html_image_factory_stop_animations (HTMLImageFactory *factory)
 {
+	DA (g_warning ("stop animations");)
 	g_hash_table_foreach (factory->loaded_images, stop_anim, NULL);
+}
+
+static void
+start_anim (gpointer key, gpointer value, gpointer user_data)
+{
+	HTMLImagePointer *ip = value;
+	html_image_pointer_start_animation (ip);
+}
+
+void
+html_image_factory_start_animations (HTMLImageFactory *factory)
+{
+	DA (g_warning ("start animations");)
+	g_hash_table_foreach (factory->loaded_images, start_anim, NULL);
+}
+
+gboolean
+html_image_factory_get_animate (HTMLImageFactory *factory)
+{
+	return factory->animate;
+}
+
+void
+html_image_factory_set_animate (HTMLImageFactory *factory, gboolean animate)
+{
+	if (animate != factory->animate) {
+		factory->animate = animate;
+
+		if (animate)
+			html_image_factory_start_animations (factory);
+		else 
+			html_image_factory_stop_animations (factory);
+	}
 }
 
 static gboolean
Index: htmlimage.h
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlimage.h,v
retrieving revision 1.48
diff -u -p -r1.48 htmlimage.h
--- htmlimage.h	21 Feb 2003 08:52:54 -0000	1.48
+++ htmlimage.h	18 May 2003 20:06:35 -0000
@@ -147,6 +147,10 @@ HTMLImageFactory *html_image_factory_new
 void              html_image_factory_free                   (HTMLImageFactory *factory);
 void              html_image_factory_cleanup                (HTMLImageFactory *factory); /* Does gc etc. - removes unused image entries */
 void              html_image_factory_stop_animations        (HTMLImageFactory *factory);
+void              html_image_factory_start_animations       (HTMLImageFactory *factory);
+void              html_image_factory_set_animate            (HTMLImageFactory *factory,
+						             gboolean animate);
+gboolean          html_image_factory_get_animate            (HTMLImageFactory *factory);
 void              html_image_factory_deactivate_animations  (HTMLImageFactory *factory);
 HTMLImagePointer *html_image_factory_register               (HTMLImageFactory *factory,
 							     HTMLImage        *i,
Index: gtkhtml.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/gtkhtml.c,v
retrieving revision 1.511
diff -u -p -r1.511 gtkhtml.c
--- gtkhtml.c	16 May 2003 15:33:10 -0000	1.511
+++ gtkhtml.c	18 May 2003 20:07:19 -0000
@@ -889,7 +889,8 @@ realize (GtkWidget *widget)
 				| GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK
 				| GDK_ENTER_NOTIFY_MASK
 				| GDK_BUTTON_PRESS_MASK 
-				| GDK_BUTTON_RELEASE_MASK
+				| GDK_BUTTON_RELEASE_MASK 
+				| GDK_VISIBILITY_NOTIFY_MASK
 				| GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK));
 
 	html_engine_realize (html->engine, html->layout.bin_window);
@@ -922,6 +923,8 @@ realize (GtkWidget *widget)
 			   dnd_link_sources, DND_LINK_SOURCES, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
 
 	gtk_im_context_set_client_window (html->priv->im_context, widget->window);
+
+	html_image_factory_start_animations (html->engine->image_factory);
 }
 
 static void
@@ -933,11 +936,12 @@ unrealize (GtkWidget *widget)
 
 	gtk_im_context_set_client_window (html->priv->im_context, widget->window);
 
+	html_image_factory_stop_animations (html->engine->image_factory);
+
 	if (GTK_WIDGET_CLASS (parent_class)->unrealize)
 		(* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
 }
 
-static gint
 expose (GtkWidget *widget, GdkEventExpose *event)
 {
 	/* printf ("expose x: %d y: %d\n", GTK_HTML (widget)->engine->x_offset, GTK_HTML (widget)->engine->y_offset); */
@@ -1400,6 +1404,46 @@ motion_notify_event (GtkWidget *widget,
 	return TRUE;
 }
 
+
+static gboolean
+toplevel_unmap (GtkWidget *widget, GdkEvent *event, GtkHTML *html)
+{
+	html_image_factory_stop_animations (html->engine->image_factory);	
+}
+
+static void
+hierarchy_changed (GtkWidget *widget,
+		   GtkWidget *old_toplevel)
+{
+	GtkWidget *toplevel;
+	GtkHTMLPrivate   *priv = GTK_HTML (widget)->priv;
+	
+	if (old_toplevel && priv->toplevel_unmap_handler) {
+		g_signal_handler_disconnect (old_toplevel,
+					     priv->toplevel_unmap_handler);
+		priv->toplevel_unmap_handler = 0;
+	}
+
+	toplevel = gtk_widget_get_toplevel (widget);
+
+	if (GTK_WIDGET_TOPLEVEL (toplevel) && priv->toplevel_unmap_handler == 0) {
+		priv->toplevel_unmap_handler = g_signal_connect (G_OBJECT (toplevel), "unmap-event", 
+								 G_CALLBACK (toplevel_unmap), widget);
+	} 
+}
+
+static gint
+visibility_notify_event (GtkWidget *widget,
+			 GdkEventVisibility *event)
+{
+	if (event->state == GDK_VISIBILITY_FULLY_OBSCURED) 
+		html_image_factory_stop_animations (GTK_HTML (widget)->engine->image_factory);
+	else 
+		html_image_factory_start_animations (GTK_HTML (widget)->engine->image_factory);
+
+	return FALSE;
+}
+
 static gint
 button_press_event (GtkWidget *widget,
 		    GdkEventButton *event)
@@ -2661,6 +2705,8 @@ gtk_html_class_init (GtkHTMLClass *klass
 	widget_class->expose_event  = expose;
 	widget_class->size_allocate = size_allocate;
 	widget_class->motion_notify_event = motion_notify_event;
+	widget_class->visibility_notify_event = visibility_notify_event;
+	widget_class->hierarchy_changed = hierarchy_changed;
 	widget_class->button_press_event = button_press_event;
 	widget_class->button_release_event = button_release_event;
 	widget_class->focus_in_event = focus_in_event;
@@ -4640,8 +4686,11 @@ gtk_html_set_iframe_parent (GtkHTML *htm
 	gint depth = 0;
 	g_assert (GTK_IS_HTML (parent));
 
+	gtk_html_set_animate (html, gtk_html_get_animate (GTK_HTML (parent)));
+
 	html->iframe_parent = parent;
 	html->frame = frame;
+	
 	g_signal_emit (html_engine_get_top_html_engine (html->engine)->widget, signals [IFRAME_CREATED], 0, html);
 
 	while (html->iframe_parent) {
@@ -4996,6 +5045,38 @@ gtk_html_get_allow_frameset (GtkHTML *ht
 	g_return_val_if_fail (HTML_IS_ENGINE (html->engine), FALSE);
 
 	return html->engine->allow_frameset;	
+}
+
+static void
+frame_set_animate (HTMLObject *o, HTMLEngine *e, gpointer data)
+{
+	if (HTML_IS_FRAME (o)) {
+		html_image_factory_set_animate (GTK_HTML (HTML_FRAME (o)->html)->engine->image_factory,
+						*(gboolean *)data);
+	} else if (HTML_IS_IFRAME (o)) {
+		html_image_factory_set_animate (GTK_HTML (HTML_IFRAME (o)->html)->engine->image_factory,
+						*(gboolean *)data);
+	}
+}
+
+void
+gtk_html_set_animate (GtkHTML *html, gboolean animate)
+{
+	g_return_if_fail (GTK_IS_HTML (html));
+	g_return_if_fail (HTML_IS_ENGINE (html->engine));
+
+	html_image_factory_set_animate (html->engine->image_factory, animate);
+	if (html->engine->clue)
+		html_object_forall (html->engine->clue, html->engine, frame_set_animate, &animate);
+}
+
+gboolean
+gtk_html_get_animate (GtkHTML *html)
+{
+	g_return_val_if_fail (GTK_IS_HTML (html), FALSE);
+	g_return_val_if_fail (HTML_IS_ENGINE (html->engine), FALSE);
+
+	return html_image_factory_get_animate (html->engine->image_factory);
 }
 
 void
Index: gtkhtml.h
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/gtkhtml.h,v
retrieving revision 1.144
diff -u -p -r1.144 gtkhtml.h
--- gtkhtml.h	9 Apr 2003 07:57:34 -0000	1.144
+++ gtkhtml.h	18 May 2003 20:07:19 -0000
@@ -187,6 +187,11 @@ void                       gtk_html_set_
 								   gboolean                   editable);
 gboolean                   gtk_html_get_editable                  (const GtkHTML             *html);
 
+/* Animated Images */
+void                       gtk_html_set_animate                   (GtkHTML                   *html,
+								   gboolean                   animate);
+gboolean                   gtk_html_get_animate                   (GtkHTML                   *html);
+
 /* Printing support.  */
 void                       gtk_html_print_with_header_footer      (GtkHTML                   *html,
 								   GnomePrintContext         *print_context,
Index: gtkhtml-private.h
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/gtkhtml-private.h,v
retrieving revision 1.38
diff -u -p -r1.38 gtkhtml-private.h
--- gtkhtml-private.h	29 Apr 2003 16:02:48 -0000	1.38
+++ gtkhtml-private.h	18 May 2003 20:07:19 -0000
@@ -63,6 +63,8 @@ struct _GtkHTMLPrivate {
 
 	guint32     event_time;
 	gboolean    selection_as_cite;
+
+	gulong      toplevel_unmap_handler;
 };
 
 void  gtk_html_private_calc_scrollbars  (GtkHTML                 *html,


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