{
gint64 new_duration;
GESTimelineElement *parent =
- ges_timeline_element_get_toplevel_parent (GES_TIMELINE_ELEMENT (clip));
+ ges_timeline_element_peak_toplevel (GES_TIMELINE_ELEMENT (clip));
- if (ELEMENT_FLAG_IS_SET (parent, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
+ if (GES_TIMELINE_ELEMENT_BEING_EDITED (parent))
return;
- }
if (parent) {
GESTimelineElement *prev_topparent =
- ges_timeline_element_get_toplevel_parent (GES_TIMELINE_ELEMENT
+ ges_timeline_element_peak_toplevel (GES_TIMELINE_ELEMENT
(self->next_source));
GESTimelineElement *next_topparent =
- ges_timeline_element_get_toplevel_parent (GES_TIMELINE_ELEMENT
+ ges_timeline_element_peak_toplevel (GES_TIMELINE_ELEMENT
(self->previous_source));
- if (ELEMENT_FLAG_IS_SET (prev_topparent, GES_TIMELINE_ELEMENT_SET_SIMPLE) ||
- ELEMENT_FLAG_IS_SET (next_topparent, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
+ if (GES_TIMELINE_ELEMENT_BEING_EDITED (prev_topparent) ||
+ GES_TIMELINE_ELEMENT_BEING_EDITED (next_topparent))
return;
- }
if (parent == prev_topparent && parent == next_topparent) {
GST_DEBUG_OBJECT (self,
}
self->positioning = TRUE;
- ELEMENT_SET_FLAG (self->transition_clip, GES_TIMELINE_ELEMENT_SET_SIMPLE);
+ GES_TIMELINE_ELEMENT_SET_BEING_EDITED (self->transition_clip);
_set_start0 (GES_TIMELINE_ELEMENT (self->transition_clip),
_START (self->next_source));
_set_duration0 (GES_TIMELINE_ELEMENT (self->transition_clip), new_duration);
- ELEMENT_UNSET_FLAG (self->transition_clip, GES_TIMELINE_ELEMENT_SET_SIMPLE);
+ GES_TIMELINE_ELEMENT_UNSET_BEING_EDITED (self->transition_clip);
self->positioning = FALSE;
}
GST_TIME_FORMAT, GST_TIME_ARGS (duration_limit));
if (_CLOCK_TIME_IS_LESS (duration_limit, element->duration)
- && !ELEMENT_FLAG_IS_SET (self, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
+ && !GES_TIMELINE_ELEMENT_BEING_EDITED (self)) {
gboolean res;
GST_INFO_OBJECT (self, "Automatically reducing duration to %"
for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
GESTimelineElement *child = (GESTimelineElement *) tmp->data;
- if (child != container->initiated_move) {
- ELEMENT_SET_FLAG (child, GES_TIMELINE_ELEMENT_SET_SIMPLE);
+ if (child != container->initiated_move)
_set_duration0 (GES_TIMELINE_ELEMENT (child), duration);
- ELEMENT_UNSET_FLAG (child, GES_TIMELINE_ELEMENT_SET_SIMPLE);
- }
}
container->children_control_mode = GES_CHILDREN_UPDATE;
g_list_free_full (children, gst_object_unref);
return FALSE;
}
- if (layer->timeline
- && !ELEMENT_FLAG_IS_SET (clip, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
+ if (layer->timeline && !GES_TIMELINE_ELEMENT_BEING_EDITED (clip)) {
/* move to new layer, also checks moving of toplevel */
return timeline_tree_move (timeline_get_tree (layer->timeline),
element, (gint64) ges_layer_get_priority (current_layer) -
gst_object_ref (track));
}
- ELEMENT_SET_FLAG (clip, GES_TIMELINE_ELEMENT_SET_SIMPLE);
+ GES_TIMELINE_ELEMENT_SET_BEING_EDITED (clip);
_set_duration0 (GES_TIMELINE_ELEMENT (clip), old_duration);
- ELEMENT_UNSET_FLAG (clip, GES_TIMELINE_ELEMENT_SET_SIMPLE);
- g_object_notify (G_OBJECT (clip), "duration");
+ GES_TIMELINE_ELEMENT_UNSET_BEING_EDITED (clip);
/* add to the track after the duration change so we don't overlap! */
for (tmp = GES_CONTAINER_CHILDREN (new_object); tmp; tmp = tmp->next) {
{
GList *tmp;
GstClockTime duration, end = 0, start = G_MAXUINT64;
- gboolean was_setting_simple =
- ELEMENT_FLAG_IS_SET (container, GES_TIMELINE_ELEMENT_SET_SIMPLE);
+ gboolean was_being_edited = GES_TIMELINE_ELEMENT_BEING_EDITED (container);
if (!container->children) {
/* If we are now empty, keep the same duration and start. This works
return;
}
- ELEMENT_SET_FLAG (container, GES_TIMELINE_ELEMENT_SET_SIMPLE);
+ GES_TIMELINE_ELEMENT_SET_BEING_EDITED (container);
for (tmp = container->children; tmp; tmp = tmp->next) {
start = MIN (start, _START (tmp->data));
if (prev_dur != duration)
g_object_notify (G_OBJECT (container), "duration");
}
- if (!was_setting_simple)
- ELEMENT_UNSET_FLAG (container, GES_TIMELINE_ELEMENT_SET_SIMPLE);
+ if (!was_being_edited)
+ GES_TIMELINE_ELEMENT_UNSET_BEING_EDITED (container);
g_hash_table_foreach (container->priv->mappings,
(GHFunc) _resync_position_offsets, container);
GESContainerPrivate *priv = container->priv;
GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);
- GESChildrenControlMode pmode = container->children_control_mode;
+ GESChildrenControlMode mode = container->children_control_mode;
+
+ if (mode == GES_CHILDREN_IGNORE_NOTIFIES)
+ return;
+
+ if (GES_TIMELINE_ELEMENT_BEING_EDITED (child))
+ mode = GES_CHILDREN_UPDATE_ALL_VALUES;
map = g_hash_table_lookup (priv->mappings, child);
g_assert (map);
- if (ELEMENT_FLAG_IS_SET (child, GES_TIMELINE_ELEMENT_SET_SIMPLE))
- container->children_control_mode = GES_CHILDREN_UPDATE_ALL_VALUES;
-
- switch (container->children_control_mode) {
- case GES_CHILDREN_IGNORE_NOTIFIES:
- break;
+ switch (mode) {
case GES_CHILDREN_UPDATE_ALL_VALUES:
_update_start_duration (container, child);
break;
case GES_CHILDREN_UPDATE_OFFSETS:
map->start_offset = _START (container) - _START (child);
break;
-
case GES_CHILDREN_UPDATE:
/* We update all the children calling our set_start method */
container->initiated_move = child;
default:
break;
}
-
- container->children_control_mode = pmode;
}
static void
GESContainerPrivate *priv = container->priv;
GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);
- GESChildrenControlMode pmode = container->children_control_mode;
+ GESChildrenControlMode mode = container->children_control_mode;
- if (pmode == GES_CHILDREN_IGNORE_NOTIFIES)
+ if (mode == GES_CHILDREN_IGNORE_NOTIFIES)
return;
- if (ELEMENT_FLAG_IS_SET (child, GES_TIMELINE_ELEMENT_SET_SIMPLE))
- container->children_control_mode = GES_CHILDREN_UPDATE_ALL_VALUES;
+ if (GES_TIMELINE_ELEMENT_BEING_EDITED (child))
+ mode = GES_CHILDREN_UPDATE_ALL_VALUES;
map = g_hash_table_lookup (priv->mappings, child);
g_assert (map);
- switch (container->children_control_mode) {
- case GES_CHILDREN_IGNORE_NOTIFIES:
- break;
+ switch (mode) {
case GES_CHILDREN_UPDATE_ALL_VALUES:
_update_start_duration (container, child);
break;
default:
break;
}
-
- container->children_control_mode = pmode;
}
/****************************************************
/* sigids takes ownership of new_layer, we take ownership of old_layer */
sigids->layer = new_layer;
- if (ELEMENT_FLAG_IS_SET (clip, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
+ if (GES_TIMELINE_ELEMENT_BEING_EDITED (clip)) {
GST_DEBUG_OBJECT (container, "Not moving with change in priority of "
"clip child %" GES_FORMAT, GES_ARGS (clip));
_update_our_values (GES_GROUP (clip->parent));
return;
}
/* if a child group is simply updating its values we will do the same */
- if (child_group->priv->updating_priority) {
+ if (child_group->priv->updating_priority ||
+ GES_TIMELINE_ELEMENT_BEING_EDITED (child)) {
GST_DEBUG_OBJECT (container, "Not moving with change in priority of "
"group child %" GES_FORMAT " because it is not moving itself",
GES_ARGS (child_group));
if (GES_GROUP (element)->priv->updating_priority == TRUE)
return TRUE;
- container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
-
layers = GES_TIMELINE_ELEMENT_TIMELINE (element) ?
GES_TIMELINE_ELEMENT_TIMELINE (element)->layers : NULL;
if (layers == NULL) {
/* FIXME: why are we not shifting ->max_layer_prio? */
+ if (GES_TIMELINE_ELEMENT_BEING_EDITED (element))
+ return TRUE;
+
+ container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
+
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
GESTimelineElement *child = tmp->data;
- if (child != container->initiated_move
- || ELEMENT_FLAG_IS_SET (container, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
+ if (child != container->initiated_move) {
if (GES_IS_CLIP (child)) {
guint32 layer_prio = GES_TIMELINE_ELEMENT_LAYER_PRIORITY (child) + diff;
GESLayer *layer =
{
GList *tmp, *children;
gint64 diff = start - _START (element);
- GESTimeline *timeline;
GESContainer *container = GES_CONTAINER (element);
- GESTimelineElement *toplevel =
- ges_timeline_element_get_toplevel_parent (element);
- gst_object_unref (toplevel);
if (GES_GROUP (element)->priv->setting_value == TRUE)
/* Let GESContainer update itself */
return GES_TIMELINE_ELEMENT_CLASS (parent_class)->set_start (element,
start);
- if (ELEMENT_FLAG_IS_SET (element, GES_TIMELINE_ELEMENT_SET_SIMPLE) ||
- ELEMENT_FLAG_IS_SET (toplevel, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
- /* get copy of children, since GESContainer may resort the group */
- children = ges_container_get_children (container, FALSE);
- container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
- for (tmp = children; tmp; tmp = tmp->next)
- _set_start0 (tmp->data, _START (tmp->data) + diff);
- container->children_control_mode = GES_CHILDREN_UPDATE;
- g_list_free_full (children, gst_object_unref);
- return TRUE;
- }
-
- timeline = GES_TIMELINE_ELEMENT_TIMELINE (element);
- if (timeline)
- return ges_timeline_move_object_simple (timeline, element, NULL,
- GES_EDGE_NONE, start);
+ /* get copy of children, since GESContainer may resort the group */
+ children = ges_container_get_children (container, FALSE);
+ container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
+ for (tmp = children; tmp; tmp = tmp->next)
+ _set_start0 (tmp->data, _START (tmp->data) + diff);
+ container->children_control_mode = GES_CHILDREN_UPDATE;
+ g_list_free_full (children, gst_object_unref);
return TRUE;
}
#define GES_TRACK_ELEMENT_IS_CORE(child) \
(ges_track_element_get_creator_asset (GES_TRACK_ELEMENT (child)) != NULL)
+#define GES_TIMELINE_ELEMENT_SET_BEING_EDITED(element) \
+ ELEMENT_SET_FLAG ( \
+ ges_timeline_element_peak_toplevel (GES_TIMELINE_ELEMENT (element)), \
+ GES_TIMELINE_ELEMENT_SET_SIMPLE)
+
+#define GES_TIMELINE_ELEMENT_UNSET_BEING_EDITED(element) \
+ ELEMENT_UNSET_FLAG ( \
+ ges_timeline_element_peak_toplevel (GES_TIMELINE_ELEMENT (element)), \
+ GES_TIMELINE_ELEMENT_SET_SIMPLE)
+
+#define GES_TIMELINE_ELEMENT_BEING_EDITED(element) \
+ ELEMENT_FLAG_IS_SET ( \
+ ges_timeline_element_peak_toplevel (GES_TIMELINE_ELEMENT (element)), \
+ GES_TIMELINE_ELEMENT_SET_SIMPLE)
+
#define SUPRESS_UNUSED_WARNING(a) (void)a
GES_TIMELINE_ELEMENT_SET_SIMPLE = (1 << 1),
} GESTimelineElementFlags;
+G_GNUC_INTERNAL GESTimelineElement * ges_timeline_element_peak_toplevel (GESTimelineElement * self);
G_GNUC_INTERNAL gdouble ges_timeline_element_get_media_duration_factor(GESTimelineElement *self);
G_GNUC_INTERNAL GESTimelineElement * ges_timeline_element_get_copied_from (GESTimelineElement *self);
G_GNUC_INTERNAL GESTimelineElementFlags ges_timeline_element_flags (GESTimelineElement *self);
/*********************************************
* Internal and private helpers *
*********************************************/
+
+GESTimelineElement *
+ges_timeline_element_peak_toplevel (GESTimelineElement * self)
+{
+ GESTimelineElement *toplevel = self;
+
+ while (toplevel->parent)
+ toplevel = toplevel->parent;
+
+ return toplevel;
+}
+
gdouble
ges_timeline_element_get_media_duration_factor (GESTimelineElement * self)
{
" new start: %" GST_TIME_FORMAT,
GST_TIME_ARGS (GES_TIMELINE_ELEMENT_START (self)), GST_TIME_ARGS (start));
- toplevel_container = ges_timeline_element_get_toplevel_parent (self);
-
- if (self->timeline
- && !ELEMENT_FLAG_IS_SET (self, GES_TIMELINE_ELEMENT_SET_SIMPLE)
- && !ELEMENT_FLAG_IS_SET (toplevel_container,
- GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
-
- gst_object_unref (toplevel_container);
-
+ if (self->timeline && !GES_TIMELINE_ELEMENT_BEING_EDITED (self))
return ges_timeline_element_edit (self, NULL, -1, GES_EDIT_MODE_NORMAL,
GES_EDGE_NONE, start);
- }
+
+ toplevel_container = ges_timeline_element_peak_toplevel (self);
parent = self->parent;
/* FIXME This should not belong to GESTimelineElement */
"Can not move the object as it would imply its "
"container to have a negative start value");
- gst_object_unref (toplevel_container);
return FALSE;
}
- gst_object_unref (toplevel_container);
klass = GES_TIMELINE_ELEMENT_GET_CLASS (self);
if (klass->set_start) {
gint res = klass->set_start (self, start);
GstClockTime duration)
{
GESTimelineElementClass *klass;
- GESTimelineElement *toplevel;
g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE);
if (duration == self->duration)
return TRUE;
- toplevel = ges_timeline_element_get_toplevel_parent (self);
- if (self->timeline &&
- !ELEMENT_FLAG_IS_SET (self, GES_TIMELINE_ELEMENT_SET_SIMPLE) &&
- !ELEMENT_FLAG_IS_SET (toplevel, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
- gst_object_unref (toplevel);
+ if (self->timeline && !GES_TIMELINE_ELEMENT_BEING_EDITED (self))
return ges_timeline_element_edit (self, NULL, -1, GES_EDIT_MODE_TRIM,
GES_EDGE_END, self->start + duration);
- }
- gst_object_unref (toplevel);
GST_DEBUG_OBJECT (self, "current duration: %" GST_TIME_FORMAT
" new duration: %" GST_TIME_FORMAT,
GESTimelineElement *
ges_timeline_element_get_toplevel_parent (GESTimelineElement * self)
{
- GESTimelineElement *toplevel = self;
+ GESTimelineElement *toplevel;
g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), NULL);
- while (GES_TIMELINE_ELEMENT_PARENT (toplevel))
- toplevel = GES_TIMELINE_ELEMENT_PARENT (toplevel);
+ toplevel = ges_timeline_element_peak_toplevel (self);
return gst_object_ref (toplevel);
}
(GNodeTraverseFunc) print_node, NULL);
}
-static inline GESTimelineElement *
-get_toplevel_container (gpointer element)
-{
- GESTimelineElement *ret =
- ges_timeline_element_get_toplevel_parent ((GESTimelineElement
- *) (element));
-
- /* We own a ref to the elements ourself */
- gst_object_unref (ret);
- return ret;
-}
-
static GNode *
find_node (GNode * root, gpointer element)
{
g_signal_connect (element, "notify::parent",
G_CALLBACK (timeline_element_parent_cb), root);
- toplevel = get_toplevel_container (element);
+ toplevel = ges_timeline_element_peak_toplevel (element);
if (toplevel == element) {
GST_DEBUG ("Tracking toplevel element %" GES_FORMAT, GES_ARGS (element));
perform_element_edit (GESTimelineElement * element, EditData * edit)
{
gboolean ret = FALSE;
- GESTimelineElement *toplevel = get_toplevel_container (element);
guint32 layer_prio = ges_timeline_element_get_layer_priority (element);
switch (edit->mode) {
return FALSE;
}
- ELEMENT_SET_FLAG (element, GES_TIMELINE_ELEMENT_SET_SIMPLE);
- ELEMENT_SET_FLAG (toplevel, GES_TIMELINE_ELEMENT_SET_SIMPLE);
+ GES_TIMELINE_ELEMENT_SET_BEING_EDITED (element);
if (GST_CLOCK_TIME_IS_VALID (edit->start)) {
if (!ges_timeline_element_set_start (element, edit->start)) {
GST_ERROR_OBJECT (element, "Failed to set the start");
ret = TRUE;
done:
- ELEMENT_UNSET_FLAG (element, GES_TIMELINE_ELEMENT_SET_SIMPLE);
- ELEMENT_UNSET_FLAG (toplevel, GES_TIMELINE_ELEMENT_SET_SIMPLE);
+ GES_TIMELINE_ELEMENT_UNSET_BEING_EDITED (element);
return ret;
}
_REPLACE_TRACK_ELEMENT_WITH_PARENT (element);
- ripple_toplevel = get_toplevel_container (element);
+ ripple_toplevel = ges_timeline_element_peak_toplevel (element);
/* if EDGE_END:
* TRIM_END the element, and MOVE all toplevels whose start is after
GST_INFO_OBJECT (element, "Moving with toplevel with offset %"
G_GINT64_FORMAT " and layer offset %" G_GINT64_FORMAT, offset,
layer_priority_offset);
- element = get_toplevel_container (element);
+ element = ges_timeline_element_peak_toplevel (element);
mode = EDIT_MOVE;
break;
default: