ges: Move the notion of children properties to GESTimelineElement
authorThibault Saunier <tsaunier@gnome.org>
Wed, 18 Mar 2015 19:23:55 +0000 (20:23 +0100)
committerThibault Saunier <tsaunier@gnome.org>
Wed, 18 Mar 2015 19:23:55 +0000 (20:23 +0100)
Summary:
Deprecate the old GESTrackElement children property handling API.

New APIs:
  * ges_timeline_element_list_children_properties
  * ges_timeline_element_lookup_child
  * ges_timeline_element_get_child_property_by_pspec
  * ges_timeline_element_get_child_property_valist
  * ges_timeline_element_get_child_properties
  * ges_timeline_element_set_child_property_valist
  * ges_timeline_element_set_child_property_by_pspec
  * ges_timeline_element_set_child_properties
  * ges_timeline_element_set_child_property
  * ges_timeline_element_get_child_property
  * ges_timeline_element_add_child_property
  * ges_timeline_element_remove_child_property

Deprecated APIs:
  * ges_track_element_list_children_properties
  * ges_track_element_lookup_child
  * ges_track_element_get_child_property_by_pspec
  * ges_track_element_get_child_property_valist
  * ges_track_element_get_child_properties
  * ges_track_element_set_child_property_valist
  * ges_track_element_set_child_property_by_pspec
  * ges_track_element_set_child_properties
  * ges_track_element_set_child_property
  * ges_track_element_get_child_property
  * ges_track_element_add_child_property

Reviewers: Mathieu_Du

Reviewed By: Mathieu_Du

Differential Revision: http://phabricator.freedesktop.org/D40

12 files changed:
.arcconfig [new file with mode: 0644]
docs/libs/ges-sections.txt
ges/ges-container.c
ges/ges-timeline-element.c
ges/ges-timeline-element.h
ges/ges-timeline.c
ges/ges-timeline.h
ges/ges-track-element.c
ges/ges-track-element.h
tests/check/ges/effects.c
tests/check/ges/project.c
tests/check/ges/timelineedition.c

diff --git a/.arcconfig b/.arcconfig
new file mode 100644 (file)
index 0000000..fc70fd3
--- /dev/null
@@ -0,0 +1,3 @@
+{
+    "phabricator.uri" : "http://phabricator.freedesktop.org/"
+}
index 570caba1a3ed81c9db08fe2c93c871a3a5d46089..eee72efe0d3b09f5b537deeaf86916f5a558a0b5 100644 (file)
@@ -366,6 +366,7 @@ ges_timeline_enable_update
 ges_timeline_is_updating
 <SUBSECTION usage>
 ges_timeline_get_tracks
+ges_timeline_get_layer
 ges_timeline_get_layers
 ges_timeline_get_track_for_pad
 ges_timeline_get_pad_for_track
@@ -451,6 +452,18 @@ ges_timeline_element_get_toplevel_parent
 ges_timeline_element_copy
 ges_timeline_element_get_name
 ges_timeline_element_set_name
+ges_timeline_element_list_children_properties
+ges_timeline_element_lookup_child
+ges_timeline_element_get_child_property_by_pspec
+ges_timeline_element_get_child_property_valist
+ges_timeline_element_get_child_properties
+ges_timeline_element_set_child_property_valist
+ges_timeline_element_set_child_property_by_pspec
+ges_timeline_element_set_child_properties
+ges_timeline_element_set_child_property
+ges_timeline_element_get_child_property
+ges_timeline_element_add_child_property
+ges_timeline_element_remove_child_property
 GES_TIMELINE_ELEMENT_PARENT
 GES_TIMELINE_ELEMENT_TIMELINE
 GES_TIMELINE_ELEMENT_START
index c401059189400341bd3c74dc59dea93ec02c08c5..7b26f89e7272203233abb3acda8ce97cef6ef2b6 100644 (file)
@@ -185,6 +185,86 @@ _set_duration (GESTimelineElement * element, GstClockTime duration)
   return TRUE;
 }
 
+static void
+_ges_container_add_child_properties (GESContainer * container,
+    GESTimelineElement * child)
+{
+  guint n_props, i;
+
+  GParamSpec **child_props =
+      ges_timeline_element_list_children_properties (child,
+      &n_props);
+
+  for (i = 0; i < n_props; i++) {
+    GObject *prop_child;
+
+    if (ges_timeline_element_lookup_child (child, child_props[i]->name,
+            &prop_child, NULL)) {
+      ges_timeline_element_add_child_property (GES_TIMELINE_ELEMENT (container),
+          child_props[i], prop_child);
+
+    }
+
+    g_param_spec_unref (child_props[i]);
+  }
+
+  g_free (child_props);
+}
+
+static void
+_ges_container_remove_child_properties (GESContainer * container,
+    GESTimelineElement * child)
+{
+  guint n_props, i;
+
+  GParamSpec **child_props =
+      ges_timeline_element_list_children_properties (child,
+      &n_props);
+
+  for (i = 0; i < n_props; i++) {
+    GObject *prop_child;
+
+    if (ges_timeline_element_lookup_child (child, child_props[i]->name,
+            &prop_child, NULL)) {
+      ges_timeline_element_remove_child_property (GES_TIMELINE_ELEMENT
+          (container), child_props[i]);
+
+    }
+
+    g_param_spec_unref (child_props[i]);
+  }
+
+  g_free (child_props);
+}
+
+static GParamSpec **
+_list_children_properties (GESTimelineElement * self, guint * n_properties)
+{
+  GList *tmp;
+
+  for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next)
+    _ges_container_add_child_properties (GES_CONTAINER (self), tmp->data);
+
+  return
+      GES_TIMELINE_ELEMENT_CLASS
+      (ges_container_parent_class)->list_children_properties (self,
+      n_properties);
+}
+
+static gboolean
+_lookup_child (GESTimelineElement * self, const gchar * prop_name,
+    GObject ** child, GParamSpec ** pspec)
+{
+  GList *tmp;
+
+  for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next)
+    _ges_container_add_child_properties (GES_CONTAINER (self), tmp->data);
+
+  return
+      GES_TIMELINE_ELEMENT_CLASS (ges_container_parent_class)->lookup_child
+      (self, prop_name, child, pspec);
+}
+
 /******************************************
  *                                        *
  * GObject virtual methods implementation *
@@ -281,6 +361,8 @@ ges_container_class_init (GESContainerClass * klass)
   element_class->set_start = _set_start;
   element_class->set_duration = _set_duration;
   element_class->set_inpoint = _set_inpoint;
+  element_class->list_children_properties = _list_children_properties;
+  element_class->lookup_child = _lookup_child;
 
   /* No default implementations */
   klass->remove_child = NULL;
@@ -558,6 +640,8 @@ ges_container_add (GESContainer * container, GESTimelineElement * child)
     return FALSE;
   }
 
+  _ges_container_add_child_properties (container, child);
+
   g_signal_emit (container, ges_container_signals[CHILD_ADDED_SIGNAL], 0,
       child);
 
@@ -602,6 +686,8 @@ ges_container_remove (GESContainer * container, GESTimelineElement * child)
   /* Let it live removing from our mappings */
   g_hash_table_remove (priv->mappings, child);
 
+  _ges_container_remove_child_properties (container, child);
+
   g_signal_emit (container, ges_container_signals[CHILD_REMOVED_SIGNAL], 0,
       child);
   gst_object_unref (child);
index 3ace821a2f95089843a1c0b126aa2cf62fee77a7..0ddd28d989c3cebdff3647acf4798f789b998c75 100644 (file)
  * responsible for controlling its timing properties.
  */
 
+#include "ges-utils.h"
 #include "ges-timeline-element.h"
 #include "ges-extractable.h"
 #include "ges-meta-container.h"
 #include "ges-internal.h"
+
 #include <string.h>
+#include <gobject/gvaluecollector.h>
 
 /* maps type name quark => count */
 static GData *object_name_counts = NULL;
