timeline: Properly compute the end of groups when checking snapping
authorThibault Saunier <tsaunier@gnome.org>
Thu, 11 Aug 2016 19:12:07 +0000 (15:12 -0400)
committerThibault Saunier <thibault.saunier@osg.samsung.com>
Mon, 26 Sep 2016 16:33:19 +0000 (13:33 -0300)
Computation was not taking into account the fact that the start of
the element being moved could be at the middle of a group and not
necessarily at the start!

Fixes T7544

Reviewed-by: Alex Băluț <alexandru.balut@gmail.com>
Differential Revision: https://phabricator.freedesktop.org/D1282

ges/ges-timeline.c
tests/check/python/test_group.py

index 603e995..3d788b1 100644 (file)
@@ -2044,8 +2044,9 @@ ges_timeline_move_object_simple (GESTimeline * timeline,
     guint64 position)
 {
   GstClockTime cpos = GES_TIMELINE_ELEMENT_START (element);
-  guint64 *snap_end, *snap_st, *cur, off1, off2, end;
+  guint64 *snap_end, *snap_st, *cur, position_offset, off1, off2, top_end;
   GESTrackElement *track_element;
+  GESContainer *toplevel;
 
   /* We only work with GESSource-s and we check that we are not already moving
    * element ourself*/
@@ -2055,17 +2056,20 @@ ges_timeline_move_object_simple (GESTimeline * timeline,
 
   timeline->priv->needs_rollback = FALSE;
   track_element = GES_TRACK_ELEMENT (element);
-  end = position + _DURATION (get_toplevel_container (track_element));
+  toplevel = get_toplevel_container (track_element);
+  position_offset = position - _START (track_element);
+
+  top_end = _START (toplevel) + _DURATION (toplevel) + position_offset;
   cur = g_hash_table_lookup (timeline->priv->by_end, track_element);
 
   GST_DEBUG_OBJECT (timeline, "Moving %" GST_PTR_FORMAT "to %"
       GST_TIME_FORMAT " (end %" GST_TIME_FORMAT ")", element,
-      GST_TIME_ARGS (position), GST_TIME_ARGS (end));
+      GST_TIME_ARGS (position), GST_TIME_ARGS (top_end));
 
-  snap_end = ges_timeline_snap_position (timeline, track_element, cur, end,
+  snap_end = ges_timeline_snap_position (timeline, track_element, cur, top_end,
       FALSE);
   if (snap_end)
-    off1 = end > *snap_end ? end - *snap_end : *snap_end - end;
+    off1 = top_end > *snap_end ? top_end - *snap_end : *snap_end - top_end;
   else
     off1 = G_MAXUINT64;
 
@@ -2080,7 +2084,7 @@ ges_timeline_move_object_simple (GESTimeline * timeline,
 
   /* In the case we could snap on both sides, we snap on the end */
   if (snap_end && off1 <= off2) {
-    position = position + *snap_end - end;
+    position = position + *snap_end - top_end;
     ges_timeline_emit_snappig (timeline, track_element, snap_end);
   } else if (snap_st) {
     position = position + *snap_st - position;
index 5221f7e..ef2d3a9 100644 (file)
@@ -251,3 +251,33 @@ class TestGroup(unittest.TestCase):
         self.assertEqual(video_transition.props.duration, 10)
         self.assertEqual(audio_transition.props.start, 25)
         self.assertEqual(audio_transition.props.duration, 10)
+
+    def test_moving_group_snapping_from_the_middle(self):
+        snapped_positions = []
+        def snapping_started_cb(timeline, first_element, second_element,
+                                position, snapped_positions):
+            snapped_positions.append(position)
+
+        self.timeline.props.snapping_distance = 5
+        self.timeline.connect("snapping-started", snapping_started_cb,
+                              snapped_positions)
+
+        for start in range(0, 20, 5):
+            clip = GES.TestClip.new()
+            clip.props.start = start
+            clip.props.duration = 5
+            self.layer.add_clip(clip)
+
+        clips = self.layer.get_clips()
+        self.assertEqual(len(clips), 4)
+
+        group = GES.Container.group(clips[1:3])
+        self.assertIsNotNone(group)
+
+        self.assertEqual(clips[1].props.start, 5)
+        self.assertEqual(clips[2].props.start, 10)
+        clips[2].edit([], 0, GES.EditMode.EDIT_NORMAL, GES.Edge.EDGE_NONE, 11)
+
+        self.assertEqual(snapped_positions[0], clips[2].start + clips[2].duration)
+        self.assertEqual(clips[1].props.start, 5)
+        self.assertEqual(clips[2].props.start, 10)