static ClutterLayoutMeta *
layout_manager_real_create_child_meta (ClutterLayoutManager *manager,
                                       ClutterContainer     *container,
                                       ClutterActor         *actor)
{
    ClutterLayoutManagerClass *klass;
    GType meta_type;

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

    /* provide a default implementation to reduce common code */
    if (meta_type != G_TYPE_INVALID)
    {
        g_assert (g_type_is_a (meta_type, CLUTTER_TYPE_LAYOUT_META));

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

    return NULL;
}
/**
 * clutter_layout_manager_get_animation_progress:
 * @manager: a #ClutterLayoutManager
 *
 * 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 #ClutterAlpha:alpha
 * value
 *
 * Return value: the progress of the animation
 *
 * Since: 1.2
 */
gdouble
clutter_layout_manager_get_animation_progress (ClutterLayoutManager *manager)
{
    ClutterLayoutManagerClass *klass;

    g_return_val_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager), 1.0);

    klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);

    return klass->get_animation_progress (manager);
}
/**
 * clutter_layout_manager_set_container:
 * @manager: a #ClutterLayoutManager
 * @container: (allow-none): a #ClutterContainer using @manager
 *
 * 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
 *
 * Since: 1.2
 */
void
clutter_layout_manager_set_container (ClutterLayoutManager *manager,
                                      ClutterContainer     *container)
{
    ClutterLayoutManagerClass *klass;

    g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
    g_return_if_fail (container == NULL || CLUTTER_IS_CONTAINER (container));

    klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
    if (klass->set_container)
        klass->set_container (manager, container);
}
/**
 * clutter_layout_manager_begin_animation:
 * @manager: a #ClutterLayoutManager
 * @duration: the duration of the animation, in milliseconds
 * @mode: the easing mode of the animation
 *
 * 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
 *
 * Return value: (transfer none): The #ClutterAlpha created by the
 *   layout manager; the returned instance is owned by the layout
 *   manager and should not be unreferenced
 *
 * Since: 1.2
 */
ClutterAlpha *
clutter_layout_manager_begin_animation (ClutterLayoutManager *manager,
                                        guint                 duration,
                                        gulong                mode)
{
    ClutterLayoutManagerClass *klass;

    g_return_val_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager), NULL);

    klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);

    return klass->begin_animation (manager, duration, mode);
}
static inline ClutterLayoutMeta *
create_child_meta (ClutterLayoutManager *manager,
                   ClutterContainer     *container,
                   ClutterActor         *actor)
{
  ClutterLayoutManagerClass *klass;

  klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
  if (klass->get_child_meta_type (manager) != G_TYPE_INVALID)
    return klass->create_child_meta (manager, container, actor);

  return NULL;
}
/**
 * clutter_layout_manager_allocate:
 * @manager: a #ClutterLayoutManager
 * @container: the #ClutterContainer using @manager
 * @allocation: the #ClutterActorBox containing the allocated area
 *   of @container
 * @flags: the allocation flags
 *
 * Allocates the children of @container given an area
 *
 * See also clutter_actor_allocate()
 *
 * Since: 1.2
 */
void
clutter_layout_manager_allocate (ClutterLayoutManager   *manager,
                                 ClutterContainer       *container,
                                 const ClutterActorBox  *allocation,
                                 ClutterAllocationFlags  flags)
{
    ClutterLayoutManagerClass *klass;

    g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
    g_return_if_fail (CLUTTER_IS_CONTAINER (container));
    g_return_if_fail (allocation != NULL);

    klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
    klass->allocate (manager, container, allocation, flags);
}
/**
 * clutter_layout_manager_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: (out) (allow-none): return location for the minimum height
 *   of the layout, or %NULL
 * @nat_height_p: (out) (allow-none): return location for the natural height
 *   of the layout, or %NULL
 *
 * Computes the minimum and natural heights of the @container according
 * to @manager.
 *
 * See also clutter_actor_get_preferred_height()
 *
 * Since: 1.2
 */
void
clutter_layout_manager_get_preferred_height (ClutterLayoutManager *manager,
        ClutterContainer     *container,
        gfloat                for_width,
        gfloat               *min_height_p,
        gfloat               *nat_height_p)
{
    ClutterLayoutManagerClass *klass;

    g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
    g_return_if_fail (CLUTTER_IS_CONTAINER (container));

    klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
    klass->get_preferred_height (manager, container, for_width,
                                 min_height_p,
                                 nat_height_p);
}
static inline ClutterLayoutMeta *
create_child_meta (ClutterLayoutManager *manager,
                   ClutterContainer     *container,
                   ClutterActor         *actor)
{
    ClutterLayoutManagerClass *klass;
    ClutterLayoutMeta *meta = NULL;

    layout_manager_freeze_layout_change (manager);

    klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
    if (klass->get_child_meta_type (manager) != G_TYPE_INVALID)
        meta = klass->create_child_meta (manager, container, actor);

    layout_manager_thaw_layout_change (manager);

    return meta;
}
/**
 * clutter_layout_manager_find_child_property:
 * @manager: a #ClutterLayoutManager
 * @name: the name of the property
 *
 * Retrieves the #GParamSpec for the layout property @name inside
 * the #ClutterLayoutMeta sub-class used by @manager
 *
 * Return value: (transfer none): 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
 *
 * Since: 1.2
 */
GParamSpec *
clutter_layout_manager_find_child_property (ClutterLayoutManager *manager,
        const gchar          *name)
{
    ClutterLayoutManagerClass *klass;
    GObjectClass *meta_klass;
    GParamSpec *pspec;
    GType meta_type;

    klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
    meta_type = klass->get_child_meta_type (manager);
    if (meta_type == G_TYPE_INVALID)
        return NULL;

    meta_klass = g_type_class_ref (meta_type);

    pspec = g_object_class_find_property (meta_klass, name);

    g_type_class_unref (meta_klass);

    return pspec;
}