[gnome-shell] st: Add transition API to StAdjustment
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] st: Add transition API to StAdjustment
- Date: Wed, 7 Aug 2019 16:52:10 +0000 (UTC)
commit 9097c5e9c016d0d247e93b1fffd27fe844538607
Author: Florian Müllner <fmuellner gnome org>
Date: Fri Aug 2 16:58:39 2019 +0200
st: Add transition API to StAdjustment
StAdjustment implements the ClutterAnimatable interface, so we can
already animate its properties with ClutterPropertyTransitions.
But as it is currently not possible to associate a transition with
an adjustment, it must be owned (and kept alive in case of GC) by
the calling code.
Change that by implementing the same (add|remove|get)_transition() API
as ClutterActor, so we can use a familiar API and even duck typing in
case of javascript.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/669
src/st/st-adjustment.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++
src/st/st-adjustment.h | 8 +++
2 files changed, 172 insertions(+)
---
diff --git a/src/st/st-adjustment.c b/src/st/st-adjustment.c
index b705e6e6c..890c69903 100644
--- a/src/st/st-adjustment.c
+++ b/src/st/st-adjustment.c
@@ -45,6 +45,8 @@ struct _StAdjustmentPrivate
* not all properties may be set yet. */
guint is_constructing : 1;
+ GHashTable *transitions;
+
gdouble lower;
gdouble upper;
gdouble value;
@@ -85,6 +87,14 @@ enum
static guint signals[LAST_SIGNAL] = { 0, };
+typedef struct _TransitionClosure
+{
+ StAdjustment *adjustment;
+ ClutterTransition *transition;
+ char *name;
+ gulong completed_id;
+} TransitionClosure;
+
static gboolean st_adjustment_set_lower (StAdjustment *adjustment,
gdouble lower);
static gboolean st_adjustment_set_upper (StAdjustment *adjustment,
@@ -201,6 +211,17 @@ st_adjustment_set_property (GObject *gobject,
}
}
+static void
+st_adjustment_dispose (GObject *object)
+{
+ StAdjustmentPrivate *priv;
+
+ priv = st_adjustment_get_instance_private (ST_ADJUSTMENT (object));
+ g_clear_pointer (&priv->transitions, g_hash_table_unref);
+
+ G_OBJECT_CLASS (st_adjustment_parent_class)->dispose (object);
+}
+
static void
st_adjustment_class_init (StAdjustmentClass *klass)
{
@@ -209,6 +230,7 @@ st_adjustment_class_init (StAdjustmentClass *klass)
object_class->constructed = st_adjustment_constructed;
object_class->get_property = st_adjustment_get_property;
object_class->set_property = st_adjustment_set_property;
+ object_class->dispose = st_adjustment_dispose;
props[PROP_LOWER] =
g_param_spec_double ("lower", "Lower", "Lower bound",
@@ -588,3 +610,145 @@ st_adjustment_adjust_for_scroll_event (StAdjustment *adjustment,
new_value = priv->value + delta * scroll_unit;
st_adjustment_set_value (adjustment, new_value);
}
+
+static void
+transition_closure_free (gpointer data)
+{
+ TransitionClosure *clos;
+ ClutterTimeline *timeline;
+
+ if (G_UNLIKELY (data == NULL))
+ return;
+
+ clos = data;
+ timeline = CLUTTER_TIMELINE (clos->transition);
+
+ g_signal_handler_disconnect (clos->transition, clos->completed_id);
+
+ if (clutter_timeline_is_playing (timeline))
+ clutter_timeline_stop (timeline);
+
+ g_object_unref (clos->transition);
+ g_free (clos->name);
+ g_free (clos);
+}
+
+static void
+remove_transition (StAdjustment *adjustment,
+ const char *name)
+{
+ StAdjustmentPrivate *priv = st_adjustment_get_instance_private (adjustment);
+
+ g_hash_table_remove (priv->transitions, name);
+
+ if (g_hash_table_size (priv->transitions) == 0)
+ g_clear_pointer (&priv->transitions, g_hash_table_unref);
+}
+
+static void
+on_transition_stopped (ClutterTransition *transition,
+ gboolean is_finished,
+ TransitionClosure *clos)
+{
+ StAdjustment *adjustment = clos->adjustment;
+
+ if (!clutter_transition_get_remove_on_complete (transition))
+ return;
+
+ /* Take a reference, because removing the closure will
+ * release the reference on the transition, and we want
+ * it to survive the signal emission; ClutterTransition's
+ * own ::stopped signal closure will release it after all
+ * other handlers have run.
+ */
+ g_object_ref (transition);
+
+ remove_transition (adjustment, clos->name);
+}
+
+/**
+ * st_adjustment_get_transition:
+ * Returns: (transfer none) (nullable):
+ */
+ClutterTransition *
+st_adjustment_get_transition (StAdjustment *adjustment,
+ const char *name)
+{
+ StAdjustmentPrivate *priv;
+ TransitionClosure *clos;
+
+ g_return_val_if_fail (ST_IS_ADJUSTMENT (adjustment), NULL);
+
+ priv = st_adjustment_get_instance_private (adjustment);
+
+ if (priv->transitions == NULL)
+ return NULL;
+
+ clos = g_hash_table_lookup (priv->transitions, name);
+ if (clos == NULL)
+ return NULL;
+
+ return clos->transition;
+}
+
+void
+st_adjustment_add_transition (StAdjustment *adjustment,
+ const char *name,
+ ClutterTransition *transition)
+{
+ StAdjustmentPrivate *priv;
+ TransitionClosure *clos;
+
+ g_return_if_fail (ST_IS_ADJUSTMENT (adjustment));
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (CLUTTER_IS_TRANSITION (transition));
+
+ priv = st_adjustment_get_instance_private (adjustment);
+
+ if (priv->transitions == NULL)
+ priv->transitions = g_hash_table_new_full (g_str_hash, g_str_equal,
+ NULL,
+ transition_closure_free);
+
+ if (g_hash_table_lookup (priv->transitions, name) != NULL)
+ {
+ g_warning ("A transition with name '%s' already exists for "
+ "adjustment '%p'", name, adjustment);
+ return;
+ }
+
+ clutter_transition_set_animatable (transition, CLUTTER_ANIMATABLE (adjustment));
+
+ clos = g_new (TransitionClosure, 1);
+ clos->adjustment = adjustment;
+ clos->transition = g_object_ref (transition);
+ clos->name = g_strdup (name);
+ clos->completed_id = g_signal_connect (transition, "stopped",
+ G_CALLBACK (on_transition_stopped),
+ clos);
+
+ g_hash_table_insert (priv->transitions, clos->name, clos);
+ clutter_timeline_start (CLUTTER_TIMELINE (transition));
+}
+
+void
+st_adjustment_remove_transition (StAdjustment *adjustment,
+ const char *name)
+{
+ StAdjustmentPrivate *priv;
+ TransitionClosure *clos;
+
+ g_return_if_fail (ST_IS_ADJUSTMENT (adjustment));
+ g_return_if_fail (name != NULL);
+
+ priv = st_adjustment_get_instance_private (adjustment);
+
+ if (priv->transitions == NULL)
+ return;
+
+ clos = g_hash_table_lookup (priv->transitions, name);
+ if (clos == NULL)
+ return;
+
+ remove_transition (adjustment, name);
+}
diff --git a/src/st/st-adjustment.h b/src/st/st-adjustment.h
index 529d8628e..302755a09 100644
--- a/src/st/st-adjustment.h
+++ b/src/st/st-adjustment.h
@@ -78,6 +78,14 @@ void st_adjustment_get_values (StAdjustment *adjustment,
void st_adjustment_adjust_for_scroll_event (StAdjustment *adjustment,
gdouble delta);
+ClutterTransition * st_adjustment_get_transition (StAdjustment *adjustment,
+ const char *name);
+void st_adjustment_add_transition (StAdjustment *adjustment,
+ const char *name,
+ ClutterTransition *transition);
+void st_adjustment_remove_transition (StAdjustment *adjustment,
+ const char *name);
+
G_END_DECLS
#endif /* __ST_ADJUSTMENT_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]