@@ -67,13 +70,90 @@ enum
   PROP_LAST
 };
 
+enum
+{
+  DEEP_NOTIFY,
+  LAST_SIGNAL
+};
+
+static guint ges_timeline_element_signals[LAST_SIGNAL] = { 0 };
+
 static GParamSpec *properties[PROP_LAST] = { NULL, };
 
 struct _GESTimelineElementPrivate
 {
   gboolean serialize;
+
+  /* We keep a link between properties name and elements internally
+   * The hashtable should look like
+   * {GParamaSpec ---> child}*/
+  GHashTable *children_props;
 };
 
+static gboolean
+_lookup_child (GESTimelineElement * self, const gchar * prop_name,
+    GObject ** child, GParamSpec ** pspec)
+{
+  GHashTableIter iter;
+  gpointer key, value;
+  gchar **names, *name, *classename;
+  gboolean res;
+
+  classename = NULL;
+  res = FALSE;
+
+  names = g_strsplit (prop_name, "::", 2);
+  if (names[1] != NULL) {
+    classename = names[0];
+    name = names[1];
+  } else
+    name = names[0];
+
+  g_hash_table_iter_init (&iter, self->priv->children_props);
+  while (g_hash_table_iter_next (&iter, &key, &value)) {
+    if (g_strcmp0 (G_PARAM_SPEC (key)->name, name) == 0) {
+      if (classename == NULL ||
+          g_strcmp0 (G_OBJECT_TYPE_NAME (G_OBJECT (value)), classename) == 0) {
+        GST_DEBUG_OBJECT (self, "The %s property from %s has been found", name,
+            classename);
+        if (child)
+          *child = gst_object_ref (value);
+
+        if (pspec)
+          *pspec = g_param_spec_ref (key);
+        res = TRUE;
+        break;
+      }
+    }
+  }
+  g_strfreev (names);
+
+  return res;
+}
+
+static GParamSpec **
+default_list_children_properties (GESTimelineElement * self,
+    guint * n_properties)
+{
+  GParamSpec **pspec, *spec;
+  GHashTableIter iter;
+  gpointer key, value;
+
+  guint i = 0;
+
+  *n_properties = g_hash_table_size (self->priv->children_props);
+  pspec = g_new (GParamSpec *, *n_properties);
+
+  g_hash_table_iter_init (&iter, self->priv->children_props);
+  while (g_hash_table_iter_next (&iter, &key, &value)) {
+    spec = G_PARAM_SPEC (key);
+    pspec[i] = g_param_spec_ref (spec);
+    i++;
+  }
+
+  return pspec;
+}
+
 static void
 _get_property (GObject * object, guint property_id,
     GValue * value, GParamSpec * pspec)
@@ -169,6 +249,10 @@ ges_timeline_element_init (GESTimelineElement * self)
       GES_TYPE_TIMELINE_ELEMENT, GESTimelineElementPrivate);
 
   self->priv->serialize = TRUE;
+
+  self->priv->children_props =
+      g_hash_table_new_full ((GHashFunc) ges_pspec_hash, ges_pspec_equal,
+      (GDestroyNotify) g_param_spec_unref, gst_object_unref);
 }
 
 static void
@@ -268,6 +352,21 @@ ges_timeline_element_class_init (GESTimelineElementClass * klass)
 
   g_object_class_install_properties (object_class, PROP_LAST, properties);
 
+  /**
+   * GESTimelineElement::deep-notify:
+   * @timeline_element: a #GESTtimelineElement
+   * @prop_object: the object that originated the signal
+   * @prop: the property that changed
+   *
+   * The deep notify signal is used to be notified of property changes of all
+   * the childs of @timeline_element
+   */
+  ges_timeline_element_signals[DEEP_NOTIFY] =
+      g_signal_new ("deep-notify", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED |
+      G_SIGNAL_NO_HOOKS, 0, NULL, NULL, g_cclosure_marshal_generic,
+      G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_PARAM);
+
   object_class->finalize = ges_timeline_element_finalize;
 
   klass->set_parent = NULL;
@@ -282,6 +381,9 @@ ges_timeline_element_class_init (GESTimelineElementClass * klass)
   klass->roll_start = NULL;
   klass->roll_end = NULL;
   klass->trim = NULL;
+
+  klass->list_children_properties = default_list_children_properties;
+  klass->lookup_child = _lookup_child;
 }
 
 static void
@@ -1082,3 +1184,440 @@ had_timeline:
     return FALSE;
   }
 }
