[evolution-patches] animation changes
- From: Larry Ewing <lewing ximian com>
- To: patches <evolution-patches ximian com>, Radek Doulik <rodo ximian com>
- Subject: [evolution-patches] animation changes
- Date: 18 May 2003 15:08:38 -0500
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]