## ClutterLayoutManager

ClutterLayoutManager — Layout managers base class

## Synopsis

    struct              ClutterLayoutManager;
    struct              ClutterLayoutManagerClass;
    void                clutter_layout_manager_get_preferred_width
                                                            (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             gfloat for_height,
                                                             gfloat *min_width_p,
                                                             gfloat *nat_width_p);
    void                clutter_layout_manager_get_preferred_height
                                                            (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             gfloat for_width,
                                                             gfloat *min_height_p,
                                                             gfloat *nat_height_p);
    void                clutter_layout_manager_allocate     (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             const ClutterActorBox *allocation,
                                                             ClutterAllocationFlags flags);
    void                clutter_layout_manager_layout_changed
                                                            (ClutterLayoutManager *manager);
    void                clutter_layout_manager_set_container
                                                            (ClutterLayoutManager *manager,
                                                             ClutterContainer *container);

    ClutterLayoutMeta * clutter_layout_manager_get_child_meta
                                                            (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             ClutterActor *actor);
    void                clutter_layout_manager_child_set    (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             ClutterActor *actor,
                                                             const gchar *first_property,
                                                             ...);
    void                clutter_layout_manager_child_set_property
                                                            (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             ClutterActor *actor,
                                                             const gchar *property_name,
                                                             const GValue *value);
    void                clutter_layout_manager_child_get    (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             ClutterActor *actor,
                                                             const gchar *first_property,
                                                             ...);
    void                clutter_layout_manager_child_get_property
                                                            (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             ClutterActor *actor,
                                                             const gchar *property_name,
                                                             GValue *value);

    GParamSpec *        clutter_layout_manager_find_child_property
                                                            (ClutterLayoutManager *manager,
                                                             const gchar *name);
    GParamSpec **       clutter_layout_manager_list_child_properties
                                                            (ClutterLayoutManager *manager,
                                                             guint *n_pspecs);

    ClutterAlpha *      clutter_layout_manager_begin_animation
                                                            (ClutterLayoutManager *manager,
                                                             guint duration,
                                                             gulong mode);
    void                clutter_layout_manager_end_animation
                                                            (ClutterLayoutManager *manager);
    gdouble             clutter_layout_manager_get_animation_progress
                                                            (ClutterLayoutManager *manager);

## Object Hierarchy

      GObject
       +----GInitiallyUnowned
             +----ClutterLayoutManager
                   +----ClutterBinLayout
                   +----ClutterBoxLayout
                   +----ClutterFixedLayout
                   +----ClutterFlowLayout
                   +----ClutterTableLayout

## Signals

      "layout-changed"                                 : Run Last

## Description

ClutterLayoutManager is a base abstract class for layout managers. A layout manager implements the layouting policy for a composite or a container actor: it controls the preferred size of the actor to which it has been paired, and it controls the allocation of its children.

Any composite or container ClutterActor subclass can delegate the layouting of its children to a ClutterLayoutManager. Clutter provides a generic container using ClutterLayoutManager called ClutterBox.

Clutter provides some simple ClutterLayoutManager sub-classes, like ClutterFlowLayout and ClutterBinLayout.

### Using a Layout Manager inside an Actor

In order to use a ClutterLayoutManager inside a ClutterActor sub-class you should invoke `clutter_layout_manager_get_preferred_width()` inside the ClutterActor::`get_preferred_width()` virtual function and `clutter_layout_manager_get_preferred_height()` inside the ClutterActor::`get_preferred_height()` virtual function implementations. You should also call `clutter_layout_manager_allocate()` inside the implementation of the ClutterActor::`allocate()` virtual function.

In order to receive notifications for changes in the layout manager policies you should also connect to the "layout-changed" signal and queue a relayout on your actor. The following code should be enough if the actor does not need to perform specific operations whenever a layout manager changes:

    1
    2
    3
    4

    g_signal_connect_swapped (layout_manager,
                              "layout-changed",
                              G_CALLBACK (clutter_actor_queue_relayout),
                              actor);