+
+static void
+child_prop_changed_cb (GObject * child, GParamSpec * arg
+    G_GNUC_UNUSED, GESTimelineElement * self)
+{
+  g_signal_emit (self, ges_timeline_element_signals[DEEP_NOTIFY], 0,
+      child, arg);
+}
+
+gboolean
+ges_timeline_element_add_child_property (GESTimelineElement * self,
+    GParamSpec * pspec, GObject * child)
+{
+  GST_DEBUG_OBJECT (self, "Adding child property: %" GST_PTR_FORMAT "::%s",
+      child, pspec->name);
+
+  if (g_hash_table_insert (self->priv->children_props,
+          g_param_spec_ref (pspec), gst_object_ref (child))) {
+    gchar *signame = g_strconcat ("notify::", pspec->name, NULL);
+
+    g_signal_connect (child, signame, G_CALLBACK (child_prop_changed_cb), self);
+
+    g_free (signame);
+
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+ * ges_track_element_get_child_property_by_pspec:
+ * @self: a #GESTrackElement
+ * @pspec: The #GParamSpec that specifies the property you want to get
+ * @value: (out): return location for the value
+ *
+ * Gets a property of a child of @self.
+ */
+void
+ges_timeline_element_get_child_property_by_pspec (GESTimelineElement * self,
+    GParamSpec * pspec, GValue * value)
+{
+  GstElement *element;
+
+  g_return_if_fail (GES_IS_TIMELINE_ELEMENT (self));
+
+  element = g_hash_table_lookup (self->priv->children_props, pspec);
+  if (!element)
+    goto not_found;
+
+  g_object_get_property (G_OBJECT (element), pspec->name, value);
+
+  return;
+
+not_found:
+  {
+    GST_ERROR_OBJECT (self, "The %s property doesn't exist", pspec->name);
+    return;
+  }
+}
+
+/**
+ * ges_timeline_element_set_child_property_by_pspec:
+ * @self: a #GESTimelineElement
+ * @pspec: The #GParamSpec that specifies the property you want to set
+ * @value: the value
+ *
+ * Sets a property of a child of @self.
+ */
+void
+ges_timeline_element_set_child_property_by_pspec (GESTimelineElement * self,
+    GParamSpec * pspec, GValue * value)
+{
+  GObject *child;
+
+  g_return_if_fail (GES_IS_TRACK_ELEMENT (self));
+
+  if (!ges_timeline_element_lookup_child (self, pspec->name, &child, &pspec))
+    goto not_found;
+
+  g_object_set_property (child, pspec->name, value);
+
+  return;
+
+not_found:
+  {
+    GST_ERROR ("The %s property doesn't exist", pspec->name);
+    return;
+  }
+}
+
+/**
+ * ges_timeline_element_set_child_property:
+ * @self: The origin #GESTimelineElement
+ * @property_name: The name of the property
+ * @value: the value
+ *
+ * Sets a property of a child of @self
+ *
+ * Note that #ges_timeline_element_set_child_property is really
+ * intended for language bindings, #ges_timeline_element_set_child_properties
+ * is much more convenient for C programming.
+ *
+ * Returns: %TRUE if the property was set, %FALSE otherwize
+ */
+gboolean
+ges_timeline_element_set_child_property (GESTimelineElement * self,
+    const gchar * property_name, GValue * value)
+{
+  GParamSpec *pspec;
+  GObject *child;
+
+  g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE);
+
+  if (!ges_timeline_element_lookup_child (self, property_name, &child, &pspec))
+    goto not_found;
+
+  g_object_set_property (child, pspec->name, value);
+
+  gst_object_unref (child);
+  g_param_spec_unref (pspec);
+
+  return TRUE;
+
+not_found:
+  {
+    GST_WARNING_OBJECT (self, "The %s property doesn't exist", property_name);
+
+    return FALSE;
+  }
+}
+
+/**
+* ges_timeline_element_get_child_property:
+* @object: The origin #GESTimelineElement
+* @property_name: The name of the property
+* @value: (out): return location for the property value, it will
+* be initialized if it is initialized with 0
+*
+* In general, a copy is made of the property contents and
+* the caller is responsible for freeing the memory by calling
+* g_value_unset().
+*
+* Gets a property of a GstElement contained in @object.
+*
+* Note that #ges_timeline_element_get_child_property is really
+* intended for language bindings, #ges_timeline_element_get_child_properties
+* is much more convenient for C programming.
+*
+* Returns: %TRUE if the property was found, %FALSE otherwize
+*/
+gboolean
+ges_timeline_element_get_child_property (GESTimelineElement * self,
+    const gchar * property_name, GValue * value)
+{
+  GParamSpec *pspec;
+  GObject *child;
+
+  g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE);
+
+  if (!ges_timeline_element_lookup_child (self, property_name, &child, &pspec))
+    goto not_found;
+
+  if (G_VALUE_TYPE (value) == G_TYPE_INVALID)
+    g_value_init (value, pspec->value_type);
+
+  g_object_get_property (child, pspec->name, value);
+
+  gst_object_unref (child);
+  g_param_spec_unref (pspec);
+
+  return TRUE;
+
+not_found:
+  {
+    GST_WARNING_OBJECT (self, "The %s property doesn't exist", property_name);
+
+    return FALSE;
+  }
+}
+
+/**
+ * ges_timeline_element_lookup_child:
+ * @self: object to lookup the property in
+ * @prop_name: name of the property to look up. You can specify the name of the
+ *     class as such: "ClassName::property-name", to guarantee that you get the
+ *     proper GParamSpec in case various GstElement-s contain the same property
+ *     name. If you don't do so, you will get the first element found, having
+ *     this property and the and the corresponding GParamSpec.
+ * @element: (out) (allow-none) (transfer full): pointer to a #GstElement that
+ *     takes the real object to set property on
+ * @pspec: (out) (allow-none) (transfer full): pointer to take the #GParamSpec
+ *     describing the property
+ *
+ * Looks up which @element and @pspec would be effected by the given @name. If various
+ * contained elements have this property name you will get the first one, unless you
+ * specify the class name in @name.
+ *
+ * Returns: TRUE if @element and @pspec could be found. FALSE otherwise. In that
+ * case the values for @pspec and @element are not modified. Unref @element after
+ * usage.
+ */
+gboolean
+ges_timeline_element_lookup_child (GESTimelineElement * self,
+    const gchar * prop_name, GObject ** child, GParamSpec ** pspec)
+{
+  GESTimelineElementClass *class;
+
+  g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE);
+  class = GES_TIMELINE_ELEMENT_GET_CLASS (self);
+  g_return_val_if_fail (class->lookup_child, FALSE);
+
+  return class->lookup_child (self, prop_name, child, pspec);
+}
+
+/**
+ * ges_timeline_element_set_child_property_valist:
+ * @self: The #GESTimelineElement parent object
+ * @first_property_name: The name of the first property to set
+ * @var_args: value for the first property, followed optionally by more
+ * name/return location pairs, followed by NULL
+ *
+ * Sets a property of a child of @self. If there are various child elements
+ * that have the same property name, you can distinguish them using the following
+ * syntax: 'ClasseName::property_name' as property name. If you don't, the
+ * corresponding property of the first element found will be set.
+ */
+void
+ges_timeline_element_set_child_property_valist (GESTimelineElement * self,
+    const gchar * first_property_name, va_list var_args)
+{
+  const gchar *name;
+  GParamSpec *pspec;
+  GObject *child;
+
+  gchar *error = NULL;
+  GValue value = { 0, };
+
+  g_return_if_fail (GES_IS_TIMELINE_ELEMENT (self));
+
+  name = first_property_name;
+
+  /* Note: This part is in big part copied from the gst_child_object_set_valist
+   * method. */
+
+  /* iterate over pairs */
+  while (name) {
+    if (!ges_timeline_element_lookup_child (self, name, &child, &pspec))
+      goto not_found;
+
+    G_VALUE_COLLECT_INIT (&value, pspec->value_type, var_args,
+        G_VALUE_NOCOPY_CONTENTS, &error);
+
+    if (error)
+      goto cant_copy;
+
+    g_object_set_property (child, pspec->name, &value);
+
+    gst_object_unref (child);
+    g_value_unset (&value);
+
+    name = va_arg (var_args, gchar *);
+  }
+  return;
+
+not_found:
+  {
+    GST_WARNING_OBJECT (self, "No property %s in OBJECT\n", name);
+    return;
+  }
+cant_copy:
+  {
+    GST_WARNING_OBJECT (self, "error copying value %s in %p: %s", pspec->name,
+        self, error);
+
+    g_value_unset (&value);
+    return;
+  }
+}
+
+/**
+ * ges_timeline_element_set_child_properties:
+ * @self: The #GESTimelineElement parent object
+ * @first_property_name: The name of the first property to set
+ * @...: value for the first property, followed optionally by more
+ * name/return location pairs, followed by NULL
+ *
+ * Sets a property of a child of @self. If there are various child elements
+ * that have the same property name, you can distinguish them using the following
+ * syntax: 'ClasseName::property_name' as property name. If you don't, the
+ * corresponding property of the first element found will be set.
+ */
+void
+ges_timeline_element_set_child_properties (GESTimelineElement * self,
+    const gchar * first_property_name, ...)
+{
+  va_list var_args;
+
+  g_return_if_fail (GES_IS_TIMELINE_ELEMENT (self));
+
+  va_start (var_args, first_property_name);
+  ges_timeline_element_set_child_property_valist (self, first_property_name,
+      var_args);
+  va_end (var_args);
+}
+
+/**
+ * ges_timeline_element_get_child_property_valist:
+ * @self: The #GESTimelineElement parent object
+ * @first_property_name: The name of the first property to get
+ * @var_args: value for the first property, followed optionally by more
+ * name/return location pairs, followed by NULL
+ *
+ * Gets a property of a child of @self. If there are various child elements
+ * that have the same property name, you can distinguish them using the following
+ * syntax: 'ClasseName::property_name' as property name. If you don't, the
+ * corresponding property of the first element found will be set.
+ */
+void
+ges_timeline_element_get_child_property_valist (GESTimelineElement * self,
+    const gchar * first_property_name, va_list var_args)
+{
+  const gchar *name;
+  gchar *error = NULL;
+  GValue value = { 0, };
+  GParamSpec *pspec;
+  GObject *child;
+
+  g_return_if_fail (GES_IS_TIMELINE_ELEMENT (self));
+
+  name = first_property_name;
+
+  /* This part is in big part copied from the gst_child_object_get_valist method */
+  while (name) {
+    if (!ges_timeline_element_lookup_child (self, name, &child, &pspec))
+      goto not_found;
+
+    g_value_init (&value, pspec->value_type);
+    g_object_get_property (child, pspec->name, &value);
+    gst_object_unref (child);
+
+    G_VALUE_LCOPY (&value, var_args, 0, &error);
+    if (error)
+      goto cant_copy;
+    g_value_unset (&value);
+    name = va_arg (var_args, gchar *);
+  }
+  return;
+
+not_found:
+  {
+    GST_WARNING_OBJECT (self, "no child property %s", name);
+    return;
+  }
+cant_copy:
+  {
+    GST_WARNING_OBJECT (self, "error copying value %s in %s", pspec->name,
+        error);
+
+    g_value_unset (&value);
+    return;
+  }
+}
+
+static gint
+compare_gparamspec (GParamSpec ** a, GParamSpec ** b, gpointer udata)
+{
+  return g_strcmp0 ((*a)->name, (*b)->name);
+}
+
+
+/**
+ * ges_timeline_element_list_children_properties:
+ * @self: The #GESTimelineElement to get the list of children properties from
+ * @n_properties: (out): return location for the length of the returned array
+ *
+ * Gets an array of #GParamSpec* for all configurable properties of the
+ * children of @self.
+ *
+ * Returns: (transfer full) (array length=n_properties): an array of #GParamSpec* which should be freed after use or
+ * %NULL if something went wrong
+ */
+GParamSpec **
+ges_timeline_element_list_children_properties (GESTimelineElement * self,
+    guint * n_properties)
+{
+  GParamSpec **ret;
+  GESTimelineElementClass *class;
+
+  g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), NULL);
+
+  class = GES_TIMELINE_ELEMENT_GET_CLASS (self);
+
+  if (!class->list_children_properties) {
+    GST_INFO_OBJECT (self, "No %s->list_children_properties implementation",
+        G_OBJECT_TYPE_NAME (self));
+
+    *n_properties = 0;
+    return NULL;
+  }
+
+  ret = class->list_children_properties (self, n_properties);
+  g_qsort_with_data (ret, *n_properties, sizeof (GParamSpec *),
+      (GCompareDataFunc) compare_gparamspec, NULL);
+
+  return ret;
+}
+
+/**
+ * ges_timeline_element_get_child_properties:
+ * @self: The origin #GESTimelineElement
+ * @first_property_name: The name of the first property to get
+ * @...: return location for the first property, followed optionally by more
+ * name/return location pairs, followed by NULL
+ *
+ * Gets properties of a child of @self.
+ */
+void
+ges_timeline_element_get_child_properties (GESTimelineElement * self,
+    const gchar * first_property_name, ...)
+{
+  va_list var_args;
+
+  g_return_if_fail (GES_IS_TIMELINE_ELEMENT (self));
+
+  va_start (var_args, first_property_name);
+  ges_timeline_element_get_child_property_valist (self, first_property_name,
+      var_args);
+  va_end (var_args);
+}
+
+gboolean
+ges_timeline_element_remove_child_property (GESTimelineElement * self,
+    GParamSpec * pspec)
+{
+  return g_hash_table_remove (self->priv->children_props, pspec);
+}
index d787d66819961b40252bc6a79017dd9b5c9aa69c..ba0d5615c5b66ad27569b66999803183d91ada58 100644 (file)
@@ -185,11 +185,15 @@ struct _GESTimelineElementClass
   gboolean (*roll_start)       (GESTimelineElement *self, guint64  start);
   gboolean (*roll_end)         (GESTimelineElement *self, guint64  end);
   gboolean (*trim)             (GESTimelineElement *self, guint64  start);
