From cb29c3133747476759c6ada767a990545883c018 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Sun, 22 Apr 2012 13:09:11 -0400 Subject: [PATCH] timelineobject: Make changing start/duration sensible to snapping Adapt the documentation so users are aware of the behaviour Conflicts: ges/ges-timeline-object.c --- ges/ges-timeline-object.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- ges/ges-timeline-object.h | 6 +++++- ges/ges-timeline-source.c | 3 +++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/ges/ges-timeline-object.c b/ges/ges-timeline-object.c index ff8cae2..a6b183a 100644 --- a/ges/ges-timeline-object.c +++ b/ges/ges-timeline-object.c @@ -393,6 +393,7 @@ ges_timeline_object_class_init (GESTimelineObjectClass * klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); klass->need_fill_track = TRUE; + klass->snaps = FALSE; } static void @@ -768,12 +769,21 @@ ges_timeline_object_set_start_internal (GESTimelineObject * object, GList *tmp; GESTrackObject *tr; ObjectMapping *map; + GESTimeline *timeline = NULL; + GESTimelineObjectPrivate *priv = object->priv; + gboolean snap = FALSE; g_return_val_if_fail (GES_IS_TIMELINE_OBJECT (object), FALSE); GST_DEBUG ("object:%p, start:%" GST_TIME_FORMAT, object, GST_TIME_ARGS (start)); + /* If the class has snapping enabled and the object is in a timeline, + * we snap */ + if (priv->layer && GES_TIMELINE_OBJECT_GET_CLASS (object)->snaps) + timeline = ges_timeline_layer_get_timeline (object->priv->layer); + snap = timeline && priv->initiated_move == NULL ? TRUE : FALSE; + object->priv->ignore_notifies = TRUE; for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) { @@ -790,7 +800,12 @@ ges_timeline_object_set_start_internal (GESTimelineObject * object, continue; } - ges_track_object_set_start (tr, new_start); + /* Make the snapping happen if in a timeline */ + if (snap) + ges_timeline_move_object_simple (timeline, tr, NULL, GES_EDGE_NONE, + start); + else + ges_track_object_set_start (tr, start); } else { /* ... or update the offset */ map->start_offset = start - tr->start; @@ -809,6 +824,9 @@ ges_timeline_object_set_start_internal (GESTimelineObject * object, * @start: the position in #GstClockTime * * Set the position of the object in its containing layer + * + * Note that if the timeline snap-distance property of the timeline containing + * @object is set, @object will properly snap to its neighboors. */ void ges_timeline_object_set_start (GESTimelineObject * object, guint64 start) @@ -870,18 +888,34 @@ ges_timeline_object_set_duration_internal (GESTimelineObject * object, { GList *tmp; GESTrackObject *tr; + GESTimeline *timeline = NULL; + GESTimelineObjectPrivate *priv = object->priv; + gboolean snap = FALSE; g_return_val_if_fail (GES_IS_TIMELINE_OBJECT (object), FALSE); GST_DEBUG ("object:%p, duration:%" GST_TIME_FORMAT, object, GST_TIME_ARGS (duration)); + /* If the class has snapping enabled and the object is in a timeline, + * we snap */ + if (priv->layer && GES_TIMELINE_OBJECT_GET_CLASS (object)->snaps) + timeline = ges_timeline_layer_get_timeline (object->priv->layer); + + snap = timeline && priv->initiated_move == NULL ? TRUE : FALSE; + for (tmp = object->priv->trackobjects; tmp; tmp = g_list_next (tmp)) { tr = (GESTrackObject *) tmp->data; - if (ges_track_object_is_locked (tr)) - /* call set_duration on each trackobject */ - ges_track_object_set_duration (tr, duration); + if (ges_track_object_is_locked (tr)) { + /* call set_duration on each trackobject + * and make the snapping happen if in a timeline */ + if (G_LIKELY (snap)) + ges_timeline_trim_object_simple (timeline, tr, NULL, GES_EDGE_END, + tr->start + duration, TRUE); + else + ges_track_object_set_duration (tr, duration); + } } object->duration = duration; @@ -894,6 +928,9 @@ ges_timeline_object_set_duration_internal (GESTimelineObject * object, * @duration: the duration in #GstClockTime * * Set the duration of the object + * + * Note that if the timeline snap-distance property of the timeline containing + * @object is set, @object will properly snap to its neighboors. */ void ges_timeline_object_set_duration (GESTimelineObject * object, guint64 duration) @@ -1365,7 +1402,7 @@ ges_timeline_object_edit (GESTimelineObject * object, GList * layers, priority_offset = new_layer_priority - ges_timeline_layer_get_priority (layer); - ret &= timeline_context_to_layer (layer->timeline, object, priority_offset); + ret &= timeline_context_to_layer (layer->timeline, priority_offset); } return ret; diff --git a/ges/ges-timeline-object.h b/ges/ges-timeline-object.h index 9b8f5a5..5c752cd 100644 --- a/ges/ges-timeline-object.h +++ b/ges/ges-timeline-object.h @@ -182,6 +182,9 @@ struct _GESTimelineObject { * #GESTrack. * @fill_track_object: method to fill an associated #GESTrackObject. * @need_fill_track: Set to TRUE if @fill_track_object needs to be called. + * @snaps: Set to %TRUE if the objects of this type snap with + * other objects in a timeline %FALSE otherwise (default is %FALSE). Basically only + * sources snap. * @track_object_added: Should be overridden by subclasses if they need to perform an * operation when a #GESTrackObject is added. Since: 0.10.2 * @track_object_released: Should be overridden by subclasses if they need to perform @@ -202,6 +205,7 @@ struct _GESTimelineObjectClass { /* FIXME : might need a release_track_object */ GESFillTrackObjectFunc fill_track_object; gboolean need_fill_track; + gboolean snaps; void (*track_object_added) (GESTimelineObject *object, GESTrackObject *tck_object); @@ -212,7 +216,7 @@ struct _GESTimelineObjectClass { /*< private >*/ /* Padding for API extension */ - gpointer _ges_reserved[GES_PADDING - 3]; + gpointer _ges_reserved[GES_PADDING - 4]; }; GType ges_timeline_object_get_type (void); diff --git a/ges/ges-timeline-source.c b/ges/ges-timeline-source.c index c0d2c2b..50c4e7e 100644 --- a/ges/ges-timeline-source.c +++ b/ges/ges-timeline-source.c @@ -79,6 +79,9 @@ ges_timeline_source_class_init (GESTimelineSourceClass * klass) object_class->get_property = ges_timeline_source_get_property; object_class->set_property = ges_timeline_source_set_property; object_class->finalize = ges_timeline_source_finalize; + + /* All subclasses should have snapping enabled */ + GES_TIMELINE_OBJECT_CLASS (klass)->snaps = TRUE; } static void -- 2.7.4