clip: Rollback moving clips when moving a contained TrackElement fails
authorThibault Saunier <tsaunier@igalia.com>
Fri, 8 Feb 2019 19:05:18 +0000 (16:05 -0300)
committerThibault Saunier <tsaunier@gnome.org>
Fri, 15 Mar 2019 23:51:55 +0000 (23:51 +0000)
And fix unit tests to match the correct behaviour

ges/ges-clip.c
ges/ges-source-clip.c
tests/check/ges/timelineedition.c

index ad02cdc..ba8dda4 100644 (file)
@@ -151,7 +151,6 @@ static gboolean
 _set_start (GESTimelineElement * element, GstClockTime start)
 {
   GList *tmp;
-  GESTimeline *timeline;
   GESContainer *container = GES_CONTAINER (element);
 
   GST_DEBUG_OBJECT (element, "Setting children start, (initiated_move: %"
@@ -163,17 +162,7 @@ _set_start (GESTimelineElement * element, GstClockTime start)
   for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
     GESTimelineElement *child = (GESTimelineElement *) tmp->data;
 
-    if (child != container->initiated_move) {
-      /* Make the snapping happen if in a timeline */
-      timeline = GES_TIMELINE_ELEMENT_TIMELINE (child);
-      if (timeline && !container->initiated_move) {
-        if (ges_timeline_move_object_simple (timeline, child, NULL,
-                GES_EDGE_NONE, start))
-          continue;
-      }
-
-      _set_start0 (GES_TIMELINE_ELEMENT (child), start);
-    }
+    _set_start0 (GES_TIMELINE_ELEMENT (child), start);
   }
   container->children_control_mode = GES_CHILDREN_UPDATE;
 
index 21c9f95..461bb70 100644 (file)
@@ -46,6 +46,48 @@ enum
 
 G_DEFINE_TYPE_WITH_PRIVATE (GESSourceClip, ges_source_clip, GES_TYPE_CLIP);
 
+static gboolean
+_set_start (GESTimelineElement * element, GstClockTime start)
+{
+  GList *tmp;
+  GESTimeline *timeline;
+  GESContainer *container = GES_CONTAINER (element);
+  GstClockTime rollback_start = GES_TIMELINE_ELEMENT_START (element);
+
+  GST_DEBUG_OBJECT (element, "Setting children start, (initiated_move: %"
+      GST_PTR_FORMAT ")", container->initiated_move);
+
+  element->start = start;
+  g_object_notify (G_OBJECT (element), "start");
+  container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
+  for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
+    GESTimelineElement *child = (GESTimelineElement *) tmp->data;
+
+    if (child != container->initiated_move) {
+      /* Make the snapping happen if in a timeline */
+      timeline = GES_TIMELINE_ELEMENT_TIMELINE (child);
+      if (timeline && !container->initiated_move) {
+        if (!ges_timeline_move_object_simple (timeline, child, NULL,
+                GES_EDGE_NONE, start)) {
+          for (tmp = container->children; tmp; tmp = g_list_next (tmp))
+            ges_timeline_element_set_start (tmp->data, rollback_start);
+
+          element->start = rollback_start;
+          g_object_notify (G_OBJECT (element), "start");
+          container->children_control_mode = GES_CHILDREN_UPDATE;
+          return FALSE;
+        }
+      }
+
+      _set_start0 (GES_TIMELINE_ELEMENT (child), start);
+    }
+  }
+
+  container->children_control_mode = GES_CHILDREN_UPDATE;
+
+  return FALSE;
+}
+
 static void
 ges_source_clip_get_property (GObject * object, guint property_id,
     GValue * value, GParamSpec * pspec)
@@ -76,10 +118,13 @@ static void
 ges_source_clip_class_init (GESSourceClipClass * klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GESTimelineElementClass *element_class = GES_TIMELINE_ELEMENT_CLASS (klass);
 
   object_class->get_property = ges_source_clip_get_property;
   object_class->set_property = ges_source_clip_set_property;
   object_class->finalize = ges_source_clip_finalize;
+
+  element_class->set_start = _set_start;
 }
 
 static void