-  void (*deep_copy)            (GESTimelineElement *self, GESTimelineElement *copy);
+  void     (*deep_copy)        (GESTimelineElement *self, GESTimelineElement *copy);
+
+  GParamSpec** (*list_children_properties) (GESTimelineElement * self, guint *n_properties);
+  gboolean (*lookup_child)                 (GESTimelineElement *self, const gchar *prop_name,
+                                            GObject **child, GParamSpec **pspec);
 
   /*< private > */
   /* Padding for API extension */
-  gpointer _ges_reserved[GES_PADDING_LARGE];
+  gpointer _ges_reserved[GES_PADDING_LARGE - 2];
 };
 
 GType ges_timeline_element_get_type (void) G_GNUC_CONST;
@@ -220,6 +224,57 @@ gboolean ges_timeline_element_trim                   (GESTimelineElement *self,
 GESTimelineElement * ges_timeline_element_copy       (GESTimelineElement *self, gboolean deep);
 gchar  * ges_timeline_element_get_name               (GESTimelineElement *self);
 gboolean  ges_timeline_element_set_name              (GESTimelineElement *self, const gchar *name);
+GParamSpec **
+ges_timeline_element_list_children_properties        (GESTimelineElement *self,
+                                                      guint *n_properties);
+
+gboolean ges_timeline_element_lookup_child           (GESTimelineElement *self,
+                                                      const gchar *prop_name,
+                                                      GObject  **child,
+                                                      GParamSpec **pspec);
+
+void
+ges_timeline_element_get_child_property_by_pspec     (GESTimelineElement * self,
+                                                      GParamSpec * pspec,
+                                                      GValue * value);
+
+void
+ges_timeline_element_get_child_property_valist       (GESTimelineElement * self,
+                                                      const gchar * first_property_name,
+                                                      va_list var_args);
+
+void ges_timeline_element_get_child_properties       (GESTimelineElement *self,
+                                                      const gchar * first_property_name,
+                                                      ...) G_GNUC_NULL_TERMINATED;
+
+void
+ges_timeline_element_set_child_property_valist      (GESTimelineElement * self,
+                                                     const gchar * first_property_name,
+                                                     va_list var_args);
+
+void
+ges_timeline_element_set_child_property_by_pspec    (GESTimelineElement * self,
+                                                     GParamSpec * pspec,
+                                                     GValue * value);
+
+void ges_timeline_element_set_child_properties     (GESTimelineElement * self,
+                                                     const gchar * first_property_name,
+                                                     ...) G_GNUC_NULL_TERMINATED;
+
+gboolean ges_timeline_element_set_child_property   (GESTimelineElement *self,
+                                                    const gchar *property_name,
+                                                    GValue * value);
+
+gboolean ges_timeline_element_get_child_property   (GESTimelineElement *self,
+                                                    const gchar *property_name,
+                                                    GValue * value);
+
+gboolean ges_timeline_element_add_child_property   (GESTimelineElement * self,
+                                                    GParamSpec *pspec,
+                                                    GObject *child);
+
+gboolean ges_timeline_element_remove_child_property(GESTimelineElement * self,
+                                                    GParamSpec *pspec);
 
 G_END_DECLS
 
index b753f9e25967f4e7b987d1f244bdbddffd74fafd..5b67253af97a4bd71c7d13174573c16bb1b1bc9e 100644 (file)
@@ -3214,3 +3214,34 @@ ges_timeline_is_empty (GESTimeline * timeline)
 
   return TRUE;
 }
+
+/**
+ * ges_timeline_get_layer:
+ * @timeline: The #GESTimeline to retrive a layer from
+ * @priority: The priority of the layer to find
+ *
+ * Retrieve the layer with @priority as a priority
+ *
+ * Returns: A #GESLayer or %NULL if no layer with @priority was found
+ *
+ * Since 1.6
+ */
+GESLayer *
+ges_timeline_get_layer (GESTimeline * timeline, guint priority)
+{
+  GList *tmp;
+  GESLayer *layer = NULL;
+
+  for (tmp = timeline->layers; tmp; tmp = tmp->next) {
+    GESLayer *tmp_layer = GES_LAYER (tmp->data);
+    guint tmp_priority;
+
+    g_object_get (tmp_layer, "priority", &tmp_priority, NULL);
+    if (tmp_priority == priority) {
+      layer = gst_object_ref (tmp_layer);
+      break;
+    }
+  }
+
+  return layer;
+}
index bbcc83aa3e20ae5e931d4f4c9173387acca6b4cc..fd5e6ec24f1d104fe7865c8926bad68966017128 100644 (file)
@@ -109,6 +109,7 @@ gboolean ges_timeline_add_layer (GESTimeline *timeline, GESLayer *layer);
 GESLayer * ges_timeline_append_layer (GESTimeline * timeline);
 gboolean ges_timeline_remove_layer (GESTimeline *timeline, GESLayer *layer);
 GList* ges_timeline_get_layers (GESTimeline *timeline);
