diff --git a/clutter/clutter-container.c b/clutter/clutter-container.c index 2f918074c..9f41349c4 100644 --- a/clutter/clutter-container.c +++ b/clutter/clutter-container.c @@ -399,3 +399,70 @@ clutter_container_find_child_by_id (ClutterContainer *container, return CLUTTER_CONTAINER_GET_IFACE (container)->find_child_by_id (container, child_id); } + +/** + * clutter_container_raise: + * @container: a #ClutterContainer + * @actor: the actor to raise + * @sibling: the sibling to raise to, or %NULL to raise at the top + * + * Raises @actor at @sibling level, in the depth ordering. + * + * Since: 0.6 + */ +void +clutter_container_raise (ClutterContainer *container, + ClutterActor *actor, + ClutterActor *sibling) +{ + g_return_if_fail (CLUTTER_IS_CONTAINER (container)); + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling)); + + if (actor == sibling) + return; + + CLUTTER_CONTAINER_GET_IFACE (container)->raise (container, actor, sibling); +} + +/** + * clutter_container_lower: + * @container: a #ClutterContainer + * @actor: the actor to raise + * @sibling: the sibling to lower to, or %NULL to lower at the bottom + * + * Lowers @actor at @sibling level, in the depth ordering. + * + * Since: 0.6 + */ +void +clutter_container_lower (ClutterContainer *container, + ClutterActor *actor, + ClutterActor *sibling) +{ + g_return_if_fail (CLUTTER_IS_CONTAINER (container)); + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling)); + + if (actor == sibling) + return; + + CLUTTER_CONTAINER_GET_IFACE (container)->raise (container, actor, sibling); +} + +/** + * clutter_container_sort_depth_order: + * @container: a #ClutterContainer + * + * Sorts a container children using their depth. This function should not + * be normally used by applications. + * + * Since: 0.6 + */ +void +clutter_container_sort_depth_order (ClutterContainer *container) +{ + g_return_if_fail (CLUTTER_IS_CONTAINER (container)); + + CLUTTER_CONTAINER_GET_IFACE (container)->sort_depth_order (container); +} diff --git a/clutter/clutter-container.h b/clutter/clutter-container.h index 0e85d2ac8..013bb46da 100644 --- a/clutter/clutter-container.h +++ b/clutter/clutter-container.h @@ -49,6 +49,10 @@ typedef struct _ClutterContainerIface ClutterContainerIface; * @find_child_by_id: virtual function for searching a container children * using its unique id. Should recurse through its children. This function * is used when "picking" actors (e.g. by clutter_stage_get_actor_at_pos()) + * @raise: virtual function for raising a child + * @lower: virtual function for lowering a child + * @sort_depth_order: virtual function for sorting the children of a + * container depending on their depth * @actor_added: signal class handler for ClutterContainer::actor_added * @actor_removed: signal class handler for ClutterContainer::actor_removed * @@ -71,6 +75,13 @@ struct _ClutterContainerIface gpointer user_data); ClutterActor *(* find_child_by_id) (ClutterContainer *container, guint child_id); + void (* raise) (ClutterContainer *container, + ClutterActor *actor, + ClutterActor *sibling); + void (* lower) (ClutterContainer *container, + ClutterActor *actor, + ClutterActor *sibling); + void (* sort_depth_order) (ClutterContainer *container); /* signals */ void (* actor_added) (ClutterContainer *container, @@ -103,7 +114,13 @@ void clutter_container_foreach (ClutterContainer *container, gpointer user_data); ClutterActor *clutter_container_find_child_by_id (ClutterContainer *container, guint child_id); - +void clutter_container_raise (ClutterContainer *container, + ClutterActor *actor, + ClutterActor *sibling); +void clutter_container_lower (ClutterContainer *container, + ClutterActor *actor, + ClutterActor *sibling); +void clutter_container_sort_depth_order (ClutterContainer *container); G_END_DECLS diff --git a/clutter/clutter-group.c b/clutter/clutter-group.c index 5d5ce4747..c67cc1d9e 100644 --- a/clutter/clutter-group.c +++ b/clutter/clutter-group.c @@ -317,6 +317,114 @@ clutter_group_real_find_child_by_id (ClutterContainer *container, return actor; } +static void +clutter_group_real_raise (ClutterContainer *container, + ClutterActor *actor, + ClutterActor *sibling) +{ + ClutterGroup *self = CLUTTER_GROUP (container); + ClutterGroupPrivate *priv = self->priv; + gint pos; + + pos = g_list_index (priv->children, actor) + 1; + + priv->children = g_list_remove (priv->children, actor); + + /* Raise at the top */ + if (!sibling) + { + GList *last_item; + + last_item = g_list_last (priv->children); + + if (last_item) + sibling = last_item->data; + + priv->children = g_list_append (priv->children, actor); + } + else + { + priv->children = g_list_insert (priv->children, actor, pos); + } + + /* set Z ordering a value below, this will then call sort + * as values are equal ordering shouldn't change but Z + * values will be correct. + * + * FIXME: optimise + */ + if (sibling && + clutter_actor_get_depth (sibling) != clutter_actor_get_depth (actor)) + { + clutter_actor_set_depth (actor, clutter_actor_get_depth (sibling)); + } +} + +static void +clutter_group_real_lower (ClutterContainer *container, + ClutterActor *actor, + ClutterActor *sibling) +{ + ClutterGroup *self = CLUTTER_GROUP (container); + ClutterGroupPrivate *priv = self->priv; + gint pos; + + pos = g_list_index (priv->children, actor) - 1; + + priv->children = g_list_remove (priv->children, actor); + + /* Push to bottom */ + if (!sibling) + { + GList *last_item; + + last_item = g_list_first (priv->children); + + if (last_item) + sibling = last_item->data; + + priv->children = g_list_prepend (priv->children, actor); + } + else + priv->children = g_list_insert (priv->children, actor, pos); + + /* See comment in group_raise for this */ + if (sibling && + clutter_actor_get_depth (sibling) != clutter_actor_get_depth (actor)) + { + clutter_actor_set_depth (actor, clutter_actor_get_depth (sibling)); + } +} + +static gint +sort_z_order (gconstpointer a, + gconstpointer b) +{ + ClutterActor *actor_a = CLUTTER_ACTOR (a); + ClutterActor *actor_b = CLUTTER_ACTOR (b); + + if (clutter_actor_get_depth (actor_a) == clutter_actor_get_depth (actor_b)) + return 0; + + if (clutter_actor_get_depth (actor_a) > clutter_actor_get_depth (actor_b)) + return 1; + + return -1; +} + +static void +clutter_group_real_sort_depth_order (ClutterContainer *container) +{ + ClutterGroup *self = CLUTTER_GROUP (container); + ClutterGroupPrivate *priv = self->priv; + + priv->children = g_list_sort (priv->children, sort_z_order); + + if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (self))) + clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); + +} + static void clutter_container_iface_init (ClutterContainerIface *iface) { @@ -324,6 +432,9 @@ clutter_container_iface_init (ClutterContainerIface *iface) iface->remove = clutter_group_real_remove; iface->foreach = clutter_group_real_foreach; iface->find_child_by_id = clutter_group_real_find_child_by_id; + iface->raise = clutter_group_real_raise; + iface->lower = clutter_group_real_lower; + iface->sort_depth_order = clutter_group_real_sort_depth_order; } static void @@ -589,50 +700,22 @@ clutter_group_find_child_by_id (ClutterGroup *self, * @sibling: a #ClutterActor * * FIXME + * + * Deprecated: 0.6: Use clutter_container_raise() instead. */ void clutter_group_raise (ClutterGroup *self, ClutterActor *actor, ClutterActor *sibling) { - ClutterGroupPrivate *priv; - gint pos; + g_return_if_fail (CLUTTER_IS_GROUP (self)); + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling)); - g_return_if_fail (actor != sibling); - - priv = self->priv; - - pos = g_list_index (priv->children, actor) + 1; - - priv->children = g_list_remove (priv->children, actor); - - if (sibling == NULL) - { - GList *last_item; - - /* Raise top */ - last_item = g_list_last (priv->children); - - if (last_item) - sibling = last_item->data; - - priv->children = g_list_append (priv->children, actor); - } - else - { - priv->children = g_list_insert (priv->children, actor, pos); - } - - /* set Z ordering a value below, this will then call sort - * as values are equal ordering shouldn't change but Z - * values will be correct. - * FIXME: optimise - */ - if ( sibling && - clutter_actor_get_depth(sibling) != clutter_actor_get_depth (actor)) - clutter_actor_set_depth (actor, - clutter_actor_get_depth (sibling)); + if (actor == sibling) + return; + clutter_container_raise (CLUTTER_CONTAINER (self), actor, sibling); } /** @@ -642,57 +725,22 @@ clutter_group_raise (ClutterGroup *self, * @sibling: a #ClutterActor * * FIXME + * + * Deprecated: 0.6: Use clutter_container_lower() instead */ void -clutter_group_lower (ClutterGroup *self, +clutter_group_lower (ClutterGroup *self, ClutterActor *actor, ClutterActor *sibling) { - ClutterGroupPrivate *priv; - gint pos; + g_return_if_fail (CLUTTER_IS_GROUP (self)); + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling)); - g_return_if_fail (actor != sibling); + if (actor == sibling) + return; - priv = self->priv; - - pos = g_list_index (priv->children, actor) - 1; - - priv->children = g_list_remove (priv->children, actor); - - if (sibling == NULL) - { - GList *last_item; - /* Raise top */ - last_item = g_list_first (priv->children); - - if (last_item) - sibling = last_item->data; - - priv->children = g_list_prepend (priv->children, actor); - } - else - priv->children = g_list_insert (priv->children, actor, pos); - - /* See comment in group_raise for this */ - if (sibling && - clutter_actor_get_depth(sibling) != clutter_actor_get_depth(actor)) - clutter_actor_set_depth (actor, - clutter_actor_get_depth(sibling)); -} - -static gint -sort_z_order (gconstpointer a, - gconstpointer b) -{ - if (clutter_actor_get_depth (CLUTTER_ACTOR(a)) - == clutter_actor_get_depth (CLUTTER_ACTOR(b))) - return 0; - - if (clutter_actor_get_depth (CLUTTER_ACTOR(a)) - > clutter_actor_get_depth (CLUTTER_ACTOR(b))) - return 1; - - return -1; + clutter_container_lower (CLUTTER_CONTAINER (self), actor, sibling); } /** @@ -701,18 +749,13 @@ sort_z_order (gconstpointer a, * * Sorts a #ClutterGroup's children by there depth value. * This function should not be used by applications. - **/ + * + * Deprecated: 0.6: Use clutter_container_sort_depth_order() instead. + */ void clutter_group_sort_depth_order (ClutterGroup *self) { - ClutterGroupPrivate *priv; + g_return_if_fail (CLUTTER_IS_GROUP (self)); - g_return_if_fail (CLUTTER_IS_GROUP(self)); - - priv = self->priv; - - priv->children = g_list_sort (priv->children, sort_z_order); - - if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR(self))) - clutter_actor_queue_redraw (CLUTTER_ACTOR(self)); + clutter_container_sort_depth_order (CLUTTER_CONTAINER (self)); } diff --git a/clutter/clutter-group.h b/clutter/clutter-group.h index 360bdf23c..d36f6a285 100644 --- a/clutter/clutter-group.h +++ b/clutter/clutter-group.h @@ -104,8 +104,6 @@ void clutter_group_remove (ClutterGroup *group, ClutterActor *actor); ClutterActor *clutter_group_find_child_by_id (ClutterGroup *self, guint id); -#endif /* CLUTTER_DISABLE_DEPRECATED */ - void clutter_group_raise (ClutterGroup *self, ClutterActor *actor, ClutterActor *sibling); @@ -113,6 +111,7 @@ void clutter_group_lower (ClutterGroup *self, ClutterActor *actor, ClutterActor *sibling); void clutter_group_sort_depth_order (ClutterGroup *self); +#endif /* CLUTTER_DISABLE_DEPRECATED */ G_END_DECLS diff --git a/doc/reference/clutter-sections.txt b/doc/reference/clutter-sections.txt index 6026a4534..ee6158e1c 100644 --- a/doc/reference/clutter-sections.txt +++ b/doc/reference/clutter-sections.txt @@ -219,6 +219,9 @@ clutter_container_remove_valist clutter_container_get_children clutter_container_foreach clutter_container_find_child_by_id +clutter_container_raise +clutter_container_lower +clutter_container_sort_depth_order ClutterContainer CLUTTER_TYPE_CONTAINER