mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-27 10:40:34 +00:00
container: Let full control of children priorities to subclasses
For that we make the children_control_mode a protected filed, directly usable by subclasses, removing the method to set it. And we let the subclass set and get the priority offsets to the container class.
This commit is contained in:
parent
ed9dcddef4
commit
9e15e13983
3 changed files with 75 additions and 74 deletions
|
@ -85,11 +85,9 @@ enum
|
|||
|
||||
static GParamSpec *properties[PROP_LAST];
|
||||
|
||||
/*****************************************************
|
||||
* *
|
||||
* GESTimelineElement virtual methods implementation *
|
||||
* *
|
||||
*****************************************************/
|
||||
/****************************************************
|
||||
* Listen to our children *
|
||||
****************************************************/
|
||||
|
||||
static void
|
||||
_get_priority_range (GESContainer * container, guint32 * min_priority,
|
||||
|
@ -106,6 +104,31 @@ _get_priority_range (GESContainer * container, guint32 * min_priority,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_child_priority_changed_cb (GESTimelineElement * child,
|
||||
GParamSpec * arg G_GNUC_UNUSED, GESContainer * container)
|
||||
{
|
||||
guint32 min_prio, max_prio;
|
||||
|
||||
GST_DEBUG_OBJECT (container, "TimelineElement %p priority changed to %i",
|
||||
child, _PRIORITY (child));
|
||||
|
||||
if (container->children_control_mode == GES_CHILDREN_IGNORE_NOTIFIES)
|
||||
return;
|
||||
|
||||
/* Update mapping */
|
||||
_get_priority_range (container, &min_prio, &max_prio);
|
||||
|
||||
_ges_container_set_priority_offset (container, child,
|
||||
min_prio + _PRIORITY (container) - _PRIORITY (child));
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* *
|
||||
* GESTimelineElement virtual methods implementation *
|
||||
* *
|
||||
*****************************************************/
|
||||
|
||||
static gboolean
|
||||
_set_start (GESTimelineElement * element, GstClockTime start)
|
||||
{
|
||||
|
@ -116,8 +139,7 @@ _set_start (GESTimelineElement * element, GstClockTime start)
|
|||
GST_DEBUG_OBJECT (element, "Setting children start, (initiated_move: %"
|
||||
GST_PTR_FORMAT ")", container->initiated_move);
|
||||
|
||||
_ges_container_set_children_control_mode (container,
|
||||
GES_CHILDREN_IGNORE_NOTIFIES);
|
||||
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
|
||||
GESTimelineElement *child = (GESTimelineElement *) tmp->data;
|
||||
|
||||
|
@ -130,7 +152,7 @@ _set_start (GESTimelineElement * element, GstClockTime start)
|
|||
|
||||
}
|
||||
}
|
||||
_ges_container_set_children_control_mode (container, GES_CHILDREN_UPDATE);
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -141,8 +163,7 @@ _set_inpoint (GESTimelineElement * element, GstClockTime inpoint)
|
|||
GList *tmp;
|
||||
GESContainer *container = GES_CONTAINER (element);
|
||||
|
||||
_ges_container_set_children_control_mode (container,
|
||||
GES_CHILDREN_IGNORE_NOTIFIES);
|
||||
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
|
||||
GESTimelineElement *child = (GESTimelineElement *) tmp->data;
|
||||
|
||||
|
@ -150,7 +171,7 @@ _set_inpoint (GESTimelineElement * element, GstClockTime inpoint)
|
|||
_set_inpoint0 (child, inpoint);
|
||||
}
|
||||
}
|
||||
_ges_container_set_children_control_mode (container, GES_CHILDREN_UPDATE);
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -163,8 +184,7 @@ _set_duration (GESTimelineElement * element, GstClockTime duration)
|
|||
|
||||
GESContainer *container = GES_CONTAINER (element);
|
||||
|
||||
_ges_container_set_children_control_mode (container,
|
||||
GES_CHILDREN_IGNORE_NOTIFIES);
|
||||
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
|
||||
GESTimelineElement *child = (GESTimelineElement *) tmp->data;
|
||||
|
||||
|
@ -176,7 +196,7 @@ _set_duration (GESTimelineElement * element, GstClockTime duration)
|
|||
_set_duration0 (GES_TIMELINE_ELEMENT (child), duration);
|
||||
}
|
||||
}
|
||||
_ges_container_set_children_control_mode (container, GES_CHILDREN_UPDATE);
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -203,6 +223,7 @@ _set_priority (GESTimelineElement * element, guint32 priority)
|
|||
|
||||
_get_priority_range (container, &min_prio, &max_prio);
|
||||
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE_OFFSETS;
|
||||
for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
|
||||
guint32 real_tck_prio;
|
||||
GESTimelineElement *child = (GESTimelineElement *) tmp->data;
|
||||
|
@ -222,7 +243,7 @@ _set_priority (GESTimelineElement * element, guint32 priority)
|
|||
}
|
||||
_set_priority0 (child, real_tck_prio);
|
||||
}
|
||||
_ges_container_set_children_control_mode (container, GES_CHILDREN_UPDATE);
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
_compute_height (container);
|
||||
|
||||
return TRUE;
|
||||
|
@ -301,12 +322,11 @@ _add_child (GESContainer * container, GESTimelineElement * element)
|
|||
|
||||
/* We set the timing value of the child to ours, we avoid infinite loop
|
||||
* making sure the container ignore notifies from the child */
|
||||
_ges_container_set_children_control_mode (container,
|
||||
GES_CHILDREN_IGNORE_NOTIFIES);
|
||||
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
_set_start0 (element, GES_TIMELINE_ELEMENT_START (container));
|
||||
_set_inpoint0 (element, GES_TIMELINE_ELEMENT_INPOINT (container));
|
||||
_set_duration0 (element, GES_TIMELINE_ELEMENT_DURATION (container));
|
||||
_ges_container_set_children_control_mode (container, GES_CHILDREN_UPDATE);
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -325,6 +345,8 @@ _remove_child (GESContainer * container, GESTimelineElement * element)
|
|||
static void
|
||||
_child_added (GESContainer * container, GESTimelineElement * element)
|
||||
{
|
||||
g_signal_connect (G_OBJECT (element), "notify::priority",
|
||||
G_CALLBACK (_child_priority_changed_cb), container);
|
||||
_compute_height (container);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,6 @@ typedef struct
|
|||
guint start_notifyid;
|
||||
guint duration_notifyid;
|
||||
guint inpoint_notifyid;
|
||||
guint priority_notifyid;
|
||||
} ChildMapping;
|
||||
|
||||
enum
|
||||
|
@ -76,7 +75,6 @@ struct _GESContainerPrivate
|
|||
/* Set to TRUE when the container is doing updates of track object
|
||||
* properties so we don't end up in infinite property update loops
|
||||
*/
|
||||
GESChildrenControlMode children_control_mode;
|
||||
GHashTable *mappings;
|
||||
guint nb_effects;
|
||||
};
|
||||
|
@ -102,7 +100,6 @@ _free_mapping (ChildMapping * mapping)
|
|||
g_signal_handler_disconnect (child, mapping->start_notifyid);
|
||||
g_signal_handler_disconnect (child, mapping->duration_notifyid);
|
||||
g_signal_handler_disconnect (child, mapping->inpoint_notifyid);
|
||||
g_signal_handler_disconnect (child, mapping->priority_notifyid);
|
||||
|
||||
ges_timeline_element_set_parent (child, NULL);
|
||||
g_slice_free (ChildMapping, mapping);
|
||||
|
@ -150,17 +147,11 @@ _set_start (GESTimelineElement * element, GstClockTime start)
|
|||
map = g_hash_table_lookup (priv->mappings, child);
|
||||
map->start_offset = start - _START (child);
|
||||
}
|
||||
priv->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_priority (GESTimelineElement * element, guint32 priority)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_inpoint (GESTimelineElement * element, GstClockTime inpoint)
|
||||
{
|
||||
|
@ -288,7 +279,6 @@ ges_container_class_init (GESContainerClass * klass)
|
|||
element_class->set_start = _set_start;
|
||||
element_class->set_duration = _set_duration;
|
||||
element_class->set_inpoint = _set_inpoint;
|
||||
element_class->set_priority = _set_priority;
|
||||
|
||||
/* No default implementations */
|
||||
klass->remove_child = NULL;
|
||||
|
@ -329,7 +319,7 @@ _child_start_changed_cb (GESTimelineElement * child,
|
|||
GESContainerPrivate *priv = container->priv;
|
||||
GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);
|
||||
|
||||
if (priv->children_control_mode == GES_CHILDREN_IGNORE_NOTIFIES)
|
||||
if (container->children_control_mode == GES_CHILDREN_IGNORE_NOTIFIES)
|
||||
return;
|
||||
|
||||
map = g_hash_table_lookup (priv->mappings, child);
|
||||
|
@ -353,7 +343,7 @@ _child_inpoint_changed_cb (GESTimelineElement * child,
|
|||
GESContainerPrivate *priv = container->priv;
|
||||
GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);
|
||||
|
||||
if (priv->children_control_mode == GES_CHILDREN_IGNORE_NOTIFIES)
|
||||
if (container->children_control_mode == GES_CHILDREN_IGNORE_NOTIFIES)
|
||||
return;
|
||||
|
||||
map = g_hash_table_lookup (priv->mappings, child);
|
||||
|
@ -374,7 +364,7 @@ _child_duration_changed_cb (GESTimelineElement * child,
|
|||
GESContainerPrivate *priv = container->priv;
|
||||
GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);
|
||||
|
||||
if (priv->children_control_mode == GES_CHILDREN_IGNORE_NOTIFIES)
|
||||
if (container->children_control_mode == GES_CHILDREN_IGNORE_NOTIFIES)
|
||||
return;
|
||||
|
||||
map = g_hash_table_lookup (priv->mappings, child);
|
||||
|
@ -386,30 +376,6 @@ _child_duration_changed_cb (GESTimelineElement * child,
|
|||
container->initiated_move = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_child_priority_changed_cb (GESTimelineElement * child,
|
||||
GParamSpec * arg G_GNUC_UNUSED, GESContainer * container)
|
||||
{
|
||||
ChildMapping *map;
|
||||
guint32 min_prio, max_prio;
|
||||
GESContainerPrivate *priv = container->priv;
|
||||
|
||||
GST_DEBUG_OBJECT (container, "TimelineElement %p priority changed to %i",
|
||||
child, _PRIORITY (child));
|
||||
|
||||
if (priv->children_control_mode == GES_CHILDREN_IGNORE_NOTIFIES)
|
||||
return;
|
||||
|
||||
/* Update mapping */
|
||||
map = g_hash_table_lookup (priv->mappings, child);
|
||||
g_assert (map);
|
||||
|
||||
GES_CONTAINER_GET_CLASS (container)->get_priority_range (container, &min_prio,
|
||||
&max_prio);
|
||||
|
||||
map->priority_offset = min_prio + _PRIORITY (container) - _PRIORITY (child);
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
* *
|
||||
* Internal methods implementation *
|
||||
|
@ -430,13 +396,6 @@ _ges_container_sort_children_by_end (GESContainer * container)
|
|||
(GCompareFunc) element_end_compare);
|
||||
}
|
||||
|
||||
void
|
||||
_ges_container_set_children_control_mode (GESContainer * container,
|
||||
GESChildrenControlMode children_control_mode)
|
||||
{
|
||||
container->priv->children_control_mode = children_control_mode;
|
||||
}
|
||||
|
||||
void
|
||||
_ges_container_set_height (GESContainer * container, guint32 height)
|
||||
{
|
||||
|
@ -447,6 +406,28 @@ _ges_container_set_height (GESContainer * container, guint32 height)
|
|||
}
|
||||
}
|
||||
|
||||
gint
|
||||
_ges_container_get_priority_offset (GESContainer * container,
|
||||
GESTimelineElement * elem)
|
||||
{
|
||||
ChildMapping *map = g_hash_table_lookup (container->priv->mappings, elem);
|
||||
|
||||
g_return_val_if_fail (map, 0);
|
||||
|
||||
return map->priority_offset;
|
||||
}
|
||||
|
||||
void
|
||||
_ges_container_set_priority_offset (GESContainer * container,
|
||||
GESTimelineElement * elem, gint32 priority_offset)
|
||||
{
|
||||
ChildMapping *map = g_hash_table_lookup (container->priv->mappings, elem);
|
||||
|
||||
g_return_if_fail (map);
|
||||
|
||||
map->priority_offset = priority_offset;
|
||||
}
|
||||
|
||||
/**********************************************
|
||||
* *
|
||||
* API implementation *
|
||||
|
@ -480,15 +461,15 @@ ges_container_add (GESContainer * container, GESTimelineElement * child)
|
|||
GST_DEBUG_OBJECT (container, "adding timeline element %" GST_PTR_FORMAT,
|
||||
child);
|
||||
|
||||
priv->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
if (class->add_child) {
|
||||
if (class->add_child (container, child) == FALSE) {
|
||||
priv->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
GST_WARNING_OBJECT (container, "Erreur adding child %p", child);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
priv->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
|
||||
mapping = g_slice_new0 (ChildMapping);
|
||||
mapping->child = gst_object_ref (child);
|
||||
|
@ -497,8 +478,6 @@ ges_container_add (GESContainer * container, GESTimelineElement * child)
|
|||
mapping->inpoint_offset = _INPOINT (container) - _INPOINT (child);
|
||||
GES_CONTAINER_GET_CLASS (container)->get_priority_range (container,
|
||||
&min_prio, &max_prio);
|
||||
mapping->priority_offset =
|
||||
min_prio + _PRIORITY (container) - _PRIORITY (child);
|
||||
|
||||
g_hash_table_insert (priv->mappings, child, mapping);
|
||||
|
||||
|
@ -514,10 +493,6 @@ ges_container_add (GESContainer * container, GESTimelineElement * child)
|
|||
mapping->inpoint_notifyid =
|
||||
g_signal_connect (G_OBJECT (child), "notify::in-point",
|
||||
G_CALLBACK (_child_inpoint_changed_cb), container);
|
||||
mapping->priority_notifyid =
|
||||
g_signal_connect (G_OBJECT (child), "notify::priority",
|
||||
G_CALLBACK (_child_priority_changed_cb), container);
|
||||
|
||||
|
||||
if (ges_timeline_element_set_parent (child, GES_TIMELINE_ELEMENT (container))
|
||||
== FALSE) {
|
||||
|
|
|
@ -84,6 +84,7 @@ struct _GESContainer
|
|||
guint32 height; /* the span of priorities this object needs */
|
||||
|
||||
/* <protected> */
|
||||
GESChildrenControlMode children_control_mode;
|
||||
/*< readonly >*/
|
||||
GESTimelineElement *initiated_move;
|
||||
|
||||
|
@ -144,8 +145,6 @@ GList * ges_container_ungroup (GESContainer * container, gboolean recursive)
|
|||
GESContainer *ges_container_group (GList *containers);
|
||||
|
||||
/* To be used by subclasses only */
|
||||
void _ges_container_set_children_control_mode (GESContainer * container,
|
||||
GESChildrenControlMode children_control_mode);
|
||||
void _ges_container_set_height (GESContainer * container,
|
||||
guint32 height);
|
||||
gboolean ges_container_edit (GESContainer * container,
|
||||
|
@ -153,6 +152,11 @@ gboolean ges_container_edit (GESContainer * container,
|
|||
GESEditMode mode,
|
||||
GESEdge edge,
|
||||
guint64 position);
|
||||
gint _ges_container_get_priority_offset (GESContainer * container,
|
||||
GESTimelineElement *elem);
|
||||
void _ges_container_set_priority_offset (GESContainer * container,
|
||||
GESTimelineElement *elem,
|
||||
gint32 priority_offset);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
|
Loading…
Reference in a new issue