+GESLayer* ges_timeline_get_layer (GESTimeline *timeline, guint priority);
 
 gboolean ges_timeline_add_track (GESTimeline *timeline, GESTrack *track);
 gboolean ges_timeline_remove_track (GESTimeline *timeline, GESTrack *track);
index fdeaa8ac03e69bda6c0deb36b23682631a5a2650..dab9a7efc52dcf9ade8a0ba4cd98e0d749091cfe 100644 (file)
  * its container, like the start position, the inpoint, the duration and the
  * priority.
  */
-#include "ges-utils.h"
 #include "ges-internal.h"
 #include "ges-extractable.h"
 #include "ges-track-element.h"
 #include "ges-clip.h"
 #include "ges-meta-container.h"
-#include <gobject/gvaluecollector.h>
 
 G_DEFINE_ABSTRACT_TYPE (GESTrackElement, ges_track_element,
     GES_TYPE_TIMELINE_ELEMENT);
@@ -54,11 +52,6 @@ struct _GESTrackElementPrivate
   GstElement *nleobject;        /* The NleObject */
   GstElement *element;          /* The element contained in the nleobject (can be NULL) */
 
-  /* We keep a link between properties name and elements internally
-   * The hashtable should look like
-   * {GParamaSpec ---> element,}*/
-  GHashTable *children_props;
-
   GESTrack *track;
 
   gboolean valid;
@@ -92,7 +85,6 @@ static GParamSpec *properties[PROP_LAST];
 
 enum
 {
-  DEEP_NOTIFY,
   CONTROL_BINDING_ADDED,
   LAST_SIGNAL
 };
@@ -102,11 +94,6 @@ static guint ges_track_element_signals[LAST_SIGNAL] = { 0 };
 static GstElement *ges_track_element_create_nle_object_func (GESTrackElement *
     object);
 
-static void connect_properties_signals (GESTrackElement * object);
-static void connect_signal (gpointer key, gpointer value, gpointer user_data);
-static void gst_element_prop_changed_cb (GstElement * element, GParamSpec * arg
-    G_GNUC_UNUSED, GESTrackElement * track_element);
-
 static gboolean _set_start (GESTimelineElement * element, GstClockTime start);
 static gboolean _set_inpoint (GESTimelineElement * element,
     GstClockTime inpoint);
@@ -125,42 +112,27 @@ static gboolean
 _lookup_child (GESTrackElement * object,
     const gchar * prop_name, GstElement ** element, GParamSpec ** pspec)
 {
-  GHashTableIter iter;
-  gpointer key, value;
-  gchar **names, *name, *classename;
-  gboolean res;
-
-  classename = NULL;
-  res = FALSE;
-
-  names = g_strsplit (prop_name, "::", 2);
-  if (names[1] != NULL) {
-    classename = names[0];
-    name = names[1];
-  } else
-    name = names[0];
-
-  g_hash_table_iter_init (&iter, object->priv->children_props);
-  while (g_hash_table_iter_next (&iter, &key, &value)) {
-    if (g_strcmp0 (G_PARAM_SPEC (key)->name, name) == 0) {
-      if (classename == NULL ||
-          g_strcmp0 (G_OBJECT_TYPE_NAME (G_OBJECT (value)), classename) == 0) {
-        GST_DEBUG ("The %s property from %s has been found", name, classename);
-        if (element)
-          *element = gst_object_ref (value);
-
-        *pspec = g_param_spec_ref (key);
-        res = TRUE;
-        break;
-      }
-    }
+  return
+      GES_TIMELINE_ELEMENT_GET_CLASS (object)->lookup_child
+      (GES_TIMELINE_ELEMENT (object), prop_name, (GObject **) element, pspec);
+}
+
+static gboolean
+strv_find_str (const gchar ** strv, const char *str)
+{
+  guint i;
+
+  if (strv == NULL)
+    return FALSE;
+
+  for (i = 0; strv[i]; i++) {
+    if (g_strcmp0 (strv[i], str) == 0)
+      return TRUE;
   }
-  g_strfreev (names);
 
-  return res;
+  return FALSE;
 }
 
-
 static void
 ges_track_element_get_property (GObject * object, guint property_id,
     GValue * value, GParamSpec * pspec)
@@ -206,7 +178,6 @@ ges_track_element_dispose (GObject * object)
   GESTrackElement *element = GES_TRACK_ELEMENT (object);
   GESTrackElementPrivate *priv = element->priv;
 
-  g_hash_table_destroy (priv->children_props);
   if (priv->bindings_hashtable)
     g_hash_table_destroy (priv->bindings_hashtable);
 
@@ -277,21 +248,6 @@ ges_track_element_class_init (GESTrackElementClass * klass)
   g_object_class_install_property (object_class, PROP_TRACK,
       properties[PROP_TRACK]);
 
-  /**
-   * GESTrackElement::deep-notify:
-   * @track_element: a #GESTrackElement
-   * @prop_object: the object that originated the signal
-   * @prop: the property that changed
-   *
-   * The deep notify signal is used to be notified of property changes of all
-   * the childs of @track_element
-   */
-  ges_track_element_signals[DEEP_NOTIFY] =
-      g_signal_new ("deep-notify", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED |
-      G_SIGNAL_NO_HOOKS, 0, NULL, NULL, g_cclosure_marshal_generic,
-      G_TYPE_NONE, 2, GST_TYPE_ELEMENT, G_TYPE_PARAM);
-
   /**
    * GESTrackElement::control-binding-added:
    * @track_element: a #GESTrackElement
@@ -330,16 +286,6 @@ ges_track_element_init (GESTrackElement * self)
   priv->pending_active = TRUE;
   priv->bindings_hashtable = g_hash_table_new_full (g_str_hash, g_str_equal,
       g_free, NULL);
-  priv->children_props =
-      g_hash_table_new_full ((GHashFunc) ges_pspec_hash, ges_pspec_equal,
-      (GDestroyNotify) g_param_spec_unref, gst_object_unref);
-
-}
-
-static gint
-compare_gparamspec (GParamSpec ** a, GParamSpec ** b, gpointer udata)
-{
-  return g_strcmp0 ((*a)->name, (*b)->name);
 }
 
 static gfloat
@@ -591,33 +537,6 @@ ges_track_element_get_track_type (GESTrackElement * object)
   return object->priv->track_type;
 }
 
-static void
-gst_element_prop_changed_cb (GstElement * element, GParamSpec * arg
-    G_GNUC_UNUSED, GESTrackElement * track_element)
-{
-  g_signal_emit (track_element, ges_track_element_signals[DEEP_NOTIFY], 0,
-      GST_ELEMENT (element), arg);
-}
-
-static void
-connect_signal (gpointer key, gpointer value, gpointer user_data)
-{
-  gchar *signame = g_strconcat ("notify::", G_PARAM_SPEC (key)->name, NULL);
-
-  g_signal_connect (G_OBJECT (value),
-      signame, G_CALLBACK (gst_element_prop_changed_cb),
-      GES_TRACK_ELEMENT (user_data));
-
-  g_free (signame);
-}
-
-static void
-connect_properties_signals (GESTrackElement * object)
-{
-  g_hash_table_foreach (object->priv->children_props,
-      (GHFunc) connect_signal, object);
-}
-
 /* default 'create_nle_object' virtual method implementation */
 static GstElement *
 ges_track_element_create_nle_object_func (GESTrackElement * self)
@@ -768,22 +687,6 @@ done:
   return res;
 }
 