### Implementing a ClutterLayoutManager

The implementation of a layout manager does not differ from the implementation of the size requisition and allocation bits of ClutterActor, so you should read the relative documentation for subclassing ClutterActor.

The layout manager implementation can hold a back pointer to the ClutterContainer by implementing the ``set_container()`` virtual function. The layout manager should not hold a real reference (i.e. call `g_object_ref()`) on the container actor, to avoid reference cycles.

If the layout manager has properties affecting the layout policies then it should emit the "layout-changed" signal on itself by using the `clutter_layout_manager_layout_changed()` function whenever one of these properties changes.

If the layout manager has layout properties, that is properties that should exist only as the result of the presence of a specific (layout manager, container actor, child actor) combination, and it wishes to store those properties inside a ClutterLayoutMeta then it should override the ClutterLayoutManager::`get_child_meta_type()` virtual function to return the GType of the ClutterLayoutMeta sub-class used to store the layout properties; optionally, the ClutterLayoutManager sub-class might also override the ClutterLayoutManager::`create_child_meta()` virtual function to control how the ClutterLayoutMeta instance is created, otherwise the default implementation will be equivalent to:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    ClutterLayoutManagerClass *klass;
    GType meta_type;

    klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
    meta_type = klass->get_child_meta_type (manager);

    return g_object_new (meta_type,
                         "manager", manager,
                         "container", container,
                         "actor", actor,
                         NULL);

Where `manager` is the ClutterLayoutManager, `container` is the ClutterContainer using the ClutterLayoutManager and `actor` is the ClutterActor child of the ClutterContainer.

### Animating a ClutterLayoutManager

A layout manager is used to let a ClutterContainer take complete ownership over the layout (that is: the position and sizing) of its children; this means that using the Clutter animation API, like `clutter_actor_animate()`, to animate the position and sizing of a child of a layout manager it is not going to work properly, as the animation will automatically override any setting done by the layout manager itself.

It is possible for a ClutterLayoutManager sub-class to animate its children layout by using the base class animation support. The ClutterLayoutManager animation support consists of three virtual functions: ``begin_animation()``, ``get_animation_progress()`` and ``end_animation()``.

`begin_animation (duration, easing)`

This virtual function is invoked when the layout manager should begin an animation. The implementation should set up the state for the animation and create the ancillary objects for animating the layout. The default implementation creates a ClutterTimeline for the given duration and a ClutterAlpha binding the timeline to the given easing mode. This function returns a ClutterAlpha which should be used to control the animation from the caller perspective.

``get_animation_progress()`` | This virtual function should be invoked when animating a layout manager. It returns the progress of the animation, using the same semantics as the "alpha" value.
``end_animation()`` | This virtual function is invoked when the animation of a layout manager ends, and it is meant to be used for bookkeeping the objects created in the ``begin_animation()`` function. The default implementation will call it implicitly when the timeline is complete.

The simplest way to animate a layout is to create a ClutterTimeline inside the ``begin_animation()`` virtual function, along with a ClutterAlpha, and for each "new-frame" signal emission call `clutter_layout_manager_layout_changed()`, which will cause a relayout. The "completed" signal emission should cause `clutter_layout_manager_end_animation()` to be called. The default implementation provided internally by ClutterLayoutManager does exactly this, so most sub-classes should either not override any animation-related virtual function or simply override ``begin_animation()`` and ``end_animation()`` to set up ad hoc state, and then chain up to the parent's implementation.

Example 2. Animation of a Layout Manager

The code below shows how a ClutterLayoutManager sub-class should provide animating the allocation of its children from within the ``allocate()`` virtual function implementation. The animation is computed between the last stable allocation performed before the animation started and the desired final allocation.

