[gtk+] Add gtk_style_context_cancel_animations()
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] Add gtk_style_context_cancel_animations()
- Date: Mon, 10 Jan 2011 02:53:43 +0000 (UTC)
commit e6277d3b82440168e073bc83bf10fceb76d63995
Author: Carlos Garnacho <carlosg gnome org>
Date: Mon Jan 10 03:31:35 2011 +0100
Add gtk_style_context_cancel_animations()
This function takes a region ID and cancels all animations
on or beneath that region (as in push/pop_animatable_region).
First user of this is GtkWidget itself, so unmapped widgets
have looping animations cancelled. Fixes bug #638119, reported
by Jesse van den Kieboom.
docs/reference/gtk/gtk3-sections.txt | 1 +
gtk/gtk.symbols | 1 +
gtk/gtkstylecontext.c | 72 +++++++++++++++++++++++++++++----
gtk/gtkstylecontext.h | 3 +
gtk/gtkwidget.c | 3 +
5 files changed, 71 insertions(+), 9 deletions(-)
---
diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt
index 3ae7fa8..16372a5 100644
--- a/docs/reference/gtk/gtk3-sections.txt
+++ b/docs/reference/gtk/gtk3-sections.txt
@@ -5547,6 +5547,7 @@ gtk_style_context_lookup_icon_set
gtk_style_context_notify_state_change
gtk_style_context_pop_animatable_region
gtk_style_context_push_animatable_region
+gtk_style_context_cancel_animations
gtk_style_context_remove_provider
gtk_style_context_remove_provider_for_screen
gtk_style_context_reset_widgets
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index 919ddd4..ead590e 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -2461,6 +2461,7 @@ gtk_style_context_add_class
gtk_style_context_add_provider
gtk_style_context_add_provider_for_screen
gtk_style_context_add_region
+gtk_style_context_cancel_animations
gtk_style_context_get
gtk_style_context_get_background_color
gtk_style_context_get_border
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 162c971..3d1b0aa 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -454,6 +454,12 @@ struct AnimationInfo
GtkTimeline *timeline;
gpointer region_id;
+
+ /* Region stack (until region_id) at the time of
+ * rendering, this is used for nested cancellation.
+ */
+ GSList *parent_regions;
+
GdkWindow *window;
GtkStateType state;
gboolean target_value;
@@ -749,6 +755,7 @@ animation_info_free (AnimationInfo *info)
cairo_region_destroy (info->invalidation_region);
g_array_free (info->rectangles, TRUE);
+ g_slist_free (info->parent_regions);
g_slice_free (AnimationInfo, info);
}
@@ -1572,7 +1579,6 @@ context_has_animatable_region (GtkStyleContext *context,
gpointer region_id)
{
GtkStyleContextPrivate *priv;
- GSList *r;
/* NULL region_id means everything
* rendered through the style context
@@ -1581,14 +1587,7 @@ context_has_animatable_region (GtkStyleContext *context,
return TRUE;
priv = context->priv;
-
- for (r = priv->animation_regions; r; r = r->next)
- {
- if (r->data == region_id)
- return TRUE;
- }
-
- return FALSE;
+ return g_slist_find (priv->animation_regions, region_id) != NULL;
}
/**
@@ -2920,6 +2919,53 @@ gtk_style_context_notify_state_change (GtkStyleContext *context,
}
/**
+ * gtk_style_context_cancel_animations:
+ * @context: a #GtkStyleContext
+ * @region_id: (allow-none): animatable region to stop, or %NULL.
+ * See gtk_style_context_push_animatable_region()
+ *
+ * Stops all running animations for @region_id and all animatable
+ * regions underneath.
+ *
+ * A %NULL @region_id will stop all ongoing animations in @context,
+ * when dealing with a #GtkStyleContext obtained through
+ * gtk_widget_get_style_context(), this is normally done for you
+ * in all circumstances you would expect all widget to be stopped,
+ * so this should be only used in complex widgets with different
+ * animatable regions.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_style_context_cancel_animations (GtkStyleContext *context,
+ gpointer region_id)
+{
+ GtkStyleContextPrivate *priv;
+ AnimationInfo *info;
+ GSList *l, *node;
+
+ g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
+
+ priv = context->priv;
+ l = priv->animations;
+
+ while (l)
+ {
+ info = l->data;
+ node = l;
+ l = l->next;
+
+ if (!region_id ||
+ info->region_id == region_id ||
+ g_slist_find (info->parent_regions, region_id))
+ {
+ priv->animations = g_slist_remove (priv->animations, info);
+ animation_info_free (info);
+ }
+ }
+}
+
+/**
* gtk_style_context_push_animatable_region:
* @context: a #GtkStyleContext
* @region_id: unique identifier for the animatable region
@@ -3096,6 +3142,14 @@ store_animation_region (GtkStyleContext *context,
rect.height = (gint) height;
g_array_append_val (info->rectangles, rect);
+
+ if (!info->parent_regions)
+ {
+ GSList *parent_regions;
+
+ parent_regions = g_slist_find (priv->animation_regions, info->region_id);
+ info->parent_regions = g_slist_copy (parent_regions);
+ }
}
}
}
diff --git a/gtk/gtkstylecontext.h b/gtk/gtkstylecontext.h
index ab9be70..ceedc52 100644
--- a/gtk/gtkstylecontext.h
+++ b/gtk/gtkstylecontext.h
@@ -522,6 +522,9 @@ void gtk_style_context_notify_state_change (GtkStyleContext *context,
gpointer region_id,
GtkStateType state,
gboolean state_value);
+void gtk_style_context_cancel_animations (GtkStyleContext *context,
+ gpointer region_id);
+
void gtk_style_context_push_animatable_region (GtkStyleContext *context,
gpointer region_id);
void gtk_style_context_pop_animatable_region (GtkStyleContext *context);
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index b7c3141..f0c56b4 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -4191,6 +4191,9 @@ gtk_widget_unmap (GtkWidget *widget)
g_signal_emit (widget, widget_signals[UNMAP], 0);
gtk_widget_pop_verify_invariants (widget);
+
+ if (priv->context)
+ gtk_style_context_cancel_animations (priv->context, NULL);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]