diff options
-rw-r--r-- | gtk/gtkcsstypes.c | 4 | ||||
-rw-r--r-- | gtk/gtkcsstypesprivate.h | 5 | ||||
-rw-r--r-- | gtk/gtkstylecontext.c | 83 |
3 files changed, 89 insertions, 3 deletions
diff --git a/gtk/gtkcsstypes.c b/gtk/gtkcsstypes.c index f83880afab..b69b0fecca 100644 --- a/gtk/gtkcsstypes.c +++ b/gtk/gtkcsstypes.c @@ -56,7 +56,8 @@ _gtk_css_change_for_sibling (GtkCssChange match) { GTK_CSS_CHANGE_NAME, GTK_CSS_CHANGE_SIBLING_NAME }, { GTK_CSS_CHANGE_POSITION, GTK_CSS_CHANGE_SIBLING_POSITION }, { GTK_CSS_CHANGE_STATE, GTK_CSS_CHANGE_SIBLING_STATE }, - { GTK_CSS_CHANGE_SOURCE, 0 } + { GTK_CSS_CHANGE_SOURCE, 0 }, + { GTK_CSS_CHANGE_ANIMATE, 0 } }; return gtk_css_change_translate (match, table, G_N_ELEMENTS (table)); @@ -75,6 +76,7 @@ _gtk_css_change_for_child (GtkCssChange match) { GTK_CSS_CHANGE_SIBLING_POSITION, GTK_CSS_CHANGE_PARENT_SIBLING_POSITION }, { GTK_CSS_CHANGE_SIBLING_STATE, GTK_CSS_CHANGE_PARENT_SIBLING_STATE }, { GTK_CSS_CHANGE_SOURCE, 0 }, + { GTK_CSS_CHANGE_ANIMATE, 0 } }; return gtk_css_change_translate (match, table, G_N_ELEMENTS (table)); diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h index 8890a5cce9..b0db18d0b9 100644 --- a/gtk/gtkcsstypesprivate.h +++ b/gtk/gtkcsstypesprivate.h @@ -43,10 +43,11 @@ typedef enum { /*< skip >*/ GTK_CSS_CHANGE_PARENT_SIBLING_POSITION = (1 << 14), GTK_CSS_CHANGE_PARENT_SIBLING_STATE = (1 << 15), /* add more */ - GTK_CSS_CHANGE_SOURCE = (1 << 16) + GTK_CSS_CHANGE_SOURCE = (1 << 16), + GTK_CSS_CHANGE_ANIMATE = (1 << 17) } GtkCssChange; -#define GTK_CSS_CHANGE_ANY ((1 << 17) - 1) +#define GTK_CSS_CHANGE_ANY ((1 << 18) - 1) #define GTK_CSS_CHANGE_ANY_SELF (GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_STATE) #define GTK_CSS_CHANGE_ANY_SIBLING (GTK_CSS_CHANGE_SIBLING_CLASS | GTK_CSS_CHANGE_SIBLING_NAME | \ GTK_CSS_CHANGE_SIBLING_POSITION | GTK_CSS_CHANGE_SIBLING_STATE) diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index 0ac8eb3a96..8375328f94 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -350,6 +350,9 @@ struct _GtkStyleContextPrivate GtkStyleCascade *cascade; + GtkStyleContext *animation_list_prev; + GtkStyleContext *animation_list_next; + GtkStyleContext *parent; GSList *children; GtkWidget *widget; @@ -379,6 +382,8 @@ enum { }; static guint signals[LAST_SIGNAL] = { 0 }; +static GtkStyleContext *_running_animations = NULL; +guint _running_animations_timer_id = 0; static void gtk_style_context_finalize (GObject *object); @@ -675,6 +680,82 @@ gtk_style_context_init (GtkStyleContext *style_context) _gtk_style_cascade_get_for_screen (priv->screen)); } +static gboolean +gtk_style_context_do_animations (gpointer unused) +{ + GtkStyleContext *context; + + for (context = _running_animations; + context != NULL; + context = context->priv->animation_list_next) + { + _gtk_style_context_queue_invalidate (context, GTK_CSS_CHANGE_ANIMATE); + } + + return TRUE; +} + +static gboolean +gtk_style_context_is_animating (GtkStyleContext *context) +{ + GtkStyleContextPrivate *priv = context->priv; + + return priv->animation_list_prev != NULL + || _running_animations == context; +} + +static void +gtk_style_context_stop_animating (GtkStyleContext *context) +{ + GtkStyleContextPrivate *priv = context->priv; + + if (!gtk_style_context_is_animating (context)) + return; + + if (priv->animation_list_prev == NULL) + { + _running_animations = priv->animation_list_next; + + if (_running_animations == NULL) + { + /* we were the last animation */ + g_source_remove (_running_animations_timer_id); + _running_animations_timer_id = 0; + } + } + else + priv->animation_list_prev->priv->animation_list_next = priv->animation_list_next; + + if (priv->animation_list_next) + priv->animation_list_next->priv->animation_list_prev = priv->animation_list_prev; + + priv->animation_list_next = NULL; + priv->animation_list_prev = NULL; +} + +static void G_GNUC_UNUSED +gtk_style_context_start_animating (GtkStyleContext *context) +{ + GtkStyleContextPrivate *priv = context->priv; + + if (gtk_style_context_is_animating (context)) + return; + + if (_running_animations == NULL) + { + _running_animations_timer_id = gdk_threads_add_timeout (25, + gtk_style_context_do_animations, + NULL); + _running_animations = context; + } + else + { + priv->animation_list_next = _running_animations; + _running_animations->priv->animation_list_prev = context; + _running_animations = context; + } +} + static void gtk_style_context_finalize (GObject *object) { @@ -684,6 +765,8 @@ gtk_style_context_finalize (GObject *object) style_context = GTK_STYLE_CONTEXT (object); priv = style_context->priv; + gtk_style_context_stop_animating (style_context); + /* children hold a reference to us */ g_assert (priv->children == NULL); |