timeline: Properly compute the end of groups when checking snapping

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
This commit is contained in:
Thibault Saunier 2016-08-11 15:12:07 -04:00 committed by Thibault Saunier
parent 1757ae2e5e
commit cd76231f64
2 changed files with 40 additions and 6 deletions

View 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;

View 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)