[Xfce4-commits] [apps/xfdashboard] 01/01: Adding support to animate actor when a class or a pseudo-class was added or removed.
noreply at xfce.org
noreply at xfce.org
Fri Jan 31 15:47:27 CET 2020
This is an automated email from the git hooks/post-receive script.
n o m a d p u s h e d a c o m m i t t o b r a n c h m a s t e r
in repository apps/xfdashboard.
commit 232b866b6a3aff2f44ae6f3b070967a8161a16c3
Author: Stephan Haller <nomad at froevel.de>
Date: Fri Jan 31 15:46:47 2020 +0100
Adding support to animate actor when a class or a pseudo-class was added or removed.
---
libxfdashboard/actor.c | 245 ++++++++++++++++++++++++++++++++++++++-
libxfdashboard/animation.c | 45 ++++---
libxfdashboard/theme-animation.c | 6 -
3 files changed, 272 insertions(+), 24 deletions(-)
diff --git a/libxfdashboard/actor.c b/libxfdashboard/actor.c
index 89531c1..a285406 100644
--- a/libxfdashboard/actor.c
+++ b/libxfdashboard/actor.c
@@ -32,6 +32,7 @@
#include <libxfdashboard/application.h>
#include <libxfdashboard/stylable.h>
#include <libxfdashboard/focusable.h>
+#include <libxfdashboard/animation.h>
#include <libxfdashboard/utils.h>
#include <libxfdashboard/compat.h>
#include <libxfdashboard/debug.h>
@@ -59,6 +60,7 @@ struct _XfdashboardActorPrivate
GHashTable *lastThemeStyleSet;
gboolean forceStyleRevalidation;
gboolean isFirstParent;
+ GSList *animations;
};
/* Properties */
@@ -79,16 +81,35 @@ enum
static GParamSpec* XfdashboardActorProperties[PROP_LAST]={ 0, };
/* IMPLEMENTATION: Private variables and methods */
-static GParamSpecPool *_xfdashboard_actor_stylable_properties_pool=NULL;
+typedef struct _XfdashboardActorAnimationEntry XfdashboardActorAnimationEntry;
+struct _XfdashboardActorAnimationEntry
+{
+ gchar *signal;
+ XfdashboardAnimation *animation;
+};
#define XFDASHBOARD_ACTOR_PARAM_SPEC_REF (_xfdashboard_actor_param_spec_ref_quark())
+static GParamSpecPool *_xfdashboard_actor_stylable_properties_pool=NULL;
+
+
/* Quark declarations */
static GQuark _xfdashboard_actor_param_spec_ref_quark(void)
{
return(g_quark_from_static_string("xfdashboard-actor-param-spec-ref-quark"));
}
+
+/* Free an animation entry */
+static void _xfdashboard_actor_animation_entry_free(XfdashboardActorAnimationEntry *inData)
+{
+ g_return_if_fail(inData);
+
+ /* Release allocated resources */
+ if(inData->signal) g_free(inData->signal);
+ g_free(inData);
+}
+
/* Invalidate all stylable children recursively beginning at given actor */
static void _xfdashboard_actor_invalidate_recursive(ClutterActor *inActor)
{
@@ -708,6 +729,218 @@ static void _xfdashboard_actor_stylable_invalidate(XfdashboardStylable *inStylab
g_object_thaw_notify(G_OBJECT(self));
}
+/* Animation has completed, so remove from list */
+static void _xfdashboard_actor_animation_done(XfdashboardAnimation *inAnimation,
+ gpointer inUserData)
+{
+ XfdashboardActor *self;
+ XfdashboardActorPrivate *priv;
+ GSList *iter;
+ XfdashboardActorAnimationEntry *data;
+
+ g_return_if_fail(XFDASHBOARD_IS_ANIMATION(inAnimation));
+ g_return_if_fail(XFDASHBOARD_IS_ACTOR(inUserData));
+
+ self=XFDASHBOARD_ACTOR(inUserData);
+ priv=self->priv;
+
+ /* Lookup animation done in list of animation and remove animation entry */
+ for(iter=priv->animations; iter; iter=g_slist_next(iter))
+ {
+ /* Get animation entry at iterator */
+ data=(XfdashboardActorAnimationEntry*)iter->data;
+ if(!data) continue;
+
+ /* Check if animation entry matches the animation done */
+ if(data->animation==inAnimation)
+ {
+ XFDASHBOARD_DEBUG(self, ANIMATION,
+ "Removing stopped animation '%s'",
+ xfdashboard_animation_get_id(data->animation));
+
+ /* Remove entry from list */
+ _xfdashboard_actor_animation_entry_free(data);
+ priv->animations=g_slist_delete_link(priv->animations, iter);
+
+ /* An animation with equal pointer can be stored only once, so
+ * stop further iteration.
+ */
+ break;
+ }
+ }
+}
+
+/* Remove animations for signal and (pseudo-)class */
+static void _xfdashboard_actor_remove_animation(XfdashboardStylable *inStylable,
+ const gchar *inSignalPrefix,
+ const gchar *inClass)
+{
+ XfdashboardActor *self;
+ XfdashboardActorPrivate *priv;
+ gchar *animationSignal;
+ GSList *iter;
+ XfdashboardActorAnimationEntry *data;
+
+ g_return_if_fail(XFDASHBOARD_IS_ACTOR(inStylable));
+
+ self=XFDASHBOARD_ACTOR(inStylable);
+ priv=self->priv;
+
+ /* Get signal to lookup animation */
+ animationSignal=g_strdup_printf("%s:%s", inSignalPrefix, inClass);
+
+ /* Iterate through list of animation and lookup animation for signal. If an
+ * animation is found, stop it. It will be remove from list of animations
+ * automatically.
+ */
+ for(iter=priv->animations; iter; iter=g_slist_next(iter))
+ {
+ /* Get animation entry at iterator */
+ data=(XfdashboardActorAnimationEntry*)iter->data;
+ if(!data) continue;
+
+ /* Check if animation entry matches the signal to lookup */
+ if(g_strcmp0(data->signal, animationSignal)==0)
+ {
+ XFDASHBOARD_DEBUG(self, ANIMATION,
+ "Stopping and removing animation '%s' for signal '%s'",
+ xfdashboard_animation_get_id(data->animation),
+ animationSignal);
+
+ /* Stop animation by unreffing object instance */
+ g_object_unref(data->animation);
+ }
+ }
+
+ /* Release allocated resources */
+ g_free(animationSignal);
+}
+
+/* Lookup animations for signal and (pseudo-)class and run animation at actor */
+static void _xfdashboard_actor_add_animation(XfdashboardStylable *inStylable,
+ const gchar *inSignalPrefix,
+ const gchar *inClass)
+{
+ XfdashboardActor *self;
+ XfdashboardActorPrivate *priv;
+ XfdashboardAnimation *animation;
+ gchar *animationSignal;
+ XfdashboardActorAnimationEntry *data;
+
+ g_return_if_fail(XFDASHBOARD_IS_ACTOR(inStylable));
+
+ self=XFDASHBOARD_ACTOR(inStylable);
+ priv=self->priv;
+
+ /* Get signal to lookup animation */
+ animationSignal=g_strdup_printf("%s:%s", inSignalPrefix, inClass);
+
+ /* Lookup animation for signal-(pseudo-)class combination and if any found
+ * (i.e. has an ID) add it to list of animations of actor and run it.
+ */
+ animation=xfdashboard_animation_new(XFDASHBOARD_ACTOR(self), animationSignal);
+ if(!xfdashboard_animation_get_id(animation))
+ {
+ /* Empty or invalid animation, so release allocated resources and return */
+ g_object_unref(animation);
+ g_free(animationSignal);
+
+ return;
+ }
+
+ /* Check for duplicate animation */
+ if(clutter_actor_get_transition(CLUTTER_ACTOR(self), xfdashboard_animation_get_id(animation)))
+ {
+ XFDASHBOARD_DEBUG(self, ANIMATION,
+ "Duplicate animation found for signal '%s'",
+ animationSignal);
+
+ /* Release allocated resources */
+ g_object_unref(animation);
+ g_free(animationSignal);
+
+ return;
+ }
+
+ /* Create animation entry data and add to list of animations */
+ data=g_new0(XfdashboardActorAnimationEntry, 1);
+ if(!data)
+ {
+ g_critical(_("Cannot allocate memory for animation entry for animation '%s' with signal '%s'"),
+ xfdashboard_animation_get_id(animation),
+ animationSignal);
+
+ /* Release allocated resources */
+ g_object_unref(animation);
+ g_free(animationSignal);
+
+ return;
+ }
+
+ data->signal=g_strdup(animationSignal);
+ data->animation=animation;
+
+ priv->animations=g_slist_prepend(priv->animations, data);
+
+ /* Start animation */
+ xfdashboard_animation_run(animation, _xfdashboard_actor_animation_done, self);
+ XFDASHBOARD_DEBUG(self, ANIMATION,
+ "Found and starting animation '%s' for signal '%s'",
+ xfdashboard_animation_get_id(animation),
+ animationSignal);
+
+ /* Release allocated resources */
+ g_free(animationSignal);
+}
+
+/* Signal handler for "class-added" signal of stylable interface */
+static void _xfdashboard_actor_stylable_class_added(XfdashboardStylable *inStylable, const gchar *inClass)
+{
+ g_return_if_fail(XFDASHBOARD_IS_ACTOR(inStylable));
+
+ /* Remove any animation that was added when this class was removed */
+ _xfdashboard_actor_remove_animation(inStylable, "class-removed", inClass);
+
+ /* Create animation for this class added */
+ _xfdashboard_actor_add_animation(inStylable, "class-added", inClass);
+}
+
+/* Signal handler for "class-removed" signal of stylable interface */
+static void _xfdashboard_actor_stylable_class_removed(XfdashboardStylable *inStylable, const gchar *inClass)
+{
+ g_return_if_fail(XFDASHBOARD_IS_ACTOR(inStylable));
+
+ /* Remove any animation that was added when this class was added */
+ _xfdashboard_actor_remove_animation(inStylable, "class-added", inClass);
+
+ /* Create animation for this class removed */
+ _xfdashboard_actor_add_animation(inStylable, "class-removed", inClass);
+}
+
+/* Signal handler for "pseudo-class-added" signal of stylable interface */
+static void _xfdashboard_actor_stylable_pseudo_class_added(XfdashboardStylable *inStylable, const gchar *inClass)
+{
+ g_return_if_fail(XFDASHBOARD_IS_ACTOR(inStylable));
+
+ /* Remove any animation that was added when this pseudo-class was removed */
+ _xfdashboard_actor_remove_animation(inStylable, "pseudo-class-removed", inClass);
+
+ /* Create animation for this pseudo-class added */
+ _xfdashboard_actor_add_animation(inStylable, "pseudo-class-added", inClass);
+}
+
+/* Signal handler for "pseudo-class-removed" signal of stylable interface */
+static void _xfdashboard_actor_stylable_pseudo_class_removed(XfdashboardStylable *inStylable, const gchar *inClass)
+{
+ g_return_if_fail(XFDASHBOARD_IS_ACTOR(inStylable));
+
+ /* Remove any animation that was added when this pseudo-class was added */
+ _xfdashboard_actor_remove_animation(inStylable, "pseudo-class-added", inClass);
+
+ /* Create animation for this pseudo-class removed */
+ _xfdashboard_actor_add_animation(inStylable, "pseudo-class-removed", inClass);
+}
+
/* Interface initialization
* Set up default functions
*/
@@ -718,8 +951,12 @@ static void _xfdashboard_actor_stylable_iface_init(XfdashboardStylableInterface
iface->get_parent=_xfdashboard_actor_stylable_get_parent;
iface->get_classes=_xfdashboard_actor_stylable_get_classes;
iface->set_classes=_xfdashboard_actor_stylable_set_classes;
+ iface->class_added=_xfdashboard_actor_stylable_class_added;
+ iface->class_removed=_xfdashboard_actor_stylable_class_removed;
iface->get_pseudo_classes=_xfdashboard_actor_stylable_get_pseudo_classes;
iface->set_pseudo_classes=_xfdashboard_actor_stylable_set_pseudo_classes;
+ iface->pseudo_class_added=_xfdashboard_actor_stylable_pseudo_class_added;
+ iface->pseudo_class_removed=_xfdashboard_actor_stylable_pseudo_class_removed;
iface->invalidate=_xfdashboard_actor_stylable_invalidate;
}
@@ -899,6 +1136,11 @@ static void _xfdashboard_actor_dispose(GObject *inObject)
priv->lastThemeStyleSet=NULL;
}
+ if(priv->animations)
+ {
+ // TODO: Release list of animations
+ }
+
/* Call parent's class dispose method */
G_OBJECT_CLASS(xfdashboard_actor_parent_class)->dispose(inObject);
}
@@ -1056,6 +1298,7 @@ void xfdashboard_actor_init(XfdashboardActor *self)
priv->stylePseudoClasses=NULL;
priv->lastThemeStyleSet=NULL;
priv->isFirstParent=TRUE;
+ priv->animations=NULL;
/* Connect signals */
g_signal_connect(self, "notify::mapped", G_CALLBACK(_xfdashboard_actor_on_mapped_changed), NULL);
diff --git a/libxfdashboard/animation.c b/libxfdashboard/animation.c
index a70a71f..387a228 100644
--- a/libxfdashboard/animation.c
+++ b/libxfdashboard/animation.c
@@ -658,26 +658,37 @@ void xfdashboard_animation_run(XfdashboardAnimation *self,
priv->doneCallback=inCallback;
priv->doneUserData=inUserData;
- /* Add all transition to their actors now */
- for(iter=priv->entries; iter; iter=g_slist_next(iter))
+ /* Add all transition to their actors now if any available ... */
+ if(priv->entries)
{
- /* Get entry */
- entry=(XfdashboardAnimationEntry*)iter->data;
- if(!entry) continue;
+ for(iter=priv->entries; iter; iter=g_slist_next(iter))
+ {
+ /* Get entry */
+ entry=(XfdashboardAnimationEntry*)iter->data;
+ if(!entry) continue;
- /* Add transition to actor which will start immediately */
- clutter_actor_add_transition(entry->actor, priv->id, entry->transition);
+ /* Add transition to actor which will start immediately */
+ clutter_actor_add_transition(entry->actor, priv->id, entry->transition);
#ifdef DEBUG
- XFDASHBOARD_DEBUG(self, ANIMATION,
- "Animation '%s' added transition %p to actor %s@%p",
- priv->id,
- entry->transition,
- G_OBJECT_TYPE_NAME(entry->actor),
- entry->actor);
+ XFDASHBOARD_DEBUG(self, ANIMATION,
+ "Animation '%s' added transition %p to actor %s@%p",
+ priv->id,
+ entry->transition,
+ G_OBJECT_TYPE_NAME(entry->actor),
+ entry->actor);
#endif
- }
+ }
- XFDASHBOARD_DEBUG(self, ANIMATION,
- "Started animation '%s'",
- priv->id);
+ XFDASHBOARD_DEBUG(self, ANIMATION,
+ "Started animation '%s'",
+ priv->id);
+ }
+ /* ... otherwise destroy empty animation immediately to get callback
+ * function called and to avoid memory leaks.
+ */
+ else
+ {
+ /* Destroy empty animation */
+ g_object_unref(self);
+ }
}
diff --git a/libxfdashboard/theme-animation.c b/libxfdashboard/theme-animation.c
index d21671f..4203d8d 100644
--- a/libxfdashboard/theme-animation.c
+++ b/libxfdashboard/theme-animation.c
@@ -1168,12 +1168,6 @@ static void _xfdashboard_theme_animation_parse_trigger_start(GMarkupParseContext
return;
}
- if(!_xfdashboard_theme_animation_string_to_gint(timelineDelayText, &timelineDelay, &error))
- {
- g_propagate_error(outError, error);
- return;
- }
-
timelineMode=xfdashboard_get_enum_value_from_nickname(CLUTTER_TYPE_ANIMATION_MODE, timelineModeText);
if(timelineMode==G_MININT)
{
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the Xfce4-commits
mailing list