The `is_animating` variable is stored inside the ClutterLayoutManager sub-class and it is updated by overriding the ``begin_animation()`` and ``end_animation()`` virtual functions and chaining up to the base class implementation.

The last stable allocation is stored within a ClutterLayoutMeta sub-class used by the implementation.

    static void
    my_layout_manager_allocate (ClutterLayoutManager   *manager,
                                ClutterContainer       *container,
                                const ClutterActorBox  *allocation,
                                ClutterAllocationFlags  flags)
    {
      MyLayoutManager *self = MY_LAYOUT_MANAGER (manager);
      GList *children, *l;

      children = clutter_container_get_children (container);

      for (l = children; l != NULL; l = l->next)
        {
          ClutterActor *child = l->data;
          ClutterLayoutMeta *meta;
          MyLayoutMeta *my_meta;

          /* retrieve the layout meta-object */
          meta = clutter_layout_manager_get_child_meta (manager,
                                                        container,
                                                        child);
          my_meta = MY_LAYOUT_META (meta);

          /* compute the desired allocation for the child */
          compute_allocation (self, my_meta, child,
                              allocation, flags,
                              &child_box);

          /* this is the additional code that deals with the animation
           * of the layout manager
           */
          if (!self->is_animating)
            {
              /* store the last stable allocation for later use */
              my_meta->last_alloc = clutter_actor_box_copy (&child_box);
            }
          else
            {
              ClutterActorBox end = { 0, };
              gdouble p;

              /* get the progress of the animation */
              p = clutter_layout_manager_get_animation_progress (manager);

              if (my_meta->last_alloc != NULL)
                {
                  /* copy the desired allocation as the final state */
                  end = child_box;

                  /* then interpolate the initial and final state
                   * depending on the progress of the animation,
                   * and put the result inside the box we will use
                   * to allocate the child
                   */
                  clutter_actor_box_interpolate (my_meta->last_alloc,
                                                 &end,
                                                 p,
                                                 &child_box);
                }
              else
                {
                  /* if there is no stable allocation then the child was
                   * added while animating; one possible course of action
                   * is to just bail out and fall through to the allocation
                   * to position the child directly at its final state
                   */
                  my_meta->last_alloc =
                    clutter_actor_box_copy (&child_box);
                }
            }

          /* allocate the child */
          clutter_actor_allocate (child, &child_box, flags);
        }

      g_list_free (children);
    }

Sub-classes of ClutterLayoutManager that support animations of the layout changes should call `clutter_layout_manager_begin_animation()` whenever a layout property changes value, e.g.:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    if (self->orientation != new_orientation)
      {
        ClutterLayoutManager *manager;

        self->orientation = new_orientation;

        manager = CLUTTER_LAYOUT_MANAGER (self);
        clutter_layout_manager_layout_changed (manager);
        clutter_layout_manager_begin_animation (manager, 500, CLUTTER_LINEAR);

        g_object_notify (G_OBJECT (self), "orientation");
      }

The code above will animate a change in the `orientation` layout property of a layout manager.

ClutterLayoutManager is available since Clutter 1.2

## Details

### struct ClutterLayoutManager

    struct ClutterLayoutManager;

The ClutterLayoutManager structure contains only private data and should be accessed using the provided API

Since 1.2