-static gboolean
-strv_find_str (const gchar ** strv, const char *str)
-{
-  guint i;
-
-  if (strv == NULL)
-    return FALSE;
-
-  for (i = 0; strv[i]; i++) {
-    if (g_strcmp0 (strv[i], str) == 0)
-      return TRUE;
-  }
-
-  return FALSE;
-}
-
 /**
  * ges_track_element_add_children_props:
  * @self: The #GESTrackElement to set chidlren props on
@@ -830,8 +733,8 @@ ges_track_element_add_children_props (GESTrackElement * self,
       }
 
       if (pspec->flags & G_PARAM_WRITABLE) {
-        g_hash_table_insert (self->priv->children_props,
-            g_param_spec_ref (pspec), gst_object_ref (element));
+        ges_timeline_element_add_child_property (GES_TIMELINE_ELEMENT (self),
+            pspec, G_OBJECT (element));
         GST_LOG_OBJECT (self,
             "added property %s to controllable properties successfully !",
             whitelist[i]);
@@ -841,8 +744,6 @@ ges_track_element_add_children_props (GESTrackElement * self,
             whitelist[i], gst_element_get_name (element));
 
     }
-
-    connect_properties_signals (self);
     return;
   }
 
@@ -881,8 +782,8 @@ ges_track_element_add_children_props (GESTrackElement * self,
             for (i = 0; i < nb_specs; i++) {
               if ((parray[i]->flags & G_PARAM_WRITABLE) &&
                   (!whitelist || strv_find_str (whitelist, parray[i]->name))) {
-                g_hash_table_insert (self->priv->children_props,
-                    g_param_spec_ref (parray[i]), gst_object_ref (child));
+                ges_timeline_element_add_child_property (GES_TIMELINE_ELEMENT
+                    (self), parray[i], G_OBJECT (child));
               }
             }
             g_free (parray);
@@ -915,8 +816,6 @@ ges_track_element_add_children_props (GESTrackElement * self,
     g_value_unset (&item);
   }
   gst_iterator_free (it);
-
-  connect_properties_signals (self);
 }
 
 /* INTERNAL USAGE */
@@ -1080,18 +979,15 @@ ges_track_element_is_active (GESTrackElement * object)
  * Returns: TRUE if @element and @pspec could be found. FALSE otherwise. In that
  * case the values for @pspec and @element are not modified. Unref @element after
  * usage.
