actor: Use proper internal API

Inside the set_child_[above|below]_sibling() and set_child_at_index() we
should be using the internal API for mutating the children list, instead
of the delegate functions. This ensures that we go through a single,
well-defined code path for all operations on the list of children of
an actor.
This commit is contained in:
Emmanuele Bassi 2011-12-27 19:28:47 +00:00
parent b835e1f8c4
commit 6f4578838c

View File

@ -9490,7 +9490,18 @@ typedef void (* ClutterActorAddChildFunc) (ClutterActor *parent,
typedef enum { typedef enum {
ADD_CHILD_CREATE_META = 1 << 0, ADD_CHILD_CREATE_META = 1 << 0,
ADD_CHILD_EMIT_PARENT_SET = 1 << 1, ADD_CHILD_EMIT_PARENT_SET = 1 << 1,
ADD_CHILD_EMIT_ACTOR_ADDED = 1 << 2 ADD_CHILD_EMIT_ACTOR_ADDED = 1 << 2,
ADD_CHILD_CHECK_STATE = 1 << 3,
/* default flags for public API */
ADD_CHILD_DEFAULT_FLAGS = ADD_CHILD_CREATE_META |
ADD_CHILD_EMIT_PARENT_SET |
ADD_CHILD_EMIT_ACTOR_ADDED |
ADD_CHILD_CHECK_STATE,
/* flags for legacy/deprecated API */
ADD_CHILD_LEGACY_FLAGS = ADD_CHILD_EMIT_PARENT_SET |
ADD_CHILD_CHECK_STATE
} ClutterActorAddChildFlags; } ClutterActorAddChildFlags;
/*< private > /*< private >
@ -9517,7 +9528,7 @@ clutter_actor_add_child_internal (ClutterActor *self,
gpointer data) gpointer data)
{ {
ClutterTextDirection text_dir; ClutterTextDirection text_dir;
gboolean create_meta, emit_parent_set, emit_actor_added; gboolean create_meta, emit_parent_set, emit_actor_added, check_state;
if (child->priv->parent != NULL) if (child->priv->parent != NULL)
{ {
@ -9541,6 +9552,7 @@ clutter_actor_add_child_internal (ClutterActor *self,
create_meta = (flags & ADD_CHILD_CREATE_META) != 0; create_meta = (flags & ADD_CHILD_CREATE_META) != 0;
emit_parent_set = (flags & ADD_CHILD_EMIT_PARENT_SET) != 0; emit_parent_set = (flags & ADD_CHILD_EMIT_PARENT_SET) != 0;
emit_actor_added = (flags & ADD_CHILD_EMIT_ACTOR_ADDED) != 0; emit_actor_added = (flags & ADD_CHILD_EMIT_ACTOR_ADDED) != 0;
check_state = (flags & ADD_CHILD_CHECK_STATE) != 0;
if (create_meta) if (create_meta)
clutter_container_create_child_meta (CLUTTER_CONTAINER (self), child); clutter_container_create_child_meta (CLUTTER_CONTAINER (self), child);
@ -9563,6 +9575,8 @@ clutter_actor_add_child_internal (ClutterActor *self,
if (emit_parent_set && !CLUTTER_ACTOR_IN_REPARENT (child)) if (emit_parent_set && !CLUTTER_ACTOR_IN_REPARENT (child))
g_signal_emit (child, actor_signals[PARENT_SET], 0, NULL); g_signal_emit (child, actor_signals[PARENT_SET], 0, NULL);
if (check_state)
{
/* If parent is mapped or realized, we need to also be mapped or /* If parent is mapped or realized, we need to also be mapped or
* realized once we're inside the parent. * realized once we're inside the parent.
*/ */
@ -9571,6 +9585,7 @@ clutter_actor_add_child_internal (ClutterActor *self,
/* propagate the parent's text direction to the child */ /* propagate the parent's text direction to the child */
text_dir = clutter_actor_get_text_direction (self); text_dir = clutter_actor_get_text_direction (self);
clutter_actor_set_text_direction (child, text_dir); clutter_actor_set_text_direction (child, text_dir);
}
if (child->priv->show_on_set_parent) if (child->priv->show_on_set_parent)
clutter_actor_show (child); clutter_actor_show (child);
@ -9628,9 +9643,7 @@ clutter_actor_add_child (ClutterActor *self,
g_return_if_fail (child->priv->parent == NULL); g_return_if_fail (child->priv->parent == NULL);
clutter_actor_add_child_internal (self, child, clutter_actor_add_child_internal (self, child,
ADD_CHILD_CREATE_META | ADD_CHILD_DEFAULT_FLAGS,
ADD_CHILD_EMIT_PARENT_SET |
ADD_CHILD_EMIT_ACTOR_ADDED,
insert_child_at_depth, insert_child_at_depth,
NULL); NULL);
} }
@ -9666,9 +9679,7 @@ clutter_actor_insert_child_at_index (ClutterActor *self,
g_return_if_fail (child->priv->parent == NULL); g_return_if_fail (child->priv->parent == NULL);
clutter_actor_add_child_internal (self, child, clutter_actor_add_child_internal (self, child,
ADD_CHILD_CREATE_META | ADD_CHILD_DEFAULT_FLAGS,
ADD_CHILD_EMIT_PARENT_SET |
ADD_CHILD_EMIT_ACTOR_ADDED,
insert_child_at_index, insert_child_at_index,
GINT_TO_POINTER (index_)); GINT_TO_POINTER (index_));
} }
@ -9709,9 +9720,7 @@ clutter_actor_insert_child_above (ClutterActor *self,
sibling->priv->parent == self)); sibling->priv->parent == self));
clutter_actor_add_child_internal (self, child, clutter_actor_add_child_internal (self, child,
ADD_CHILD_CREATE_META | ADD_CHILD_DEFAULT_FLAGS,
ADD_CHILD_EMIT_PARENT_SET |
ADD_CHILD_EMIT_ACTOR_ADDED,
insert_child_above, insert_child_above,
sibling); sibling);
} }
@ -9752,9 +9761,7 @@ clutter_actor_insert_child_below (ClutterActor *self,
sibling->priv->parent == self)); sibling->priv->parent == self));
clutter_actor_add_child_internal (self, child, clutter_actor_add_child_internal (self, child,
ADD_CHILD_CREATE_META | ADD_CHILD_DEFAULT_FLAGS,
ADD_CHILD_EMIT_PARENT_SET |
ADD_CHILD_EMIT_ACTOR_ADDED,
insert_child_below, insert_child_below,
sibling); sibling);
} }
@ -9790,8 +9797,7 @@ clutter_actor_set_parent (ClutterActor *self,
* emit the ::actor-added signal, to avoid recursion or double * emit the ::actor-added signal, to avoid recursion or double
* emissions * emissions
*/ */
clutter_actor_add_child_internal (parent, self, clutter_actor_add_child_internal (parent, self, ADD_CHILD_LEGACY_FLAGS,
ADD_CHILD_EMIT_PARENT_SET,
insert_child_at_depth, insert_child_at_depth,
NULL); NULL);
} }
@ -9875,7 +9881,21 @@ remove_child (ClutterActor *self,
typedef enum { typedef enum {
REMOVE_CHILD_DESTROY_META = 1 << 0, REMOVE_CHILD_DESTROY_META = 1 << 0,
REMOVE_CHILD_EMIT_PARENT_SET = 1 << 1, REMOVE_CHILD_EMIT_PARENT_SET = 1 << 1,
REMOVE_CHILD_EMIT_ACTOR_REMOVED = 1 << 2 REMOVE_CHILD_EMIT_ACTOR_REMOVED = 1 << 2,
REMOVE_CHILD_CHECK_STATE = 1 << 3,
REMOVE_CHILD_FLUSH_QUEUE = 1 << 4,
/* default flags for public API */
REMOVE_CHILD_DEFAULT_FLAGS = REMOVE_CHILD_DESTROY_META |
REMOVE_CHILD_EMIT_PARENT_SET |
REMOVE_CHILD_EMIT_ACTOR_REMOVED |
REMOVE_CHILD_CHECK_STATE |
REMOVE_CHILD_FLUSH_QUEUE,
/* flags for legacy/deprecated API */
REMOVE_CHILD_LEGACY_FLAGS = REMOVE_CHILD_CHECK_STATE |
REMOVE_CHILD_FLUSH_QUEUE |
REMOVE_CHILD_EMIT_PARENT_SET
} ClutterActorRemoveChildFlags; } ClutterActorRemoveChildFlags;
/*< private > /*< private >
@ -9891,16 +9911,21 @@ clutter_actor_remove_child_internal (ClutterActor *self,
ClutterActor *child, ClutterActor *child,
ClutterActorRemoveChildFlags flags) ClutterActorRemoveChildFlags flags)
{ {
gboolean destroy_meta, emit_parent_set, emit_actor_removed; gboolean destroy_meta, emit_parent_set, emit_actor_removed, check_state;
gboolean flush_queue;
gboolean was_mapped; gboolean was_mapped;
destroy_meta = (flags & REMOVE_CHILD_DESTROY_META) != 0; destroy_meta = (flags & REMOVE_CHILD_DESTROY_META) != 0;
emit_parent_set = (flags & REMOVE_CHILD_EMIT_PARENT_SET) != 0; emit_parent_set = (flags & REMOVE_CHILD_EMIT_PARENT_SET) != 0;
emit_actor_removed = (flags & REMOVE_CHILD_EMIT_ACTOR_REMOVED) != 0; emit_actor_removed = (flags & REMOVE_CHILD_EMIT_ACTOR_REMOVED) != 0;
check_state = (flags & REMOVE_CHILD_CHECK_STATE) != 0;
flush_queue = (flags & REMOVE_CHILD_FLUSH_QUEUE) != 0;
if (destroy_meta) if (destroy_meta)
clutter_container_destroy_child_meta (CLUTTER_CONTAINER (self), child); clutter_container_destroy_child_meta (CLUTTER_CONTAINER (self), child);
if (check_state)
{
was_mapped = CLUTTER_ACTOR_IS_MAPPED (child); was_mapped = CLUTTER_ACTOR_IS_MAPPED (child);
/* we need to unrealize *before* we set parent_actor to NULL, /* we need to unrealize *before* we set parent_actor to NULL,
@ -9910,7 +9935,12 @@ clutter_actor_remove_child_internal (ClutterActor *self,
* unless we're reparenting. * unless we're reparenting.
*/ */
clutter_actor_update_map_state (child, MAP_STATE_MAKE_UNREALIZED); clutter_actor_update_map_state (child, MAP_STATE_MAKE_UNREALIZED);
}
else
was_mapped = FALSE;
if (flush_queue)
{
/* We take this opportunity to invalidate any queue redraw entry /* We take this opportunity to invalidate any queue redraw entry
* associated with the actor and descendants since we won't be able to * associated with the actor and descendants since we won't be able to
* determine the appropriate stage after this. * determine the appropriate stage after this.
@ -9929,6 +9959,7 @@ clutter_actor_remove_child_internal (ClutterActor *self,
invalidate_queue_redraw_entry, invalidate_queue_redraw_entry,
NULL, NULL,
NULL); NULL);
}
child->priv->parent = NULL; child->priv->parent = NULL;
@ -9982,9 +10013,7 @@ clutter_actor_remove_child (ClutterActor *self,
g_return_if_fail (child->priv->parent == self); g_return_if_fail (child->priv->parent == self);
clutter_actor_remove_child_internal (self, child, clutter_actor_remove_child_internal (self, child,
REMOVE_CHILD_DESTROY_META | REMOVE_CHILD_DEFAULT_FLAGS);
REMOVE_CHILD_EMIT_PARENT_SET |
REMOVE_CHILD_EMIT_ACTOR_REMOVED);
} }
/** /**
@ -10014,9 +10043,7 @@ clutter_actor_remove_all_children (ClutterActor *self)
ClutterActor *next = iter->priv->next_sibling; ClutterActor *next = iter->priv->next_sibling;
clutter_actor_remove_child_internal (self, iter, clutter_actor_remove_child_internal (self, iter,
REMOVE_CHILD_DESTROY_META | REMOVE_CHILD_DEFAULT_FLAGS);
REMOVE_CHILD_EMIT_PARENT_SET |
REMOVE_CHILD_EMIT_ACTOR_REMOVED);
iter = next; iter = next;
} }
@ -10086,16 +10113,12 @@ clutter_actor_replace_child (ClutterActor *self,
next_sibling = old_child->priv->next_sibling; next_sibling = old_child->priv->next_sibling;
clutter_actor_remove_child_internal (self, old_child, clutter_actor_remove_child_internal (self, old_child,
REMOVE_CHILD_DESTROY_META | REMOVE_CHILD_DEFAULT_FLAGS);
REMOVE_CHILD_EMIT_PARENT_SET |
REMOVE_CHILD_EMIT_ACTOR_REMOVED);
clos.prev_sibling = prev_sibling; clos.prev_sibling = prev_sibling;
clos.next_sibling = next_sibling; clos.next_sibling = next_sibling;
clutter_actor_add_child_internal (self, new_child, clutter_actor_add_child_internal (self, new_child,
ADD_CHILD_CREATE_META | ADD_CHILD_DEFAULT_FLAGS,
ADD_CHILD_EMIT_PARENT_SET |
ADD_CHILD_EMIT_ACTOR_ADDED,
insert_child_between, insert_child_between,
&clos); &clos);
} }
@ -10127,7 +10150,7 @@ clutter_actor_unparent (ClutterActor *self)
return; return;
clutter_actor_remove_child_internal (self->priv->parent, self, clutter_actor_remove_child_internal (self->priv->parent, self,
REMOVE_CHILD_EMIT_PARENT_SET); REMOVE_CHILD_LEGACY_FLAGS);
} }
/** /**
@ -10280,8 +10303,17 @@ clutter_actor_set_child_above_sibling (ClutterActor *self,
if (sibling != NULL) if (sibling != NULL)
g_return_if_fail (sibling->priv->parent == self); g_return_if_fail (sibling->priv->parent == self);
remove_child (self, child); /* we don't want to change the state of child, or emit signals, or
insert_child_above (self, child, sibling); * regenerate ChildMeta instances here, but we still want to follow
* the correct sequence of steps encoded in remove_child() and
* add_child(), so that correctness is ensured, and we only go
* through one known code path.
*/
g_object_ref (child);
clutter_actor_remove_child_internal (self, child, 0);
clutter_actor_add_child_internal (self, child, 0,
insert_child_above,
sibling);
clutter_actor_queue_relayout (self); clutter_actor_queue_relayout (self);
} }
@ -10316,8 +10348,12 @@ clutter_actor_set_child_below_sibling (ClutterActor *self,
if (sibling != NULL) if (sibling != NULL)
g_return_if_fail (sibling->priv->parent == self); g_return_if_fail (sibling->priv->parent == self);
remove_child (self, child); /* see the comment in set_child_above_sibling() */
insert_child_below (self, child, sibling); g_object_ref (child);
clutter_actor_remove_child_internal (self, child, 0);
clutter_actor_add_child_internal (self, child, 0,
insert_child_below,
sibling);
clutter_actor_queue_relayout (self); clutter_actor_queue_relayout (self);
} }
@ -10346,8 +10382,11 @@ clutter_actor_set_child_at_index (ClutterActor *self,
g_return_if_fail (child->priv->parent == self); g_return_if_fail (child->priv->parent == self);
g_return_if_fail (index_ <= self->priv->n_children); g_return_if_fail (index_ <= self->priv->n_children);
remove_child (self, child); g_object_ref (child);
insert_child_at_index (self, child, GINT_TO_POINTER (index_)); clutter_actor_remove_child_internal (self, child, 0);
clutter_actor_add_child_internal (self, child, 0,
insert_child_at_index,
GINT_TO_POINTER (index_));
clutter_actor_queue_relayout (self); clutter_actor_queue_relayout (self);
} }