### struct ClutterLayoutManagerClass

    struct ClutterLayoutManagerClass {
      /* vfuncs, not signals */
      void               (* get_preferred_width)    (ClutterLayoutManager   *manager,
                                                     ClutterContainer       *container,
                                                     gfloat                  for_height,
                                                     gfloat                 *min_width_p,
                                                     gfloat                 *nat_width_p);
      void               (* get_preferred_height)   (ClutterLayoutManager   *manager,
                                                     ClutterContainer       *container,
                                                     gfloat                  for_width,
                                                     gfloat                 *min_height_p,
                                                     gfloat                 *nat_height_p);
      void               (* allocate)               (ClutterLayoutManager   *manager,
                                                     ClutterContainer       *container,
                                                     const ClutterActorBox  *allocation,
                                                     ClutterAllocationFlags  flags);

      void               (* set_container)          (ClutterLayoutManager   *manager,
                                                     ClutterContainer       *container);

      GType              (* get_child_meta_type)    (ClutterLayoutManager   *manager);
      ClutterLayoutMeta *(* create_child_meta)      (ClutterLayoutManager   *manager,
                                                     ClutterContainer       *container,
                                                     ClutterActor           *actor);

      ClutterAlpha *     (* begin_animation)        (ClutterLayoutManager   *manager,
                                                     guint                   duration,
                                                     gulong                  mode);
      gdouble            (* get_animation_progress) (ClutterLayoutManager   *manager);
      void               (* end_animation)          (ClutterLayoutManager   *manager);

      /* signals */
      void               (* layout_changed)         (ClutterLayoutManager   *manager);
    };

The ClutterLayoutManagerClass structure contains only private data and should be accessed using the provided API

`get_preferred_width` () | virtual function; override to provide a preferred width for the layout manager. See also the `get_preferred_width()` virtual function in ClutterActor
`get_preferred_height` () | virtual function; override to provide a preferred height for the layout manager. See also the `get_preferred_height()` virtual function in ClutterActor
`allocate` () | virtual function; override to allocate the children of the layout manager. See also the `allocate()` virtual function in ClutterActor
`set_container` () | virtual function; override to set a back pointer on the ClutterContainer using the layout manager. The implementation should not take a reference on the container, but just take a weak reference, to avoid potential leaks due to reference cycles
`get_child_meta_type` () | virtual function; override to return the GType of the ClutterLayoutMeta sub-class used by the ClutterLayoutManager
`create_child_meta` () | virtual function; override to create a ClutterLayoutMeta instance associated to a ClutterContainer and a child ClutterActor, used to maintain layout manager specific properties
`begin_animation` () | virtual function; override to control the animation of a ClutterLayoutManager with the given duration and easing mode
`get_animation_progress` () | virtual function; override to control the progress of the animation of a ClutterLayoutManager
`end_animation` () | virtual function; override to end an animation started by `clutter_layout_manager_begin_animation()`
`layout_changed` () | class handler for the "layout-changed" signal

Since 1.2

### clutter_layout_manager_get_preferred_width ()

    void                clutter_layout_manager_get_preferred_width
                                                            (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             gfloat for_height,
                                                             gfloat *min_width_p,
                                                             gfloat *nat_width_p);

Computes the minimum and natural widths of the `container` according to `manager`.

See also `clutter_actor_get_preferred_width()`

`manager` : | a ClutterLayoutManager
`container` : | the ClutterContainer using `manager`
`for_height` : | the height for which the width should be computed, or -1
`min_width_p` : | return location for the minimum width of the layout, or `NULL`. [out][allow-none]
`nat_width_p` : | return location for the natural width of the layout, or `NULL`. [out][allow-none]

Since 1.2

### clutter_layout_manager_get_preferred_height ()

    void                clutter_layout_manager_get_preferred_height
                                                            (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             gfloat for_width,
                                                             gfloat *min_height_p,
                                                             gfloat *nat_height_p);

Computes the minimum and natural heights of the `container` according to `manager`.

See also `clutter_actor_get_preferred_height()`

`manager` : | a ClutterLayoutManager
`container` : | the ClutterContainer using `manager`
`for_width` : | the width for which the height should be computed, or -1
`min_height_p` : | return location for the minimum height of the layout, or `NULL`. [out][allow-none]
`nat_height_p` : | return location for the natural height of the layout, or `NULL`. [out][allow-none]

Since 1.2

### clutter_layout_manager_allocate ()

    void                clutter_layout_manager_allocate     (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             const ClutterActorBox *allocation,
                                                             ClutterAllocationFlags flags);

Allocates the children of `container` given an area

See also `clutter_actor_allocate()`

