From 7b63da69cf294b4d076e405e0af5c8afe47c2253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Dapena=20Paz?= Date: Wed, 17 Mar 2010 16:16:09 +0100 Subject: [PATCH] Add "homogeneous" mode to ClutterBoxLayout. Added new "homogeneous" mode to ClutterBoxLayout, that makes layout children get all the same size. This is heavily inspired in the "homogeneous" attribute available in GtkBox, but simplified as we don't have padding nor borders in box layout, only spacing. Also added to test-box-layout a key to set/unset homogeneous mode. * Coding style fixes. * Added proper test for homogeneous mode in box layout. * Fix in homogeneous mode. http://bugzilla.openedhand.com/show_bug.cgi?id=2034 Signed-off-by: Emmanuele Bassi --- clutter/clutter-box-layout.c | 122 ++++++++++++++++++++++++++-- clutter/clutter-box-layout.h | 3 + tests/interactive/test-box-layout.c | 6 ++ 3 files changed, 126 insertions(+), 5 deletions(-) diff --git a/clutter/clutter-box-layout.c b/clutter/clutter-box-layout.c index 121dde3c4..b4902317b 100644 --- a/clutter/clutter-box-layout.c +++ b/clutter/clutter-box-layout.c @@ -47,6 +47,9 @@ * if a child is set to expand but not to fill then * it is possible to control the alignment using the X and Y alignment * layout properties. + * if the #ClutterBoxLayout:homogeneous boolean property + * is set, then all widgets will get the same size, ignoring expand + * settings and the preferred sizes * * *
@@ -101,6 +104,7 @@ struct _ClutterBoxLayoutPrivate guint is_pack_start : 1; guint is_animating : 1; guint use_animations : 1; + guint is_homogeneous : 1; }; struct _ClutterBoxChild @@ -138,6 +142,7 @@ enum PROP_SPACING, PROP_VERTICAL, + PROP_HOMOGENEOUS, PROP_PACK_START, PROP_USE_ANIMATIONS, PROP_EASING_MODE, @@ -747,7 +752,9 @@ allocate_box_child (ClutterBoxLayout *self, child_box.y1 = floorf (*position + 0.5); - if (box_child->expand) + if (priv->is_homogeneous) + child_box.y2 = floorf (*position + extra_space + 0.5); + else if (box_child->expand) child_box.y2 = floorf (*position + child_nat + extra_space + 0.5); else child_box.y2 = floorf (*position + child_nat + 0.5); @@ -762,7 +769,9 @@ allocate_box_child (ClutterBoxLayout *self, child_box.x1 = floorf (*position + 0.5); - if (box_child->expand) + if (priv->is_homogeneous) + child_box.x2 = floorf (*position + extra_space + 0.5); + else if (box_child->expand) child_box.x2 = floorf (*position + child_nat + extra_space + 0.5); else child_box.x2 = floorf (*position + child_nat + 0.5); @@ -820,7 +829,9 @@ allocate_box_child (ClutterBoxLayout *self, do_allocate: clutter_actor_allocate (child, &child_box, flags); - if (box_child->expand) + if (priv->is_homogeneous) + *position += (priv->spacing + extra_space); + else if (box_child->expand) *position += (child_nat + priv->spacing + extra_space); else *position += (child_nat + priv->spacing); @@ -918,8 +929,24 @@ clutter_box_layout_allocate (ClutterLayoutManager *layout, n_expand_children++; } - if (n_expand_children == 0) - extra_space = 0; + if (priv->is_homogeneous) + { + gint n_children; + + n_children = g_list_length (children); + if (priv->is_vertical) + { + extra_space = (avail_height - (n_children - 1)*priv->spacing)/n_children; + } + else + { + extra_space = (avail_width - (n_children - 1)*priv->spacing)/n_children; + } + } + else if (n_expand_children == 0) + { + extra_space = 0; + } else { if (priv->is_vertical) @@ -1021,6 +1048,10 @@ clutter_box_layout_set_property (GObject *gobject, clutter_box_layout_set_vertical (self, g_value_get_boolean (value)); break; + case PROP_HOMOGENEOUS: + clutter_box_layout_set_homogeneous (self, g_value_get_boolean (value)); + break; + case PROP_SPACING: clutter_box_layout_set_spacing (self, g_value_get_uint (value)); break; @@ -1061,6 +1092,10 @@ clutter_box_layout_get_property (GObject *gobject, g_value_set_boolean (value, priv->is_vertical); break; + case PROP_HOMOGENEOUS: + g_value_set_boolean (value, priv->is_homogeneous); + break; + case PROP_SPACING: g_value_set_uint (value, priv->spacing); break; @@ -1128,6 +1163,22 @@ clutter_box_layout_class_init (ClutterBoxLayoutClass *klass) CLUTTER_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_VERTICAL, pspec); + /** + * ClutterBoxLayout:homogeneous: + * + * Whether the #ClutterBoxLayout should arrange its children + * homogeneously, i.e. all childs get the same size + * + * Since: 1.4 + */ + pspec = g_param_spec_boolean ("homogeneous", + "Homogeneous", + "Whether the layout should be homogeneous, i.e." + "all childs get the same size", + FALSE, + CLUTTER_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_HOMOGENEOUS, pspec); + /** * ClutterBoxLayout:pack-start: * @@ -1222,6 +1273,7 @@ clutter_box_layout_init (ClutterBoxLayout *layout) layout->priv = priv = CLUTTER_BOX_LAYOUT_GET_PRIVATE (layout); priv->is_vertical = FALSE; + priv->is_homogeneous = FALSE; priv->is_pack_start = FALSE; priv->spacing = 0; @@ -1364,6 +1416,66 @@ clutter_box_layout_get_vertical (ClutterBoxLayout *layout) return layout->priv->is_vertical; } +/** + * clutter_box_layout_set_homogeneous: + * @layout: a #ClutterBoxLayout + * @vertical: %TRUE if the layout should be homogeneous + * + * Sets whether the size of @layout children should be + * homogeneous + * + * Since: 1.4 + */ +void +clutter_box_layout_set_homogeneous (ClutterBoxLayout *layout, + gboolean homogeneous) +{ + ClutterBoxLayoutPrivate *priv; + + g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout)); + + priv = layout->priv; + + if (priv->is_homogeneous != homogeneous) + { + ClutterLayoutManager *manager; + + priv->is_homogeneous = !!homogeneous; + + manager = CLUTTER_LAYOUT_MANAGER (layout); + + if (priv->use_animations) + { + clutter_layout_manager_begin_animation (manager, + priv->easing_duration, + priv->easing_mode); + } + else + clutter_layout_manager_layout_changed (manager); + + g_object_notify (G_OBJECT (layout), "homogeneous"); + } +} + +/** + * clutter_box_layout_get_homogeneous: + * @layout: a #ClutterBoxLayout + * + * Retrieves if the children sizes are allocated homogeneously. + * + * Return value: %TRUE if the #ClutterBoxLayout is arranging its children + * homogeneously, and %FALSE otherwise + * + * Since: 1.4 + */ +gboolean +clutter_box_layout_get_homogeneous (ClutterBoxLayout *layout) +{ + g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), FALSE); + + return layout->priv->is_homogeneous; +} + /** * clutter_box_layout_set_pack_start: * @layout: a #ClutterBoxLayout diff --git a/clutter/clutter-box-layout.h b/clutter/clutter-box-layout.h index 035368ac2..e220c0262 100644 --- a/clutter/clutter-box-layout.h +++ b/clutter/clutter-box-layout.h @@ -105,6 +105,9 @@ guint clutter_box_layout_get_spacing (ClutterBoxLayout void clutter_box_layout_set_vertical (ClutterBoxLayout *layout, gboolean vertical); gboolean clutter_box_layout_get_vertical (ClutterBoxLayout *layout); +void clutter_box_layout_set_homogeneous (ClutterBoxLayout *layout, + gboolean homogeneous); +gboolean clutter_box_layout_get_homogeneous (ClutterBoxLayout *layout); void clutter_box_layout_set_pack_start (ClutterBoxLayout *layout, gboolean pack_start); gboolean clutter_box_layout_get_pack_start (ClutterBoxLayout *layout); diff --git a/tests/interactive/test-box-layout.c b/tests/interactive/test-box-layout.c index 67e1fec30..9e31ff6da 100644 --- a/tests/interactive/test-box-layout.c +++ b/tests/interactive/test-box-layout.c @@ -27,6 +27,7 @@ #define INSTRUCTIONS \ "Press v\t\342\236\236\tSwitch horizontal/vertical\n" \ + "Press h\t\342\236\236\tSwitch homogeneous\n" \ "Press p\t\342\236\236\tSwitch pack start/end\n" \ "Press s\t\342\236\236\tIncrement spacing (up to 12px)\n" \ "Press a\t\342\236\236\tSwitch animations on/off\n" \ @@ -180,6 +181,11 @@ key_release_cb (ClutterActor *actor, clutter_box_layout_set_vertical (layout, !toggle); break; + case CLUTTER_h: + toggle = clutter_box_layout_get_homogeneous (layout); + clutter_box_layout_set_homogeneous (layout, !toggle); + break; + case CLUTTER_p: toggle = clutter_box_layout_get_pack_start (layout); clutter_box_layout_set_pack_start (layout, !toggle);