Blame clutter/clutter-container.c

Packit 31ecd5
/*
Packit 31ecd5
 * Clutter.
Packit 31ecd5
 *
Packit 31ecd5
 * An OpenGL based 'interactive canvas' library.
Packit 31ecd5
 *
Packit 31ecd5
 * Authored By Matthew Allum  <mallum@openedhand.com>
Packit 31ecd5
 *
Packit 31ecd5
 * Copyright (C) 2006 OpenedHand
Packit 31ecd5
 *
Packit 31ecd5
 * This library is free software; you can redistribute it and/or
Packit 31ecd5
 * modify it under the terms of the GNU Lesser General Public
Packit 31ecd5
 * License as published by the Free Software Foundation; either
Packit 31ecd5
 * version 2 of the License, or (at your option) any later version.
Packit 31ecd5
 *
Packit 31ecd5
 * This library is distributed in the hope that it will be useful,
Packit 31ecd5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 31ecd5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 31ecd5
 * Lesser General Public License for more details.
Packit 31ecd5
 *
Packit 31ecd5
 * You should have received a copy of the GNU Lesser General Public
Packit 31ecd5
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
Packit 31ecd5
 *
Packit 31ecd5
 *
Packit 31ecd5
 *
Packit 31ecd5
 * ClutterContainer: Generic actor container interface.
Packit 31ecd5
 * Author: Emmanuele Bassi <ebassi@openedhand.com>
Packit 31ecd5
 */
Packit 31ecd5
Packit 31ecd5
#ifdef HAVE_CONFIG_H
Packit 31ecd5
#include "config.h"
Packit 31ecd5
#endif
Packit 31ecd5
Packit 31ecd5
#include <stdarg.h>
Packit 31ecd5
#include <glib-object.h>
Packit 31ecd5
#include <gobject/gvaluecollector.h>
Packit 31ecd5
Packit 31ecd5
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
Packit 31ecd5
#include "deprecated/clutter-container.h"
Packit 31ecd5
Packit 31ecd5
#include "clutter-actor-private.h"
Packit 31ecd5
#include "clutter-child-meta.h"
Packit 31ecd5
#include "clutter-debug.h"
Packit 31ecd5
#include "clutter-main.h"
Packit 31ecd5
#include "clutter-marshal.h"
Packit 31ecd5
#include "clutter-private.h"
Packit 31ecd5
#include "clutter-enum-types.h"
Packit 31ecd5
Packit 31ecd5
#define CLUTTER_CONTAINER_WARN_NOT_IMPLEMENTED(container,vfunc) \
Packit 31ecd5
        G_STMT_START { \
Packit 31ecd5
          g_warning ("Container of type '%s' does not implement " \
Packit 31ecd5
                     "the required ClutterContainer::%s virtual " \
Packit 31ecd5
                     "function.",                                 \
Packit 31ecd5
                     G_OBJECT_TYPE_NAME ((container)),            \
Packit 31ecd5
                     (vfunc));                                    \
Packit 31ecd5
        } G_STMT_END
Packit 31ecd5
Packit 31ecd5
#define CLUTTER_CONTAINER_NOTE_NOT_IMPLEMENTED(container,vfunc) \
Packit 31ecd5
        G_STMT_START { \
Packit 31ecd5
          CLUTTER_NOTE (ACTOR, "Container of type '%s' does not "    \
Packit 31ecd5
                               "implement the ClutterContainer::%s " \
Packit 31ecd5
                               "virtual function.",                  \
Packit 31ecd5
                        G_OBJECT_TYPE_NAME ((container)),            \
Packit 31ecd5
                        (vfunc));                                    \
Packit 31ecd5
        } G_STMT_END
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * SECTION:clutter-container
Packit 31ecd5
 * @short_description: An interface for container actors
Packit 31ecd5
 *
Packit 31ecd5
 * #ClutterContainer is an interface implemented by #ClutterActor, and
Packit 31ecd5
 * it provides some common API for notifying when a child actor is added
Packit 31ecd5
 * or removed, as well as the infrastructure for accessing child properties
Packit 31ecd5
 * through #ClutterChildMeta.
Packit 31ecd5
 *
Packit 31ecd5
 * Until Clutter 1.10, the #ClutterContainer interface was also the public
Packit 31ecd5
 * API for implementing container actors; this part of the interface has
Packit 31ecd5
 * been deprecated: #ClutterContainer has a default implementation which
Packit 31ecd5
 * defers to #ClutterActor the child addition and removal, as well as the
Packit 31ecd5
 * iteration. See the documentation of #ClutterContainerIface for the list
Packit 31ecd5
 * of virtual functions that should be overridden.
Packit 31ecd5
 */
Packit 31ecd5
Packit 31ecd5
enum
Packit 31ecd5
{
Packit 31ecd5
  ACTOR_ADDED,
Packit 31ecd5
  ACTOR_REMOVED,
Packit 31ecd5
  CHILD_NOTIFY,
Packit 31ecd5
Packit 31ecd5
  LAST_SIGNAL
Packit 31ecd5
};
Packit 31ecd5
Packit 31ecd5
static guint container_signals[LAST_SIGNAL] = { 0, };
Packit 31ecd5
static GQuark quark_child_meta = 0;
Packit 31ecd5
Packit 31ecd5
static ClutterChildMeta *get_child_meta     (ClutterContainer *container,
Packit 31ecd5
                                             ClutterActor     *actor);
Packit 31ecd5
static void              create_child_meta  (ClutterContainer *container,
Packit 31ecd5
                                             ClutterActor     *actor);
Packit 31ecd5
static void              destroy_child_meta (ClutterContainer *container,
Packit 31ecd5
                                             ClutterActor     *actor);
Packit 31ecd5
static void              child_notify       (ClutterContainer *container,
Packit 31ecd5
                                             ClutterActor     *child,
Packit 31ecd5
                                             GParamSpec       *pspec);
Packit 31ecd5
Packit 31ecd5
typedef ClutterContainerIface   ClutterContainerInterface;
Packit 31ecd5
Packit 31ecd5
G_DEFINE_INTERFACE (ClutterContainer, clutter_container, G_TYPE_OBJECT);
Packit 31ecd5
Packit 31ecd5
static void
Packit 31ecd5
container_real_add (ClutterContainer *container,
Packit 31ecd5
                    ClutterActor     *actor)
