[clutter/wip/apocalypses/apocalypse-1: 20/92] actor: Add child insertion methods



commit f96d737ad203f7757f4aa3a82da3c6b23cd3ba62
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Tue Nov 29 17:41:33 2011 +0000

    actor: Add child insertion methods
    
    We should allow inserting children at given indices, and at given
    stacking positions (relative or not to other children).

 clutter/clutter-actor.c |  268 ++++++++++++++++++++++++++++++++++++++++++-----
 clutter/clutter-actor.h |   18 +++-
 2 files changed, 256 insertions(+), 30 deletions(-)
---
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index 9a4c9a5..5bdbff6 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -8983,7 +8983,7 @@ clutter_actor_get_children (ClutterActor *self)
 }
 
 /*< private >
- * clutter_actor_insert_child:
+ * insert_child_at_depth:
  * @self: a #ClutterActor
  * @child: a #ClutterActor
  *
@@ -8991,8 +8991,9 @@ clutter_actor_get_children (ClutterActor *self)
  * the depth as the insertion criteria.
  */
 static void
-clutter_actor_insert_child (ClutterActor *self,
-                            ClutterActor *child)
+insert_child_at_depth (ClutterActor *self,
+                       ClutterActor *child,
+                       gpointer      dummy G_GNUC_UNUSED)
 {
   ClutterActorPrivate *priv = self->priv;
   GList *l, *prev = NULL;
@@ -9021,30 +9022,113 @@ clutter_actor_insert_child (ClutterActor *self,
     }
   else
     priv->children = l;
+}
+
+static void
+insert_child_at_index (ClutterActor *self,
+                       ClutterActor *child,
+                       gpointer      data_)
+{
+  gint index_ = GPOINTER_TO_INT (data_);
+  ClutterActorPrivate *priv;
+
+  priv = self->priv;
 
-  priv->n_children++;
+  if (index_ == 0)
+    priv->children = g_list_prepend (priv->children, child);
+  else if (index < 0)
+    priv->children = g_list_append (priv->children, child);
+  else
+    priv->children = g_list_insert (priv->children, child, index_);
 }
 