`manager` : | a ClutterLayoutManager
`container` : | the ClutterContainer using `manager`
`allocation` : | the ClutterActorBox containing the allocated area of `container`
`flags` : | the allocation flags

Since 1.2

### clutter_layout_manager_layout_changed ()

    void                clutter_layout_manager_layout_changed
                                                            (ClutterLayoutManager *manager);

Emits the "layout-changed" signal on `manager`

This function should only be called by implementations of the ClutterLayoutManager class

`manager` : | a ClutterLayoutManager

Since 1.2

### clutter_layout_manager_set_container ()

    void                clutter_layout_manager_set_container
                                                            (ClutterLayoutManager *manager,
                                                             ClutterContainer *container);

If the ClutterLayoutManager sub-class allows it, allow adding a weak reference of the `container` using `manager` from within the layout manager

The layout manager should not increase the reference count of the `container`

`manager` : | a ClutterLayoutManager
`container` : | a ClutterContainer using `manager`. [allow-none]

Since 1.2

### clutter_layout_manager_get_child_meta ()

    ClutterLayoutMeta * clutter_layout_manager_get_child_meta
                                                            (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             ClutterActor *actor);

Retrieves the ClutterLayoutMeta that the layout `manager` associated to the `actor` child of `container`, eventually by creating one if the ClutterLayoutManager supports layout properties

`manager` : | a ClutterLayoutManager
`container` : | a ClutterContainer using `manager`
`actor` : | a ClutterActor child of `container`
Returns : | a ClutterLayoutMeta, or `NULL` if the ClutterLayoutManager does not have layout properties. The returned layout meta instance is owned by the ClutterLayoutManager and it should not be unreferenced. [transfer none]

Since 1.0

### clutter_layout_manager_child_set ()

    void                clutter_layout_manager_child_set    (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             ClutterActor *actor,
                                                             const gchar *first_property,
                                                             ...);

Sets a list of properties and their values on the ClutterLayoutMeta associated by `manager` to a child of `container`

Languages bindings should use `clutter_layout_manager_child_set_property()` instead

`manager` : | a ClutterLayoutManager
`container` : | a ClutterContainer using `manager`
`actor` : | a ClutterActor child of `container`
`first_property` : | the first property name
`...` : | a list of property name and value pairs

Since 1.2

### clutter_layout_manager_child_set_property ()

    void                clutter_layout_manager_child_set_property
                                                            (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             ClutterActor *actor,
                                                             const gchar *property_name,
                                                             const GValue *value);

Sets a property on the ClutterLayoutMeta created by `manager` and attached to a child of `container`

`manager` : | a ClutterLayoutManager
`container` : | a ClutterContainer using `manager`
`actor` : | a ClutterActor child of `container`
`property_name` : | the name of the property to set
`value` : | a GValue with the value of the property to set

Since 1.2

### clutter_layout_manager_child_get ()

    void                clutter_layout_manager_child_get    (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             ClutterActor *actor,
                                                             const gchar *first_property,
                                                             ...);

Retrieves the values for a list of properties out of the ClutterLayoutMeta created by `manager` and attached to the child of a `container`

`manager` : | a ClutterLayoutManager
`container` : | a ClutterContainer using `manager`
`actor` : | a ClutterActor child of `container`
`first_property` : | the name of the first property
`...` : | a list of property name and return location for the value pairs

Since 1.2

### clutter_layout_manager_child_get_property ()

    void                clutter_layout_manager_child_get_property
                                                            (ClutterLayoutManager *manager,
                                                             ClutterContainer *container,
                                                             ClutterActor *actor,
                                                             const gchar *property_name,
                                                             GValue *value);

Gets a property on the ClutterLayoutMeta created by `manager` and attached to a child of `container`

The GValue must already be initialized to the type of the property and has to be unset with `g_value_unset()` after extracting the real value out of it

