mirror of
https://github.com/brl/mutter.git
synced 2025-02-16 21:34:09 +00:00
2008-05-28 Emmanuele Bassi <ebassi@openedhand.com>
Bug 882 - Allow child properties for containers implementing the ClutterContainer interface (Øyvind Kolås) * clutter/clutter-child-meta.[ch]: Base class for the metadata of a ClutterActor inside a ClutterContainer; the ChildMeta object implements a wrapper for storing data that is attached to a ClutterActor only when it's part of a ClutterContainer. The ChildMeta object is used to store the child properties accessible through the ClutterContainer API. * clutter/clutter-container.[ch]: Creates the ChildMeta for each actor, in case the Container specifies the ChildMeta type to use. * clutter/Makefile.am: Add clutter-child-meta.[ch] to the build. * clutter/clutter-marshal.list: Add the marshaller for the ClutterContainer::child-notify signal. * clutter/clutter-types.h: Declare ClutterContainer and ClutterChildMeta to avoid recursive inclusion.
This commit is contained in:
parent
717d9768ed
commit
a0747e8c2d
34
ChangeLog
34
ChangeLog
@ -1,3 +1,32 @@
|
|||||||
|
2008-05-28 Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
|
||||||
|
Bug 882 - Allow child properties for containers implementing the
|
||||||
|
ClutterContainer interface (Øyvind Kolås)
|
||||||
|
|
||||||
|
* clutter/clutter-child-meta.[ch]: Base class for the metadata
|
||||||
|
of a ClutterActor inside a ClutterContainer; the ChildMeta
|
||||||
|
object implements a wrapper for storing data that is attached
|
||||||
|
to a ClutterActor only when it's part of a ClutterContainer.
|
||||||
|
The ChildMeta object is used to store the child properties
|
||||||
|
accessible through the ClutterContainer API.
|
||||||
|
|
||||||
|
* clutter/clutter-container.[ch]: Creates the ChildMeta for
|
||||||
|
each actor, in case the Container specifies the ChildMeta
|
||||||
|
type to use.
|
||||||
|
|
||||||
|
* clutter/Makefile.am: Add clutter-child-meta.[ch] to the build.
|
||||||
|
|
||||||
|
* clutter/clutter-marshal.list: Add the marshaller for the
|
||||||
|
ClutterContainer::child-notify signal.
|
||||||
|
|
||||||
|
* clutter/clutter-types.h: Declare ClutterContainer and
|
||||||
|
ClutterChildMeta to avoid recursive inclusion.
|
||||||
|
|
||||||
|
2008-05-28 Neil Roberts <neil@o-hand.com>
|
||||||
|
|
||||||
|
* clutter/cogl/gles/Makefile.am: Use old-style Makefile rules for
|
||||||
|
the stringify script so that automake won't complain.
|
||||||
|
|
||||||
2008-05-28 Emmanuele Bassi <ebassi@openedhand.com>
|
2008-05-28 Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
|
||||||
* tests/test-script.c:
|
* tests/test-script.c:
|
||||||
@ -24,11 +53,6 @@
|
|||||||
table holding the objects - we are already holding it inside
|
table holding the objects - we are already holding it inside
|
||||||
the value.
|
the value.
|
||||||
|
|
||||||
2008-05-28 Neil Roberts <neil@o-hand.com>
|
|
||||||
|
|
||||||
* clutter/cogl/gles/Makefile.am: Use old-style Makefile rules for
|
|
||||||
the stringify script so that automake won't complain.
|
|
||||||
|
|
||||||
2008-05-28 Neil Roberts <neil@o-hand.com>
|
2008-05-28 Neil Roberts <neil@o-hand.com>
|
||||||
|
|
||||||
* clutter/cogl/gles/cogl-gles2-wrapper.c (cogl_wrap_glGetFixedv):
|
* clutter/cogl/gles/cogl-gles2-wrapper.c (cogl_wrap_glGetFixedv):
|
||||||
|
@ -58,6 +58,7 @@ source_h = \
|
|||||||
$(srcdir)/clutter-behaviour-path.h \
|
$(srcdir)/clutter-behaviour-path.h \
|
||||||
$(srcdir)/clutter-behaviour-rotate.h \
|
$(srcdir)/clutter-behaviour-rotate.h \
|
||||||
$(srcdir)/clutter-behaviour-scale.h \
|
$(srcdir)/clutter-behaviour-scale.h \
|
||||||
|
$(srcdir)/clutter-child-meta.h \
|
||||||
$(srcdir)/clutter-clone-texture.h \
|
$(srcdir)/clutter-clone-texture.h \
|
||||||
$(srcdir)/clutter-color.h \
|
$(srcdir)/clutter-color.h \
|
||||||
$(srcdir)/clutter-container.h \
|
$(srcdir)/clutter-container.h \
|
||||||
@ -143,6 +144,7 @@ source_c = \
|
|||||||
clutter-behaviour-path.c \
|
clutter-behaviour-path.c \
|
||||||
clutter-behaviour-rotate.c \
|
clutter-behaviour-rotate.c \
|
||||||
clutter-behaviour-scale.c \
|
clutter-behaviour-scale.c \
|
||||||
|
clutter-child-meta.c \
|
||||||
clutter-clone-texture.c \
|
clutter-clone-texture.c \
|
||||||
clutter-color.c \
|
clutter-color.c \
|
||||||
clutter-container.c \
|
clutter-container.c \
|
||||||
|
160
clutter/clutter-child-meta.c
Normal file
160
clutter/clutter-child-meta.c
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
* Clutter.
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||||
|
* Jorn Baayen <jorn@openedhand.com>
|
||||||
|
* Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
* Tomas Frydrych <tf@openedhand.com>
|
||||||
|
* Øyvind Kolås <ok@openedhand.com>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 OpenedHand
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:clutter-child-data
|
||||||
|
* @short_description: Wrapper for actors inside a container
|
||||||
|
*
|
||||||
|
* #ClutterChildMeta is a wrapper object created by #ClutterContainer
|
||||||
|
* implementations in order to store child-specific data and properties.
|
||||||
|
*
|
||||||
|
* A #ClutterChildMeta wraps a #ClutterActor inside a #ClutterContainer.
|
||||||
|
*
|
||||||
|
* #ClutterChildMeta is available since Clutter 0.8
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "clutter-child-meta.h"
|
||||||
|
#include "clutter-container.h"
|
||||||
|
#include "clutter-debug.h"
|
||||||
|
#include "clutter-private.h"
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ClutterChildMeta, clutter_child_meta, G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_CONTAINER,
|
||||||
|
PROP_ACTOR
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_child_meta_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterChildMeta *child_meta = CLUTTER_CHILD_META (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_CONTAINER:
|
||||||
|
g_value_set_object (value, child_meta->container);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_ACTOR:
|
||||||
|
g_value_set_object (value, child_meta->actor);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_child_meta_class_init (ClutterChildMetaClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
gobject_class->get_property = clutter_child_meta_get_property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterChildMeta:container:
|
||||||
|
*
|
||||||
|
* The #ClutterContainer that created this #ClutterChildMeta.
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_object ("container",
|
||||||
|
"Container",
|
||||||
|
"The container that created this data",
|
||||||
|
CLUTTER_TYPE_CONTAINER,
|
||||||
|
CLUTTER_PARAM_READABLE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_CONTAINER, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterChildMeta:actor:
|
||||||
|
*
|
||||||
|
* The #ClutterActor being wrapped by this #ClutterChildMeta
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_object ("actor",
|
||||||
|
"Actor",
|
||||||
|
"The actor wrapped by this data",
|
||||||
|
CLUTTER_TYPE_ACTOR,
|
||||||
|
CLUTTER_PARAM_READABLE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_ACTOR, pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_child_meta_init (ClutterChildMeta *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_child_meta_get_container:
|
||||||
|
* @data: a #ClutterChildMeta
|
||||||
|
*
|
||||||
|
* Retrieves the container using @data
|
||||||
|
*
|
||||||
|
* Return value: a #ClutterContainer
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
ClutterContainer *
|
||||||
|
clutter_child_meta_get_container (ClutterChildMeta *data)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_CHILD_META (data), NULL);
|
||||||
|
|
||||||
|
return data->container;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_child_meta_get_actor:
|
||||||
|
* @data: a #ClutterChildMeta
|
||||||
|
*
|
||||||
|
* Retrieves the actor wrapped by @data
|
||||||
|
*
|
||||||
|
* Return value: a #ClutterActor
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
ClutterActor *
|
||||||
|
clutter_child_meta_get_actor (ClutterChildMeta *data)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_CHILD_META (data), NULL);
|
||||||
|
|
||||||
|
return data->actor;
|
||||||
|
}
|
110
clutter/clutter-child-meta.h
Normal file
110
clutter/clutter-child-meta.h
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* Clutter.
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||||
|
* Jorn Baayen <jorn@openedhand.com>
|
||||||
|
* Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
* Tomas Frydrych <tf@openedhand.com>
|
||||||
|
* Øyvind Kolås <ok@openedhand.com>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 OpenedHand
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CLUTTER_CHILD_META_H__
|
||||||
|
#define __CLUTTER_CHILD_META_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <clutter/clutter-types.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLUTTER_TYPE_CHILD_META (clutter_child_meta_get_type ())
|
||||||
|
#define CLUTTER_CHILD_META(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CHILD_META, ClutterChildMeta))
|
||||||
|
#define CLUTTER_CHILD_META_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CHILD_META, ClutterChildMetaClass))
|
||||||
|
#define CLUTTER_IS_CHILD_META(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CHILD_META))
|
||||||
|
#define CLUTTER_IS_CHILD_META_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CHILD_META))
|
||||||
|
#define CLUTTER_CHILD_META_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CHILD_META, ClutterChildMetaClass))
|
||||||
|
|
||||||
|
typedef struct _ClutterChildMetaClass ClutterChildMetaClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterChildMeta:
|
||||||
|
* @container: the container handling this data
|
||||||
|
* @actor: the actor wrapped by this data
|
||||||
|
*
|
||||||
|
* Base interface for container specific state for child actors. A child
|
||||||
|
* data is meant to be used when you need to keep track of information
|
||||||
|
* about each individual child added to a container.
|
||||||
|
*
|
||||||
|
* In order to use it you should create your own subclass of
|
||||||
|
* #ClutterChildMeta and set the #ClutterContainerIface::child_meta_type
|
||||||
|
* interface member to your subclass type, like:
|
||||||
|
*
|
||||||
|
* |[
|
||||||
|
* static void
|
||||||
|
* my_container_iface_init (ClutterContainerIface *iface)
|
||||||
|
* {
|
||||||
|
* /* set the rest of the #ClutterContainer vtable */
|
||||||
|
*
|
||||||
|
* container_iface->child_meta_type = MY_TYPE_CHILD_META;
|
||||||
|
* }
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* This will automatically create a #ClutterChildMeta of type
|
||||||
|
* MY_TYPE_CHILD_META for every actor that is added to the container.
|
||||||
|
*
|
||||||
|
* The child data for an actor can be retrieved using the
|
||||||
|
* clutter_container_get_child_meta() function.
|
||||||
|
*
|
||||||
|
* The properties of the data and your subclass can be manipulated with
|
||||||
|
* clutter_container_child_set() and clutter_container_child_get() which
|
||||||
|
* act like g_object_set() and g_object_get().
|
||||||
|
*
|
||||||
|
* You can provide hooks for your own storage as well as control the
|
||||||
|
* instantiation by overriding #ClutterContainerIface::create_child_meta,
|
||||||
|
* #ClutterContainerIface::destroy_child_meta and
|
||||||
|
* #ClutterContainerIface::get_child_meta.
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
struct _ClutterChildMeta
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
/*< public >*/
|
||||||
|
ClutterContainer *container;
|
||||||
|
ClutterActor *actor;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _ClutterChildMetaClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
GObjectClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType clutter_child_meta_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
ClutterContainer *clutter_child_meta_get_container (ClutterChildMeta *data);
|
||||||
|
ClutterActor *clutter_child_meta_get_actor (ClutterChildMeta *data);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __CLUTTER_CHILD_META_H__ */
|
@ -32,8 +32,10 @@
|
|||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
#include <gobject/gvaluecollector.h>
|
||||||
|
|
||||||
#include "clutter-container.h"
|
#include "clutter-container.h"
|
||||||
|
#include "clutter-child-meta.h"
|
||||||
|
|
||||||
#include "clutter-debug.h"
|
#include "clutter-debug.h"
|
||||||
#include "clutter-main.h"
|
#include "clutter-main.h"
|
||||||
@ -41,6 +43,7 @@
|
|||||||
#include "clutter-private.h"
|
#include "clutter-private.h"
|
||||||
#include "clutter-enum-types.h"
|
#include "clutter-enum-types.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:clutter-container
|
* SECTION:clutter-container
|
||||||
* @short_description: An interface for implementing container actors
|
* @short_description: An interface for implementing container actors
|
||||||
@ -58,11 +61,33 @@ enum
|
|||||||
{
|
{
|
||||||
ACTOR_ADDED,
|
ACTOR_ADDED,
|
||||||
ACTOR_REMOVED,
|
ACTOR_REMOVED,
|
||||||
|
CHILD_NOTIFY,
|
||||||
|
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
static guint container_signals[LAST_SIGNAL] = { 0, };
|
static guint container_signals[LAST_SIGNAL] = { 0, };
|
||||||
|
static GQuark quark_child_meta = 0;
|
||||||
|
|
||||||
|
static ClutterChildMeta *
|
||||||
|
get_child_meta (ClutterContainer *container,
|
||||||
|
ClutterActor *actor);
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_child_meta (ClutterContainer *container,
|
||||||
|
ClutterActor *actor);
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_child_meta (ClutterContainer *container,
|
||||||
|
ClutterActor *actor);
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_container_create_child_meta (ClutterContainer *container,
|
||||||
|
ClutterActor *actor);
|
||||||
|
static void
|
||||||
|
clutter_container_destroy_child_meta (ClutterContainer *container,
|
||||||
|
ClutterActor *actor);
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_container_base_init (gpointer g_iface)
|
clutter_container_base_init (gpointer g_iface)
|
||||||
@ -72,9 +97,13 @@ clutter_container_base_init (gpointer g_iface)
|
|||||||
if (!initialised)
|
if (!initialised)
|
||||||
{
|
{
|
||||||
GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
|
GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
|
||||||
|
ClutterContainerIface *iface = g_iface;
|
||||||
|
|
||||||
initialised = TRUE;
|
initialised = TRUE;
|
||||||
|
|
||||||
|
quark_child_meta =
|
||||||
|
g_quark_from_static_string ("clutter-container-child-data");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterContainer::actor-added:
|
* ClutterContainer::actor-added:
|
||||||
* @container: the actor which received the signal
|
* @container: the actor which received the signal
|
||||||
@ -86,7 +115,7 @@ clutter_container_base_init (gpointer g_iface)
|
|||||||
* Since: 0.4
|
* Since: 0.4
|
||||||
*/
|
*/
|
||||||
container_signals[ACTOR_ADDED] =
|
container_signals[ACTOR_ADDED] =
|
||||||
g_signal_new ("actor-added",
|
g_signal_new (I_("actor-added"),
|
||||||
iface_type,
|
iface_type,
|
||||||
G_SIGNAL_RUN_FIRST,
|
G_SIGNAL_RUN_FIRST,
|
||||||
G_STRUCT_OFFSET (ClutterContainerIface, actor_added),
|
G_STRUCT_OFFSET (ClutterContainerIface, actor_added),
|
||||||
@ -105,7 +134,7 @@ clutter_container_base_init (gpointer g_iface)
|
|||||||
* Since: 0.4
|
* Since: 0.4
|
||||||
*/
|
*/
|
||||||
container_signals[ACTOR_REMOVED] =
|
container_signals[ACTOR_REMOVED] =
|
||||||
g_signal_new ("actor-removed",
|
g_signal_new (I_("actor-removed"),
|
||||||
iface_type,
|
iface_type,
|
||||||
G_SIGNAL_RUN_FIRST,
|
G_SIGNAL_RUN_FIRST,
|
||||||
G_STRUCT_OFFSET (ClutterContainerIface, actor_removed),
|
G_STRUCT_OFFSET (ClutterContainerIface, actor_removed),
|
||||||
@ -113,6 +142,32 @@ clutter_container_base_init (gpointer g_iface)
|
|||||||
clutter_marshal_VOID__OBJECT,
|
clutter_marshal_VOID__OBJECT,
|
||||||
G_TYPE_NONE, 1,
|
G_TYPE_NONE, 1,
|
||||||
CLUTTER_TYPE_ACTOR);
|
CLUTTER_TYPE_ACTOR);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterContainer::child-notify:
|
||||||
|
* @container: the container which received the signal
|
||||||
|
* @actor: the child that has had a property set.
|
||||||
|
*
|
||||||
|
* The ::child-notify signal is emitted each time a property is
|
||||||
|
* being set through the clutter_container_child_set() and
|
||||||
|
* clutter_container_child_set_property() calls.
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
container_signals[CHILD_NOTIFY] =
|
||||||
|
g_signal_new (I_("child-notify"),
|
||||||
|
iface_type,
|
||||||
|
G_SIGNAL_RUN_FIRST,
|
||||||
|
G_STRUCT_OFFSET (ClutterContainerIface, child_notify),
|
||||||
|
NULL, NULL,
|
||||||
|
clutter_marshal_VOID__OBJECT_OBJECT_PARAM,
|
||||||
|
G_TYPE_NONE, 2,
|
||||||
|
CLUTTER_TYPE_ACTOR, G_TYPE_PARAM);
|
||||||
|
|
||||||
|
iface->child_meta_type = G_TYPE_INVALID;
|
||||||
|
iface->create_child_meta = create_child_meta;
|
||||||
|
iface->destroy_child_meta = destroy_child_meta;
|
||||||
|
iface->get_child_meta = get_child_meta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,11 +182,11 @@ clutter_container_get_type (void)
|
|||||||
{
|
{
|
||||||
sizeof (ClutterContainerIface),
|
sizeof (ClutterContainerIface),
|
||||||
clutter_container_base_init,
|
clutter_container_base_init,
|
||||||
NULL, /* iface_finalize */
|
NULL, /* iface_base_finalize */
|
||||||
};
|
};
|
||||||
|
|
||||||
container_type = g_type_register_static (G_TYPE_INTERFACE,
|
container_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||||
"ClutterContainer",
|
I_("ClutterContainer"),
|
||||||
&container_info, 0);
|
&container_info, 0);
|
||||||
|
|
||||||
g_type_interface_add_prerequisite (container_type, G_TYPE_OBJECT);
|
g_type_interface_add_prerequisite (container_type, G_TYPE_OBJECT);
|
||||||
@ -201,6 +256,7 @@ clutter_container_add_actor (ClutterContainer *container,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clutter_container_create_child_meta (container, actor);
|
||||||
CLUTTER_CONTAINER_GET_IFACE (container)->add (container, actor);
|
CLUTTER_CONTAINER_GET_IFACE (container)->add (container, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,6 +349,7 @@ clutter_container_remove_actor (ClutterContainer *container,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clutter_container_destroy_child_meta (container, actor);
|
||||||
CLUTTER_CONTAINER_GET_IFACE (container)->remove (container, actor);
|
CLUTTER_CONTAINER_GET_IFACE (container)->remove (container, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,7 +377,6 @@ clutter_container_remove_valist (ClutterContainer *container,
|
|||||||
while (actor)
|
while (actor)
|
||||||
{
|
{
|
||||||
clutter_container_remove_actor (container, actor);
|
clutter_container_remove_actor (container, actor);
|
||||||
|
|
||||||
actor = va_arg (var_args, ClutterActor*);
|
actor = va_arg (var_args, ClutterActor*);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -376,7 +432,9 @@ clutter_container_foreach (ClutterContainer *container,
|
|||||||
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
g_return_if_fail (callback != NULL);
|
g_return_if_fail (callback != NULL);
|
||||||
|
|
||||||
CLUTTER_CONTAINER_GET_IFACE (container)->foreach (container, callback, user_data);
|
CLUTTER_CONTAINER_GET_IFACE (container)->foreach (container,
|
||||||
|
callback,
|
||||||
|
user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -392,7 +450,7 @@ clutter_container_foreach (ClutterContainer *container,
|
|||||||
void
|
void
|
||||||
clutter_container_raise_child (ClutterContainer *container,
|
clutter_container_raise_child (ClutterContainer *container,
|
||||||
ClutterActor *actor,
|
ClutterActor *actor,
|
||||||
ClutterActor *sibling)
|
ClutterActor *sibling)
|
||||||
{
|
{
|
||||||
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
@ -436,7 +494,7 @@ clutter_container_raise_child (ClutterContainer *container,
|
|||||||
void
|
void
|
||||||
clutter_container_lower_child (ClutterContainer *container,
|
clutter_container_lower_child (ClutterContainer *container,
|
||||||
ClutterActor *actor,
|
ClutterActor *actor,
|
||||||
ClutterActor *sibling)
|
ClutterActor *sibling)
|
||||||
{
|
{
|
||||||
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
@ -506,10 +564,11 @@ clutter_container_find_child_by_name (ClutterContainer *container,
|
|||||||
ClutterActor *actor = NULL;
|
ClutterActor *actor = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL);
|
g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL);
|
||||||
|
g_return_val_if_fail (child_name != NULL, NULL);
|
||||||
|
|
||||||
children = clutter_container_get_children (container);
|
children = clutter_container_get_children (container);
|
||||||
|
|
||||||
for (iter=children; iter; iter = g_list_next (iter))
|
for (iter = children; iter; iter = g_list_next (iter))
|
||||||
{
|
{
|
||||||
ClutterActor *a;
|
ClutterActor *a;
|
||||||
const gchar *iter_name;
|
const gchar *iter_name;
|
||||||
@ -532,6 +591,529 @@ clutter_container_find_child_by_name (ClutterContainer *container,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_list_free (children);
|
g_list_free (children);
|
||||||
|
|
||||||
return actor;
|
return actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ClutterChildMeta *
|
||||||
|
get_child_meta (ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container);
|
||||||
|
|
||||||
|
if (iface->child_meta_type == G_TYPE_INVALID)
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClutterChildMeta *child_meta = NULL;
|
||||||
|
GSList *list, *iter;
|
||||||
|
|
||||||
|
list = g_object_get_qdata (G_OBJECT (container), quark_child_meta);
|
||||||
|
for (iter = list; iter; iter = g_slist_next (iter))
|
||||||
|
{
|
||||||
|
child_meta = iter->data;
|
||||||
|
|
||||||
|
if (child_meta->actor == actor)
|
||||||
|
return child_meta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_child_meta (ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container);
|
||||||
|
ClutterChildMeta *child_meta = NULL;
|
||||||
|
GSList *data_list = NULL;
|
||||||
|
|
||||||
|
if (iface->child_meta_type == G_TYPE_INVALID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!g_type_is_a (iface->child_meta_type, CLUTTER_TYPE_CHILD_META))
|
||||||
|
{
|
||||||
|
g_warning ("%s: Child data of type `%s' is not a ClutterChildMeta",
|
||||||
|
G_STRLOC, g_type_name (iface->child_meta_type));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
child_meta = g_object_new (iface->child_meta_type, NULL);
|
||||||
|
child_meta->container = container;
|
||||||
|
child_meta->actor = actor;
|
||||||
|
|
||||||
|
data_list = g_object_get_qdata (G_OBJECT (container), quark_child_meta);
|
||||||
|
data_list = g_slist_prepend (data_list, child_meta);
|
||||||
|
g_object_set_qdata (G_OBJECT (container), quark_child_meta, data_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_child_meta (ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container);
|
||||||
|
GObject *object = G_OBJECT (container);
|
||||||
|
|
||||||
|
if (iface->child_meta_type == G_TYPE_INVALID)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClutterChildMeta *child_meta = NULL;
|
||||||
|
GSList *list = g_object_get_qdata (object, quark_child_meta);
|
||||||
|
GSList *iter;
|
||||||
|
|
||||||
|
for (iter = list; iter; iter = g_slist_next (iter))
|
||||||
|
{
|
||||||
|
child_meta = iter->data;
|
||||||
|
|
||||||
|
if (child_meta->actor == actor)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
child_meta = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child_meta)
|
||||||
|
{
|
||||||
|
list = g_slist_remove (list, child_meta);
|
||||||
|
g_object_set_qdata (object, quark_child_meta, list);
|
||||||
|
|
||||||
|
g_object_unref (child_meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_container_get_child_meta:
|
||||||
|
* @container: a #ClutterContainer
|
||||||
|
* @actor: a #ClutterActor that is a child of @container.
|
||||||
|
*
|
||||||
|
* Retrieves the #ClutterChildMeta which contains the data about the
|
||||||
|
* @container specific state for @actor.
|
||||||
|
*
|
||||||
|
* Return value: the #ClutterChildMeta for the @actor child of @container
|
||||||
|
* or %NULL if the specifiec actor does not exist or the container is not
|
||||||
|
* configured to provide #ClutterChildMeta<!-- -->s
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
ClutterChildMeta *
|
||||||
|
clutter_container_get_child_meta (ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container);
|
||||||
|
|
||||||
|
if (iface->child_meta_type == G_TYPE_INVALID)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (G_LIKELY (iface->get_child_meta))
|
||||||
|
return iface->get_child_meta (container, actor);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clutter_container_create_child_meta:
|
||||||
|
* @container: a #ClutterContainer
|
||||||
|
* @actor: a #ClutterActor
|
||||||
|
*
|
||||||
|
* Creates the #ClutterChildMeta wrapping @actor inside the
|
||||||
|
* @container, if the #ClutterContainerIface::child_meta_type
|
||||||
|
* class member is not set to %G_TYPE_INVALID.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
clutter_container_create_child_meta (ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container);
|
||||||
|
|
||||||
|
if (iface->child_meta_type == G_TYPE_INVALID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_assert (g_type_is_a (iface->child_meta_type, CLUTTER_TYPE_CHILD_META));
|
||||||
|
|
||||||
|
if (G_LIKELY (iface->create_child_meta))
|
||||||
|
iface->create_child_meta (container, actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clutter_container_destroy_child_meta:
|
||||||
|
* @container: a #ClutterContainer
|
||||||
|
* @actor: a #ClutterActor
|
||||||
|
*
|
||||||
|
* Destroys the #ClutterChildMeta wrapping @actor inside the
|
||||||
|
* @container, if any.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
clutter_container_destroy_child_meta (ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container);
|
||||||
|
|
||||||
|
if (iface->child_meta_type == G_TYPE_INVALID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (G_LIKELY (iface->destroy_child_meta))
|
||||||
|
iface->destroy_child_meta (container, actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_container_class_find_child_property:
|
||||||
|
* @klass: a #GObjectClass implementing the #ClutterContainer interface.
|
||||||
|
* @property_name: a property name.
|
||||||
|
*
|
||||||
|
* Looks up the #GParamSpec for a child property of @klass.
|
||||||
|
*
|
||||||
|
* Return value: The #GParamSpec for the property or %NULL if no such
|
||||||
|
* property exist.
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
GParamSpec *
|
||||||
|
clutter_container_class_find_child_property (GObjectClass *klass,
|
||||||
|
const gchar *property_name)
|
||||||
|
{
|
||||||
|
ClutterContainerIface *iface;
|
||||||
|
GObjectClass *child_class;
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_OBJECT_CLASS (klass), NULL);
|
||||||
|
g_return_val_if_fail (property_name != NULL, NULL);
|
||||||
|
g_return_val_if_fail (g_type_is_a (G_TYPE_FROM_CLASS (klass),
|
||||||
|
CLUTTER_TYPE_CONTAINER),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
iface = g_type_interface_peek (klass, CLUTTER_TYPE_CONTAINER);
|
||||||
|
g_return_val_if_fail (iface != NULL, NULL);
|
||||||
|
|
||||||
|
if (iface->child_meta_type == G_TYPE_INVALID)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
child_class = g_type_class_ref (iface->child_meta_type);
|
||||||
|
pspec = g_object_class_find_property (child_class, property_name);
|
||||||
|
g_type_class_unref (child_class);
|
||||||
|
|
||||||
|
return pspec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_container_class_list_child_properties:
|
||||||
|
* @klass: a #GObjectClass implementing the #ClutterContainer interface.
|
||||||
|
* @n_properties: return location for length of returned array.
|
||||||
|
*
|
||||||
|
* Returns an array of #GParamSpec for all child properties.
|
||||||
|
*
|
||||||
|
* Return value: an array of #GParamSpec<!-- -->s which should be freed
|
||||||
|
* after use.
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
GParamSpec **
|
||||||
|
clutter_container_class_list_child_properties (GObjectClass *klass,
|
||||||
|
guint *n_properties)
|
||||||
|
{
|
||||||
|
ClutterContainerIface *iface;
|
||||||
|
GObjectClass *child_class;
|
||||||
|
GParamSpec **retval;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_OBJECT_CLASS (klass), NULL);
|
||||||
|
g_return_val_if_fail (g_type_is_a (G_TYPE_FROM_CLASS (klass),
|
||||||
|
CLUTTER_TYPE_CONTAINER),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
iface = g_type_interface_peek (klass, CLUTTER_TYPE_CONTAINER);
|
||||||
|
g_return_val_if_fail (iface != NULL, NULL);
|
||||||
|
|
||||||
|
if (iface->child_meta_type == G_TYPE_INVALID)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
child_class = g_type_class_ref (iface->child_meta_type);
|
||||||
|
retval = g_object_class_list_properties (child_class, n_properties);
|
||||||
|
g_type_class_unref (child_class);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
container_set_child_property (ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterChildMeta *data;
|
||||||
|
ClutterContainerIface *iface;
|
||||||
|
|
||||||
|
data = clutter_container_get_child_meta (container, actor);
|
||||||
|
g_object_set_property (G_OBJECT (data), pspec->name, value);
|
||||||
|
|
||||||
|
iface = CLUTTER_CONTAINER_GET_IFACE (container);
|
||||||
|
if (G_LIKELY (iface->child_notify))
|
||||||
|
iface->child_notify (container, actor, pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_container_child_set_property:
|
||||||
|
* @container: a #ClutterContainer
|
||||||
|
* @actor: a #ClutterActor that is a child of @container.
|
||||||
|
* @property: the name of the property to set.
|
||||||
|
* @value: the value.
|
||||||
|
*
|
||||||
|
* Sets a container-specific property on a child of @container.
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_container_child_set_property (ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *property,
|
||||||
|
const GValue *value)
|
||||||
|
{
|
||||||
|
GObjectClass *klass;
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
|
g_return_if_fail (property != NULL);
|
||||||
|
g_return_if_fail (value != NULL);
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (container);
|
||||||
|
|
||||||
|
pspec = clutter_container_class_find_child_property (klass, property);
|
||||||
|
if (!pspec)
|
||||||
|
{
|
||||||
|
g_warning ("%s: Containers of type `%s' have no child "
|
||||||
|
"property named `%s'",
|
||||||
|
G_STRLOC, G_OBJECT_TYPE_NAME (container), property);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pspec->flags & G_PARAM_WRITABLE))
|
||||||
|
{
|
||||||
|
g_warning ("%s: Child property `%s' of the container `%s' "
|
||||||
|
"is not writable",
|
||||||
|
G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (container));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
container_set_child_property (container, actor, value, pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_container_child_set:
|
||||||
|
* @container: a #ClutterContainer
|
||||||
|
* @actor: a #ClutterActor that is a child of @container.
|
||||||
|
* @first_prop: name of the first property to be set.
|
||||||
|
* @...: value for the first property, followed optionally by more name/value
|
||||||
|
* pairs terminated with NULL.
|
||||||
|
*
|
||||||
|
* Sets container specific properties on the child of a container.
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_container_child_set (ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *first_prop,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
GObjectClass *klass;
|
||||||
|
const gchar *name;
|
||||||
|
va_list var_args;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (container);
|
||||||
|
|
||||||
|
va_start (var_args, first_prop);
|
||||||
|
|
||||||
|
name = first_prop;
|
||||||
|
while (name)
|
||||||
|
{
|
||||||
|
GValue value = { 0, };
|
||||||
|
gchar *error = NULL;
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
pspec = clutter_container_class_find_child_property (klass, name);
|
||||||
|
if (!pspec)
|
||||||
|
{
|
||||||
|
g_warning ("%s: Containers of type `%s' have no child "
|
||||||
|
"property named `%s'",
|
||||||
|
G_STRLOC, G_OBJECT_TYPE_NAME (container), name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pspec->flags & G_PARAM_WRITABLE))
|
||||||
|
{
|
||||||
|
g_warning ("%s: Child property `%s' of the container `%s' "
|
||||||
|
"is not writable",
|
||||||
|
G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (container));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||||
|
G_VALUE_COLLECT (&value, var_args, 0, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
/* we intentionally leak the GValue because it might
|
||||||
|
* be in an undefined state and calling g_value_unset()
|
||||||
|
* on it might crash
|
||||||
|
*/
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error);
|
||||||
|
g_free (error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
container_set_child_property (container, actor, &value, pspec);
|
||||||
|
|
||||||
|
g_value_unset (&value);
|
||||||
|
|
||||||
|
name = va_arg (var_args, gchar*);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end (var_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
container_get_child_property (ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterChildMeta *data;
|
||||||
|
|
||||||
|
data = clutter_container_get_child_meta (container, actor);
|
||||||
|
g_object_set_property (G_OBJECT (data), pspec->name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_container_child_get_property:
|
||||||
|
* @container: a #ClutterContainer
|
||||||
|
* @actor: a #ClutterActor that is a child of @container.
|
||||||
|
* @property: the name of the property to set.
|
||||||
|
* @value: the value.
|
||||||
|
*
|
||||||
|
* Gets a container specific property of a child of @container, In general,
|
||||||
|
* a copy is made of the property contents and the caller is responsible for
|
||||||
|
* freeing the memory by calling g_value_unset().
|
||||||
|
*
|
||||||
|
* Note that clutter_container_child_set_property() is really intended for
|
||||||
|
* language bindings, clutter_container_child_set() is much more convenient
|
||||||
|
* for C programming.
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_container_child_get_property (ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *property,
|
||||||
|
GValue *value)
|
||||||
|
{
|
||||||
|
GObjectClass *klass;
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
|
g_return_if_fail (property != NULL);
|
||||||
|
g_return_if_fail (value != NULL);
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (container);
|
||||||
|
|
||||||
|
pspec = clutter_container_class_find_child_property (klass, property);
|
||||||
|
if (!pspec)
|
||||||
|
{
|
||||||
|
g_warning ("%s: Containers of type `%s' have no child "
|
||||||
|
"property named `%s'",
|
||||||
|
G_STRLOC, G_OBJECT_TYPE_NAME (container), property);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pspec->flags & G_PARAM_READABLE))
|
||||||
|
{
|
||||||
|
g_warning ("%s: Child property `%s' of the container `%s' "
|
||||||
|
"is not writable",
|
||||||
|
G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (container));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
container_get_child_property (container, actor, value, pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_container_child_get:
|
||||||
|
* @container: a #ClutterContainer
|
||||||
|
* @actor: a #ClutterActor that is a child of @container.
|
||||||
|
* @first_prop: name of the first property to be set.
|
||||||
|
* @...: value for the first property, followed optionally by more name/value
|
||||||
|
* pairs terminated with NULL.
|
||||||
|
*
|
||||||
|
* Gets @container specific properties of an actor.
|
||||||
|
*
|
||||||
|
* In general, a copy is made of the property contents and the caller is
|
||||||
|
* responsible for freeing the memory in the appropriate manner for the type, for
|
||||||
|
* instance by calling g_free() or g_object_unref().
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_container_child_get (ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *first_prop,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
GObjectClass *klass;
|
||||||
|
const gchar *name;
|
||||||
|
va_list var_args;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (container);
|
||||||
|
|
||||||
|
va_start (var_args, first_prop);
|
||||||
|
|
||||||
|
name = first_prop;
|
||||||
|
while (name)
|
||||||
|
{
|
||||||
|
GValue value = { 0, };
|
||||||
|
gchar *error = NULL;
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
pspec = clutter_container_class_find_child_property (klass, name);
|
||||||
|
if (!pspec)
|
||||||
|
{
|
||||||
|
g_warning ("%s: container `%s' has no child property named `%s'",
|
||||||
|
G_STRLOC, G_OBJECT_TYPE_NAME (container), name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pspec->flags & G_PARAM_READABLE))
|
||||||
|
{
|
||||||
|
g_warning ("%s: child property `%s' of container `%s' is not readable",
|
||||||
|
G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (container));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||||
|
|
||||||
|
container_get_child_property (container, actor, &value, pspec);
|
||||||
|
|
||||||
|
G_VALUE_LCOPY (&value, var_args, 0, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error);
|
||||||
|
g_free (error);
|
||||||
|
g_value_unset (&value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_unset (&value);
|
||||||
|
|
||||||
|
name = va_arg (var_args, gchar*);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end (var_args);
|
||||||
|
}
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#define __CLUTTER_CONTAINER_H__
|
#define __CLUTTER_CONTAINER_H__
|
||||||
|
|
||||||
#include <clutter/clutter-actor.h>
|
#include <clutter/clutter-actor.h>
|
||||||
|
#include <clutter/clutter-child-meta.h>
|
||||||
|
#include <clutter/clutter-types.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -38,7 +40,6 @@ G_BEGIN_DECLS
|
|||||||
#define CLUTTER_IS_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CONTAINER))
|
#define CLUTTER_IS_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CONTAINER))
|
||||||
#define CLUTTER_CONTAINER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_CONTAINER, ClutterContainerIface))
|
#define CLUTTER_CONTAINER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_CONTAINER, ClutterContainerIface))
|
||||||
|
|
||||||
typedef struct _ClutterContainer ClutterContainer; /* dummy */
|
|
||||||
typedef struct _ClutterContainerIface ClutterContainerIface;
|
typedef struct _ClutterContainerIface ClutterContainerIface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,6 +51,15 @@ typedef struct _ClutterContainerIface ClutterContainerIface;
|
|||||||
* @lower: virtual function for lowering a child
|
* @lower: virtual function for lowering a child
|
||||||
* @sort_depth_order: virtual function for sorting the children of a
|
* @sort_depth_order: virtual function for sorting the children of a
|
||||||
* container depending on their depth
|
* container depending on their depth
|
||||||
|
* @child_record_type: The GType used for storing auxiliary information about
|
||||||
|
* each of the containers children.
|
||||||
|
* @create_child_record: virtual function that gets called for each added
|
||||||
|
* child, the function should instantiate @child_record_type, set the container
|
||||||
|
* and actor fields in the instance and add the record to a data structure for
|
||||||
|
* subsequent access for get_child_record.
|
||||||
|
* @destroy_child_record: virtual function that gets called when a child is removed
|
||||||
|
* it shuld release all resources held by the record.
|
||||||
|
* @get_child_record: return the record for a container child.
|
||||||
* @actor_added: signal class handler for ClutterContainer::actor_added
|
* @actor_added: signal class handler for ClutterContainer::actor_added
|
||||||
* @actor_removed: signal class handler for ClutterContainer::actor_removed
|
* @actor_removed: signal class handler for ClutterContainer::actor_removed
|
||||||
*
|
*
|
||||||
@ -63,26 +73,40 @@ struct _ClutterContainerIface
|
|||||||
GTypeInterface g_iface;
|
GTypeInterface g_iface;
|
||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
void (* add) (ClutterContainer *container,
|
void (* add) (ClutterContainer *container,
|
||||||
ClutterActor *actor);
|
ClutterActor *actor);
|
||||||
void (* remove) (ClutterContainer *container,
|
void (* remove) (ClutterContainer *container,
|
||||||
ClutterActor *actor);
|
ClutterActor *actor);
|
||||||
void (* foreach) (ClutterContainer *container,
|
void (* foreach) (ClutterContainer *container,
|
||||||
ClutterCallback callback,
|
ClutterCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
void (* raise) (ClutterContainer *container,
|
void (* raise) (ClutterContainer *container,
|
||||||
ClutterActor *actor,
|
ClutterActor *actor,
|
||||||
ClutterActor *sibling);
|
ClutterActor *sibling);
|
||||||
void (* lower) (ClutterContainer *container,
|
void (* lower) (ClutterContainer *container,
|
||||||
ClutterActor *actor,
|
ClutterActor *actor,
|
||||||
ClutterActor *sibling);
|
ClutterActor *sibling);
|
||||||
void (* sort_depth_order) (ClutterContainer *container);
|
void (* sort_depth_order) (ClutterContainer *container);
|
||||||
|
|
||||||
|
/* ClutterChildMeta management */
|
||||||
|
|
||||||
|
GType child_meta_type;
|
||||||
|
void (* create_child_meta) (ClutterContainer *container,
|
||||||
|
ClutterActor *actor);
|
||||||
|
void (* destroy_child_meta) (ClutterContainer *container,
|
||||||
|
ClutterActor *actor);
|
||||||
|
ClutterChildMeta *(* get_child_meta) (ClutterContainer *container,
|
||||||
|
ClutterActor *actor);
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
void (* actor_added) (ClutterContainer *container,
|
void (* actor_added) (ClutterContainer *container,
|
||||||
ClutterActor *actor);
|
ClutterActor *actor);
|
||||||
void (* actor_removed) (ClutterContainer *container,
|
void (* actor_removed) (ClutterContainer *container,
|
||||||
ClutterActor *actor);
|
ClutterActor *actor);
|
||||||
|
|
||||||
|
void (* child_notify) (ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
GParamSpec *pspec);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType clutter_container_get_type (void) G_GNUC_CONST;
|
GType clutter_container_get_type (void) G_GNUC_CONST;
|
||||||
@ -107,15 +131,43 @@ GList * clutter_container_get_children (ClutterContainer *container);
|
|||||||
void clutter_container_foreach (ClutterContainer *container,
|
void clutter_container_foreach (ClutterContainer *container,
|
||||||
ClutterCallback callback,
|
ClutterCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
ClutterActor *clutter_container_find_child_by_name(ClutterContainer *container,
|
ClutterActor *clutter_container_find_child_by_name (ClutterContainer *container,
|
||||||
const gchar *child_name);
|
const gchar *child_name);
|
||||||
void clutter_container_raise_child (ClutterContainer *container,
|
void clutter_container_raise_child (ClutterContainer *container,
|
||||||
ClutterActor *actor,
|
ClutterActor *actor,
|
||||||
ClutterActor *sibling);
|
ClutterActor *sibling);
|
||||||
void clutter_container_lower_child (ClutterContainer *container,
|
void clutter_container_lower_child (ClutterContainer *container,
|
||||||
ClutterActor *actor,
|
ClutterActor *actor,
|
||||||
ClutterActor *sibling);
|
ClutterActor *sibling);
|
||||||
void clutter_container_sort_depth_order (ClutterContainer *container);
|
void clutter_container_sort_depth_order (ClutterContainer *container);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GParamSpec * clutter_container_class_find_child_property (GObjectClass *klass,
|
||||||
|
const gchar *property_name);
|
||||||
|
GParamSpec ** clutter_container_class_list_child_properties (GObjectClass *klass,
|
||||||
|
guint *n_properties);
|
||||||
|
|
||||||
|
ClutterChildMeta *clutter_container_get_child_meta (ClutterContainer *container,
|
||||||
|
ClutterActor *actor);
|
||||||
|
|
||||||
|
void clutter_container_child_set_property (ClutterContainer *container,
|
||||||
|
ClutterActor *child,
|
||||||
|
const gchar * property,
|
||||||
|
const GValue *value);
|
||||||
|
void clutter_container_child_get_property (ClutterContainer *container,
|
||||||
|
ClutterActor *child,
|
||||||
|
const gchar *property,
|
||||||
|
GValue *value);
|
||||||
|
void clutter_container_child_set (ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *first_prop,
|
||||||
|
...) G_GNUC_NULL_TERMINATED;
|
||||||
|
void clutter_container_child_get (ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *first_prop,
|
||||||
|
...) G_GNUC_NULL_TERMINATED;
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
VOID:INT64,INT64,FLOAT,BOOLEAN
|
|
||||||
VOID:STRING,BOOLEAN,BOOLEAN
|
|
||||||
VOID:INT
|
|
||||||
VOID:INT,INT
|
|
||||||
VOID:INT,INT,INT,INT
|
|
||||||
VOID:BOXED
|
|
||||||
VOID:OBJECT
|
|
||||||
VOID:VOID
|
|
||||||
VOID:OBJECT,POINTER
|
|
||||||
VOID:STRING,UINT
|
|
||||||
BOOLEAN:BOXED
|
BOOLEAN:BOXED
|
||||||
UINT:VOID
|
UINT:VOID
|
||||||
|
VOID:BOXED
|
||||||
|
VOID:INT
|
||||||
|
VOID:INT64,INT64,FLOAT,BOOLEAN
|
||||||
|
VOID:INT,INT
|
||||||
|
VOID:INT,INT,INT,INT
|
||||||
|
VOID:OBJECT
|
||||||
|
VOID:OBJECT,OBJECT,PARAM
|
||||||
|
VOID:OBJECT,POINTER
|
||||||
|
VOID:STRING,BOOLEAN,BOOLEAN
|
||||||
|
VOID:STRING,UINT
|
||||||
|
VOID:VOID
|
||||||
|
@ -38,8 +38,10 @@ G_BEGIN_DECLS
|
|||||||
#define CLUTTER_TYPE_VERTEX (clutter_vertex_get_type ())
|
#define CLUTTER_TYPE_VERTEX (clutter_vertex_get_type ())
|
||||||
|
|
||||||
/* Forward delarations to avoid header catch 22's */
|
/* Forward delarations to avoid header catch 22's */
|
||||||
typedef struct _ClutterActor ClutterActor;
|
typedef struct _ClutterActor ClutterActor;
|
||||||
typedef struct _ClutterStage ClutterStage;
|
typedef struct _ClutterStage ClutterStage;
|
||||||
|
typedef struct _ClutterContainer ClutterContainer; /* dummy */
|
||||||
|
typedef struct _ClutterChildMeta ClutterChildMeta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterGravity:
|
* ClutterGravity:
|
||||||
|
@ -327,6 +327,7 @@
|
|||||||
<title>Abstract classes and interfaces</title>
|
<title>Abstract classes and interfaces</title>
|
||||||
<xi:include href="xml/clutter-actor.xml"/>
|
<xi:include href="xml/clutter-actor.xml"/>
|
||||||
<xi:include href="xml/clutter-container.xml"/>
|
<xi:include href="xml/clutter-container.xml"/>
|
||||||
|
<xi:include href="xml/clutter-child-data.xml"/>
|
||||||
<xi:include href="xml/clutter-media.xml"/>
|
<xi:include href="xml/clutter-media.xml"/>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
|
@ -247,10 +247,24 @@ clutter_container_remove
|
|||||||
clutter_container_remove_valist
|
clutter_container_remove_valist
|
||||||
clutter_container_get_children
|
clutter_container_get_children
|
||||||
clutter_container_foreach
|
clutter_container_foreach
|
||||||
|
|
||||||
|
<SUBSECTION>
|
||||||
clutter_container_find_child_by_name
|
clutter_container_find_child_by_name
|
||||||
clutter_container_raise_child
|
clutter_container_raise_child
|
||||||
clutter_container_lower_child
|
clutter_container_lower_child
|
||||||
clutter_container_sort_depth_order
|
clutter_container_sort_depth_order
|
||||||
|
|
||||||
|
<SUBSECTION>
|
||||||
|
clutter_container_find_child_property
|
||||||
|
clutter_container_list_child_properties
|
||||||
|
clutter_container_child_set_property
|
||||||
|
clutter_container_child_get_property
|
||||||
|
clutter_container_child_set
|
||||||
|
clutter_container_child_get
|
||||||
|
|
||||||
|
<SUBSECTION>
|
||||||
|
clutter_container_get_child_data
|
||||||
|
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
CLUTTER_TYPE_CONTAINER
|
CLUTTER_TYPE_CONTAINER
|
||||||
CLUTTER_CONTAINER
|
CLUTTER_CONTAINER
|
||||||
@ -260,6 +274,24 @@ CLUTTER_CONTAINER_GET_IFACE
|
|||||||
clutter_container_get_type
|
clutter_container_get_type
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<FILE>clutter-child-data</FILE>
|
||||||
|
<TITLE>ClutterChildData<TITLE>
|
||||||
|
ClutterChildData
|
||||||
|
ClutterChildDataClass
|
||||||
|
clutter_child_data_get_container
|
||||||
|
clutter_child_data_get_actor
|
||||||
|
<SUBSECTION Standard>
|
||||||
|
CLUTTER_TYPE_CHILD_DATA
|
||||||
|
CLUTTER_CHILD_DATA
|
||||||
|
CLUTTER_IS_CHILD_DATA
|
||||||
|
CLUTTER_CHILD_DATA_CLASS
|
||||||
|
CLUTTER_IS_CHILD_DATA_CLASS
|
||||||
|
CLUTTER_CHILD_DATA_GET_CLASS
|
||||||
|
<SUBSECTION Private>
|
||||||
|
clutter_child_data_get_type
|
||||||
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>clutter-rectangle</FILE>
|
<FILE>clutter-rectangle</FILE>
|
||||||
<TITLE>ClutterRectangle</TITLE>
|
<TITLE>ClutterRectangle</TITLE>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user