ClutterLayoutManager

ClutterLayoutManager — Layout managers base class

Synopsis

                    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
               +----ClutterGridLayout
               +----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 ClutterActorClass.get_preferred_width() virtual function and clutter_layout_manager_get_preferred_height() inside the ClutterActorClass.get_preferred_height() virtual functions implementation. You should also call clutter_layout_manager_allocate() inside the implementation of the ClutterActorClass.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 a 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.

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: ClutterLayoutManagerClass.begin_animation(), ClutterLayoutManagerClass.get_animation_progress(), and ClutterLayoutManagerClass.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 ClutterLayoutManagerClass.begin_animation() and ClutterLayoutManagerClass.end_animation() to set up ad hoc state, and then chain up to the parent's implementation.

Example 1. 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 ClutterLayoutManagerClass.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 ClutterLayoutManagerClass.begin_animation() and the ClutterLayoutManagerClass.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);
  ClutterActor *child;

  for (child = clutter_actor_get_first_child (CLUTTER_ACTOR (container));
       child != NULL;
       child = clutter_actor_get_next_sibling (child))
    {
      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);
    }
}
    

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.

Layout Properties

If a 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 ClutterLayoutManagerClass.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 ClutterLayoutManagerClass.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.

Using ClutterLayoutManager with ClutterScript

ClutterLayoutManager instance can be created in the same way as other objects in ClutterScript; properties can be set using the common syntax.

Layout properties can be set on children of a container with a ClutterLayoutManager using the layout:: modifier on the property name, for instance:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
  "type" : "ClutterBox",
  "layout-manager" : { "type" : "ClutterTableLayout" },
  "children" : [
    {
      "type" : "ClutterTexture",
      "filename" : "image-00.png",

      "layout::row" : 0,
      "layout::column" : 0,
      "layout::x-align" : "left",
      "layout::y-align" : "center",
      "layout::x-expand" : true,
      "layout::y-expand" : true
    },
    {
      "type" : "ClutterTexture",
      "filename" : "image-01.png",

      "layout::row" : 0,
      "layout::column" : 1,
      "layout::x-align" : "right",
      "layout::y-align" : "center",
      "layout::x-expand" : true,
      "layout::y-expand" : true
    }
  ]
}

ClutterLayoutManager is available since Clutter 1.2

Details

ClutterLayoutManager

typedef struct _ClutterLayoutManager ClutterLayoutManager;

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

Since 1.2


struct ClutterLayoutManagerClass

struct ClutterLayoutManagerClass {
  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);

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

  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. This virtual function is deprecated, and it should not be overridden in newly written code.

get_animation_progress ()

virtual function; override to control the progress of the animation of a ClutterLayoutManager. This virtual function is deprecated, and it should not be overridden in newly written code.

end_animation ()

virtual function; override to end an animation started by clutter_layout_manager_begin_animation(). This virtual function is deprecated, and it should not be overriden in newly written code.

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

Warning

clutter_layout_manager_begin_animation is deprecated and should not be used in newly-written code. 1.12

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

Warning

clutter_layout_manager_end_animation is deprecated and should not be used in newly-written code. 1.12

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

Warning

clutter_layout_manager_get_animation_progress is deprecated and should not be used in newly-written code. 1.12

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