+ *
+ * Deprecated: Use #ges_timeline_element_lookup_child
  */
 gboolean
 ges_track_element_lookup_child (GESTrackElement * object,
     const gchar * prop_name, GstElement ** element, GParamSpec ** pspec)
 {
-  GESTrackElementClass *class;
-
-  g_return_val_if_fail (GES_IS_TRACK_ELEMENT (object), FALSE);
-  class = GES_TRACK_ELEMENT_GET_CLASS (object);
-  g_return_val_if_fail (class->lookup_child, FALSE);
-
-  return class->lookup_child (object, prop_name, element, pspec);
+  return ges_timeline_element_lookup_child (GES_TIMELINE_ELEMENT (object),
+      prop_name, ((GObject **) element), pspec);
 }
 
 /**
@@ -1101,26 +997,19 @@ ges_track_element_lookup_child (GESTrackElement * object,
  * @value: the value
  *
  * Sets a property of a child of @object.
+ *
+ * Deprecated: Use #ges_timeline_element_set_child_property_by_spec
  */
 void
 ges_track_element_set_child_property_by_pspec (GESTrackElement * object,
     GParamSpec * pspec, GValue * value)
 {
-  GstElement *element;
   g_return_if_fail (GES_IS_TRACK_ELEMENT (object));
 
-  if (!ges_track_element_lookup_child (object, pspec->name, &element, &pspec))
-    goto not_found;
-
-  g_object_set_property (G_OBJECT (element), pspec->name, value);
+  ges_timeline_element_set_child_property_by_pspec (GES_TIMELINE_ELEMENT
+      (object), pspec, value);
 
   return;
-
-not_found:
-  {
-    GST_ERROR ("The %s property doesn't exist", pspec->name);
-    return;
-  }
 }
 
 /**
@@ -1134,62 +1023,15 @@ not_found:
  * that have the same property name, you can distinguish them using the following
  * syntax: 'ClasseName::property_name' as property name. If you don't, the
  * corresponding property of the first element found will be set.
+ *
+ * Deprecated: Use #ges_timeline_element_set_child_property_valist
  */
 void
 ges_track_element_set_child_property_valist (GESTrackElement * object,
     const gchar * first_property_name, va_list var_args)
 {
-  const gchar *name;
-  GParamSpec *pspec;
-  GstElement *element;
-
-  gchar *error = NULL;
-  GValue value = { 0, };
-
-  g_return_if_fail (GES_IS_TRACK_ELEMENT (object));
-
-  name = first_property_name;
-
-  /* Note: This part is in big part copied from the gst_child_object_set_valist
-   * method. */
-
-  /* iterate over pairs */
-  while (name) {
-    if (!ges_track_element_lookup_child (object, name, &element, &pspec))
-      goto not_found;
-
-#if GLIB_CHECK_VERSION(2,23,3)
-    G_VALUE_COLLECT_INIT (&value, pspec->value_type, var_args,
-        G_VALUE_NOCOPY_CONTENTS, &error);
-#else
-    g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
-    G_VALUE_COLLECT (&value, var_args, G_VALUE_NOCOPY_CONTENTS, &error);
-#endif
-
-    if (error)
-      goto cant_copy;
-
-    g_object_set_property (G_OBJECT (element), pspec->name, &value);
-
-    gst_object_unref (element);
-    g_value_unset (&value);
-
-    name = va_arg (var_args, gchar *);
-  }
-  return;
-
-not_found:
-  {
-    GST_WARNING ("No property %s in OBJECT\n", name);
-    return;
-  }
-cant_copy:
-  {
-    GST_WARNING ("error copying value %s in object %p: %s", pspec->name, object,
-        error);
-    g_value_unset (&value);
-    return;
-  }
+  ges_timeline_element_set_child_property_valist (GES_TIMELINE_ELEMENT (object),
+      first_property_name, var_args);
 }
 
 /**
@@ -1203,6 +1045,8 @@ cant_copy:
  * that have the same property name, you can distinguish them using the following
  * syntax: 'ClasseName::property_name' as property name. If you don't, the
  * corresponding property of the first element found will be set.
+ *
+ * Deprecated: Use #ges_timeline_element_set_child_properties
  */
 void
 ges_track_element_set_child_properties (GESTrackElement * object,
@@ -1229,50 +1073,15 @@ ges_track_element_set_child_properties (GESTrackElement * object,
  * that have the same property name, you can distinguish them using the following
  * syntax: 'ClasseName::property_name' as property name. If you don't, the
  * corresponding property of the first element found will be set.
+ *
+ * Deprecated: Use #ges_timeline_element_get_child_property_valist
  */
 void
 ges_track_element_get_child_property_valist (GESTrackElement * object,
     const gchar * first_property_name, va_list var_args)
 {
-  const gchar *name;
-  gchar *error = NULL;
-  GValue value = { 0, };
-  GParamSpec *pspec;
-  GstElement *element;
-
-  g_return_if_fail (G_IS_OBJECT (object));
-
-  name = first_property_name;
-
-  /* This part is in big part copied from the gst_child_object_get_valist method */
-  while (name) {
-    if (!ges_track_element_lookup_child (object, name, &element, &pspec))
-      goto not_found;
-
-    g_value_init (&value, pspec->value_type);
-    g_object_get_property (G_OBJECT (element), pspec->name, &value);
-    gst_object_unref (element);
-
-    G_VALUE_LCOPY (&value, var_args, 0, &error);
-    if (error)
-      goto cant_copy;
-    g_value_unset (&value);
-    name = va_arg (var_args, gchar *);
-  }
-  return;
-
-not_found:
-  {
-    GST_WARNING ("no property %s in object", name);
-    return;
-  }
-cant_copy:
-  {
-    GST_WARNING ("error copying value %s in object %p: %s", pspec->name, object,
-        error);
-    g_value_unset (&value);
-    return;
-  }
+  ges_timeline_element_get_child_property_valist (GES_TIMELINE_ELEMENT (object),
+      first_property_name, var_args);
 }
 
 /**
@@ -1285,23 +1094,16 @@ cant_copy:
  *
  * Returns: (transfer full) (array length=n_properties): an array of #GParamSpec* which should be freed after use or
  * %NULL if something went wrong
+ *
+ * Deprecated: Use #ges_timeline_element_list_children_properties
  */
 GParamSpec **
 ges_track_element_list_children_properties (GESTrackElement * object,
     guint * n_properties)
 {
-  GParamSpec **ret;
-  GESTrackElementClass *class;
-
-  g_return_val_if_fail (GES_IS_TRACK_ELEMENT (object), NULL);
-
-  class = GES_TRACK_ELEMENT_GET_CLASS (object);
-
-  ret = class->list_children_properties (object, n_properties);
-  g_qsort_with_data (ret, *n_properties, sizeof (GParamSpec *),
-      (GCompareDataFunc) compare_gparamspec, NULL);
-
-  return ret;
+  return
+      ges_timeline_element_list_children_properties (GES_TIMELINE_ELEMENT
+      (object), n_properties);
 }
 
 /**
@@ -1312,6 +1114,8 @@ ges_track_element_list_children_properties (GESTrackElement * object,
  * name/return location pairs, followed by NULL
  *
  * Gets properties of a child of @object.
+ *
+ * Deprecated: Use #ges_timeline_element_get_child_properties
  */
 void
 ges_track_element_get_child_properties (GESTrackElement * object,
@@ -1334,28 +1138,15 @@ ges_track_element_get_child_properties (GESTrackElement * object,
  * @value: (out): return location for the value
  *
  * Gets a property of a child of @object.
+ *
+ * Deprecated: Use #ges_timeline_element_get_child_property_by_pspec
  */
 void
 ges_track_element_get_child_property_by_pspec (GESTrackElement * object,
     GParamSpec * pspec, GValue * value)
 {
-  GstElement *element;
-
-  g_return_if_fail (GES_IS_TRACK_ELEMENT (object));
-
-  element = g_hash_table_lookup (object->priv->children_props, pspec);
-  if (!element)
-    goto not_found;
-
-  g_object_get_property (G_OBJECT (element), pspec->name, value);
-
-  return;
-
-not_found:
-  {
-    GST_ERROR ("The %s property doesn't exist", pspec->name);
-    return;
-  }
+  ges_timeline_element_get_child_property_by_pspec (GES_TIMELINE_ELEMENT
+      (object), pspec, value);
 }
 
 /**
@@ -1371,104 +1162,53 @@ not_found:
  * is much more convenient for C programming.
  *
  * Returns: %TRUE if the property was set, %FALSE otherwize
+ *
+ * Deprecated: use #ges_timeline_element_set_child_property instead
  */
 gboolean
 ges_track_element_set_child_property (GESTrackElement * object,
     const gchar * property_name, GValue * value)
 {
-  GParamSpec *pspec;
-  GstElement *element;
-
-  g_return_val_if_fail (GES_IS_TRACK_ELEMENT (object), FALSE);
-
-  if (!ges_track_element_lookup_child (object, property_name, &element, &pspec))
-    goto not_found;
-
-  g_object_set_property (G_OBJECT (element), pspec->name, value);
-
-  gst_object_unref (element);
-  g_param_spec_unref (pspec);
-
-  return TRUE;
-
-not_found:
-  {
-    GST_WARNING_OBJECT (object, "The %s property doesn't exist", property_name);
-
-    return FALSE;
-  }
+  return ges_timeline_element_set_child_property (GES_TIMELINE_ELEMENT (object),
+      property_name, value);
 }
 
 /**
-* ges_track_element_get_child_property:
-* @object: The origin #GESTrackElement
-* @property_name: The name of the property
-* @value: (out): return location for the property value, it will
-* be initialized if it is initialized with 0
-*
-* In general, a copy is made of the property contents and
-* the caller is responsible for freeing the memory by calling
-* g_value_unset().
-*
-* Gets a property of a GstElement contained in @object.
-*
-* Note that #ges_track_element_get_child_property is really
-* intended for language bindings, #ges_track_element_get_child_properties
-* is much more convenient for C programming.
-*
-* Returns: %TRUE if the property was found, %FALSE otherwize
-*/
+ * ges_track_element_get_child_property:
+ * @object: The origin #GESTrackElement
+ * @property_name: The name of the property
+ * @value: (out): return location for the property value, it will
+ * be initialized if it is initialized with 0
+ *
+ * In general, a copy is made of the property contents and
+ * the caller is responsible for freeing the memory by calling
+ * g_value_unset().
+ *
+ * Gets a property of a GstElement contained in @object.
+ *
+ * Note that #ges_track_element_get_child_property is really
+ * intended for language bindings, #ges_track_element_get_child_properties
+ * is much more convenient for C programming.
+ *
+ * Returns: %TRUE if the property was found, %FALSE otherwize
+ *
+ * Deprecated: Use #ges_timeline_element_get_child_property
+ */
 gboolean
 ges_track_element_get_child_property (GESTrackElement * object,
     const gchar * property_name, GValue * value)
 {
-  GParamSpec *pspec;
-  GstElement *element;
-
-  g_return_val_if_fail (GES_IS_TRACK_ELEMENT (object), FALSE);
-
-  if (!ges_track_element_lookup_child (object, property_name, &element, &pspec))
-    goto not_found;
-
-  if (G_VALUE_TYPE (value) == G_TYPE_INVALID)
-    g_value_init (value, pspec->value_type);
-
-  g_object_get_property (G_OBJECT (element), pspec->name, value);
-
-  gst_object_unref (element);
-  g_param_spec_unref (pspec);
-
-  return TRUE;
-
-not_found:
-  {
-    GST_WARNING_OBJECT (object, "The %s property doesn't exist", property_name);
-
-    return FALSE;
-  }
+  return ges_timeline_element_get_child_property (GES_TIMELINE_ELEMENT (object),
+      property_name, value);
 }
 
 static GParamSpec **
 default_list_children_properties (GESTrackElement * object,
     guint * n_properties)
 {
-  GParamSpec **pspec, *spec;
-  GHashTableIter iter;
-  gpointer key, value;
-
-  guint i = 0;
-
-  *n_properties = g_hash_table_size (object->priv->children_props);
-  pspec = g_new (GParamSpec *, *n_properties);
-
-  g_hash_table_iter_init (&iter, object->priv->children_props);
-  while (g_hash_table_iter_next (&iter, &key, &value)) {
-    spec = G_PARAM_SPEC (key);
-    pspec[i] = g_param_spec_ref (spec);
-    i++;
-  }
-
-  return pspec;
+  return
+      GES_TIMELINE_ELEMENT_GET_CLASS (object)->list_children_properties
+      (GES_TIMELINE_ELEMENT (object), n_properties);
 }
 
 void
index 67249ec313ab59a54f28c0ac0ab94d34a1b28e6f..370a08312db3736431d60476b7e4d7b4fa2129d3 100644 (file)
@@ -80,6 +80,7 @@ struct _GESTrackElement {
  *                            The default implementation will create an object
  *                            of type @nleobject_factorytype and call
  *                            @create_element.
+ *                            DeprecatedUse: GESTimelineElement.list_children_properties instead
  * @lookup_child: method letting subclasses look for a child, overriding the
  *                simple standard behaviour. This vmethod can be used for example
  *                in the case where you want the name of a child property to be
@@ -90,6 +91,7 @@ struct _GESTrackElement {
  *                has been overriden so that we tweak the name passed has parametter
  *                to rename "background" to "foreground-backend" making our API
  *                understandable.
+ *                Deprecated: use GESTimelineElement.lookup_child instead
  *
  * Subclasses can override the @create_nle_object method to override what type
  * of GNonLin object will be created.
@@ -114,8 +116,6 @@ struct _GESTrackElementClass {
   /* virtual methods for subclasses */
   GParamSpec** (*list_children_properties) (GESTrackElement * object,
               guint *n_properties);
-
-
   gboolean (*lookup_child)                 (GESTrackElement *object,
                                             const gchar *prop_name,
                                             GstElement **element,
index 00bd4a25e5b1959d6fe809dc698d42e73b3b6116..3bd7280fc178a4e3351ae078bb428e8aa1ad5022 100644 (file)
@@ -354,7 +354,7 @@ GST_START_TEST (test_effect_set_properties)
   GESLayer *layer;
   GESTrack *track_video;
   GESEffectClip *effect_clip;
-  GESTrackElement *effect;
+  GESTimelineElement *effect;
   guint scratch_line, n_props, i;
   gboolean color_aging;
   GParamSpec **pspecs, *spec;
@@ -377,21 +377,21 @@ GST_START_TEST (test_effect_set_properties)
 
   ges_layer_add_clip (layer, (GESClip *) effect_clip);
 
-  effect = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
+  effect = GES_TIMELINE_ELEMENT (ges_effect_new ("agingtv"));
   fail_unless (ges_container_add (GES_CONTAINER (effect_clip),
           GES_TIMELINE_ELEMENT (effect)));
   fail_unless (ges_track_element_get_track (GES_TRACK_ELEMENT (effect)) ==
       track_video);
 
-  ges_track_element_set_child_properties (effect,
+  ges_timeline_element_set_child_properties (effect,
       "GstAgingTV::scratch-lines", 17, "color-aging", FALSE, NULL);
-  ges_track_element_get_child_properties (effect,
+  ges_timeline_element_get_child_properties (effect,
       "GstAgingTV::scratch-lines", &scratch_line,
       "color-aging", &color_aging, NULL);
   fail_unless (scratch_line == 17);
   fail_unless (color_aging == FALSE);
 
-  pspecs = ges_track_element_list_children_properties (effect, &n_props);
+  pspecs = ges_timeline_element_list_children_properties (effect, &n_props);
   fail_unless (n_props == 7);
 
   spec = pspecs[0];
@@ -404,8 +404,8 @@ GST_START_TEST (test_effect_set_properties)
   g_value_init (&nval, G_TYPE_UINT);
   g_value_set_uint (&val, 10);
 
-  ges_track_element_set_child_property_by_pspec (effect, spec, &val);
-  ges_track_element_get_child_property_by_pspec (effect, spec, &nval);
+  ges_timeline_element_set_child_property_by_pspec (effect, spec, &val);
+  ges_timeline_element_get_child_property_by_pspec (effect, spec, &nval);
   fail_unless (g_value_get_uint (&nval) == 10);
 
   for (i = 0; i < n_props; i++) {
@@ -444,7 +444,7 @@ GST_START_TEST (test_clip_signals)
   GESLayer *layer;
   GESTrack *track_video;
   GESEffectClip *effect_clip;
-  GESEffect *effect;
+  GESTimelineElement *effect;
   GValue val = { 0, };
   gboolean effect_added = FALSE;
 
@@ -466,9 +466,8 @@ GST_START_TEST (test_clip_signals)
 
   ges_layer_add_clip (layer, (GESClip *) effect_clip);
 
-  effect = ges_effect_new ("agingtv");
-  fail_unless (ges_container_add (GES_CONTAINER (effect_clip),
-          GES_TIMELINE_ELEMENT (effect)));
+  effect = GES_TIMELINE_ELEMENT (ges_effect_new ("agingtv"));
+  fail_unless (ges_container_add (GES_CONTAINER (effect_clip), effect));
   fail_unless (effect_added);
   g_signal_handlers_disconnect_by_func (effect_clip, effect_added_cb,
       &effect_added);
@@ -477,11 +476,11 @@ GST_START_TEST (test_clip_signals)
   g_signal_connect (effect, "deep-notify", (GCallback) deep_prop_changed_cb,
       effect);
 
-  ges_track_element_set_child_properties (GES_TRACK_ELEMENT (effect),
+  ges_timeline_element_set_child_properties (effect,
       "GstAgingTV::scratch-lines", 17, NULL);
 
   g_value_init (&val, G_TYPE_UINT);
-  ges_track_element_get_child_property (GES_TRACK_ELEMENT (effect),
+  ges_timeline_element_get_child_property (effect,
       "GstAgingTV::scratch-lines", &val);
   fail_unless (G_VALUE_HOLDS_UINT (&val));
   g_value_unset (&val);
index 7325e5b040c8f6d9705947507a7b0ca92a53aa44..13f8df7a76e357336cef44a2829ecf016e9ebded 100644 (file)
@@ -249,7 +249,7 @@ _test_project (GESProject * project, GESTimeline * timeline)
           if (GES_IS_BASE_EFFECT (trackelement)) {
             guint nb_scratch_lines;
 
-            ges_track_element_get_child_properties (trackelement,
+            ges_timeline_element_get_child_properties (tmptrackelement->data,
                 "scratch-lines", &nb_scratch_lines, NULL);
             assert_equals_int (nb_scratch_lines, 12);
 
@@ -339,10 +339,10 @@ _add_properties (GESTimeline * timeline)
           /* Adding children properties */
           else if (GES_IS_VIDEO_SOURCE (element)) {
             gint64 posx = 42;
-            ges_track_element_set_child_properties (element, "posx", posx,
-                NULL);
-            ges_track_element_get_child_properties (element, "posx", &posx,
-                NULL);
+            ges_timeline_element_set_child_properties (GES_TIMELINE_ELEMENT
+                (element), "posx", posx, NULL);
+            ges_timeline_element_get_child_properties (GES_TIMELINE_ELEMENT
+                (element), "posx", &posx, NULL);
             fail_unless_equals_int64 (posx, 42);
           }
         }
@@ -406,8 +406,8 @@ _check_properties (GESTimeline * timeline)
           else if (GES_IS_VIDEO_SOURCE (element)) {
             /* Init 'posx' with a wrong value */
             gint64 posx = 27;
-            ges_track_element_get_child_properties (element, "posx", &posx,
-                NULL);
+            ges_timeline_element_get_child_properties (GES_TIMELINE_ELEMENT
+                (element), "posx", &posx, NULL);
             fail_unless_equals_int64 (posx, 42);
           }
         }
index 714c4fa86ad11a0f5beab2a21e80139209b4f7a9..34e34e2c32b5b063454ca90605fe7affe99571f5 100644 (file)
@@ -1265,9 +1265,11 @@ _set_track_element_width_height (GESTrackElement * trksrc, gint wvalue,
   g_value_set_int (&width, wvalue);
   g_value_set_int (&height, hvalue);
   if (wvalue >= 0)
-    ges_track_element_set_child_property (trksrc, "width", &width);
+    ges_timeline_element_set_child_property (GES_TIMELINE_ELEMENT (trksrc),
+        "width", &width);
   if (hvalue >= 0)
-    ges_track_element_set_child_property (trksrc, "height", &height);
+    ges_timeline_element_set_child_property (GES_TIMELINE_ELEMENT (trksrc),
+        "height", &height);
 }
 
 static gboolean
@@ -1285,8 +1287,10 @@ check_frame_positionner_size (GESClip * clip, gint width, gint height)
   g_value_init (&val_width, G_TYPE_INT);
   g_value_init (&val_height, G_TYPE_INT);
 
-  ges_track_element_get_child_property (trksrc, "width", &val_width);
-  ges_track_element_get_child_property (trksrc, "height", &val_height);
+  ges_timeline_element_get_child_property (GES_TIMELINE_ELEMENT (trksrc),
+      "width", &val_width);
+  ges_timeline_element_get_child_property (GES_TIMELINE_ELEMENT (trksrc),
+      "height", &val_height);
 
   real_width = g_value_get_int (&val_width);
   real_height = g_value_get_int (&val_height);