`manager` : | a ClutterLayoutManager
`container` : | a ClutterContainer using `manager`
`actor` : | a ClutterActor child of `container`
`property_name` : | the name of the property to get
`value` : | a GValue with the value of the property to get

Since 1.2

### clutter_layout_manager_find_child_property ()

    GParamSpec *        clutter_layout_manager_find_child_property
                                                            (ClutterLayoutManager *manager,
                                                             const gchar *name);

Retrieves the GParamSpec for the layout property `name` inside the ClutterLayoutMeta sub-class used by `manager`

`manager` : | a ClutterLayoutManager
`name` : | the name of the property
Returns : | a GParamSpec describing the property, or `NULL` if no property with that name exists. The returned GParamSpec is owned by the layout manager and should not be modified or freed. [transfer none]

Since 1.2

### clutter_layout_manager_list_child_properties ()

    GParamSpec **       clutter_layout_manager_list_child_properties
                                                            (ClutterLayoutManager *manager,
                                                             guint *n_pspecs);

Retrieves all the GParamSpecs for the layout properties stored inside the ClutterLayoutMeta sub-class used by `manager`

`manager` : | a ClutterLayoutManager
`n_pspecs` : | return location for the number of returned GParamSpecs. [out]
Returns : | the newly-allocated, `NULL`-terminated array of GParamSpecs. Use `g_free()` to free the resources allocated for the array. [transfer full][array length=n_pspecs]

Since 1.2

### clutter_layout_manager_begin_animation ()

    ClutterAlpha *      clutter_layout_manager_begin_animation
                                                            (ClutterLayoutManager *manager,
                                                             guint duration,
                                                             gulong mode);

Begins an animation of `duration` milliseconds, using the provided easing `mode`

The easing mode can be specified either as a ClutterAnimationMode or as a logical id returned by `clutter_alpha_register_func()`

The result of this function depends on the `manager` implementation

`manager` : | a ClutterLayoutManager
`duration` : | the duration of the animation, in milliseconds
`mode` : | the easing mode of the animation
Returns : | The ClutterAlpha created by the layout manager; the returned instance is owned by the layout manager and should not be unreferenced. [transfer none]

Since 1.2

### clutter_layout_manager_end_animation ()

    void                clutter_layout_manager_end_animation
                                                            (ClutterLayoutManager *manager);

Ends an animation started by `clutter_layout_manager_begin_animation()`

The result of this call depends on the `manager` implementation

`manager` : | a ClutterLayoutManager

Since 1.2

### clutter_layout_manager_get_animation_progress ()

    gdouble             clutter_layout_manager_get_animation_progress
                                                            (ClutterLayoutManager *manager);

Retrieves the progress of the animation, if one has been started by `clutter_layout_manager_begin_animation()`

The returned value has the same semantics of the "alpha" value

`manager` : | a ClutterLayoutManager
Returns : | the progress of the animation

Since 1.2

## Signal Details

### The `"layout-changed"` signal

    void                user_function                      (ClutterLayoutManager *manager,
                                                            gpointer              user_data)      : Run Last

The ::layout-changed signal is emitted each time a layout manager has been changed. Every ClutterActor using the `manager` instance as a layout manager should connect a handler to the ::layout-changed signal and queue a relayout on themselves:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    static void layout_changed (ClutterLayoutManager *manager,
                                ClutterActor         *self)
    {
      clutter_actor_queue_relayout (self);
    }
    ...
      self->manager = g_object_ref_sink (manager);
      g_signal_connect (self->manager, "layout-changed",
                        G_CALLBACK (layout_changed),
                        self);

Sub-classes of ClutterLayoutManager that implement a layout that can be controlled or changed using parameters should emit the ::layout-changed signal whenever one of the parameters changes, by using `clutter_layout_manager_layout_changed()`.

`manager` : | the ClutterLayoutManager that emitted the signal
`user_data` : | user data set when the signal handler was connected.

Since 1.2