Packit 31ecd5
{
Packit 31ecd5
  clutter_actor_add_child (CLUTTER_ACTOR (container), actor);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static void
Packit 31ecd5
container_real_remove (ClutterContainer *container,
Packit 31ecd5
                       ClutterActor     *actor)
Packit 31ecd5
{
Packit 31ecd5
  clutter_actor_remove_child (CLUTTER_ACTOR (container), actor);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
typedef struct {
Packit 31ecd5
  ClutterCallback callback;
Packit 31ecd5
  gpointer data;
Packit 31ecd5
} ForeachClosure;
Packit 31ecd5
Packit 31ecd5
static gboolean
Packit 31ecd5
foreach_cb (ClutterActor *actor,
Packit 31ecd5
            gpointer      data)
Packit 31ecd5
{
Packit 31ecd5
  ForeachClosure *clos = data;
Packit 31ecd5
Packit 31ecd5
  clos->callback (actor, clos->data);
Packit 31ecd5
Packit 31ecd5
  return TRUE;
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static void
Packit 31ecd5
container_real_foreach (ClutterContainer *container,
Packit 31ecd5
                        ClutterCallback   callback,
Packit 31ecd5
                        gpointer          user_data)
Packit 31ecd5
{
Packit 31ecd5
  ForeachClosure clos;
Packit 31ecd5
Packit 31ecd5
  clos.callback = callback;
Packit 31ecd5
  clos.data = user_data;
Packit 31ecd5
Packit 31ecd5
  _clutter_actor_foreach_child (CLUTTER_ACTOR (container),
Packit 31ecd5
                                foreach_cb,
Packit 31ecd5
                                &clos);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static void
Packit 31ecd5
container_real_raise (ClutterContainer *container,
Packit 31ecd5
                      ClutterActor     *child,
Packit 31ecd5
                      ClutterActor     *sibling)
Packit 31ecd5
{
Packit 31ecd5
  ClutterActor *self = CLUTTER_ACTOR (container);
Packit 31ecd5
Packit 31ecd5
  clutter_actor_set_child_above_sibling (self, child, sibling);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static void
Packit 31ecd5
container_real_lower (ClutterContainer *container,
Packit 31ecd5
                      ClutterActor     *child,
Packit 31ecd5
                      ClutterActor     *sibling)
Packit 31ecd5
{
Packit 31ecd5
  ClutterActor *self = CLUTTER_ACTOR (container);
Packit 31ecd5
Packit 31ecd5
  clutter_actor_set_child_below_sibling (self, child, sibling);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static void
Packit 31ecd5
container_real_sort_depth_order (ClutterContainer *container)
Packit 31ecd5
{
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static void
Packit 31ecd5
clutter_container_default_init (ClutterContainerInterface *iface)
Packit 31ecd5
{
Packit 31ecd5
  GType iface_type = G_TYPE_FROM_INTERFACE (iface);
Packit 31ecd5
Packit 31ecd5
  quark_child_meta =
Packit 31ecd5
    g_quark_from_static_string ("clutter-container-child-data");
Packit 31ecd5
Packit 31ecd5
  /**
Packit 31ecd5
   * ClutterContainer::actor-added:
Packit 31ecd5
   * @container: the actor which received the signal
Packit 31ecd5
   * @actor: the new child that has been added to @container
Packit 31ecd5
   *
Packit 31ecd5
   * The ::actor-added signal is emitted each time an actor
Packit 31ecd5
   * has been added to @container.
Packit 31ecd5
   *
Packit 31ecd5
   * Since: 0.4
Packit 31ecd5
   */
Packit 31ecd5
  container_signals[ACTOR_ADDED] =
Packit 31ecd5
    g_signal_new (I_("actor-added"),
Packit 31ecd5
                  iface_type,
Packit 31ecd5
                  G_SIGNAL_RUN_FIRST,
Packit 31ecd5
                  G_STRUCT_OFFSET (ClutterContainerIface, actor_added),
Packit 31ecd5
                  NULL, NULL,
Packit 31ecd5
                  _clutter_marshal_VOID__OBJECT,
Packit 31ecd5
                  G_TYPE_NONE, 1,
Packit 31ecd5
                  CLUTTER_TYPE_ACTOR);
Packit 31ecd5
  /**
Packit 31ecd5
   * ClutterContainer::actor-removed:
Packit 31ecd5
   * @container: the actor which received the signal
Packit 31ecd5
   * @actor: the child that has been removed from @container
Packit 31ecd5
   *
Packit 31ecd5
   * The ::actor-removed signal is emitted each time an actor
Packit 31ecd5
   * is removed from @container.
Packit 31ecd5
   *
Packit 31ecd5
   * Since: 0.4
Packit 31ecd5
   */
Packit 31ecd5
  container_signals[ACTOR_REMOVED] =
Packit 31ecd5
    g_signal_new (I_("actor-removed"),
Packit 31ecd5
                  iface_type,
Packit 31ecd5
                  G_SIGNAL_RUN_FIRST,
Packit 31ecd5
                  G_STRUCT_OFFSET (ClutterContainerIface, actor_removed),
Packit 31ecd5
                  NULL, NULL,
Packit 31ecd5
                  _clutter_marshal_VOID__OBJECT,
Packit 31ecd5
                  G_TYPE_NONE, 1,
Packit 31ecd5
                  CLUTTER_TYPE_ACTOR);
Packit 31ecd5
Packit 31ecd5
  /**
Packit 31ecd5
   * ClutterContainer::child-notify:
Packit 31ecd5
   * @container: the container which received the signal
Packit 31ecd5
   * @actor: the child that has had a property set
Packit 31ecd5
   * @pspec: (type GParamSpec): the #GParamSpec of the property set
Packit 31ecd5
   *
Packit 31ecd5
   * The ::child-notify signal is emitted each time a property is
Packit 31ecd5
   * being set through the clutter_container_child_set() and
Packit 31ecd5
   * clutter_container_child_set_property() calls.
Packit 31ecd5
   *
Packit 31ecd5
   * Since: 0.8
Packit 31ecd5
   */
Packit 31ecd5
  container_signals[CHILD_NOTIFY] =
Packit 31ecd5
    g_signal_new (I_("child-notify"),
Packit 31ecd5
                  iface_type,
Packit 31ecd5
                  G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED,
Packit 31ecd5
                  G_STRUCT_OFFSET (ClutterContainerIface, child_notify),
Packit 31ecd5
                  NULL, NULL,
Packit 31ecd5
                  _clutter_marshal_VOID__OBJECT_PARAM,
Packit 31ecd5
                  G_TYPE_NONE, 2,
Packit 31ecd5
                  CLUTTER_TYPE_ACTOR, G_TYPE_PARAM);
Packit 31ecd5
Packit 31ecd5
  iface->add = container_real_add;
Packit 31ecd5
  iface->remove = container_real_remove;
Packit 31ecd5
  iface->foreach = container_real_foreach;
Packit 31ecd5
  iface->raise = container_real_raise;
Packit 31ecd5
  iface->lower = container_real_lower;
Packit 31ecd5
  iface->sort_depth_order = container_real_sort_depth_order;
Packit 31ecd5
Packit 31ecd5
  iface->child_meta_type = G_TYPE_INVALID;
Packit 31ecd5
  iface->create_child_meta = create_child_meta;
Packit 31ecd5
  iface->destroy_child_meta = destroy_child_meta;
Packit 31ecd5
  iface->get_child_meta = get_child_meta;
Packit 31ecd5
  iface->child_notify = child_notify;
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static inline void
Packit 31ecd5
container_add_actor (ClutterContainer *container,
Packit 31ecd5
                     ClutterActor     *actor)
Packit 31ecd5
{
Packit 31ecd5
  ClutterActor *parent;
Packit 31ecd5
Packit 31ecd5
  parent = clutter_actor_get_parent (actor);
Packit 31ecd5
  if (G_UNLIKELY (parent != NULL))
Packit 31ecd5
    {
Packit 31ecd5
      g_warning ("Attempting to add actor of type '%s' to a "
Packit 31ecd5
		 "container of type '%s', but the actor has "
Packit 31ecd5
                 "already a parent of type '%s'.",
Packit 31ecd5
		 g_type_name (G_OBJECT_TYPE (actor)),
Packit 31ecd5
		 g_type_name (G_OBJECT_TYPE (container)),
Packit 31ecd5
		 g_type_name (G_OBJECT_TYPE (parent)));
Packit 31ecd5
      return;
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  clutter_container_create_child_meta (container, actor);
Packit 31ecd5
Packit 31ecd5
#ifdef CLUTTER_ENABLE_DEBUG
Packit 31ecd5
  if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
Packit 31ecd5
    {
Packit 31ecd5
      ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container);
Packit 31ecd5
Packit 31ecd5
      if (iface->add != container_real_add)
Packit 31ecd5
        _clutter_diagnostic_message ("The ClutterContainer::add() virtual "
Packit 31ecd5
                                     "function has been deprecated and it "
Packit 31ecd5
                                     "should not be overridden by newly "
Packit 31ecd5
                                     "written code");
Packit 31ecd5
    }
Packit 31ecd5
#endif /* CLUTTER_ENABLE_DEBUG */
Packit 31ecd5
Packit 31ecd5
  CLUTTER_CONTAINER_GET_IFACE (container)->add (container, actor);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static inline void
Packit 31ecd5
container_remove_actor (ClutterContainer *container,
Packit 31ecd5
                        ClutterActor     *actor)
Packit 31ecd5
{
Packit 31ecd5
  ClutterActor *parent;
Packit 31ecd5
Packit 31ecd5
  parent = clutter_actor_get_parent (actor);
Packit 31ecd5
  if (parent != CLUTTER_ACTOR (container))
Packit 31ecd5
    {
Packit 31ecd5
      g_warning ("Attempting to remove actor of type '%s' from "
Packit 31ecd5
		 "group of class '%s', but the container is not "
Packit 31ecd5
                 "the actor's parent.",
Packit 31ecd5
		 g_type_name (G_OBJECT_TYPE (actor)),
Packit 31ecd5
		 g_type_name (G_OBJECT_TYPE (container)));
Packit 31ecd5
      return;
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  clutter_container_destroy_child_meta (container, actor);
Packit 31ecd5
Packit 31ecd5
#ifdef CLUTTER_ENABLE_DEBUG
Packit 31ecd5
  if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
Packit 31ecd5
    {
Packit 31ecd5
      ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container);
Packit 31ecd5
Packit 31ecd5
      if (iface->remove != container_real_remove)
Packit 31ecd5
        _clutter_diagnostic_message ("The ClutterContainer::remove() virtual "
Packit 31ecd5
                                     "function has been deprecated and it "
Packit 31ecd5
                                     "should not be overridden by newly "
Packit 31ecd5
                                     "written code");
Packit 31ecd5
    }
Packit 31ecd5
#endif /* CLUTTER_ENABLE_DEBUG */
Packit 31ecd5
Packit 31ecd5
  CLUTTER_CONTAINER_GET_IFACE (container)->remove (container, actor);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static inline void
Packit 31ecd5
container_add_valist (ClutterContainer *container,
Packit 31ecd5
                      ClutterActor     *first_actor,
Packit 31ecd5
                      va_list           args)
Packit 31ecd5
{
Packit 31ecd5
  ClutterActor *actor = first_actor;
Packit 31ecd5
Packit 31ecd5
  while (actor != NULL)
Packit 31ecd5
    {
Packit 31ecd5
      container_add_actor (container, actor);
Packit 31ecd5
      actor = va_arg (args, ClutterActor *);
Packit 31ecd5
    }
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static inline void
Packit 31ecd5
container_remove_valist (ClutterContainer *container,
Packit 31ecd5
                         ClutterActor     *first_actor,
Packit 31ecd5
                         va_list           args)
Packit 31ecd5
{
Packit 31ecd5
  ClutterActor *actor = first_actor;
Packit 31ecd5
Packit 31ecd5
  while (actor != NULL)
Packit 31ecd5
    {
Packit 31ecd5
      container_remove_actor (container, actor);
Packit 31ecd5
      actor = va_arg (args, ClutterActor *);
Packit 31ecd5
    }
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_add: (skip)
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @first_actor: the first #ClutterActor to add
Packit 31ecd5
 * @...: %NULL terminated list of actors to add
Packit 31ecd5
 *
Packit 31ecd5
 * Adds a list of #ClutterActors to @container. Each time and
Packit 31ecd5
 * actor is added, the "actor-added" signal is emitted. Each actor should
Packit 31ecd5
 * be parented to @container, which takes a reference on the actor. You
Packit 31ecd5
 * cannot add a #ClutterActor to more than one #ClutterContainer.
Packit 31ecd5
 *
Packit 31ecd5
 * This function will call #ClutterContainerIface.add(), which is a
Packit 31ecd5
 * deprecated virtual function. The default implementation will
Packit 31ecd5
 * call clutter_actor_add_child().
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.4
Packit 31ecd5
 *
Packit 31ecd5
 * Deprecated: 1.10: Use clutter_actor_add_child() instead.
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_add (ClutterContainer *container,
Packit 31ecd5
                       ClutterActor     *first_actor,
Packit 31ecd5
                       ...)
Packit 31ecd5
{
Packit 31ecd5
  va_list args;
Packit 31ecd5
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (first_actor));
Packit 31ecd5
Packit 31ecd5
  va_start (args, first_actor);
Packit 31ecd5
  container_add_valist (container, first_actor, args);
Packit 31ecd5
  va_end (args);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_add_actor: (virtual add)
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @actor: the first #ClutterActor to add
Packit 31ecd5
 *
Packit 31ecd5
 * Adds a #ClutterActor to @container. This function will emit the
Packit 31ecd5
 * "actor-added" signal. The actor should be parented to
Packit 31ecd5
 * @container. You cannot add a #ClutterActor to more than one
Packit 31ecd5
 * #ClutterContainer.
Packit 31ecd5
 *
Packit 31ecd5
 * This function will call #ClutterContainerIface.add(), which is a
Packit 31ecd5
 * deprecated virtual function. The default implementation will
Packit 31ecd5
 * call clutter_actor_add_child().
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.4
Packit 31ecd5
 *
Packit 31ecd5
 * Deprecated: 1.10: Use clutter_actor_add_child() instead.
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_add_actor (ClutterContainer *container,
Packit 31ecd5
                             ClutterActor     *actor)
Packit 31ecd5
{
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (actor));
Packit 31ecd5
Packit 31ecd5
  container_add_actor (container, actor);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_add_valist: (skip)
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @first_actor: the first #ClutterActor to add
Packit 31ecd5
 * @var_args: list of actors to add, followed by %NULL
Packit 31ecd5
 *
Packit 31ecd5
 * Alternative va_list version of clutter_container_add().
Packit 31ecd5
 *
Packit 31ecd5
 * This function will call #ClutterContainerIface.add(), which is a
Packit 31ecd5
 * deprecated virtual function. The default implementation will
Packit 31ecd5
 * call clutter_actor_add_child().
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.4
Packit 31ecd5
 *
Packit 31ecd5
 * Deprecated: 1.10: Use clutter_actor_add_child() instead.
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_add_valist (ClutterContainer *container,
Packit 31ecd5
                              ClutterActor     *first_actor,
Packit 31ecd5
                              va_list           var_args)
Packit 31ecd5
{
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (first_actor));
Packit 31ecd5
Packit 31ecd5
  container_add_valist (container, first_actor, var_args);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_remove: (skip)
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @first_actor: first #ClutterActor to remove
Packit 31ecd5
 * @...: a %NULL-terminated list of actors to remove
Packit 31ecd5
 *
Packit 31ecd5
 * Removes a %NULL terminated list of #ClutterActors from
Packit 31ecd5
 * @container. Each actor should be unparented, so if you want to keep it
Packit 31ecd5
 * around you must hold a reference to it yourself, using g_object_ref().
Packit 31ecd5
 * Each time an actor is removed, the "actor-removed" signal is
Packit 31ecd5
 * emitted by @container.
Packit 31ecd5
 *
Packit 31ecd5
 * This function will call #ClutterContainerIface.remove(), which is a
Packit 31ecd5
 * deprecated virtual function. The default implementation will call
Packit 31ecd5
 * clutter_actor_remove_child().
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.4
Packit 31ecd5
 *
Packit 31ecd5
 * Deprecated: 1.10: Use clutter_actor_remove_child() instead.
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_remove (ClutterContainer *container,
Packit 31ecd5
                          ClutterActor     *first_actor,
Packit 31ecd5
                          ...)
Packit 31ecd5
{
Packit 31ecd5
  va_list var_args;
Packit 31ecd5
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (first_actor));
Packit 31ecd5
Packit 31ecd5
  va_start (var_args, first_actor);
Packit 31ecd5
  container_remove_valist (container, first_actor, var_args);
Packit 31ecd5
  va_end (var_args);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_remove_actor: (virtual remove)
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @actor: a #ClutterActor
Packit 31ecd5
 *
Packit 31ecd5
 * Removes @actor from @container. The actor should be unparented, so
Packit 31ecd5
 * if you want to keep it around you must hold a reference to it
Packit 31ecd5
 * yourself, using g_object_ref(). When the actor has been removed,
Packit 31ecd5
 * the "actor-removed" signal is emitted by @container.
Packit 31ecd5
 *
Packit 31ecd5
 * This function will call #ClutterContainerIface.remove(), which is a
Packit 31ecd5
 * deprecated virtual function. The default implementation will call
Packit 31ecd5
 * clutter_actor_remove_child().
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.4
Packit 31ecd5
 *
Packit 31ecd5
 * Deprecated: 1.10: Use clutter_actor_remove_child() instead.
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_remove_actor (ClutterContainer *container,
Packit 31ecd5
                                ClutterActor     *actor)
Packit 31ecd5
{
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (actor));
Packit 31ecd5
Packit 31ecd5
  container_remove_actor (container, actor);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_remove_valist: (skip)
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @first_actor: the first #ClutterActor to add
Packit 31ecd5
 * @var_args: list of actors to remove, followed by %NULL
Packit 31ecd5
 *
Packit 31ecd5
 * Alternative va_list version of clutter_container_remove().
Packit 31ecd5
 *
Packit 31ecd5
 * This function will call #ClutterContainerIface.remove(), which is a
Packit 31ecd5
 * deprecated virtual function. The default implementation will call
Packit 31ecd5
 * clutter_actor_remove_child().
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.4
Packit 31ecd5
 *
Packit 31ecd5
 * Deprecated: 1.10: Use clutter_actor_remove_child() instead.
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_remove_valist (ClutterContainer *container,
Packit 31ecd5
                                 ClutterActor     *first_actor,
Packit 31ecd5
                                 va_list           var_args)
Packit 31ecd5
{
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (first_actor));
Packit 31ecd5
Packit 31ecd5
  container_remove_valist (container, first_actor, var_args);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static void
Packit 31ecd5
get_children_cb (ClutterActor *child,
Packit 31ecd5
                 gpointer      data)
Packit 31ecd5
{
Packit 31ecd5
  GList **children = data;
Packit 31ecd5
Packit 31ecd5
  *children = g_list_prepend (*children, child);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_get_children:
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 *
Packit 31ecd5
 * Retrieves all the children of @container.
Packit 31ecd5
 *
Packit 31ecd5
 * Return value: (element-type Clutter.Actor) (transfer container): a list
Packit 31ecd5
 *   of #ClutterActors. Use g_list_free() on the returned
Packit 31ecd5
 *   list when done.
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.4
Packit 31ecd5
 *
Packit 31ecd5
 * Deprecated: 1.10: Use clutter_actor_get_children() instead.
Packit 31ecd5
 */
Packit 31ecd5
GList *
Packit 31ecd5
clutter_container_get_children (ClutterContainer *container)
Packit 31ecd5
{
Packit 31ecd5
  GList *retval;
Packit 31ecd5
Packit 31ecd5
  g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL);
Packit 31ecd5
Packit 31ecd5
  retval = NULL;
Packit 31ecd5
  clutter_container_foreach (container, get_children_cb, &retval);
Packit 31ecd5
Packit 31ecd5
  return g_list_reverse (retval);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_foreach:
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @callback: (scope call): a function to be called for each child
Packit 31ecd5
 * @user_data: data to be passed to the function, or %NULL
Packit 31ecd5
 *
Packit 31ecd5
 * Calls @callback for each child of @container that was added
Packit 31ecd5
 * by the application (with clutter_container_add_actor()). Does
Packit 31ecd5
 * not iterate over "internal" children that are part of the
Packit 31ecd5
 * container's own implementation, if any.
Packit 31ecd5
 *
Packit 31ecd5
 * This function calls the #ClutterContainerIface.foreach()
Packit 31ecd5
 * virtual function, which has been deprecated.
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.4
Packit 31ecd5
 *
Packit 31ecd5
 * Deprecated: 1.10: Use clutter_actor_get_first_child() or
Packit 31ecd5
 *   clutter_actor_get_last_child() to retrieve the beginning of
Packit 31ecd5
 *   the list of children, and clutter_actor_get_next_sibling()
Packit 31ecd5
 *   and clutter_actor_get_previous_sibling() to iterate over it;
Packit 31ecd5
 *   alternatively, use the #ClutterActorIter API.
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_foreach (ClutterContainer *container,
Packit 31ecd5
                           ClutterCallback   callback,
Packit 31ecd5
                           gpointer          user_data)
Packit 31ecd5
{
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (callback != NULL);
Packit 31ecd5
Packit 31ecd5
#ifdef CLUTTER_ENABLE_DEBUG
Packit 31ecd5
  if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
Packit 31ecd5
    {
Packit 31ecd5
      ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container);
Packit 31ecd5
Packit 31ecd5
      if (iface->foreach != container_real_foreach)
Packit 31ecd5
        _clutter_diagnostic_message ("The ClutterContainer::foreach() "
Packit 31ecd5
                                     "virtual function has been deprecated "
Packit 31ecd5
                                     "and it should not be overridden by "
Packit 31ecd5
                                     "newly written code");
Packit 31ecd5
    }
Packit 31ecd5
#endif /* CLUTTER_ENABLE_DEBUG */
Packit 31ecd5
Packit 31ecd5
  CLUTTER_CONTAINER_GET_IFACE (container)->foreach (container,
Packit 31ecd5
                                                    callback,
Packit 31ecd5
                                                    user_data);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_foreach_with_internals:
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @callback: (scope call): a function to be called for each child
Packit 31ecd5
 * @user_data: data to be passed to the function, or %NULL
Packit 31ecd5
 *
Packit 31ecd5
 * Calls @callback for each child of @container, including "internal"
Packit 31ecd5
 * children built in to the container itself that were never added
Packit 31ecd5
 * by the application.
Packit 31ecd5
 *
Packit 31ecd5
 * This function calls the #ClutterContainerIface.foreach_with_internals()
Packit 31ecd5
 * virtual function, which has been deprecated.
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 1.0
Packit 31ecd5
 *
Packit 31ecd5
 * Deprecated: 1.10: See clutter_container_foreach().
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_foreach_with_internals (ClutterContainer *container,
Packit 31ecd5
                                          ClutterCallback   callback,
Packit 31ecd5
                                          gpointer          user_data)
Packit 31ecd5
{
Packit 31ecd5
  ClutterContainerIface *iface;
Packit 31ecd5
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (callback != NULL);
Packit 31ecd5
Packit 31ecd5
  iface = CLUTTER_CONTAINER_GET_IFACE (container);
Packit 31ecd5
Packit 31ecd5
#ifdef CLUTTER_ENABLE_DEBUG
Packit 31ecd5
  if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
Packit 31ecd5
    {
Packit 31ecd5
      if (iface->foreach_with_internals != NULL)
Packit 31ecd5
        _clutter_diagnostic_message ("The ClutterContainer::foreach_with_internals() "
Packit 31ecd5
                                     "virtual function has been deprecated "
Packit 31ecd5
                                     "and it should not be overridden by "
Packit 31ecd5
                                     "newly written code");
Packit 31ecd5
    }
Packit 31ecd5
#endif /* CLUTTER_ENABLE_DEBUG */
Packit 31ecd5
Packit 31ecd5
  if (iface->foreach_with_internals != NULL)
Packit 31ecd5
    iface->foreach_with_internals (container, callback, user_data);
Packit 31ecd5
  else
Packit 31ecd5
    iface->foreach (container, callback, user_data);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_raise_child: (virtual raise)
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @actor: the actor to raise
Packit 31ecd5
 * @sibling: (allow-none): the sibling to raise to, or %NULL to raise
Packit 31ecd5
 *   to the top
Packit 31ecd5
 *
Packit 31ecd5
 * Raises @actor to @sibling level, in the depth ordering.
Packit 31ecd5
 *
Packit 31ecd5
 * This function calls the #ClutterContainerIface.raise() virtual function,
Packit 31ecd5
 * which has been deprecated. The default implementation will call
Packit 31ecd5
 * clutter_actor_set_child_above_sibling().
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.6
Packit 31ecd5
 *
Packit 31ecd5
 * Deprecated: 1.10: Use clutter_actor_set_child_above_sibling() instead.
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_raise_child (ClutterContainer *container,
Packit 31ecd5
                               ClutterActor     *actor,
Packit 31ecd5
                               ClutterActor     *sibling)
Packit 31ecd5
{
Packit 31ecd5
  ClutterContainerIface *iface;
Packit 31ecd5
  ClutterActor *self;
Packit 31ecd5
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (actor));
Packit 31ecd5
  g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling));
Packit 31ecd5
Packit 31ecd5
  if (actor == sibling)
Packit 31ecd5
    return;
Packit 31ecd5
Packit 31ecd5
  self = CLUTTER_ACTOR (container);
Packit 31ecd5
Packit 31ecd5
  if (clutter_actor_get_parent (actor) != self)
Packit 31ecd5
    {
Packit 31ecd5
      g_warning ("Actor of type '%s' is not a child of the container "
Packit 31ecd5
                 "of type '%s'",
Packit 31ecd5
                 g_type_name (G_OBJECT_TYPE (actor)),
Packit 31ecd5
                 g_type_name (G_OBJECT_TYPE (container)));
Packit 31ecd5
      return;
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  if (sibling != NULL &&
Packit 31ecd5
      clutter_actor_get_parent (sibling) != self)
Packit 31ecd5
    {
Packit 31ecd5
      g_warning ("Actor of type '%s' is not a child of the container "
Packit 31ecd5
                 "of type '%s'",
Packit 31ecd5
                 g_type_name (G_OBJECT_TYPE (sibling)),
Packit 31ecd5
                 g_type_name (G_OBJECT_TYPE (container)));
Packit 31ecd5
      return;
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  iface = CLUTTER_CONTAINER_GET_IFACE (container);
Packit 31ecd5
Packit 31ecd5
#ifdef CLUTTER_ENABLE_DEBUG
Packit 31ecd5
  if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
Packit 31ecd5
    {
Packit 31ecd5
      if (iface->raise != container_real_raise)
Packit 31ecd5
        _clutter_diagnostic_message ("The ClutterContainer::raise() "
Packit 31ecd5
                                     "virtual function has been deprecated "
Packit 31ecd5
                                     "and it should not be overridden by "
Packit 31ecd5
                                     "newly written code");
Packit 31ecd5
    }
Packit 31ecd5
#endif /* CLUTTER_ENABLE_DEBUG */
Packit 31ecd5
Packit 31ecd5
  iface->raise (container, actor, sibling);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_lower_child: (virtual lower)
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @actor: the actor to raise
Packit 31ecd5
 * @sibling: (allow-none): the sibling to lower to, or %NULL to lower
Packit 31ecd5
 *   to the bottom
Packit 31ecd5
 *
Packit 31ecd5
 * Lowers @actor to @sibling level, in the depth ordering.
Packit 31ecd5
 *
Packit 31ecd5
 * This function calls the #ClutterContainerIface.lower() virtual function,
Packit 31ecd5
 * which has been deprecated. The default implementation will call
Packit 31ecd5
 * clutter_actor_set_child_below_sibling().
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.6
Packit 31ecd5
 *
Packit 31ecd5
 * Deprecated: 1.10: Use clutter_actor_set_child_below_sibling() instead.
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_lower_child (ClutterContainer *container,
Packit 31ecd5
                               ClutterActor     *actor,
Packit 31ecd5
                               ClutterActor     *sibling)
Packit 31ecd5
{
Packit 31ecd5
  ClutterContainerIface *iface;
Packit 31ecd5
  ClutterActor *self;
Packit 31ecd5
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (actor));
Packit 31ecd5
  g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling));
Packit 31ecd5
Packit 31ecd5
  if (actor == sibling)
Packit 31ecd5
    return;
Packit 31ecd5
Packit 31ecd5
  self = CLUTTER_ACTOR (container);
Packit 31ecd5
Packit 31ecd5
  if (clutter_actor_get_parent (actor) != self)
Packit 31ecd5
    {
Packit 31ecd5
      g_warning ("Actor of type '%s' is not a child of the container "
Packit 31ecd5
                 "of type '%s'",
Packit 31ecd5
                 g_type_name (G_OBJECT_TYPE (actor)),
Packit 31ecd5
                 g_type_name (G_OBJECT_TYPE (container)));
Packit 31ecd5
      return;
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  if (sibling != NULL&&
Packit 31ecd5
      clutter_actor_get_parent (sibling) != self)
Packit 31ecd5
    {
Packit 31ecd5
      g_warning ("Actor of type '%s' is not a child of the container "
Packit 31ecd5
                 "of type '%s'",
Packit 31ecd5
                 g_type_name (G_OBJECT_TYPE (sibling)),
Packit 31ecd5
                 g_type_name (G_OBJECT_TYPE (container)));
Packit 31ecd5
      return;
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  iface = CLUTTER_CONTAINER_GET_IFACE (container);
Packit 31ecd5
Packit 31ecd5
#ifdef CLUTTER_ENABLE_DEBUG
Packit 31ecd5
  if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
Packit 31ecd5
    {
Packit 31ecd5
      if (iface->lower != container_real_lower)
Packit 31ecd5
        _clutter_diagnostic_message ("The ClutterContainer::lower() "
Packit 31ecd5
                                     "virtual function has been deprecated "
Packit 31ecd5
                                     "and it should not be overridden by "
Packit 31ecd5
                                     "newly written code");
Packit 31ecd5
    }
Packit 31ecd5
#endif /* CLUTTER_ENABLE_DEBUG */
Packit 31ecd5
Packit 31ecd5
  iface->lower (container, actor, sibling);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_sort_depth_order:
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 *
Packit 31ecd5
 * Sorts a container's children using their depth. This function should not
Packit 31ecd5
 * be normally used by applications.
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.6
Packit 31ecd5
 *
Packit 31ecd5
 * Deprecated: 1.10: The #ClutterContainerIface.sort_depth_order() virtual
Packit 31ecd5
 *   function should not be used any more; the default implementation in
Packit 31ecd5
 *   #ClutterContainer does not do anything.
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_sort_depth_order (ClutterContainer *container)
Packit 31ecd5
{
Packit 31ecd5
  ClutterContainerIface *iface;
Packit 31ecd5
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
Packit 31ecd5
  iface = CLUTTER_CONTAINER_GET_IFACE (container);
Packit 31ecd5
Packit 31ecd5
#ifdef CLUTTER_ENABLE_DEBUG
Packit 31ecd5
  if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
Packit 31ecd5
    {
Packit 31ecd5
      if (iface->sort_depth_order != container_real_sort_depth_order)
Packit 31ecd5
        _clutter_diagnostic_message ("The ClutterContainer::sort_depth_order() "
Packit 31ecd5
                                     "virtual function has been deprecated "
Packit 31ecd5
                                     "and it should not be overridden by "
Packit 31ecd5
                                     "newly written code");
Packit 31ecd5
    }
Packit 31ecd5
#endif /* CLUTTER_ENABLE_DEBUG */
Packit 31ecd5
Packit 31ecd5
  iface->sort_depth_order (container);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_find_child_by_name:
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @child_name: the name of the requested child.
Packit 31ecd5
 *
Packit 31ecd5
 * Finds a child actor of a container by its name. Search recurses
Packit 31ecd5
 * into any child container.
Packit 31ecd5
 *
Packit 31ecd5
 * Return value: (transfer none): The child actor with the requested name,
Packit 31ecd5
 *   or %NULL if no actor with that name was found.
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.6
Packit 31ecd5
 */
Packit 31ecd5
ClutterActor *
Packit 31ecd5
clutter_container_find_child_by_name (ClutterContainer *container,
Packit 31ecd5
                                      const gchar      *child_name)
Packit 31ecd5
{
Packit 31ecd5
  GList        *children;
Packit 31ecd5
  GList        *iter;
Packit 31ecd5
  ClutterActor *actor = NULL;
Packit 31ecd5
Packit 31ecd5
  g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL);
Packit 31ecd5
  g_return_val_if_fail (child_name != NULL, NULL);
Packit 31ecd5
Packit 31ecd5
  children = clutter_container_get_children (container);
Packit 31ecd5
Packit 31ecd5
  for (iter = children; iter; iter = g_list_next (iter))
Packit 31ecd5
    {
Packit 31ecd5
      ClutterActor *a;
Packit 31ecd5
      const gchar  *iter_name;
Packit 31ecd5
Packit 31ecd5
      a = CLUTTER_ACTOR (iter->data);
Packit 31ecd5
      iter_name = clutter_actor_get_name (a);
Packit 31ecd5
Packit 31ecd5
      if (iter_name && !strcmp (iter_name, child_name))
Packit 31ecd5
        {
Packit 31ecd5
          actor = a;
Packit 31ecd5
          break;
Packit 31ecd5
        }
Packit 31ecd5
Packit 31ecd5
      if (CLUTTER_IS_CONTAINER (a))
Packit 31ecd5
        {
Packit 31ecd5
          ClutterContainer *c = CLUTTER_CONTAINER (a);
Packit 31ecd5
Packit 31ecd5
          actor = clutter_container_find_child_by_name (c, child_name);
Packit 31ecd5
          if (actor)
Packit 31ecd5
            break;
Packit 31ecd5
	}
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  g_list_free (children);
Packit 31ecd5
Packit 31ecd5
  return actor;
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static ClutterChildMeta *
Packit 31ecd5
get_child_meta (ClutterContainer *container,
Packit 31ecd5
                ClutterActor     *actor)
Packit 31ecd5
{
Packit 31ecd5
  ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container);
Packit 31ecd5
  ClutterChildMeta *meta;
Packit 31ecd5
Packit 31ecd5
  if (iface->child_meta_type == G_TYPE_INVALID)
Packit 31ecd5
    return NULL;
Packit 31ecd5
Packit 31ecd5
  meta = g_object_get_qdata (G_OBJECT (actor), quark_child_meta);
Packit 31ecd5
  if (meta != NULL && meta->actor == actor)
Packit 31ecd5
    return meta;
Packit 31ecd5
Packit 31ecd5
  return NULL;
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static void
Packit 31ecd5
create_child_meta (ClutterContainer *container,
Packit 31ecd5
                   ClutterActor     *actor)
Packit 31ecd5
{
Packit 31ecd5
  ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container);
Packit 31ecd5
  ClutterChildMeta *child_meta = NULL;
Packit 31ecd5
Packit 31ecd5
  if (iface->child_meta_type == G_TYPE_INVALID)
Packit 31ecd5
    return;
Packit 31ecd5
Packit 31ecd5
  if (!g_type_is_a (iface->child_meta_type, CLUTTER_TYPE_CHILD_META))
Packit 31ecd5
    {
Packit 31ecd5
      g_warning ("%s: Child data of type '%s' is not a ClutterChildMeta",
Packit 31ecd5
                 G_STRLOC, g_type_name (iface->child_meta_type));
Packit 31ecd5
      return;
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  child_meta = g_object_new (iface->child_meta_type,
Packit 31ecd5
                             "container", container,
Packit 31ecd5
                             "actor", actor,
Packit 31ecd5
                             NULL);
Packit 31ecd5
Packit 31ecd5
  g_object_set_qdata_full (G_OBJECT (actor), quark_child_meta,
Packit 31ecd5
                           child_meta,
Packit 31ecd5
                           (GDestroyNotify) g_object_unref);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static void
Packit 31ecd5
destroy_child_meta (ClutterContainer *container,
Packit 31ecd5
                    ClutterActor     *actor)
Packit 31ecd5
{
Packit 31ecd5
  ClutterContainerIface *iface  = CLUTTER_CONTAINER_GET_IFACE (container);
Packit 31ecd5
Packit 31ecd5
  if (iface->child_meta_type == G_TYPE_INVALID)
Packit 31ecd5
    return;
Packit 31ecd5
Packit 31ecd5
  g_object_set_qdata (G_OBJECT (actor), quark_child_meta, NULL);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_get_child_meta:
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @actor: a #ClutterActor that is a child of @container.
Packit 31ecd5
 *
Packit 31ecd5
 * Retrieves the #ClutterChildMeta which contains the data about the
Packit 31ecd5
 * @container specific state for @actor.
Packit 31ecd5
 *
Packit 31ecd5
 * Return value: (transfer none): the #ClutterChildMeta for the @actor child
Packit 31ecd5
 *   of @container or %NULL if the specifiec actor does not exist or the
Packit 31ecd5
 *   container is not configured to provide #ClutterChildMetas
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.8
Packit 31ecd5
 */
Packit 31ecd5
ClutterChildMeta *
Packit 31ecd5
clutter_container_get_child_meta (ClutterContainer *container,
Packit 31ecd5
                                  ClutterActor     *actor)
Packit 31ecd5
{
Packit 31ecd5
  ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container);
Packit 31ecd5
Packit 31ecd5
  if (iface->child_meta_type == G_TYPE_INVALID)
Packit 31ecd5
    return NULL;
Packit 31ecd5
Packit 31ecd5
  if (G_LIKELY (iface->get_child_meta))
Packit 31ecd5
    return iface->get_child_meta (container, actor);
Packit 31ecd5
Packit 31ecd5
  return NULL;
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_create_child_meta:
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @actor: a #ClutterActor
Packit 31ecd5
 *
Packit 31ecd5
 * Creates the #ClutterChildMeta wrapping @actor inside the
Packit 31ecd5
 * @container, if the #ClutterContainerIface::child_meta_type
Packit 31ecd5
 * class member is not set to %G_TYPE_INVALID.
Packit 31ecd5
 *
Packit 31ecd5
 * This function is only useful when adding a #ClutterActor to
Packit 31ecd5
 * a #ClutterContainer implementation outside of the
Packit 31ecd5
 * #ClutterContainer::add() virtual function implementation.
Packit 31ecd5
 *
Packit 31ecd5
 * Applications should not call this function.
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 1.2
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_create_child_meta (ClutterContainer *container,
Packit 31ecd5
                                     ClutterActor     *actor)
Packit 31ecd5
{
Packit 31ecd5
  ClutterContainerIface *iface;
Packit 31ecd5
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (actor));
Packit 31ecd5
Packit 31ecd5
  iface = CLUTTER_CONTAINER_GET_IFACE (container);
Packit 31ecd5
Packit 31ecd5
  if (iface->child_meta_type == G_TYPE_INVALID)
Packit 31ecd5
    return;
Packit 31ecd5
Packit 31ecd5
  g_assert (g_type_is_a (iface->child_meta_type, CLUTTER_TYPE_CHILD_META));
Packit 31ecd5
Packit 31ecd5
  if (G_LIKELY (iface->create_child_meta))
Packit 31ecd5
    iface->create_child_meta (container, actor);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_destroy_child_meta:
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @actor: a #ClutterActor
Packit 31ecd5
 *
Packit 31ecd5
 * Destroys the #ClutterChildMeta wrapping @actor inside the
Packit 31ecd5
 * @container, if any.
Packit 31ecd5
 *
Packit 31ecd5
 * This function is only useful when removing a #ClutterActor to
Packit 31ecd5
 * a #ClutterContainer implementation outside of the
Packit 31ecd5
 * #ClutterContainer::add() virtual function implementation.
Packit 31ecd5
 *
Packit 31ecd5
 * Applications should not call this function.
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 1.2
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_destroy_child_meta (ClutterContainer *container,
Packit 31ecd5
                                      ClutterActor     *actor)
Packit 31ecd5
{
Packit 31ecd5
  ClutterContainerIface *iface;
Packit 31ecd5
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (actor));
Packit 31ecd5
Packit 31ecd5
  iface = CLUTTER_CONTAINER_GET_IFACE (container);
Packit 31ecd5
Packit 31ecd5
  if (iface->child_meta_type == G_TYPE_INVALID)
Packit 31ecd5
    return;
Packit 31ecd5
Packit 31ecd5
  if (G_LIKELY (iface->destroy_child_meta))
Packit 31ecd5
    iface->destroy_child_meta (container, actor);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_class_find_child_property:
Packit 31ecd5
 * @klass: a #GObjectClass implementing the #ClutterContainer interface.
Packit 31ecd5
 * @property_name: a property name.
Packit 31ecd5
 *
Packit 31ecd5
 * Looks up the #GParamSpec for a child property of @klass.
Packit 31ecd5
 *
Packit 31ecd5
 * Return value: (transfer none): The #GParamSpec for the property or %NULL
Packit 31ecd5
 *   if no such property exist.
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.8
Packit 31ecd5
 */
Packit 31ecd5
GParamSpec *
Packit 31ecd5
clutter_container_class_find_child_property (GObjectClass *klass,
Packit 31ecd5
                                             const gchar  *property_name)
Packit 31ecd5
{
Packit 31ecd5
  ClutterContainerIface *iface;
Packit 31ecd5
  GObjectClass          *child_class;
Packit 31ecd5
  GParamSpec            *pspec;
Packit 31ecd5
Packit 31ecd5
  g_return_val_if_fail (G_IS_OBJECT_CLASS (klass), NULL);
Packit 31ecd5
  g_return_val_if_fail (property_name != NULL, NULL);
Packit 31ecd5
  g_return_val_if_fail (g_type_is_a (G_TYPE_FROM_CLASS (klass),
Packit 31ecd5
                                     CLUTTER_TYPE_CONTAINER),
Packit 31ecd5
                        NULL);
Packit 31ecd5
Packit 31ecd5
  iface = g_type_interface_peek (klass, CLUTTER_TYPE_CONTAINER);
Packit 31ecd5
  g_return_val_if_fail (iface != NULL, NULL);
Packit 31ecd5
Packit 31ecd5
  if (iface->child_meta_type == G_TYPE_INVALID)
Packit 31ecd5
    return NULL;
Packit 31ecd5
Packit 31ecd5
  child_class = g_type_class_ref (iface->child_meta_type);
Packit 31ecd5
  pspec = g_object_class_find_property (child_class, property_name);
Packit 31ecd5
  g_type_class_unref (child_class);
Packit 31ecd5
Packit 31ecd5
  return pspec;
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_class_list_child_properties:
Packit 31ecd5
 * @klass: a #GObjectClass implementing the #ClutterContainer interface.
Packit 31ecd5
 * @n_properties: return location for length of returned array.
Packit 31ecd5
 *
Packit 31ecd5
 * Returns an array of #GParamSpec for all child properties.
Packit 31ecd5
 *
Packit 31ecd5
 * Return value: (array length=n_properties) (transfer full): an array
Packit 31ecd5
 *   of #GParamSpecs which should be freed after use.
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.8
Packit 31ecd5
 */
Packit 31ecd5
GParamSpec **
Packit 31ecd5
clutter_container_class_list_child_properties (GObjectClass *klass,
Packit 31ecd5
                                               guint        *n_properties)
Packit 31ecd5
{
Packit 31ecd5
  ClutterContainerIface *iface;
Packit 31ecd5
  GObjectClass          *child_class;
Packit 31ecd5
  GParamSpec           **retval;
Packit 31ecd5
Packit 31ecd5
  g_return_val_if_fail (G_IS_OBJECT_CLASS (klass), NULL);
Packit 31ecd5
  g_return_val_if_fail (g_type_is_a (G_TYPE_FROM_CLASS (klass),
Packit 31ecd5
                                     CLUTTER_TYPE_CONTAINER),
Packit 31ecd5
                        NULL);
Packit 31ecd5
Packit 31ecd5
  iface = g_type_interface_peek (klass, CLUTTER_TYPE_CONTAINER);
Packit 31ecd5
  g_return_val_if_fail (iface != NULL, NULL);
Packit 31ecd5
Packit 31ecd5
  if (iface->child_meta_type == G_TYPE_INVALID)
Packit 31ecd5
    return NULL;
Packit 31ecd5
Packit 31ecd5
  child_class = g_type_class_ref (iface->child_meta_type);
Packit 31ecd5
  retval = g_object_class_list_properties (child_class, n_properties);
Packit 31ecd5
  g_type_class_unref (child_class);
Packit 31ecd5
Packit 31ecd5
  return retval;
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static void
Packit 31ecd5
child_notify (ClutterContainer *container,
Packit 31ecd5
              ClutterActor     *actor,
Packit 31ecd5
              GParamSpec       *pspec)
Packit 31ecd5
{
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static inline void
Packit 31ecd5
container_set_child_property (ClutterContainer *container,
Packit 31ecd5
                              ClutterActor     *actor,
Packit 31ecd5
                              const GValue     *value,
Packit 31ecd5
                              GParamSpec       *pspec)
Packit 31ecd5
{
Packit 31ecd5
  ClutterChildMeta *data;
Packit 31ecd5
Packit 31ecd5
  data = clutter_container_get_child_meta (container, actor);
Packit 31ecd5
  g_object_set_property (G_OBJECT (data), pspec->name, value);
Packit 31ecd5
Packit 31ecd5
  g_signal_emit (container, container_signals[CHILD_NOTIFY],
Packit 31ecd5
                 (pspec->flags & G_PARAM_STATIC_NAME)
Packit 31ecd5
                   ? g_quark_from_static_string (pspec->name)
Packit 31ecd5
                   : g_quark_from_string (pspec->name),
Packit 31ecd5
                 actor, pspec);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_child_set_property:
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @child: a #ClutterActor that is a child of @container.
Packit 31ecd5
 * @property: the name of the property to set.
Packit 31ecd5
 * @value: the value.
Packit 31ecd5
 *
Packit 31ecd5
 * Sets a container-specific property on a child of @container.
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.8
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_child_set_property (ClutterContainer *container,
Packit 31ecd5
                                      ClutterActor     *child,
Packit 31ecd5
                                      const gchar      *property,
Packit 31ecd5
                                      const GValue     *value)
Packit 31ecd5
{
Packit 31ecd5
  GObjectClass *klass;
Packit 31ecd5
  GParamSpec   *pspec;
Packit 31ecd5
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (child));
Packit 31ecd5
  g_return_if_fail (property != NULL);
Packit 31ecd5
  g_return_if_fail (value != NULL);
Packit 31ecd5
Packit 31ecd5
  klass = G_OBJECT_GET_CLASS (container);
Packit 31ecd5
Packit 31ecd5
  pspec = clutter_container_class_find_child_property (klass, property);
Packit 31ecd5
  if (!pspec)
Packit 31ecd5
    {
Packit 31ecd5
      g_warning ("%s: Containers of type '%s' have no child "
Packit 31ecd5
                 "property named '%s'",
Packit 31ecd5
                 G_STRLOC, G_OBJECT_TYPE_NAME (container), property);
Packit 31ecd5
      return;
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  if (!(pspec->flags & G_PARAM_WRITABLE))
Packit 31ecd5
    {
Packit 31ecd5
      g_warning ("%s: Child property '%s' of the container '%s' "
Packit 31ecd5
                 "is not writable",
Packit 31ecd5
                 G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (container));
Packit 31ecd5
      return;
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  container_set_child_property (container, child, value, pspec);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_child_set:
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @actor: a #ClutterActor that is a child of @container.
Packit 31ecd5
 * @first_prop: name of the first property to be set.
Packit 31ecd5
 * @...: value for the first property, followed optionally by more name/value
Packit 31ecd5
 * pairs terminated with NULL.
Packit 31ecd5
 *
Packit 31ecd5
 * Sets container specific properties on the child of a container.
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.8
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_child_set (ClutterContainer *container,
Packit 31ecd5
                             ClutterActor     *actor,
Packit 31ecd5
                             const gchar      *first_prop,
Packit 31ecd5
                             ...)
Packit 31ecd5
{
Packit 31ecd5
  GObjectClass *klass;
Packit 31ecd5
  const gchar *name;
Packit 31ecd5
  va_list var_args;
Packit 31ecd5
  
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (actor));
Packit 31ecd5
Packit 31ecd5
  klass = G_OBJECT_GET_CLASS (container);
Packit 31ecd5
Packit 31ecd5
  va_start (var_args, first_prop);
Packit 31ecd5
Packit 31ecd5
  name = first_prop;
Packit 31ecd5
  while (name)
Packit 31ecd5
    {
Packit 31ecd5
      GValue value = G_VALUE_INIT;
Packit 31ecd5
      gchar *error = NULL;
Packit 31ecd5
      GParamSpec *pspec;
Packit 31ecd5
    
Packit 31ecd5
      pspec = clutter_container_class_find_child_property (klass, name);
Packit 31ecd5
      if (!pspec)
Packit 31ecd5
        {
Packit 31ecd5
          g_warning ("%s: Containers of type '%s' have no child "
Packit 31ecd5
                     "property named '%s'",
Packit 31ecd5
                     G_STRLOC, G_OBJECT_TYPE_NAME (container), name);
Packit 31ecd5
          break;
Packit 31ecd5
        }
Packit 31ecd5
Packit 31ecd5
      if (!(pspec->flags & G_PARAM_WRITABLE))
Packit 31ecd5
        {
Packit 31ecd5
          g_warning ("%s: Child property '%s' of the container '%s' "
Packit 31ecd5
                     "is not writable",
Packit 31ecd5
                     G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (container));
Packit 31ecd5
          break;
Packit 31ecd5
        }
Packit 31ecd5
Packit 31ecd5
      G_VALUE_COLLECT_INIT (&value, G_PARAM_SPEC_VALUE_TYPE (pspec),
Packit 31ecd5
                            var_args, 0,
Packit 31ecd5
                            &error);
Packit 31ecd5
Packit 31ecd5
      if (error)
Packit 31ecd5
        {
Packit 31ecd5
          /* we intentionally leak the GValue because it might
Packit 31ecd5
           * be in an undefined state and calling g_value_unset()
Packit 31ecd5
           * on it might crash
Packit 31ecd5
           */
Packit 31ecd5
          g_warning ("%s: %s", G_STRLOC, error);
Packit 31ecd5
          g_free (error);
Packit 31ecd5
          break;
Packit 31ecd5
        }
Packit 31ecd5
Packit 31ecd5
      container_set_child_property (container, actor, &value, pspec);
Packit 31ecd5
Packit 31ecd5
      g_value_unset (&value);
Packit 31ecd5
Packit 31ecd5
      name = va_arg (var_args, gchar*);
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  va_end (var_args);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
static inline void
Packit 31ecd5
container_get_child_property (ClutterContainer *container,
Packit 31ecd5
                              ClutterActor     *actor,
Packit 31ecd5
                              GValue           *value,
Packit 31ecd5
                              GParamSpec       *pspec)
Packit 31ecd5
{
Packit 31ecd5
  ClutterChildMeta *data;
Packit 31ecd5
Packit 31ecd5
  data = clutter_container_get_child_meta (container, actor);
Packit 31ecd5
  g_object_get_property (G_OBJECT (data), pspec->name, value);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_child_get_property:
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @child: a #ClutterActor that is a child of @container.
Packit 31ecd5
 * @property: the name of the property to set.
Packit 31ecd5
 * @value: the value.
Packit 31ecd5
 *
Packit 31ecd5
 * Gets a container specific property of a child of @container, In general,
Packit 31ecd5
 * a copy is made of the property contents and the caller is responsible for
Packit 31ecd5
 * freeing the memory by calling g_value_unset().
Packit 31ecd5
 *
Packit 31ecd5
 * Note that clutter_container_child_set_property() is really intended for
Packit 31ecd5
 * language bindings, clutter_container_child_set() is much more convenient
Packit 31ecd5
 * for C programming.
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.8
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_child_get_property (ClutterContainer *container,
Packit 31ecd5
                                      ClutterActor     *child,
Packit 31ecd5
                                      const gchar      *property,
Packit 31ecd5
                                      GValue           *value)
Packit 31ecd5
{
Packit 31ecd5
  GObjectClass *klass;
Packit 31ecd5
  GParamSpec   *pspec;
Packit 31ecd5
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (child));
Packit 31ecd5
  g_return_if_fail (property != NULL);
Packit 31ecd5
  g_return_if_fail (value != NULL);
Packit 31ecd5
Packit 31ecd5
  klass = G_OBJECT_GET_CLASS (container);
Packit 31ecd5
Packit 31ecd5
  pspec = clutter_container_class_find_child_property (klass, property);
Packit 31ecd5
  if (!pspec)
Packit 31ecd5
    {
Packit 31ecd5
      g_warning ("%s: Containers of type '%s' have no child "
Packit 31ecd5
                 "property named '%s'",
Packit 31ecd5
                 G_STRLOC, G_OBJECT_TYPE_NAME (container), property);
Packit 31ecd5
      return;
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  if (!(pspec->flags & G_PARAM_READABLE))
Packit 31ecd5
    {
Packit 31ecd5
      g_warning ("%s: Child property '%s' of the container '%s' "
Packit 31ecd5
                 "is not writable",
Packit 31ecd5
                 G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (container));
Packit 31ecd5
      return;
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  container_get_child_property (container, child, value, pspec);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_child_get:
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @actor: a #ClutterActor that is a child of @container.
Packit 31ecd5
 * @first_prop: name of the first property to be set.
Packit 31ecd5
 * @...: value for the first property, followed optionally by more name/value
Packit 31ecd5
 * pairs terminated with NULL.
Packit 31ecd5
 *
Packit 31ecd5
 * Gets @container specific properties of an actor.
Packit 31ecd5
 *
Packit 31ecd5
 * In general, a copy is made of the property contents and the caller is
Packit 31ecd5
 * responsible for freeing the memory in the appropriate manner for the type, for
Packit 31ecd5
 * instance by calling g_free() or g_object_unref(). 
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 0.8
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_child_get (ClutterContainer *container,
Packit 31ecd5
                             ClutterActor     *actor,
Packit 31ecd5
                             const gchar      *first_prop,
Packit 31ecd5
                             ...)
Packit 31ecd5
{
Packit 31ecd5
  GObjectClass *klass;
Packit 31ecd5
  const gchar *name;
Packit 31ecd5
  va_list var_args;
Packit 31ecd5
  
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (actor));
Packit 31ecd5
Packit 31ecd5
  klass = G_OBJECT_GET_CLASS (container);
Packit 31ecd5
Packit 31ecd5
  va_start (var_args, first_prop);
Packit 31ecd5
Packit 31ecd5
  name = first_prop;
Packit 31ecd5
  while (name)
Packit 31ecd5
    {
Packit 31ecd5
      GValue value = G_VALUE_INIT;
Packit 31ecd5
      gchar *error = NULL;
Packit 31ecd5
      GParamSpec *pspec;
Packit 31ecd5
    
Packit 31ecd5
      pspec = clutter_container_class_find_child_property (klass, name);
Packit 31ecd5
      if (!pspec)
Packit 31ecd5
        {
Packit 31ecd5
          g_warning ("%s: container '%s' has no child property named '%s'",
Packit 31ecd5
                     G_STRLOC, G_OBJECT_TYPE_NAME (container), name);
Packit 31ecd5
          break;
Packit 31ecd5
        }
Packit 31ecd5
Packit 31ecd5
      if (!(pspec->flags & G_PARAM_READABLE))
Packit 31ecd5
        {
Packit 31ecd5
          g_warning ("%s: child property '%s' of container '%s' is not readable",
Packit 31ecd5
                     G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (container));
Packit 31ecd5
          break;
Packit 31ecd5
        }
Packit 31ecd5
Packit 31ecd5
      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
Packit 31ecd5
Packit 31ecd5
      container_get_child_property (container, actor, &value, pspec);
Packit 31ecd5
Packit 31ecd5
      G_VALUE_LCOPY (&value, var_args, 0, &error);
Packit 31ecd5
      if (error)
Packit 31ecd5
        {
Packit 31ecd5
          g_warning ("%s: %s", G_STRLOC, error);
Packit 31ecd5
          g_free (error);
Packit 31ecd5
          g_value_unset (&value);
Packit 31ecd5
          break;
Packit 31ecd5
        }
Packit 31ecd5
Packit 31ecd5
      g_value_unset (&value);
Packit 31ecd5
Packit 31ecd5
      name = va_arg (var_args, gchar*);
Packit 31ecd5
    }
Packit 31ecd5
Packit 31ecd5
  va_end (var_args);
Packit 31ecd5
}
Packit 31ecd5
Packit 31ecd5
/**
Packit 31ecd5
 * clutter_container_child_notify:
Packit 31ecd5
 * @container: a #ClutterContainer
Packit 31ecd5
 * @child: a #ClutterActor
Packit 31ecd5
 * @pspec: a #GParamSpec
Packit 31ecd5
 *
Packit 31ecd5
 * Calls the #ClutterContainerIface.child_notify() virtual function
Packit 31ecd5
 * of #ClutterContainer. The default implementation will emit the
Packit 31ecd5
 * #ClutterContainer::child-notify signal.
Packit 31ecd5
 *
Packit 31ecd5
 * Since: 1.6
Packit 31ecd5
 */
Packit 31ecd5
void
Packit 31ecd5
clutter_container_child_notify (ClutterContainer *container,
Packit 31ecd5
                                ClutterActor     *child,
Packit 31ecd5
                                GParamSpec       *pspec)
Packit 31ecd5
{
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_CONTAINER (container));
Packit 31ecd5
  g_return_if_fail (CLUTTER_IS_ACTOR (child));
Packit 31ecd5
  g_return_if_fail (pspec != NULL);
Packit 31ecd5
Packit 31ecd5
  g_return_if_fail (clutter_actor_get_parent (child) == CLUTTER_ACTOR (container));
Packit 31ecd5
Packit 31ecd5
  CLUTTER_CONTAINER_GET_IFACE (container)->child_notify (container,
Packit 31ecd5
                                                         child,
Packit 31ecd5
                                                         pspec);
Packit 31ecd5
}