timeline: Add a method to move layers around

summary_:
This way the timeline can handle all priorities for the user
making the API simpler to use.

API:
  + ges_timeline_move_layer

reviewers_: Mathieu_Du
Differential Revision: https://phabricator.freedesktop.org/D232
This commit is contained in:
Thibault Saunier 2015-12-12 11:29:50 +00:00 committed by Thibault Saunier
parent dc36dd1afe
commit 11b24922a1
3 changed files with 61 additions and 0 deletions

View file

@ -378,6 +378,7 @@ ges_timeline_enable_update
ges_timeline_is_updating ges_timeline_is_updating
ges_timeline_commit ges_timeline_commit
ges_timeline_commit_sync ges_timeline_commit_sync
ges_timeline_move_layer
<SUBSECTION usage> <SUBSECTION usage>
ges_timeline_get_tracks ges_timeline_get_tracks
ges_timeline_get_layer ges_timeline_get_layer

View file

@ -186,6 +186,8 @@ struct _GESTimelinePrivate
* probably through a ges_layer_get_track_elements () method */ * probably through a ges_layer_get_track_elements () method */
GHashTable *by_layer; /* {layer: GSequence of TrackElement by start/priorities} */ 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; GList *auto_transitions;
MoveContext movecontext; MoveContext movecontext;
@ -734,6 +736,22 @@ sort_layers (gpointer a, gpointer b)
return 0; 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 static void
timeline_update_duration (GESTimeline * timeline) timeline_update_duration (GESTimeline * timeline)
{ {
@ -3787,3 +3805,43 @@ ges_timeline_paste_element (GESTimeline * timeline,
return g_object_ref (res); 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;
}

View file

@ -161,6 +161,8 @@ gboolean ges_timeline_is_empty (GESTimeline * timeline);
GES_API GES_API
GESTimelineElement * ges_timeline_paste_element (GESTimeline * timeline, GESTimelineElement * ges_timeline_paste_element (GESTimeline * timeline,
GESTimelineElement * element, GstClockTime position, gint layer_priority); 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 G_END_DECLS