4 * An OpenGL based 'interactive canvas' library.
6 * Copyright (C) 2009 Intel Corporation.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
22 * Emmanuele Bassi <ebassi@linux.intel.com>
24 * Based on the NBTK NbtkBoxLayout actor by:
25 * Thomas Wood <thomas.wood@intel.com>
29 * SECTION:clutter-box-layout
30 * @short_description: A layout manager arranging children on a single line
32 * The #ClutterBoxLayout is a #ClutterLayoutManager implementing the
33 * following layout policy:
35 * <listitem><para>all children are arranged on a single
36 * line;</para></listitem>
37 * <listitem><para>the axis used is controlled by the
38 * #ClutterBoxLayout:orientation property;</para></listitem>
39 * <listitem><para>the order of the packing is determined by the
40 * #ClutterBoxLayout:pack-start boolean property;</para></listitem>
41 * <listitem><para>each child will be allocated to its natural
42 * size or, if #ClutterActor:x-expand/#ClutterActor:y-expand
43 * is set, the available size;</para></listitem>
44 * <listitem><para>honours the #ClutterActor's #ClutterActor:x-align
45 * and #ClutterActor:y-align properties to fill the available
46 * size;</para></listitem>
47 * <listitem><para>if the #ClutterBoxLayout:homogeneous boolean property
48 * is set, then all widgets will get the same size, ignoring expand
49 * settings and the preferred sizes</para></listitem>
52 * <figure id="box-layout">
53 * <title>Box layout</title>
54 * <para>The image shows a #ClutterBoxLayout with the
55 * #ClutterBoxLayout:vertical property set to %FALSE.</para>
56 * <graphic fileref="box-layout.png" format="PNG"/>
59 * It is possible to control the spacing between children of a
60 * #ClutterBoxLayout by using clutter_box_layout_set_spacing().
62 * #ClutterBoxLayout is available since Clutter 1.2
71 #define CLUTTER_DISABLE_DEPRECATION_WARNINGS
72 #include "deprecated/clutter-container.h"
73 #include "deprecated/clutter-alpha.h"
75 #include "clutter-box-layout.h"
77 #include "clutter-actor-private.h"
78 #include "clutter-debug.h"
79 #include "clutter-enum-types.h"
80 #include "clutter-layout-meta.h"
81 #include "clutter-private.h"
82 #include "clutter-types.h"
84 #define CLUTTER_TYPE_BOX_CHILD (clutter_box_child_get_type ())
85 #define CLUTTER_BOX_CHILD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BOX_CHILD, ClutterBoxChild))
86 #define CLUTTER_IS_BOX_CHILD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BOX_CHILD))
88 #define CLUTTER_BOX_LAYOUT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_BOX_LAYOUT, ClutterBoxLayoutPrivate))
90 typedef struct _ClutterBoxChild ClutterBoxChild;
91 typedef struct _ClutterLayoutMetaClass ClutterBoxChildClass;
93 struct _ClutterBoxLayoutPrivate
95 ClutterContainer *container;
100 guint easing_duration;
102 ClutterOrientation orientation;
104 guint is_pack_start : 1;
105 guint is_homogeneous : 1;
108 struct _ClutterBoxChild
110 ClutterLayoutMeta parent_instance;
112 ClutterBoxAlignment x_align;
113 ClutterBoxAlignment y_align;
142 PROP_EASING_DURATION,
147 static GParamSpec *obj_props[PROP_LAST] = { NULL, };
149 GType clutter_box_child_get_type (void);
151 G_DEFINE_TYPE (ClutterBoxChild,
153 CLUTTER_TYPE_LAYOUT_META);
155 G_DEFINE_TYPE (ClutterBoxLayout,
157 CLUTTER_TYPE_LAYOUT_MANAGER);
164 box_child_set_align (ClutterBoxChild *self,
165 ClutterBoxAlignment x_align,
166 ClutterBoxAlignment y_align)
168 gboolean x_changed = FALSE, y_changed = FALSE;
170 if (self->x_align != x_align)
172 self->x_align = x_align;
177 if (self->y_align != y_align)
179 self->y_align = y_align;
184 if (x_changed || y_changed)
186 ClutterLayoutManager *layout;
188 layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self));
190 clutter_layout_manager_layout_changed (layout);
193 g_object_notify (G_OBJECT (self), "x-align");
196 g_object_notify (G_OBJECT (self), "y-align");
201 box_child_set_fill (ClutterBoxChild *self,
205 gboolean x_changed = FALSE, y_changed = FALSE;
207 if (self->x_fill != x_fill)
209 self->x_fill = x_fill;
214 if (self->y_fill != y_fill)
216 self->y_fill = y_fill;
221 if (x_changed || y_changed)
223 ClutterLayoutManager *layout;
225 layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self));
227 clutter_layout_manager_layout_changed (layout);
230 g_object_notify (G_OBJECT (self), "x-fill");
233 g_object_notify (G_OBJECT (self), "y-fill");
238 box_child_set_expand (ClutterBoxChild *self,
241 if (self->expand != expand)
243 ClutterLayoutManager *layout;
245 self->expand = expand;
247 layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self));
249 clutter_layout_manager_layout_changed (layout);
251 g_object_notify (G_OBJECT (self), "expand");
256 clutter_box_child_set_property (GObject *gobject,
261 ClutterBoxChild *self = CLUTTER_BOX_CHILD (gobject);
265 case PROP_CHILD_X_ALIGN:
266 box_child_set_align (self,
267 g_value_get_enum (value),
271 case PROP_CHILD_Y_ALIGN:
272 box_child_set_align (self,
274 g_value_get_enum (value));
277 case PROP_CHILD_X_FILL:
278 box_child_set_fill (self,
279 g_value_get_boolean (value),
283 case PROP_CHILD_Y_FILL:
284 box_child_set_fill (self,
286 g_value_get_boolean (value));
289 case PROP_CHILD_EXPAND:
290 box_child_set_expand (self, g_value_get_boolean (value));
294 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
300 clutter_box_child_get_property (GObject *gobject,
305 ClutterBoxChild *self = CLUTTER_BOX_CHILD (gobject);
309 case PROP_CHILD_X_ALIGN:
310 g_value_set_enum (value, self->x_align);
313 case PROP_CHILD_Y_ALIGN:
314 g_value_set_enum (value, self->y_align);
317 case PROP_CHILD_X_FILL:
318 g_value_set_boolean (value, self->x_fill);
321 case PROP_CHILD_Y_FILL:
322 g_value_set_boolean (value, self->y_fill);
325 case PROP_CHILD_EXPAND:
326 g_value_set_boolean (value, self->expand);
330 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
336 clutter_box_child_class_init (ClutterBoxChildClass *klass)
338 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
341 gobject_class->set_property = clutter_box_child_set_property;
342 gobject_class->get_property = clutter_box_child_get_property;
344 pspec = g_param_spec_boolean ("expand",
346 P_("Allocate extra space for the child"),
348 CLUTTER_PARAM_READWRITE);
349 g_object_class_install_property (gobject_class, PROP_CHILD_EXPAND, pspec);
351 pspec = g_param_spec_boolean ("x-fill",
352 P_("Horizontal Fill"),
353 P_("Whether the child should receive priority "
354 "when the container is allocating spare space "
355 "on the horizontal axis"),
357 CLUTTER_PARAM_READWRITE);
358 g_object_class_install_property (gobject_class, PROP_CHILD_X_FILL, pspec);
360 pspec = g_param_spec_boolean ("y-fill",
362 P_("Whether the child should receive priority "
363 "when the container is allocating spare space "
364 "on the vertical axis"),
366 CLUTTER_PARAM_READWRITE);
367 g_object_class_install_property (gobject_class, PROP_CHILD_Y_FILL, pspec);
369 pspec = g_param_spec_enum ("x-align",
370 P_("Horizontal Alignment"),
371 P_("Horizontal alignment of the actor within "
373 CLUTTER_TYPE_BOX_ALIGNMENT,
374 CLUTTER_BOX_ALIGNMENT_CENTER,
375 CLUTTER_PARAM_READWRITE);
376 g_object_class_install_property (gobject_class, PROP_CHILD_X_ALIGN, pspec);
378 pspec = g_param_spec_enum ("y-align",
379 P_("Vertical Alignment"),
380 P_("Vertical alignment of the actor within "
382 CLUTTER_TYPE_BOX_ALIGNMENT,
383 CLUTTER_BOX_ALIGNMENT_CENTER,
384 CLUTTER_PARAM_READWRITE);
385 g_object_class_install_property (gobject_class, PROP_CHILD_Y_ALIGN, pspec);
389 clutter_box_child_init (ClutterBoxChild *self)
391 self->x_align = CLUTTER_BOX_ALIGNMENT_CENTER;
392 self->y_align = CLUTTER_BOX_ALIGNMENT_CENTER;
394 self->x_fill = self->y_fill = FALSE;
396 self->expand = FALSE;
400 get_box_alignment_factor (ClutterBoxAlignment alignment)
404 case CLUTTER_BOX_ALIGNMENT_CENTER:
407 case CLUTTER_BOX_ALIGNMENT_START:
410 case CLUTTER_BOX_ALIGNMENT_END:
418 clutter_box_layout_get_child_meta_type (ClutterLayoutManager *manager)
420 return CLUTTER_TYPE_BOX_CHILD;
424 clutter_box_layout_set_container (ClutterLayoutManager *layout,
425 ClutterContainer *container)
427 ClutterBoxLayoutPrivate *priv = CLUTTER_BOX_LAYOUT (layout)->priv;
428 ClutterLayoutManagerClass *parent_class;
430 priv->container = container;
432 if (priv->container != NULL)
434 ClutterRequestMode request_mode;
436 /* we need to change the :request-mode of the container
437 * to match the orientation
439 request_mode = priv->orientation == CLUTTER_ORIENTATION_VERTICAL
440 ? CLUTTER_REQUEST_HEIGHT_FOR_WIDTH
441 : CLUTTER_REQUEST_WIDTH_FOR_HEIGHT;
442 clutter_actor_set_request_mode (CLUTTER_ACTOR (priv->container),
446 parent_class = CLUTTER_LAYOUT_MANAGER_CLASS (clutter_box_layout_parent_class);
447 parent_class->set_container (layout, container);
451 get_preferred_width (ClutterBoxLayout *self,
452 ClutterActor *container,
455 gfloat *natural_width_p)
457 ClutterBoxLayoutPrivate *priv = self->priv;
460 gboolean is_rtl, is_vertical;
466 *natural_width_p = 0;
468 if (priv->orientation == CLUTTER_ORIENTATION_HORIZONTAL)
470 ClutterTextDirection text_dir;
472 text_dir = clutter_actor_get_text_direction (container);
473 is_rtl = (text_dir == CLUTTER_TEXT_DIRECTION_RTL) ? TRUE : FALSE;
478 is_vertical = priv->orientation == CLUTTER_ORIENTATION_VERTICAL;
480 for (child = (is_rtl) ? clutter_actor_get_last_child (container)
481 : clutter_actor_get_first_child (container);
483 child = (is_rtl) ? clutter_actor_get_previous_sibling (child)
484 : clutter_actor_get_next_sibling (child))
486 gfloat child_min = 0, child_nat = 0;
488 if (!CLUTTER_ACTOR_IS_VISIBLE (child))
493 clutter_actor_get_preferred_width (child,
494 !is_vertical ? for_height : -1,
501 *min_width_p = MAX (child_min, *min_width_p);
504 *natural_width_p = MAX (child_nat, *natural_width_p);
509 *min_width_p += child_min;
512 *natural_width_p += child_nat;
517 if (!is_vertical && n_children > 1)
520 *min_width_p += priv->spacing * (n_children - 1);
523 *natural_width_p += priv->spacing * (n_children - 1);
528 get_preferred_height (ClutterBoxLayout *self,
529 ClutterActor *container,
531 gfloat *min_height_p,
532 gfloat *natural_height_p)
534 ClutterBoxLayoutPrivate *priv = self->priv;
537 gboolean is_rtl, is_vertical;
542 if (natural_height_p)
543 *natural_height_p = 0;
545 if (priv->orientation == CLUTTER_ORIENTATION_HORIZONTAL)
547 ClutterTextDirection text_dir;
549 text_dir = clutter_actor_get_text_direction (container);
550 is_rtl = (text_dir == CLUTTER_TEXT_DIRECTION_RTL) ? TRUE : FALSE;
555 is_vertical = priv->orientation == CLUTTER_ORIENTATION_VERTICAL;
557 for (child = (is_rtl) ? clutter_actor_get_last_child (container)
558 : clutter_actor_get_first_child (container);
560 child = (is_rtl) ? clutter_actor_get_previous_sibling (child)
561 : clutter_actor_get_next_sibling (child))
563 gfloat child_min = 0, child_nat = 0;
565 if (!CLUTTER_ACTOR_IS_VISIBLE (child))
570 clutter_actor_get_preferred_height (child,
571 is_vertical ? for_width : -1,
578 *min_height_p = MAX (child_min, *min_height_p);
580 if (natural_height_p)
581 *natural_height_p = MAX (child_nat, *natural_height_p);
586 *min_height_p += child_min;
588 if (natural_height_p)
589 *natural_height_p += child_nat;
593 if (is_vertical && n_children > 1)
596 *min_height_p += priv->spacing * (n_children - 1);
598 if (natural_height_p)
599 *natural_height_p += priv->spacing * (n_children - 1);
604 allocate_box_child (ClutterBoxLayout *self,
605 ClutterContainer *container,
607 ClutterActorBox *child_box,
608 ClutterAllocationFlags flags,
609 gboolean use_animations,
610 ClutterAnimationMode easing_mode,
611 guint easing_duration,
614 ClutterBoxChild *box_child;
615 ClutterLayoutMeta *meta;
617 meta = clutter_layout_manager_get_child_meta (CLUTTER_LAYOUT_MANAGER (self),
620 box_child = CLUTTER_BOX_CHILD (meta);
622 CLUTTER_NOTE (LAYOUT, "Allocation for %s { %.2f, %.2f, %.2f, %.2f }",
623 _clutter_actor_get_debug_name (child),
624 child_box->x1, child_box->y1,
625 child_box->x2 - child_box->x1,
626 child_box->y2 - child_box->y1);
630 clutter_actor_save_easing_state (child);
631 clutter_actor_set_easing_mode (child, easing_mode);
632 clutter_actor_set_easing_duration (child, easing_duration);
633 clutter_actor_set_easing_delay (child, easing_delay);
636 /* call allocate() instead of allocate_align_fill() if the actor needs
637 * expand in either direction. this will honour the actors alignment settings
639 if (clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_HORIZONTAL) ||
640 clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_VERTICAL))
641 clutter_actor_allocate (child, child_box, flags);
643 clutter_actor_allocate_align_fill (child, child_box,
644 get_box_alignment_factor (box_child->x_align),
645 get_box_alignment_factor (box_child->y_align),
651 clutter_actor_restore_easing_state (child);
655 clutter_box_layout_get_preferred_width (ClutterLayoutManager *layout,
656 ClutterContainer *container,
659 gfloat *natural_width_p)
661 ClutterBoxLayout *self = CLUTTER_BOX_LAYOUT (layout);
663 get_preferred_width (self, CLUTTER_ACTOR (container), for_height,
669 clutter_box_layout_get_preferred_height (ClutterLayoutManager *layout,
670 ClutterContainer *container,
672 gfloat *min_height_p,
673 gfloat *natural_height_p)
675 ClutterBoxLayout *self = CLUTTER_BOX_LAYOUT (layout);
677 get_preferred_height (self, CLUTTER_ACTOR (container), for_width,
683 count_expand_children (ClutterLayoutManager *layout,
684 ClutterContainer *container,
685 gint *visible_children,
686 gint *expand_children)
688 ClutterBoxLayoutPrivate *priv = CLUTTER_BOX_LAYOUT (layout)->priv;
689 ClutterActor *actor, *child;
690 ClutterActorIter iter;
692 actor = CLUTTER_ACTOR (container);
694 *visible_children = *expand_children = 0;
696 clutter_actor_iter_init (&iter, actor);
697 while (clutter_actor_iter_next (&iter, &child))
699 if (CLUTTER_ACTOR_IS_VISIBLE (child))
701 ClutterLayoutMeta *meta;
703 *visible_children += 1;
705 meta = clutter_layout_manager_get_child_meta (layout,
709 if (clutter_actor_needs_expand (child, priv->orientation) ||
710 CLUTTER_BOX_CHILD (meta)->expand)
711 *expand_children += 1;
716 typedef struct _RequestedSize
724 /* Pulled from gtksizerequest.c from Gtk+ */
726 compare_gap (gconstpointer p1,
730 RequestedSize *sizes = data;
731 const guint *c1 = p1;
732 const guint *c2 = p2;
734 const gint d1 = MAX (sizes[*c1].natural_size -
735 sizes[*c1].minimum_size,
737 const gint d2 = MAX (sizes[*c2].natural_size -
738 sizes[*c2].minimum_size,
741 gint delta = (d2 - d1);
750 * distribute_natural_allocation:
751 * @extra_space: Extra space to redistribute among children after subtracting
752 * minimum sizes and any child padding from the overall allocation
753 * @n_requested_sizes: Number of requests to fit into the allocation
754 * @sizes: An array of structs with a client pointer and a minimum/natural size
755 * in the orientation of the allocation.
757 * Distributes @extra_space to child @sizes by bringing smaller
758 * children up to natural size first.
760 * The remaining space will be added to the @minimum_size member of the
761 * RequestedSize struct. If all sizes reach their natural size then
762 * the remaining space is returned.
764 * Returns: The remainder of @extra_space after redistributing space
767 * Pulled from gtksizerequest.c from Gtk+
770 distribute_natural_allocation (gint extra_space,
771 guint n_requested_sizes,
772 RequestedSize *sizes)
777 g_return_val_if_fail (extra_space >= 0, 0);
779 spreading = g_newa (guint, n_requested_sizes);
781 for (i = 0; i < n_requested_sizes; i++)
784 /* Distribute the container's extra space c_gap. We want to assign
785 * this space such that the sum of extra space assigned to children
786 * (c^i_gap) is equal to c_cap. The case that there's not enough
787 * space for all children to take their natural size needs some
788 * attention. The goals we want to achieve are:
790 * a) Maximize number of children taking their natural size.
791 * b) The allocated size of children should be a continuous
792 * function of c_gap. That is, increasing the container size by
793 * one pixel should never make drastic changes in the distribution.
794 * c) If child i takes its natural size and child j doesn't,
795 * child j should have received at least as much gap as child i.
797 * The following code distributes the additional space by following
801 /* Sort descending by gap and position. */
802 g_qsort_with_data (spreading,
803 n_requested_sizes, sizeof (guint),
806 /* Distribute available space.
807 * This master piece of a loop was conceived by Behdad Esfahbod.
809 for (i = n_requested_sizes - 1; extra_space > 0 && i >= 0; --i)
811 /* Divide remaining space by number of remaining children.
812 * Sort order and reducing remaining space by assigned space
813 * ensures that space is distributed equally.
815 gint glue = (extra_space + i) / (i + 1);
816 gint gap = sizes[(spreading[i])].natural_size
817 - sizes[(spreading[i])].minimum_size;
819 gint extra = MIN (glue, gap);
821 sizes[spreading[i]].minimum_size += extra;
823 extra_space -= extra;
829 /* Pulled from gtkbox.c from Gtk+ */
832 clutter_box_layout_allocate (ClutterLayoutManager *layout,
833 ClutterContainer *container,
834 const ClutterActorBox *box,
835 ClutterAllocationFlags flags)
837 ClutterBoxLayoutPrivate *priv = CLUTTER_BOX_LAYOUT (layout)->priv;
838 ClutterActor *actor, *child;
840 gint nexpand_children;
842 ClutterActorIter iter;
844 ClutterActorBox child_allocation;
845 RequestedSize *sizes;
849 gint n_extra_widgets = 0; /* Number of widgets that receive 1 extra px */
850 gint x = 0, y = 0, i;
853 gboolean use_animations;
854 ClutterAnimationMode easing_mode;
855 guint easing_duration, easing_delay;
857 count_expand_children (layout, container, &nvis_children, &nexpand_children);
859 CLUTTER_NOTE (LAYOUT, "BoxLayout for %s: visible=%d, expand=%d",
860 _clutter_actor_get_debug_name (CLUTTER_ACTOR (container)),
864 /* If there is no visible child, simply return. */
865 if (nvis_children <= 0)
868 sizes = g_newa (RequestedSize, nvis_children);
870 if (priv->orientation == CLUTTER_ORIENTATION_VERTICAL)
871 size = box->y2 - box->y1 - (nvis_children - 1) * priv->spacing;
873 size = box->x2 - box->x1 - (nvis_children - 1) * priv->spacing;
875 actor = CLUTTER_ACTOR (container);
877 use_animations = clutter_layout_manager_get_easing_state (layout,
882 /* Retrieve desired size for visible children. */
884 clutter_actor_iter_init (&iter, actor);
885 while (clutter_actor_iter_next (&iter, &child))
887 if (!CLUTTER_ACTOR_IS_VISIBLE (child))
890 if (priv->orientation == CLUTTER_ORIENTATION_VERTICAL)
891 clutter_actor_get_preferred_height (child,
893 &sizes[i].minimum_size,
894 &sizes[i].natural_size);
896 clutter_actor_get_preferred_width (child,
898 &sizes[i].minimum_size,
899 &sizes[i].natural_size);
902 /* Assert the api is working properly */
903 if (sizes[i].minimum_size < 0)
904 g_error ("ClutterBoxLayout child %s minimum %s: %f < 0 for %s %f",
905 _clutter_actor_get_debug_name (child),
906 priv->orientation == CLUTTER_ORIENTATION_VERTICAL
909 sizes[i].minimum_size,
910 priv->orientation == CLUTTER_ORIENTATION_VERTICAL
913 priv->orientation == CLUTTER_ORIENTATION_VERTICAL
915 : box->y2 - box->y1);
917 if (sizes[i].natural_size < sizes[i].minimum_size)
918 g_error ("ClutterBoxLayout child %s natural %s: %f < minimum %f for %s %f",
919 _clutter_actor_get_debug_name (child),
920 priv->orientation == CLUTTER_ORIENTATION_VERTICAL
923 sizes[i].natural_size,
924 sizes[i].minimum_size,
925 priv->orientation == CLUTTER_ORIENTATION_VERTICAL
928 priv->orientation == CLUTTER_ORIENTATION_VERTICAL
930 : box->y2 - box->y1);
932 size -= sizes[i].minimum_size;
934 sizes[i].actor = child;
939 if (priv->is_homogeneous)
941 /* If were homogenous we still need to run the above loop to get the
942 * minimum sizes for children that are not going to fill
944 if (priv->orientation == CLUTTER_ORIENTATION_VERTICAL)
945 size = box->y2 - box->y1 - (nvis_children - 1) * priv->spacing;
947 size = box->x2 - box->x1 - (nvis_children - 1) * priv->spacing;
949 extra = size / nvis_children;
950 n_extra_widgets = size % nvis_children;
954 /* Bring children up to size first */
955 size = distribute_natural_allocation (MAX (0, size), nvis_children, sizes);
957 /* Calculate space which hasn't distributed yet,
958 * and is available for expanding children.
960 if (nexpand_children > 0)
962 extra = size / nexpand_children;
963 n_extra_widgets = size % nexpand_children;
969 if (priv->orientation == CLUTTER_ORIENTATION_HORIZONTAL)
971 ClutterTextDirection text_dir;
973 text_dir = clutter_actor_get_text_direction (CLUTTER_ACTOR (container));
974 is_rtl = (text_dir == CLUTTER_TEXT_DIRECTION_RTL) ? TRUE : FALSE;
979 /* Allocate child positions. */
980 if (priv->orientation == CLUTTER_ORIENTATION_VERTICAL)
982 child_allocation.x1 = box->x1;
983 child_allocation.x2 = MAX (1.0, box->x2 - box->x1);
984 if (priv->is_pack_start)
985 y = box->y2 - box->y1;
991 child_allocation.y1 = box->y1;
992 child_allocation.y2 = MAX (1.0, box->y2 - box->y1);
993 if (priv->is_pack_start)
994 x = box->x2 - box->x1;
1000 clutter_actor_iter_init (&iter, actor);
1001 while (clutter_actor_iter_next (&iter, &child))
1003 ClutterLayoutMeta *meta;
1004 ClutterBoxChild *box_child;
1006 /* If widget is not visible, skip it. */
1007 if (!CLUTTER_ACTOR_IS_VISIBLE (child))
1010 meta = clutter_layout_manager_get_child_meta (layout,
1013 box_child = CLUTTER_BOX_CHILD (meta);
1015 /* Assign the child's size. */
1016 if (priv->is_homogeneous)
1020 if (n_extra_widgets > 0)
1028 child_size = sizes[i].minimum_size;
1030 if (clutter_actor_needs_expand (child, priv->orientation) ||
1033 child_size += extra;
1035 if (n_extra_widgets > 0)
1043 /* Assign the child's position. */
1044 if (priv->orientation == CLUTTER_ORIENTATION_VERTICAL)
1046 if (clutter_actor_needs_expand (child, priv->orientation) ||
1049 child_allocation.y1 = y;
1050 child_allocation.y2 = child_allocation.y1 + MAX (1.0, child_size);
1054 child_allocation.y1 = y + (child_size - sizes[i].minimum_size) / 2;
1055 child_allocation.y2 = child_allocation.y1 + sizes[i].minimum_size;
1058 if (priv->is_pack_start)
1060 y -= child_size + priv->spacing;
1062 child_allocation.y1 -= child_size;
1063 child_allocation.y2 -= child_size;
1067 y += child_size + priv->spacing;
1070 else /* CLUTTER_ORIENTATION_HORIZONTAL */
1072 if (clutter_actor_needs_expand (child, priv->orientation) ||
1075 child_allocation.x1 = x;
1076 child_allocation.x2 = child_allocation.x1 + MAX (1.0, child_size);
1080 child_allocation.x1 = x + (child_size - sizes[i].minimum_size) / 2;
1081 child_allocation.x2 = child_allocation.x1 + sizes[i].minimum_size;
1084 if (priv->is_pack_start)
1086 x -= child_size + priv->spacing;
1088 child_allocation.x1 -= child_size;
1089 child_allocation.x2 -= child_size;
1093 x += child_size + priv->spacing;
1098 gfloat width = child_allocation.x2 - child_allocation.x1;
1100 child_allocation.x1 = box->x2 - box->x1
1101 - child_allocation.x1
1102 - (child_allocation.x2 - child_allocation.x1);
1103 child_allocation.x2 = child_allocation.x1 + width;
1108 allocate_box_child (CLUTTER_BOX_LAYOUT (layout),
1123 clutter_box_layout_set_property (GObject *gobject,
1125 const GValue *value,
1128 ClutterBoxLayout *self = CLUTTER_BOX_LAYOUT (gobject);
1133 clutter_box_layout_set_vertical (self, g_value_get_boolean (value));
1136 case PROP_ORIENTATION:
1137 clutter_box_layout_set_orientation (self, g_value_get_enum (value));
1140 case PROP_HOMOGENEOUS:
1141 clutter_box_layout_set_homogeneous (self, g_value_get_boolean (value));
1145 clutter_box_layout_set_spacing (self, g_value_get_uint (value));
1148 case PROP_PACK_START:
1149 clutter_box_layout_set_pack_start (self, g_value_get_boolean (value));
1153 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
1159 clutter_box_layout_get_property (GObject *gobject,
1164 ClutterBoxLayoutPrivate *priv = CLUTTER_BOX_LAYOUT (gobject)->priv;
1169 g_value_set_boolean (value,
1170 priv->orientation == CLUTTER_ORIENTATION_VERTICAL);
1173 case PROP_ORIENTATION:
1174 g_value_set_enum (value, priv->orientation);
1177 case PROP_HOMOGENEOUS:
1178 g_value_set_boolean (value, priv->is_homogeneous);
1182 g_value_set_uint (value, priv->spacing);
1185 case PROP_PACK_START:
1186 g_value_set_boolean (value, priv->is_pack_start);
1190 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
1196 clutter_box_layout_class_init (ClutterBoxLayoutClass *klass)
1198 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1199 ClutterLayoutManagerClass *layout_class;
1201 layout_class = CLUTTER_LAYOUT_MANAGER_CLASS (klass);
1203 layout_class->get_preferred_width = clutter_box_layout_get_preferred_width;
1204 layout_class->get_preferred_height = clutter_box_layout_get_preferred_height;
1205 layout_class->allocate = clutter_box_layout_allocate;
1206 layout_class->set_container = clutter_box_layout_set_container;
1207 layout_class->get_child_meta_type = clutter_box_layout_get_child_meta_type;
1209 g_type_class_add_private (klass, sizeof (ClutterBoxLayoutPrivate));
1212 * ClutterBoxLayout:vertical:
1214 * Whether the #ClutterBoxLayout should arrange its children
1215 * alongside the Y axis, instead of alongside the X axis
1219 * Deprecated: 1.12: Use #ClutterBoxLayout:orientation instead.
1221 obj_props[PROP_VERTICAL] =
1222 g_param_spec_boolean ("vertical",
1224 P_("Whether the layout should be vertical, "
1225 "rather than horizontal"),
1228 G_PARAM_STATIC_STRINGS |
1229 G_PARAM_DEPRECATED);
1232 * ClutterBoxLayout:orientation:
1234 * The orientation of the #ClutterBoxLayout, either horizontal
1239 obj_props[PROP_ORIENTATION] =
1240 g_param_spec_enum ("orientation",
1242 P_("The orientation of the layout"),
1243 CLUTTER_TYPE_ORIENTATION,
1244 CLUTTER_ORIENTATION_HORIZONTAL,
1246 G_PARAM_STATIC_STRINGS);
1249 * ClutterBoxLayout:homogeneous:
1251 * Whether the #ClutterBoxLayout should arrange its children
1252 * homogeneously, i.e. all childs get the same size
1256 obj_props[PROP_HOMOGENEOUS] =
1257 g_param_spec_boolean ("homogeneous",
1259 P_("Whether the layout should be homogeneous, "
1260 "i.e. all childs get the same size"),
1262 CLUTTER_PARAM_READWRITE);
1265 * ClutterBoxLayout:pack-start:
1267 * Whether the #ClutterBoxLayout should pack items at the start
1268 * or append them at the end
1272 obj_props[PROP_PACK_START] =
1273 g_param_spec_boolean ("pack-start",
1275 P_("Whether to pack items at the start of the box"),
1277 CLUTTER_PARAM_READWRITE);
1280 * ClutterBoxLayout:spacing:
1282 * The spacing between children of the #ClutterBoxLayout, in pixels
1286 obj_props[PROP_SPACING] =
1287 g_param_spec_uint ("spacing",
1289 P_("Spacing between children"),
1291 CLUTTER_PARAM_READWRITE);
1293 /* a leftover to be compatible to the previous implementation */
1294 obj_props[PROP_EASING_DURATION] =
1295 g_param_spec_uint ("easing-duration",
1296 P_("Easing Duration"),
1297 P_("The duration of the animations"),
1299 CLUTTER_PARAM_READWRITE);
1301 gobject_class->set_property = clutter_box_layout_set_property;
1302 gobject_class->get_property = clutter_box_layout_get_property;
1303 g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
1307 clutter_box_layout_init (ClutterBoxLayout *layout)
1309 ClutterBoxLayoutPrivate *priv;
1311 layout->priv = priv = CLUTTER_BOX_LAYOUT_GET_PRIVATE (layout);
1313 priv->orientation = CLUTTER_ORIENTATION_HORIZONTAL;
1314 priv->is_homogeneous = FALSE;
1315 priv->is_pack_start = FALSE;
1320 * clutter_box_layout_new:
1322 * Creates a new #ClutterBoxLayout layout manager
1324 * Return value: the newly created #ClutterBoxLayout
1328 ClutterLayoutManager *
1329 clutter_box_layout_new (void)
1331 return g_object_new (CLUTTER_TYPE_BOX_LAYOUT, NULL);
1335 * clutter_box_layout_set_spacing:
1336 * @layout: a #ClutterBoxLayout
1337 * @spacing: the spacing between children of the layout, in pixels
1339 * Sets the spacing between children of @layout
1344 clutter_box_layout_set_spacing (ClutterBoxLayout *layout,
1347 ClutterBoxLayoutPrivate *priv;
1349 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
1351 priv = layout->priv;
1353 if (priv->spacing != spacing)
1355 ClutterLayoutManager *manager;
1357 priv->spacing = spacing;
1359 manager = CLUTTER_LAYOUT_MANAGER (layout);
1361 clutter_layout_manager_layout_changed (manager);
1363 g_object_notify (G_OBJECT (layout), "spacing");
1368 * clutter_box_layout_get_spacing:
1369 * @layout: a #ClutterBoxLayout
1371 * Retrieves the spacing set using clutter_box_layout_set_spacing()
1373 * Return value: the spacing between children of the #ClutterBoxLayout
1378 clutter_box_layout_get_spacing (ClutterBoxLayout *layout)
1380 g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), 0);
1382 return layout->priv->spacing;
1386 * clutter_box_layout_set_vertical:
1387 * @layout: a #ClutterBoxLayout
1388 * @vertical: %TRUE if the layout should be vertical
1390 * Sets whether @layout should arrange its children vertically alongside
1391 * the Y axis, instead of horizontally alongside the X axis
1395 * Deprecated: 1.12: Use clutter_box_layout_set_orientation() instead.
1398 clutter_box_layout_set_vertical (ClutterBoxLayout *layout,
1401 ClutterOrientation new_orientation, old_orientation;
1403 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
1405 old_orientation = layout->priv->orientation;
1406 new_orientation = vertical
1407 ? CLUTTER_ORIENTATION_VERTICAL
1408 : CLUTTER_ORIENTATION_HORIZONTAL;
1409 clutter_box_layout_set_orientation (layout, new_orientation);
1411 if (old_orientation != new_orientation)
1412 g_object_notify_by_pspec (G_OBJECT (layout), obj_props[PROP_VERTICAL]);
1416 * clutter_box_layout_set_orientation:
1417 * @layout: a #ClutterBoxLayout
1418 * @orientation: the orientation of the #ClutterBoxLayout
1420 * Sets the orientation of the #ClutterBoxLayout layout manager.
1425 clutter_box_layout_set_orientation (ClutterBoxLayout *layout,
1426 ClutterOrientation orientation)
1428 ClutterBoxLayoutPrivate *priv;
1429 ClutterLayoutManager *manager;
1431 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
1433 priv = layout->priv;
1435 if (priv->orientation == orientation)
1438 priv->orientation = orientation;
1440 manager = CLUTTER_LAYOUT_MANAGER (layout);
1442 clutter_layout_manager_layout_changed (manager);
1444 g_object_notify_by_pspec (G_OBJECT (layout), obj_props[PROP_ORIENTATION]);
1448 * clutter_box_layout_get_vertical:
1449 * @layout: a #ClutterBoxLayout
1451 * Retrieves the orientation of the @layout as set using the
1452 * clutter_box_layout_set_vertical() function
1454 * Return value: %TRUE if the #ClutterBoxLayout is arranging its children
1455 * vertically, and %FALSE otherwise
1459 * Deprecated: 1.12: Use clutter_box_layout_get_orientation() instead
1462 clutter_box_layout_get_vertical (ClutterBoxLayout *layout)
1464 g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), FALSE);
1466 return layout->priv->orientation == CLUTTER_ORIENTATION_VERTICAL;
1470 * clutter_box_layout_get_orientation:
1471 * @layout: a #ClutterBoxLayout
1473 * Retrieves the orientation of the @layout.
1475 * Return value: the orientation of the layout
1480 clutter_box_layout_get_orientation (ClutterBoxLayout *layout)
1482 g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout),
1483 CLUTTER_ORIENTATION_HORIZONTAL);
1485 return layout->priv->orientation;
1489 * clutter_box_layout_set_homogeneous:
1490 * @layout: a #ClutterBoxLayout
1491 * @homogeneous: %TRUE if the layout should be homogeneous
1493 * Sets whether the size of @layout children should be
1499 clutter_box_layout_set_homogeneous (ClutterBoxLayout *layout,
1500 gboolean homogeneous)
1502 ClutterBoxLayoutPrivate *priv;
1504 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
1506 priv = layout->priv;
1508 if (priv->is_homogeneous != homogeneous)
1510 ClutterLayoutManager *manager;
1512 priv->is_homogeneous = !!homogeneous;
1514 manager = CLUTTER_LAYOUT_MANAGER (layout);
1516 clutter_layout_manager_layout_changed (manager);
1518 g_object_notify (G_OBJECT (layout), "homogeneous");
1523 * clutter_box_layout_get_homogeneous:
1524 * @layout: a #ClutterBoxLayout
1526 * Retrieves if the children sizes are allocated homogeneously.
1528 * Return value: %TRUE if the #ClutterBoxLayout is arranging its children
1529 * homogeneously, and %FALSE otherwise
1534 clutter_box_layout_get_homogeneous (ClutterBoxLayout *layout)
1536 g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), FALSE);
1538 return layout->priv->is_homogeneous;
1542 * clutter_box_layout_set_pack_start:
1543 * @layout: a #ClutterBoxLayout
1544 * @pack_start: %TRUE if the @layout should pack children at the
1545 * beginning of the layout
1547 * Sets whether children of @layout should be layed out by appending
1548 * them or by prepending them
1553 clutter_box_layout_set_pack_start (ClutterBoxLayout *layout,
1554 gboolean pack_start)
1556 ClutterBoxLayoutPrivate *priv;
1558 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
1560 priv = layout->priv;
1562 if (priv->is_pack_start != pack_start)
1564 ClutterLayoutManager *manager;
1566 priv->is_pack_start = pack_start ? TRUE : FALSE;
1568 manager = CLUTTER_LAYOUT_MANAGER (layout);
1570 clutter_layout_manager_layout_changed (manager);
1572 g_object_notify (G_OBJECT (layout), "pack-start");
1577 * clutter_box_layout_get_pack_start:
1578 * @layout: a #ClutterBoxLayout
1580 * Retrieves the value set using clutter_box_layout_set_pack_start()
1582 * Return value: %TRUE if the #ClutterBoxLayout should pack children
1583 * at the beginning of the layout, and %FALSE otherwise
1588 clutter_box_layout_get_pack_start (ClutterBoxLayout *layout)
1590 g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), FALSE);
1592 return layout->priv->is_pack_start;
1596 * clutter_box_layout_pack:
1597 * @layout: a #ClutterBoxLayout
1598 * @actor: a #ClutterActor
1599 * @expand: whether the @actor should expand
1600 * @x_fill: whether the @actor should fill horizontally
1601 * @y_fill: whether the @actor should fill vertically
1602 * @x_align: the horizontal alignment policy for @actor
1603 * @y_align: the vertical alignment policy for @actor
1605 * Packs @actor inside the #ClutterContainer associated to @layout
1606 * and sets the layout properties
1609 * Deprecated: 1.12: #ClutterBoxLayout honours #ClutterActor's
1610 * align and expand properties. The preferred way is adding
1611 * the @actor with clutter_actor_add_child() and setting
1612 * #ClutterActor:x-align, #ClutterActor:y-align,
1613 * #ClutterActor:x-expand and #ClutterActor:y-expand
1616 clutter_box_layout_pack (ClutterBoxLayout *layout,
1617 ClutterActor *actor,
1621 ClutterBoxAlignment x_align,
1622 ClutterBoxAlignment y_align)
1624 ClutterBoxLayoutPrivate *priv;
1625 ClutterLayoutManager *manager;
1626 ClutterLayoutMeta *meta;
1628 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
1629 g_return_if_fail (CLUTTER_IS_ACTOR (actor));
1631 priv = layout->priv;
1633 if (priv->container == NULL)
1635 g_warning ("The layout of type '%s' must be associated to "
1636 "a ClutterContainer before adding children",
1637 G_OBJECT_TYPE_NAME (layout));
1641 clutter_container_add_actor (priv->container, actor);
1643 manager = CLUTTER_LAYOUT_MANAGER (layout);
1644 meta = clutter_layout_manager_get_child_meta (manager,
1647 g_assert (CLUTTER_IS_BOX_CHILD (meta));
1649 box_child_set_align (CLUTTER_BOX_CHILD (meta), x_align, y_align);
1650 box_child_set_fill (CLUTTER_BOX_CHILD (meta), x_fill, y_fill);
1651 box_child_set_expand (CLUTTER_BOX_CHILD (meta), expand);
1655 * clutter_box_layout_set_alignment:
1656 * @layout: a #ClutterBoxLayout
1657 * @actor: a #ClutterActor child of @layout
1658 * @x_align: Horizontal alignment policy for @actor
1659 * @y_align: Vertical alignment policy for @actor
1661 * Sets the horizontal and vertical alignment policies for @actor
1665 * Deprecated: 1.12: #ClutterBoxLayout will honour #ClutterActor's
1666 * #ClutterActor:x-align and #ClutterActor:y-align properies
1669 clutter_box_layout_set_alignment (ClutterBoxLayout *layout,
1670 ClutterActor *actor,
1671 ClutterBoxAlignment x_align,
1672 ClutterBoxAlignment y_align)
1674 ClutterBoxLayoutPrivate *priv;
1675 ClutterLayoutManager *manager;
1676 ClutterLayoutMeta *meta;
1678 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
1679 g_return_if_fail (CLUTTER_IS_ACTOR (actor));
1681 priv = layout->priv;
1683 if (priv->container == NULL)
1685 g_warning ("The layout of type '%s' must be associated to "
1686 "a ClutterContainer before querying layout "
1688 G_OBJECT_TYPE_NAME (layout));
1692 manager = CLUTTER_LAYOUT_MANAGER (layout);
1693 meta = clutter_layout_manager_get_child_meta (manager,
1698 g_warning ("No layout meta found for the child of type '%s' "
1699 "inside the layout manager of type '%s'",
1700 G_OBJECT_TYPE_NAME (actor),
1701 G_OBJECT_TYPE_NAME (manager));
1705 g_assert (CLUTTER_IS_BOX_CHILD (meta));
1707 box_child_set_align (CLUTTER_BOX_CHILD (meta), x_align, y_align);
1711 * clutter_box_layout_get_alignment:
1712 * @layout: a #ClutterBoxLayout
1713 * @actor: a #ClutterActor child of @layout
1714 * @x_align: (out): return location for the horizontal alignment policy
1715 * @y_align: (out): return location for the vertical alignment policy
1717 * Retrieves the horizontal and vertical alignment policies for @actor
1718 * as set using clutter_box_layout_pack() or clutter_box_layout_set_alignment()
1721 * Deprecated: 1.12: #ClutterBoxLayout will honour #ClutterActor's
1722 * #ClutterActor:x-align and #ClutterActor:y-align properies
1725 clutter_box_layout_get_alignment (ClutterBoxLayout *layout,
1726 ClutterActor *actor,
1727 ClutterBoxAlignment *x_align,
1728 ClutterBoxAlignment *y_align)
1730 ClutterBoxLayoutPrivate *priv;
1731 ClutterLayoutManager *manager;
1732 ClutterLayoutMeta *meta;
1734 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
1735 g_return_if_fail (CLUTTER_IS_ACTOR (actor));
1737 priv = layout->priv;
1739 if (priv->container == NULL)
1741 g_warning ("The layout of type '%s' must be associated to "
1742 "a ClutterContainer before querying layout "
1744 G_OBJECT_TYPE_NAME (layout));
1748 manager = CLUTTER_LAYOUT_MANAGER (layout);
1749 meta = clutter_layout_manager_get_child_meta (manager,
1754 g_warning ("No layout meta found for the child of type '%s' "
1755 "inside the layout manager of type '%s'",
1756 G_OBJECT_TYPE_NAME (actor),
1757 G_OBJECT_TYPE_NAME (manager));
1761 g_assert (CLUTTER_IS_BOX_CHILD (meta));
1764 *x_align = CLUTTER_BOX_CHILD (meta)->x_align;
1767 *y_align = CLUTTER_BOX_CHILD (meta)->y_align;
1771 * clutter_box_layout_set_fill:
1772 * @layout: a #ClutterBoxLayout
1773 * @actor: a #ClutterActor child of @layout
1774 * @x_fill: whether @actor should fill horizontally the allocated space
1775 * @y_fill: whether @actor should fill vertically the allocated space
1777 * Sets the horizontal and vertical fill policies for @actor
1781 * Deprecated: 1.12: #ClutterBoxLayout will honour #ClutterActor's
1782 * #ClutterActor:x-align and #ClutterActor:y-align properies
1785 clutter_box_layout_set_fill (ClutterBoxLayout *layout,
1786 ClutterActor *actor,
1790 ClutterBoxLayoutPrivate *priv;
1791 ClutterLayoutManager *manager;
1792 ClutterLayoutMeta *meta;
1794 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
1795 g_return_if_fail (CLUTTER_IS_ACTOR (actor));
1797 priv = layout->priv;
1799 if (priv->container == NULL)
1801 g_warning ("The layout of type '%s' must be associated to "
1802 "a ClutterContainer before querying layout "
1804 G_OBJECT_TYPE_NAME (layout));
1808 manager = CLUTTER_LAYOUT_MANAGER (layout);
1809 meta = clutter_layout_manager_get_child_meta (manager,
1814 g_warning ("No layout meta found for the child of type '%s' "
1815 "inside the layout manager of type '%s'",
1816 G_OBJECT_TYPE_NAME (actor),
1817 G_OBJECT_TYPE_NAME (manager));
1821 g_assert (CLUTTER_IS_BOX_CHILD (meta));
1823 box_child_set_fill (CLUTTER_BOX_CHILD (meta), x_fill, y_fill);
1827 * clutter_box_layout_get_fill:
1828 * @layout: a #ClutterBoxLayout
1829 * @actor: a #ClutterActor child of @layout
1830 * @x_fill: (out): return location for the horizontal fill policy
1831 * @y_fill: (out): return location for the vertical fill policy
1833 * Retrieves the horizontal and vertical fill policies for @actor
1834 * as set using clutter_box_layout_pack() or clutter_box_layout_set_fill()
1837 * Deprecated: 1.12: #ClutterBoxLayout will honour #ClutterActor's
1838 * #ClutterActor:x-align and #ClutterActor:y-align properies
1841 clutter_box_layout_get_fill (ClutterBoxLayout *layout,
1842 ClutterActor *actor,
1846 ClutterBoxLayoutPrivate *priv;
1847 ClutterLayoutManager *manager;
1848 ClutterLayoutMeta *meta;
1850 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
1851 g_return_if_fail (CLUTTER_IS_ACTOR (actor));
1853 priv = layout->priv;
1855 if (priv->container == NULL)
1857 g_warning ("The layout of type '%s' must be associated to "
1858 "a ClutterContainer before querying layout "
1860 G_OBJECT_TYPE_NAME (layout));
1864 manager = CLUTTER_LAYOUT_MANAGER (layout);
1865 meta = clutter_layout_manager_get_child_meta (manager,
1870 g_warning ("No layout meta found for the child of type '%s' "
1871 "inside the layout manager of type '%s'",
1872 G_OBJECT_TYPE_NAME (actor),
1873 G_OBJECT_TYPE_NAME (manager));
1877 g_assert (CLUTTER_IS_BOX_CHILD (meta));
1880 *x_fill = CLUTTER_BOX_CHILD (meta)->x_fill;
1883 *y_fill = CLUTTER_BOX_CHILD (meta)->y_fill;
1887 * clutter_box_layout_set_expand:
1888 * @layout: a #ClutterBoxLayout
1889 * @actor: a #ClutterActor child of @layout
1890 * @expand: whether @actor should expand
1892 * Sets whether @actor should expand inside @layout
1895 * Deprecated: 1.12: #ClutterBoxLayout will honour #ClutterActor's
1896 * #ClutterActor:x-expand and #ClutterActor:y-expand properies
1899 clutter_box_layout_set_expand (ClutterBoxLayout *layout,
1900 ClutterActor *actor,
1903 ClutterBoxLayoutPrivate *priv;
1904 ClutterLayoutManager *manager;
1905 ClutterLayoutMeta *meta;
1907 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
1908 g_return_if_fail (CLUTTER_IS_ACTOR (actor));
1910 priv = layout->priv;
1912 if (priv->container == NULL)
1914 g_warning ("The layout of type '%s' must be associated to "
1915 "a ClutterContainer before querying layout "
1917 G_OBJECT_TYPE_NAME (layout));
1921 manager = CLUTTER_LAYOUT_MANAGER (layout);
1922 meta = clutter_layout_manager_get_child_meta (manager,
1927 g_warning ("No layout meta found for the child of type '%s' "
1928 "inside the layout manager of type '%s'",
1929 G_OBJECT_TYPE_NAME (actor),
1930 G_OBJECT_TYPE_NAME (manager));
1934 g_assert (CLUTTER_IS_BOX_CHILD (meta));
1936 box_child_set_expand (CLUTTER_BOX_CHILD (meta), expand);
1940 * clutter_box_layout_get_expand:
1941 * @layout: a #ClutterBoxLayout
1942 * @actor: a #ClutterActor child of @layout
1944 * Retrieves whether @actor should expand inside @layout
1946 * Return value: %TRUE if the #ClutterActor should expand, %FALSE otherwise
1949 * Deprecated: 1.12: #ClutterBoxLayout will honour #ClutterActor's
1950 * #ClutterActor:x-expand and #ClutterActor:y-expand properies
1953 clutter_box_layout_get_expand (ClutterBoxLayout *layout,
1954 ClutterActor *actor)
1956 ClutterBoxLayoutPrivate *priv;
1957 ClutterLayoutManager *manager;
1958 ClutterLayoutMeta *meta;
1960 g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), FALSE);
1961 g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE);
1963 priv = layout->priv;
1965 if (priv->container == NULL)
1967 g_warning ("The layout of type '%s' must be associated to "
1968 "a ClutterContainer before querying layout "
1970 G_OBJECT_TYPE_NAME (layout));
1974 manager = CLUTTER_LAYOUT_MANAGER (layout);
1975 meta = clutter_layout_manager_get_child_meta (manager,
1980 g_warning ("No layout meta found for the child of type '%s' "
1981 "inside the layout manager of type '%s'",
1982 G_OBJECT_TYPE_NAME (actor),
1983 G_OBJECT_TYPE_NAME (manager));
1987 g_assert (CLUTTER_IS_BOX_CHILD (meta));
1989 return CLUTTER_BOX_CHILD (meta)->expand;
1993 * clutter_box_layout_set_use_animations:
1994 * @layout: a #ClutterBoxLayout
1995 * @animate: %TRUE if the @layout should use animations
1997 * Sets whether @layout should animate changes in the layout properties
1999 * The duration of the animations is controlled by
2000 * clutter_box_layout_set_easing_duration(); the easing mode to be used
2001 * by the animations is controlled by clutter_box_layout_set_easing_mode().
2003 * Enabling animations will override the easing state of each child
2004 * of the actor using @layout, and will use the #ClutterBoxLayout:easing-mode
2005 * and #ClutterBoxLayout:easing-duration properties instead.
2009 * Deprecated: 1.12: #ClutterBoxLayout will honour the
2010 * #ClutterLayoutManager:use-animations property
2013 clutter_box_layout_set_use_animations (ClutterBoxLayout *layout,
2016 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
2018 clutter_layout_manager_set_use_animations (CLUTTER_LAYOUT_MANAGER (layout),
2023 * clutter_box_layout_get_use_animations:
2024 * @layout: a #ClutterBoxLayout
2026 * Retrieves whether @layout should animate changes in the layout properties.
2028 * Return value: %TRUE if the animations should be used, %FALSE otherwise
2032 * Deprecated: 1.12: #ClutterBoxLayout will honour the
2033 * #ClutterLayoutManager:use-animations property
2036 clutter_box_layout_get_use_animations (ClutterBoxLayout *layout)
2038 ClutterLayoutManager *manager;
2040 g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), FALSE);
2042 manager = CLUTTER_LAYOUT_MANAGER (layout);
2044 return clutter_layout_manager_get_use_animations (manager);
2048 * clutter_box_layout_set_easing_mode:
2049 * @layout: a #ClutterBoxLayout
2050 * @mode: an easing mode, either from #ClutterAnimationMode or a logical id
2051 * from clutter_alpha_register_func()
2053 * Sets the easing mode to be used by @layout when animating changes in layout
2058 * Deprecated: 1.12: #ClutterBoxLayout will honour the
2059 * #ClutterLayoutManager:easing-mode property
2062 clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
2065 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
2067 clutter_layout_manager_set_easing_mode (CLUTTER_LAYOUT_MANAGER (layout),
2072 * clutter_box_layout_get_easing_mode:
2073 * @layout: a #ClutterBoxLayout
2075 * Retrieves the easing mode set using clutter_box_layout_set_easing_mode()
2077 * Return value: an easing mode
2081 * Deprecated: 1.12: #ClutterBoxLayout will honour the
2082 * #ClutterLayoutManager:easing-mode property
2085 clutter_box_layout_get_easing_mode (ClutterBoxLayout *layout)
2087 ClutterLayoutManager *manager;
2089 g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout),
2090 CLUTTER_EASE_OUT_CUBIC);
2092 manager = CLUTTER_LAYOUT_MANAGER (layout);
2094 return clutter_layout_manager_get_easing_mode (manager);
2098 * clutter_box_layout_set_easing_duration:
2099 * @layout: a #ClutterBoxLayout
2100 * @msecs: the duration of the animations, in milliseconds
2102 * Sets the duration of the animations used by @layout when animating changes
2103 * in the layout properties.
2107 * Deprecated: 1.12: #ClutterBoxLayout will honour the
2108 * #ClutterLayoutManager:easing-duration property
2111 clutter_box_layout_set_easing_duration (ClutterBoxLayout *layout,
2114 g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
2116 clutter_layout_manager_set_easing_duration (CLUTTER_LAYOUT_MANAGER (layout),
2121 * clutter_box_layout_get_easing_duration:
2122 * @layout: a #ClutterBoxLayout
2124 * Retrieves the duration set using clutter_box_layout_set_easing_duration()
2126 * Return value: the duration of the animations, in milliseconds
2130 * Deprecated: 1.12: #ClutterBoxLayout will honour the
2131 * #ClutterLayoutManager:easing-duration property
2134 clutter_box_layout_get_easing_duration (ClutterBoxLayout *layout)
2136 ClutterLayoutManager *manager;
2138 g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), 500);
2140 manager = CLUTTER_LAYOUT_MANAGER (layout);
2142 return clutter_layout_manager_get_easing_duration (manager);