Move depth ordering methods from ClutterGroup to ClutterContainer

Since ClutterActor directly calls ClutterGroup methods we need ClutterContainer
to provide them, so that every container actor behaves the same way.

This patch makes ::raise, ::lower and ::sort_depth_order virtual functions
of the ClutterContainer interface, implemented by ClutterGroup.

The documentation has been added and deprecation warnings have been added
as well.
This commit is contained in:
Emmanuele Bassi 2007-08-13 17:00:58 +00:00
parent 9635f60064
commit 27ce96150e
5 changed files with 222 additions and 93 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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));
}

View File

@ -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

View File

@ -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
<SUBSECTION Standard>
ClutterContainer
CLUTTER_TYPE_CONTAINER