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 <ebassi@linux.intel.com>
This commit is contained in:
José Dapena Paz 2010-03-17 16:16:09 +01:00 committed by Emmanuele Bassi
parent 5395a7a998
commit 7b63da69cf
3 changed files with 126 additions and 5 deletions

View File

@ -47,6 +47,9 @@
* <listitem><para>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.</para></listitem>
* <listitem><para>if the #ClutterBoxLayout:homogeneous boolean property
* is set, then all widgets will get the same size, ignoring expand
* settings and the preferred sizes</para></listitem>
* </itemizedlist>
*
* <figure id="box-layout">
@ -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

View File

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

View File

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