From 9ccdf2eb02a0d0155e27d5f9270bca6b72c08359 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 4 Dec 2009 16:54:22 +0000 Subject: [PATCH] box: Add relative packing methods ClutterBox should provide some convenience functions to pack a new child at a given position, either an absolute index or relative to a sibling. --- clutter/clutter-box.c | 221 +++++++++++++++++---- clutter/clutter-box.h | 16 ++ doc/reference/clutter/clutter-sections.txt | 3 + tests/interactive/test-bin-layout.c | 1 - 4 files changed, 203 insertions(+), 38 deletions(-) diff --git a/clutter/clutter-box.c b/clutter/clutter-box.c index f9a09d19b..67c52d096 100644 --- a/clutter/clutter-box.c +++ b/clutter/clutter-box.c @@ -661,48 +661,21 @@ clutter_box_packv (ClutterBox *box, } } -/** - * clutter_box_pack: - * @box: a #ClutterBox - * @actor: a #ClutterActor - * @first_property: the name of the first property to set, or %NULL - * @Varargs: a list of property name and value pairs, terminated by %NULL - * - * Adds @actor to @box and sets layout properties at the same time, - * if the #ClutterLayoutManager used by @box has them - * - * This function is a wrapper around clutter_container_add_actor() - * and clutter_layout_manager_child_set() - * - * Language bindings should use the vector-based clutter_box_addv() - * variant instead - * - * Since: 1.2 - */ -void -clutter_box_pack (ClutterBox *box, - ClutterActor *actor, - const gchar *first_property, - ...) +static inline void +clutter_box_set_property_valist (ClutterBox *box, + ClutterActor *actor, + const gchar *first_property, + va_list var_args) { - ClutterBoxPrivate *priv; - ClutterContainer *container; + ClutterContainer *container = CLUTTER_CONTAINER (box); + ClutterBoxPrivate *priv = box->priv; ClutterLayoutMeta *meta; GObjectClass *klass; const gchar *pname; - va_list var_args; - g_return_if_fail (CLUTTER_IS_BOX (box)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - container = CLUTTER_CONTAINER (box); - clutter_container_add_actor (container, actor); - - if (first_property == NULL || *first_property == '\0') + if (priv->manager == NULL) return; - priv = box->priv; - meta = clutter_layout_manager_get_child_meta (priv->manager, container, actor); @@ -712,8 +685,6 @@ clutter_box_pack (ClutterBox *box, klass = G_OBJECT_GET_CLASS (meta); - va_start (var_args, first_property); - pname = first_property; while (pname) { @@ -761,7 +732,183 @@ clutter_box_pack (ClutterBox *box, pname = va_arg (var_args, gchar*); } +} +/** + * clutter_box_pack: + * @box: a #ClutterBox + * @actor: a #ClutterActor + * @first_property: the name of the first property to set, or %NULL + * @Varargs: a list of property name and value pairs, terminated by %NULL + * + * Adds @actor to @box and sets layout properties at the same time, + * if the #ClutterLayoutManager used by @box has them + * + * This function is a wrapper around clutter_container_add_actor() + * and clutter_layout_manager_child_set() + * + * Language bindings should use the vector-based clutter_box_addv() + * variant instead + * + * Since: 1.2 + */ +void +clutter_box_pack (ClutterBox *box, + ClutterActor *actor, + const gchar *first_property, + ...) +{ + va_list var_args; + + g_return_if_fail (CLUTTER_IS_BOX (box)); + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + + clutter_container_add_actor (CLUTTER_CONTAINER (box), actor); + + if (first_property == NULL || *first_property == '\0') + return; + + va_start (var_args, first_property); + clutter_box_set_property_valist (box, actor, first_property, var_args); + va_end (var_args); +} + +/** + * clutter_box_pack_after: + * @box: a #ClutterBox + * @actor: a #ClutterActor + * @sibling: (allow none): a #ClutterActor or %NULL + * @first_property: the name of the first property to set, or %NULL + * @Varargs: a list of property name and value pairs, terminated by %NULL + * + * Adds @actor to @box, placing it after @sibling, and sets layout + * properties at the same time, if the #ClutterLayoutManager used by + * @box supports them + * + * If @sibling is %NULL then @actor is placed at the end of the + * list of children, to be allocated and painted after every other child + * + * This function is a wrapper around clutter_container_add_actor(), + * clutter_container_raise_child() and clutter_layout_manager_child_set() + * + * Since: 1.2 + */ +void +clutter_box_pack_after (ClutterBox *box, + ClutterActor *actor, + ClutterActor *sibling, + const gchar *first_property, + ...) +{ + va_list var_args; + + g_return_if_fail (CLUTTER_IS_BOX (box)); + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling)); + + clutter_container_add_actor (CLUTTER_CONTAINER (box), actor); + clutter_container_raise_child (CLUTTER_CONTAINER (box), actor, sibling); + + if (first_property == NULL || *first_property == '\0') + return; + + va_start (var_args, first_property); + clutter_box_set_property_valist (box, actor, first_property, var_args); + va_end (var_args); +} + +/** + * clutter_box_pack_before: + * @box: a #ClutterBox + * @actor: a #ClutterActor + * @sibling: (allow none): a #ClutterActor or %NULL + * @first_property: the name of the first property to set, or %NULL + * @Varargs: a list of property name and value pairs, terminated by %NULL + * + * Adds @actor to @box, placing it before @sibling, and sets layout + * properties at the same time, if the #ClutterLayoutManager used by + * @box supports them + * + * If @sibling is %NULL then @actor is placed at the beginning of the + * list of children, to be allocated and painted below every other child + * + * This function is a wrapper around clutter_container_add_actor(), + * clutter_container_lower_child() and clutter_layout_manager_child_set() + * + * Since: 1.2 + */ +void +clutter_box_pack_before (ClutterBox *box, + ClutterActor *actor, + ClutterActor *sibling, + const gchar *first_property, + ...) +{ + va_list var_args; + + g_return_if_fail (CLUTTER_IS_BOX (box)); + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling)); + + clutter_container_add_actor (CLUTTER_CONTAINER (box), actor); + clutter_container_lower_child (CLUTTER_CONTAINER (box), actor, sibling); + + if (first_property == NULL || *first_property == '\0') + return; + + va_start (var_args, first_property); + clutter_box_set_property_valist (box, actor, first_property, var_args); + va_end (var_args); +} + +/** + * clutter_box_pack_at: + * @box: a #ClutterBox + * @actor: a #ClutterActor + * @position: the position to insert the @actor at + * @first_property: the name of the first property to set, or %NULL + * @Varargs: a list of property name and value pairs, terminated by %NULL + * + * Adds @actor to @box, placing it at @position, and sets layout + * properties at the same time, if the #ClutterLayoutManager used by + * @box supports them + * + * If @position is a negative number, or is larger than the number of + * children of @box, the new child is added at the end of the list of + * children + * + * Since: 1.2 + */ +void +clutter_box_pack_at (ClutterBox *box, + ClutterActor *actor, + gint position, + const gchar *first_property, + ...) +{ + ClutterBoxPrivate *priv; + va_list var_args; + + g_return_if_fail (CLUTTER_IS_BOX (box)); + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + + priv = box->priv; + + /* this is really clutter_box_add() with a different insert() */ + priv->children = g_list_insert (priv->children, + actor, + position); + + clutter_actor_set_parent (actor, CLUTTER_ACTOR (box)); + clutter_actor_queue_relayout (actor); + + g_signal_emit_by_name (box, "actor-added", actor); + + if (first_property == NULL || *first_property == '\0') + return; + + va_start (var_args, first_property); + clutter_box_set_property_valist (box, actor, first_property, var_args); va_end (var_args); } diff --git a/clutter/clutter-box.h b/clutter/clutter-box.h index a44c274c1..584ea44c5 100644 --- a/clutter/clutter-box.h +++ b/clutter/clutter-box.h @@ -57,6 +57,22 @@ void clutter_box_packv (ClutterBox *box, const gchar * const properties[], const GValue *values); +void clutter_box_pack_after (ClutterBox *box, + ClutterActor *actor, + ClutterActor *sibling, + const gchar *first_property, + ...) G_GNUC_NULL_TERMINATED; +void clutter_box_pack_before (ClutterBox *box, + ClutterActor *actor, + ClutterActor *sibling, + const gchar *first_property, + ...) G_GNUC_NULL_TERMINATED; +void clutter_box_pack_at (ClutterBox *box, + ClutterActor *actor, + gint position, + const gchar *first_property, + ...) G_GNUC_NULL_TERMINATED; + G_END_DECLS #endif /* __CLUTTER_BOX_H__ */ diff --git a/doc/reference/clutter/clutter-sections.txt b/doc/reference/clutter/clutter-sections.txt index d96a6c07d..b4c84fb53 100644 --- a/doc/reference/clutter/clutter-sections.txt +++ b/doc/reference/clutter/clutter-sections.txt @@ -1836,6 +1836,9 @@ clutter_box_get_color clutter_box_pack clutter_box_packv +clutter_box_pack_after +clutter_box_pack_before +clutter_box_pack_at CLUTTER_TYPE_BOX diff --git a/tests/interactive/test-bin-layout.c b/tests/interactive/test-bin-layout.c index 84fda7b54..d61796e64 100644 --- a/tests/interactive/test-bin-layout.c +++ b/tests/interactive/test-bin-layout.c @@ -127,7 +127,6 @@ test_bin_layout_main (int argc, char *argv[]) clutter_actor_lower_bottom (rect); clutter_actor_set_name (rect, "background"); - { ClutterActor *tex; GError *error;