diff --git a/docs/libs/ges-sections.txt b/docs/libs/ges-sections.txt index 8c783ff831..2151243fed 100644 --- a/docs/libs/ges-sections.txt +++ b/docs/libs/ges-sections.txt @@ -378,6 +378,7 @@ ges_timeline_enable_update ges_timeline_is_updating ges_timeline_commit ges_timeline_commit_sync +ges_timeline_move_layer ges_timeline_get_tracks ges_timeline_get_layer diff --git a/ges/ges-timeline.c b/ges/ges-timeline.c index aba57882c1..da618e77ea 100644 --- a/ges/ges-timeline.c +++ b/ges/ges-timeline.c @@ -186,6 +186,8 @@ struct _GESTimelinePrivate * probably through a ges_layer_get_track_elements () method */ GHashTable *by_layer; /* {layer: GSequence of TrackElement by start/priorities} */ + /* Avoid sorting layers when we are actually resyncing them ourself */ + gboolean resyncing_layers; GList *auto_transitions; MoveContext movecontext; @@ -734,6 +736,22 @@ sort_layers (gpointer a, gpointer b) return 0; } +static void +_resync_layers (GESTimeline * timeline) +{ + GList *tmp; + gint i = 0; + + timeline->priv->resyncing_layers = TRUE; + for (tmp = timeline->layers; tmp; tmp = tmp->next) { + GST_ERROR_OBJECT (tmp->data, "New index: %d", i); + ges_layer_set_priority (tmp->data, i); + + i++; + } + timeline->priv->resyncing_layers = FALSE; +} + static void timeline_update_duration (GESTimeline * timeline) { @@ -3787,3 +3805,43 @@ ges_timeline_paste_element (GESTimeline * timeline, return g_object_ref (res); } + +/** + * ges_timeline_move_layer: + * @timeline: The timeline in which @layer must be + * @layer: The layer to move at @new_layer_priority + * @new_layer_priority: The index at which @layer should land + * + * Moves @layer at @new_layer_priority meaning that @layer + * we land at that position in the stack of layers inside + * the timeline. If @new_layer_priority is superior than the number + * of layers present in the time, it will move to the end of the + * stack of layers. + */ +gboolean +ges_timeline_move_layer (GESTimeline * timeline, GESLayer * layer, + guint new_layer_priority) +{ + gint current_priority; + + g_return_val_if_fail (GES_IS_TIMELINE (timeline), FALSE); + g_return_val_if_fail (GES_IS_LAYER (layer), FALSE); + g_return_val_if_fail (ges_layer_get_timeline (layer) == timeline, FALSE); + + current_priority = ges_layer_get_priority (layer); + + if (new_layer_priority == current_priority) { + GST_DEBUG_OBJECT (timeline, + "Nothing to do for %" GST_PTR_FORMAT ", same priorities", layer); + + return TRUE; + } + + timeline->layers = g_list_remove (timeline->layers, layer); + timeline->layers = g_list_insert (timeline->layers, layer, + (gint) new_layer_priority); + + _resync_layers (timeline); + + return TRUE; +} diff --git a/ges/ges-timeline.h b/ges/ges-timeline.h index ccfd1cbf16..35bae53a87 100644 --- a/ges/ges-timeline.h +++ b/ges/ges-timeline.h @@ -161,6 +161,8 @@ gboolean ges_timeline_is_empty (GESTimeline * timeline); GES_API GESTimelineElement * ges_timeline_paste_element (GESTimeline * timeline, GESTimelineElement * element, GstClockTime position, gint layer_priority); +GES_API +gboolean ges_timeline_move_layer (GESTimeline *timeline, GESLayer *layer, guint new_layer_priority); G_END_DECLS