index 6609f08..e61e191 100644 (file)
@@ -394,13 +394,14 @@ GST_START_TEST (test_snapping)
    *                  0----------
    *                  |   clip  |
    *                  25--------62
-   * inpoints           5---------- 0---------
+   * inpoints           5-----------------------+
    *                    |  clip1    ||  clip2   |
-   * time               26-------- 62 --------122
+   * time               30------------]--------122
+   *                                 67
    */
-  ges_timeline_element_set_start (GES_TIMELINE_ELEMENT (clip1), 26);
+  ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 30);
   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
-  CHECK_OBJECT_PROPS (trackelement1, 26, 5, 37);
+  CHECK_OBJECT_PROPS (trackelement1, 30, 5, 37);
   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
 
    /**
@@ -415,14 +416,15 @@ GST_START_TEST (test_snapping)
           58) == TRUE);
   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
   CHECK_OBJECT_PROPS (trackelement1, 62, 5, 37);
-  CHECK_OBJECT_PROPS (trackelement2, 98, 0, 60);
+  CHECK_OBJECT_PROPS (trackelement2, 94, 0, 60);
 
   /**
    * inpoints     0----------- 5------------   0-----------
    *              |   clip    ||  clip1    |   |  clip2    |
    * time         25----------62----------99  110--------170
    */
-  ges_timeline_element_set_start (GES_TIMELINE_ELEMENT (clip2), 110);
+  ges_container_edit (clip2, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE,
+      110);
   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
   CHECK_OBJECT_PROPS (trackelement1, 62, 5, 37);
   CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60);
@@ -465,7 +467,7 @@ GST_START_TEST (test_snapping)
    *              |   clip1    ||  clip2   ||  clip     |
    * time         62---------110--------170--------207
    */
-  g_object_set (clip, "start", (guint64) 168, NULL);
+  ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 168);
   CHECK_OBJECT_PROPS (trackelement, 170, 0, 37);
   CHECK_OBJECT_PROPS (trackelement1, 62, 5, 48);
   CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60);
@@ -1065,7 +1067,7 @@ GST_START_TEST (test_groups)
           GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 10) == TRUE);
 
   DEEP_CHECK (c, 10, 0, 10);
-  DEEP_CHECK (c1, 20, 0, 10);
+  DEEP_CHECK (c1, 10, 0, 10);
   DEEP_CHECK (c2, 30, 0, 10);
   DEEP_CHECK (c3, 40, 0, 20);
   DEEP_CHECK (c4, 50, 0, 20);
@@ -1080,7 +1082,7 @@ GST_START_TEST (test_groups)
   fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, 1,
           GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 10) == TRUE);
   DEEP_CHECK (c, 10, 0, 10);
-  DEEP_CHECK (c1, 20, 0, 10);
+  DEEP_CHECK (c1, 10, 0, 10);
   DEEP_CHECK (c2, 30, 0, 10);
   DEEP_CHECK (c3, 40, 0, 20);
   DEEP_CHECK (c4, 50, 0, 20);
@@ -1095,11 +1097,11 @@ GST_START_TEST (test_groups)
   fail_unless (ges_container_edit (GES_CONTAINER (c1), NULL, 2,
           GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 40) == TRUE);
   DEEP_CHECK (c, 10, 0, 10);
-  DEEP_CHECK (c1, 20, 0, 20);
-  DEEP_CHECK (c2, 40, 0, 10);
-  DEEP_CHECK (c3, 50, 0, 20);
-  DEEP_CHECK (c4, 60, 0, 20);
-  DEEP_CHECK (c5, 70, 0, 20);
+  DEEP_CHECK (c1, 10, 0, 30);
+  DEEP_CHECK (c2, 50, 0, 10);
+  DEEP_CHECK (c3, 60, 0, 20);
+  DEEP_CHECK (c4, 70, 0, 20);
+  DEEP_CHECK (c5, 80, 0, 20);
   check_layer (c, 1);
   check_layer (c1, 2);
   check_layer (c2, 2);
@@ -1110,11 +1112,11 @@ GST_START_TEST (test_groups)
   fail_unless (ges_container_edit (GES_CONTAINER (c1), NULL, 2,
           GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 30) == TRUE);
   DEEP_CHECK (c, 10, 0, 10);