-/**
- * 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_add_child (ClutterActor *self,
-                         ClutterActor *child)
+static void
+insert_child_above (ClutterActor *self,
+                    ClutterActor *child,
+                    gpointer      data)
 {
-  ClutterTextDirection text_dir;
+  ClutterActor *sibling = data;
+  ClutterActorPrivate *priv;
+  GList *l, *next = NULL;
 
-  g_return_if_fail (CLUTTER_IS_ACTOR (self));
-  g_return_if_fail (CLUTTER_IS_ACTOR (child));
-  g_return_if_fail (self != child);
+  priv = self->priv;
+
+  if (sibling == NULL)
+    {
+      priv->children = g_list_append (priv->children, child);
+
+      return;
+    }
+
+  for (l = priv->children; l != NULL; l = l->next)
+    {
+      ClutterActor *iter = l->data;
+
+      next = l->next;
+
+      if (iter == sibling)
+        break;
+    }
+
+  /* Insert the node after the found node */
+  l = g_list_append (l, child);
+
+  /* Fixup the links */
+  if (next != NULL)
+    {
+      l->next = next;
+      next->prev = l;
+    }
+}
+
+static void
+insert_child_below (ClutterActor *self,
+                    ClutterActor *child,
+                    gpointer      data)
+{
+  ClutterActorPrivate *priv = self->priv;
+  ClutterActor *sibling = data;
+  GList *l, *prev = NULL;
+
+  if (sibling == NULL)
+    {
+      priv->children = g_list_prepend (priv->children, child);
+
+      return;
+    }
+
+  for (l = priv->children; l != NULL; l = l->next)
+    {
+      ClutterActor *iter = l->data;
+
+      if (iter == sibling)
+        break;
+
+      prev = l;
+    }
+
+  l = g_list_prepend (l, child);
+
+  if (prev != NULL)
+    {
+      prev->next = l;
+      l->prev = prev;
+    }
+  else
+    priv->children = l;
+}
+
+typedef void (* ClutterActorAddChildFunc) (ClutterActor *parent,
+                                           ClutterActor *child,
+                                           gpointer      data);
+
+static void
+clutter_actor_add_child_internal (ClutterActor             *self,
+                                  ClutterActor             *child,
+                                  ClutterActorAddChildFunc  add_func,
+                                  gpointer                  data)
+{
+  ClutterTextDirection text_dir;
 
   if (child->priv->parent_actor != NULL)
     {
@@ -9068,8 +9152,10 @@ clutter_actor_add_child (ClutterActor *self,
   g_object_ref_sink (child);
   child->priv->parent_actor = self;
 
-  /* Maintain an explicit list of children for every actor... */
-  clutter_actor_insert_child (self, child);
+  /* delegate the actual insertion */
+  add_func (self, child, data);
+
+  self->priv->n_children += 1;
 
   /* if push_internal() has been called then we automatically set
    * the flag on the actor
@@ -9132,6 +9218,136 @@ clutter_actor_add_child (ClutterActor *self,
 }
 
 /**
+ * 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 that will only
+ * be released when calling clutter_actor_remove_child().
+ *
+ * This function will take into consideration the #ClutterActor:depth
+ * of @child, and will keep the list of children sorted.
+ *
+ * Since: 1.10
+ */
+void
+clutter_actor_add_child (ClutterActor *self,
+                         ClutterActor *child)
+{
+  g_return_if_fail (CLUTTER_IS_ACTOR (self));
+  g_return_if_fail (CLUTTER_IS_ACTOR (child));
+  g_return_if_fail (self != child);
+
+  clutter_actor_add_child_internal (self, child,
+                                    insert_child_at_depth,
+                                    NULL);
+}
+
+/**
+ * clutter_actor_insert_child_at_index:
+ * @self: a #ClutterActor
+ * @child: a #ClutterActor
+ * @index_: the index
+ *
+ * Inserts @child into the list of children of @self, using the
+ * given @index_.
+ *
+ * This function will acquire a reference on @child that will only
+ * be released when calling clutter_actor_remove_child().
+ *
+ * This function will not take into consideration the #ClutterActor:depth
+ * of @child.
+ *
+ * Since: 1.10
+ */
+void
+clutter_actor_insert_child_at_index (ClutterActor *self,
+                                     ClutterActor *child,
+                                     gint          index_)
+{
+  g_return_if_fail (CLUTTER_IS_ACTOR (self));
+  g_return_if_fail (CLUTTER_IS_ACTOR (child));
+  g_return_if_fail (child->priv->parent_actor == NULL);
+  g_return_if_fail (index_ < self->priv->n_children);
+
+  clutter_actor_add_child_internal (self, child,
+                                    insert_child_at_index,
+                                    GINT_TO_POINTER (index_));
+}
+
+/**
+ * clutter_actor_insert_child_above:
+ * @self: a #ClutterActor
+ * @child: a #ClutterActor
+ * @sibling: (allow-none): a child of @self, or %NULL
+ *
+ * Inserts @child into the list of children of @self, above another
+ * child of @self or, if @sibling is %NULL, above all the children
+ * of @self.
+ *
+ * This function will acquire a reference on @child that will only
+ * be released when calling clutter_actor_remove_child().
+ *
+ * This function will not take into consideration the #ClutterActor:depth
+ * of @child.
+ *
+ * Since: 1.10
+ */
+void
+clutter_actor_insert_child_above (ClutterActor *self,
+                                  ClutterActor *child,
+                                  ClutterActor *sibling)
+{
+  g_return_if_fail (CLUTTER_IS_ACTOR (self));
+  g_return_if_fail (CLUTTER_IS_ACTOR (child));
+  g_return_if_fail (child->priv->parent_actor == NULL);
+  g_return_if_fail (sibling == NULL ||
+                    (CLUTTER_IS_ACTOR (sibling) &&
+                     sibling->priv->parent_actor == self));
+
+  clutter_actor_add_child_internal (self, child,
+                                    insert_child_above,
+                                    sibling);
+}
+
+/**
+ * clutter_actor_insert_child_below:
+ * @self: a #ClutterActor
+ * @child: a #ClutterActor
+ * @sibling: (allow-none): a child of @self, or %NULL
+ *
+ * Inserts @child into the list of children of @self, below another
+ * child of @self or, if @sibling is %NULL, below all the children
+ * of @self.
+ *
+ * This function will acquire a reference on @child that will only
+ * be released when calling clutter_actor_remove_child().
+ *
+ * This function will not take into consideration the #ClutterActor:depth
+ * of @child.
+ *
+ * Since: 1.10
+ */
+void
+clutter_actor_insert_child_below (ClutterActor *self,
+                                  ClutterActor *child,
+                                  ClutterActor *sibling)
+{
+  g_return_if_fail (CLUTTER_IS_ACTOR (self));
+  g_return_if_fail (CLUTTER_IS_ACTOR (child));
+  g_return_if_fail (child->priv->parent_actor == NULL);
+  g_return_if_fail (sibling == NULL ||
+                    (CLUTTER_IS_ACTOR (sibling) &&
+                     sibling->priv->parent_actor == self));
+
+  clutter_actor_add_child_internal (self, child,
+                                    insert_child_below,
+                                    sibling);
+}
+
+/**
  * clutter_actor_set_parent:
  * @self: A #ClutterActor
  * @parent: A new #ClutterActor parent
@@ -9171,9 +9387,9 @@ clutter_actor_get_parent (ClutterActor *self)
  * Retrieves the 'paint' visibility of an actor recursively checking for non
  * visible parents.
  *
- * This is by definition the same as CLUTTER_ACTOR_IS_MAPPED().
+ * This is by definition the same as %CLUTTER_ACTOR_IS_MAPPED.
  *
- * Return Value: TRUE if the actor is visibile and will be painted.
+ * Return Value: %TRUE if the actor is visibile and will be painted.
  *
  * Since: 0.8.4
  */
diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h
index c72f808..761e994 100644
--- a/clutter/clutter-actor.h
+++ b/clutter/clutter-actor.h
@@ -351,6 +351,7 @@ gboolean              clutter_actor_get_fixed_position_set    (ClutterActor
 void                  clutter_actor_set_fixed_position_set    (ClutterActor          *self,
                                                                gboolean               is_set);
 
+/* Actor geometry */
 gfloat                clutter_actor_get_width                 (ClutterActor          *self);
 gfloat                clutter_actor_get_height                (ClutterActor          *self);
 void                  clutter_actor_set_width                 (ClutterActor          *self,
@@ -363,6 +364,9 @@ void                  clutter_actor_set_x                     (ClutterActor
                                                                gfloat                 x);
 void                  clutter_actor_set_y                     (ClutterActor          *self,
                                                                gfloat                 y);
+void                  clutter_actor_set_depth                 (ClutterActor          *self,
+                                                               gfloat                 depth);
+gfloat                clutter_actor_get_depth                 (ClutterActor          *self);
 void                  clutter_actor_set_layout_manager        (ClutterActor          *self,
                                                                ClutterLayoutManager  *manager);
 ClutterLayoutManager *clutter_actor_get_layout_manager        (ClutterActor          *self);
@@ -445,8 +449,18 @@ void                  clutter_actor_set_clip_to_allocation    (ClutterActor
                                                                gboolean               clip_set);
 gboolean              clutter_actor_get_clip_to_allocation    (ClutterActor          *self);
 
+/* Actor hierarchy */
 void                  clutter_actor_add_child                 (ClutterActor          *self,
                                                                ClutterActor          *child);
+void                  clutter_actor_insert_child_at_index     (ClutterActor          *self,
+                                                               ClutterActor          *child,
+                                                               gint                   index_);
+void                  clutter_actor_insert_child_above        (ClutterActor          *self,
+                                                               ClutterActor          *child,
+                                                               ClutterActor          *sibling);
+void                  clutter_actor_insert_child_below        (ClutterActor          *self,
+                                                               ClutterActor          *child,
+                                                               ClutterActor          *sibling);
 void                  clutter_actor_remove_child              (ClutterActor          *self,
                                                                ClutterActor          *child);
 GList *               clutter_actor_get_children              (ClutterActor          *self);
@@ -459,16 +473,12 @@ void                  clutter_actor_unparent                  (ClutterActor
 gboolean              clutter_actor_contains                  (ClutterActor          *self,
 							       ClutterActor          *descendant);
 ClutterActor*         clutter_actor_get_stage                 (ClutterActor          *actor);
-
 void                  clutter_actor_raise                     (ClutterActor          *self,
                                                                ClutterActor          *below);
 void                  clutter_actor_lower                     (ClutterActor          *self,
                                                                ClutterActor          *above);
 void                  clutter_actor_raise_top                 (ClutterActor          *self);
 void                  clutter_actor_lower_bottom              (ClutterActor          *self);
-void                  clutter_actor_set_depth                 (ClutterActor          *self,
-                                                               gfloat                 depth);
-gfloat                clutter_actor_get_depth                 (ClutterActor          *self);
 
 void                  clutter_actor_set_scale                 (ClutterActor          *self,
                                                                gdouble                scale_x,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]