[clutter/wip/apocalypses/apocalypse-1: 1/46] actor: Provide add/remove child and get children methods
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/wip/apocalypses/apocalypse-1: 1/46] actor: Provide add/remove child and get children methods
- Date: Thu, 8 Dec 2011 12:08:57 +0000 (UTC)
commit cdb887dc29dd1291051674ae8f66eccfbeb4a389
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Thu Nov 17 15:03:32 2011 +0000
actor: Provide add/remove child and get children methods
Let's try and move away from the reverse implicit scene graph build API,
which we mutuated from GTK+, towards a more traditional node/child API.
The set_parent()/unparent() API is confusing, unless you know the
history; having a add_child()/remove_child() methods pair makes it more
explicit.
We can easily implement the old set_parent()/unparent() pair in terms of
the newly add_child()/remove_child() one.
clutter/clutter-actor.c | 180 +++++++++++++++++++++++++++++------------------
clutter/clutter-actor.h | 5 ++
2 files changed, 116 insertions(+), 69 deletions(-)
---
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index 3c20406..795356b 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -8181,103 +8181,133 @@ clutter_actor_get_clip (ClutterActor *self,
}
/**
- * clutter_actor_set_parent:
- * @self: A #ClutterActor
- * @parent: A new #ClutterActor parent
+ * clutter_actor_get_children:
+ * @self: a #ClutterActor
+ *
+ * Retrieves the list of children of @self.
*
- * Sets the parent of @self to @parent. The opposite function is
- * clutter_actor_unparent().
+ * Return value: (transfer container) (element-type ClutterActor): A newly
+ * allocated #GList of #ClutterActor<!-- -->s. Use g_list_free() when
+ * done.
*
- * This function should not be used by applications, but by custom
- * container actor subclasses.
+ * Since: 1.10
+ */
+GList *
+clutter_actor_get_children (ClutterActor *self)
+{
+ g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL);
+
+ return g_list_copy (self->priv->children);
+}
+
+/**
+ * clutter_actor_add_child:
+ * @self: a #ClutterActor
+ * @child: a #ClutterActor
+ *
+ * Adds @child to the children of @self.
+ *
+ * This function will acquire a reference on @child.
+ *
+ * Since: 1.10
*/
void
-clutter_actor_set_parent (ClutterActor *self,
- ClutterActor *parent)
+clutter_actor_add_child (ClutterActor *self,
+ ClutterActor *child)
{
- ClutterActorPrivate *priv;
- ClutterActorPrivate *parent_priv;
ClutterTextDirection text_dir;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
- g_return_if_fail (CLUTTER_IS_ACTOR (parent));
- g_return_if_fail (self != parent);
-
- priv = self->priv;
+ g_return_if_fail (CLUTTER_IS_ACTOR (child));
+ g_return_if_fail (self != child);
- if (priv->parent_actor != NULL)
+ if (child->priv->parent_actor != NULL)
{
g_warning ("Cannot set a parent on an actor which has a parent.\n"
"You must use clutter_actor_unparent() first.\n");
return;
}
- if (CLUTTER_ACTOR_IS_TOPLEVEL (self))
+ if (CLUTTER_ACTOR_IS_TOPLEVEL (child))
{
g_warning ("Cannot set a parent on a toplevel actor\n");
return;
}
- if (CLUTTER_ACTOR_IN_DESTRUCTION (self))
+ if (CLUTTER_ACTOR_IN_DESTRUCTION (child))
{
g_warning ("Cannot set a parent currently being destroyed");
return;
}
- g_object_ref_sink (self);
- priv->parent_actor = parent;
+ g_object_ref_sink (child);
+ child->priv->parent_actor = self;
/* Maintain an explicit list of children for every actor... */
- parent_priv = parent->priv;
- parent_priv->children =
- g_list_prepend (parent_priv->children, self);
- parent_priv->n_children++;
+ self->priv->children = g_list_prepend (self->priv->children, child);
+ self->priv->n_children++;
/* if push_internal() has been called then we automatically set
* the flag on the actor
*/
- if (parent->priv->internal_child)
- CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_INTERNAL_CHILD);
+ if (self->priv->internal_child)
+ CLUTTER_SET_PRIVATE_FLAGS (child, CLUTTER_INTERNAL_CHILD);
/* clutter_actor_reparent() will emit ::parent-set for us */
- if (!CLUTTER_ACTOR_IN_REPARENT (self))
- g_signal_emit (self, actor_signals[PARENT_SET], 0, NULL);
+ if (!CLUTTER_ACTOR_IN_REPARENT (child))
+ g_signal_emit (child, actor_signals[PARENT_SET], 0, NULL);
/* If parent is mapped or realized, we need to also be mapped or
* realized once we're inside the parent.
*/
- clutter_actor_update_map_state (self, MAP_STATE_CHECK);
+ clutter_actor_update_map_state (child, MAP_STATE_CHECK);
/* propagate the parent's text direction to the child */
- text_dir = clutter_actor_get_text_direction (parent);
- clutter_actor_set_text_direction (self, text_dir);
+ text_dir = clutter_actor_get_text_direction (self);
+ clutter_actor_set_text_direction (child, text_dir);
- if (priv->show_on_set_parent)
- clutter_actor_show (self);
+ if (child->priv->show_on_set_parent)
+ clutter_actor_show (child);
- if (CLUTTER_ACTOR_IS_MAPPED (self))
- clutter_actor_queue_redraw (self);
+ if (CLUTTER_ACTOR_IS_MAPPED (child))
+ clutter_actor_queue_redraw (child);
/* maintain the invariant that if an actor needs layout,
* its parents do as well
*/
- if (priv->needs_width_request ||
- priv->needs_height_request ||
- priv->needs_allocation)
+ if (child->priv->needs_width_request ||
+ child->priv->needs_height_request ||
+ child->priv->needs_allocation)
{
/* we work around the short-circuiting we do
* in clutter_actor_queue_relayout() since we
* want to force a relayout
*/
- priv->needs_width_request = TRUE;
- priv->needs_height_request = TRUE;
- priv->needs_allocation = TRUE;
+ child->priv->needs_width_request = TRUE;
+ child->priv->needs_height_request = TRUE;
+ child->priv->needs_allocation = TRUE;
- clutter_actor_queue_relayout (priv->parent_actor);
+ clutter_actor_queue_relayout (child->priv->parent_actor);
}
}
/**
+ * clutter_actor_set_parent:
+ * @self: A #ClutterActor
+ * @parent: A new #ClutterActor parent
+ *
+ * Sets the parent of @self to @parent.
+ *
+ * This function just calls clutter_actor_add_child().
+ */
+void
+clutter_actor_set_parent (ClutterActor *self,
+ ClutterActor *parent)
+{
+ clutter_actor_add_child (parent, self);
+}
+
+/**
* clutter_actor_get_parent:
* @self: A #ClutterActor
*
@@ -8332,35 +8362,33 @@ invalidate_queue_redraw_entry (ClutterActor *self,
}
/**
- * clutter_actor_unparent:
+ * clutter_actor_remove_child:
* @self: a #ClutterActor
+ * @child: a #ClutterActor
*
- * Removes the parent of @self.
- *
- * This function should not be used in applications.
+ * Removes @child from the children of @self.
*
- * This function should only be called by implementations of the
- * #ClutterContainer interface, or by composite actors that do
- * not implicitly create their children.
+ * This function will release the reference added by
+ * clutter_actor_add_child().
*
- * Since: 0.1.1
+ * Since: 1.10
*/
void
-clutter_actor_unparent (ClutterActor *self)
+clutter_actor_remove_child (ClutterActor *self,
+ ClutterActor *child)
{
- ClutterActorPrivate *priv;
- ClutterActor *old_parent;
- ClutterActorPrivate *old_parent_priv;
gboolean was_mapped;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
+ g_return_if_fail (CLUTTER_IS_ACTOR (child));
- priv = self->priv;
+ if (child->priv->parent_actor == NULL)
+ return;
- if (priv->parent_actor == NULL)
+ if (child->priv->parent_actor != self)
return;
- was_mapped = CLUTTER_ACTOR_IS_MAPPED (self);
+ was_mapped = CLUTTER_ACTOR_IS_MAPPED (child);
/* we need to unrealize *before* we set parent_actor to NULL,
* because in an unrealize method actors are dissociating from the
@@ -8368,7 +8396,7 @@ clutter_actor_unparent (ClutterActor *self)
* clutter_actor_get_stage(). This should unmap and unrealize,
* unless we're reparenting.
*/
- clutter_actor_update_map_state (self, MAP_STATE_MAKE_UNREALIZED);
+ clutter_actor_update_map_state (child, MAP_STATE_MAKE_UNREALIZED);
/* We take this opportunity to invalidate any queue redraw entry
* associated with the actor and descendants since we won't be able to
@@ -8383,31 +8411,45 @@ clutter_actor_unparent (ClutterActor *self)
* http://bugzilla.clutter-project.org/show_bug.cgi?id=2621
* https://bugzilla.gnome.org/show_bug.cgi?id=652036
*/
- _clutter_actor_traverse (self,
+ _clutter_actor_traverse (child,
0,
invalidate_queue_redraw_entry,
NULL,
NULL);
- old_parent = priv->parent_actor;
- priv->parent_actor = NULL;
+ child->priv->parent_actor = NULL;
/* clutter_actor_reparent() will emit ::parent-set for us */
- if (!CLUTTER_ACTOR_IN_REPARENT (self))
- g_signal_emit (self, actor_signals[PARENT_SET], 0, old_parent);
+ if (!CLUTTER_ACTOR_IN_REPARENT (child))
+ g_signal_emit (child, actor_signals[PARENT_SET], 0, self);
- old_parent_priv = old_parent->priv;
- old_parent_priv->children = g_list_remove (old_parent_priv->children, self);
- old_parent_priv->n_children--;
+ self->priv->children = g_list_remove (self->priv->children, child);
+ self->priv->n_children--;
/* Queue a redraw on old_parent only if we were painted in the first
* place. Will be no-op if old parent is not shown.
*/
- if (was_mapped && !CLUTTER_ACTOR_IS_MAPPED (self))
- clutter_actor_queue_redraw (old_parent);
+ if (was_mapped && !CLUTTER_ACTOR_IS_MAPPED (child))
+ clutter_actor_queue_redraw (self);
/* remove the reference we acquired in clutter_actor_set_parent() */
- g_object_unref (self);
+ g_object_unref (child);
+}
+
+/**
+ * clutter_actor_unparent:
+ * @self: a #ClutterActor
+ *
+ * Removes the parent of @self.
+ *
+ * This function just calls clutter_actor_remove_child().
+ *
+ * Since: 0.1.1
+ */
+void
+clutter_actor_unparent (ClutterActor *self)
+{
+ clutter_actor_remove_child (self->priv->parent_actor, self);
}
/**
diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h
index 7adabf4..6cef2cb 100644
--- a/clutter/clutter-actor.h
+++ b/clutter/clutter-actor.h
@@ -409,6 +409,11 @@ void clutter_actor_set_clip_to_allocation (ClutterActor
gboolean clip_set);
gboolean clutter_actor_get_clip_to_allocation (ClutterActor *self);
+void clutter_actor_add_child (ClutterActor *self,
+ ClutterActor *child);
+void clutter_actor_remove_child (ClutterActor *self,
+ ClutterActor *child);
+GList * clutter_actor_get_children (ClutterActor *self);
void clutter_actor_set_parent (ClutterActor *self,
ClutterActor *parent);
ClutterActor * clutter_actor_get_parent (ClutterActor *self);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]