-  DEEP_CHECK (c1, 20, 0, 10);
-  DEEP_CHECK (c2, 30, 0, 10);
-  DEEP_CHECK (c3, 40, 0, 20);
-  DEEP_CHECK (c4, 50, 0, 20);
-  DEEP_CHECK (c5, 60, 0, 20);
+  DEEP_CHECK (c1, 10, 0, 20);
+  DEEP_CHECK (c2, 40, 0, 10);
+  DEEP_CHECK (c3, 50, 0, 20);
+  DEEP_CHECK (c4, 60, 0, 20);
+  DEEP_CHECK (c5, 70, 0, 20);
   check_layer (c, 1);
   check_layer (c1, 2);
   check_layer (c2, 2);
@@ -1125,11 +1127,11 @@ GST_START_TEST (test_groups)
   fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, 0,
           GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 0) == TRUE);
   DEEP_CHECK (c, 0, 0, 10);
-  DEEP_CHECK (c1, 10, 0, 10);
-  DEEP_CHECK (c2, 20, 0, 10);
-  DEEP_CHECK (c3, 30, 0, 20);
-  DEEP_CHECK (c4, 40, 0, 20);
-  DEEP_CHECK (c5, 50, 0, 20);
+  DEEP_CHECK (c1, 10, 0, 20);
+  DEEP_CHECK (c2, 30, 0, 10);
+  DEEP_CHECK (c3, 40, 0, 20);
+  DEEP_CHECK (c4, 50, 0, 20);
+  DEEP_CHECK (c5, 60, 0, 20);
   check_layer (c, 0);
   check_layer (c1, 1);
   check_layer (c2, 1);
@@ -1137,15 +1139,14 @@ GST_START_TEST (test_groups)
   check_layer (c4, 1);
   check_layer (c5, 2);
 
-  fail_unless (ges_container_edit (GES_CONTAINER (c2), NULL, -1,
+  fail_if (ges_container_edit (GES_CONTAINER (c2), NULL, -1,
           GES_EDIT_MODE_ROLL, GES_EDGE_END, 40) == TRUE);
   DEEP_CHECK (c, 0, 0, 10);
-  DEEP_CHECK (c1, 10, 0, 10);
-  DEEP_CHECK (c2, 20, 0, 20);
-  DEEP_CHECK (c3, 40, 10, 10);
-  DEEP_CHECK (c4, 40, 0, 20);
-  DEEP_CHECK (c5, 50, 0, 20);
-  CHECK_OBJECT_PROPS (group, 0, 0, 40);
+  DEEP_CHECK (c1, 10, 0, 20);
+  DEEP_CHECK (c2, 30, 0, 10);
+  DEEP_CHECK (c3, 40, 0, 20);
+  DEEP_CHECK (c4, 50, 0, 20);
+  DEEP_CHECK (c5, 60, 0, 20);
   check_layer (c, 0);
   check_layer (c1, 1);
   check_layer (c2, 1);
@@ -1156,11 +1157,11 @@ GST_START_TEST (test_groups)
   fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, 0,
           GES_EDIT_MODE_TRIM, GES_EDGE_START, 5) == TRUE);
   CHECK_OBJECT_PROPS (c, 5, 5, 5);
-  CHECK_OBJECT_PROPS (c1, 10, 0, 10);
-  CHECK_OBJECT_PROPS (c2, 20, 0, 20);
-  CHECK_OBJECT_PROPS (c3, 40, 10, 10);
-  CHECK_OBJECT_PROPS (c4, 40, 0, 20);
-  CHECK_OBJECT_PROPS (c5, 50, 0, 20);
+  DEEP_CHECK (c1, 10, 0, 20);
+  DEEP_CHECK (c2, 30, 0, 10);
+  DEEP_CHECK (c3, 40, 0, 20);
+  DEEP_CHECK (c4, 50, 0, 20);
+  DEEP_CHECK (c5, 60, 0, 20);
   CHECK_OBJECT_PROPS (group, 5, 0, 35);
   check_layer (c, 0);
   check_layer (c1, 1);