2006-07-06 Emmanuele Bassi <ebassi@openedhand.com>

Big rework of the actor management semantics: now ClutterActor
	objects behave like GtkObjects - that is they have an initial
	"floating" reference that gets "sunk" when they are added to
	a ClutterGroup.  This makes a group responsible of de-allocating
	each actor inside it, so you just have to destroy the group to
	get every child actor destroyed.  Also, now you can do:

	  clutter_group_add (group, clutter_video_texture_new ());
	
	without having to care about reference counting and explicit
	unreffing.

	* clutter/clutter-private.h: Add private flags setter and
	getter macros.

	* clutter/clutter-actor.h:
	* clutter/clutter-actor.c: Clean up; inherit from GInitiallyUnowned;
	add a "visible" property; add the "destroy", "show" and "hide"
	signals to ClutterActorClass.

	(clutter_actor_show), (clutter_actor_hide): Refactor a bit; emit
	the "show" and "hide" signals.

	(clutter_actor_set_property), (clutter_actor_get_property),
	(clutter_actor_class_init): Implement the "visible" property; add
	signals.

	(clutter_actor_finalize): Do not leak the actor's name, if it is
	set.
	
	(clutter_actor_dispose): Emit the "destroy" signal here.

	(clutter_actor_init): Sink the initial floating flag if needed.

	(clutter_actor_destroy): Add a function to explicitely destroy
	a ClutterActor.

	(clutter_actor_set_parent), (clutter_actor_get_parent),
	(clutter_actor_unparent): Make set_parent require a valid parent;
	add unparent; check on get_parent; ref_sink the actor when
	setting its parent and unref it when unsetting it.  Probably we'll
	need a function that does reparenting as unparent+set_parent in
	a single shot.

	* clutter/clutter-group.h:
	* clutter/clutter-group.c (clutter_group_dispose),
	(clutter_group_finalize), (clutter_group_add),
	(clutter_group_remove): Make the group destroy its children when
	disposing it; clean up, and use the newly-available
	clutter_actor_unparent().

	* clutter/clutter-stage.h:
	* clutter/clutter-stage.c (clutter_stage_init): ClutterStage is
	a top-level actor; clean up.

	* clutter/clutter-video-texture.h:
	* clutter/clutter-video-texture.c: Clean up.

	* examples/super-oh.c:
	* examples/test.c:
	* examples/video-player.c:
	* examples/test-text.c:
	* examples/video-cube.c: Remove the g_object_unref() call, as the
	ClutterStage object is destroyed on clutter_main_quit().
This commit is contained in:
Emmanuele Bassi 2006-07-06 17:52:57 +00:00
parent 8692008027
commit 212c4a0ee8
16 changed files with 490 additions and 374 deletions

View File

@ -1,3 +1,70 @@
2006-07-06 Emmanuele Bassi <ebassi@openedhand.com>
Big rework of the actor management semantics: now ClutterActor
objects behave like GtkObjects - that is they have an initial
"floating" reference that gets "sunk" when they are added to
a ClutterGroup. This makes a group responsible of de-allocating
each actor inside it, so you just have to destroy the group to
get every child actor destroyed. Also, now you can do:
clutter_group_add (group, clutter_video_texture_new ());
without having to care about reference counting and explicit
unreffing.
* clutter/clutter-private.h: Add private flags setter and
getter macros.
* clutter/clutter-actor.h:
* clutter/clutter-actor.c: Clean up; inherit from GInitiallyUnowned;
add a "visible" property; add the "destroy", "show" and "hide"
signals to ClutterActorClass.
(clutter_actor_show), (clutter_actor_hide): Refactor a bit; emit
the "show" and "hide" signals.
(clutter_actor_set_property), (clutter_actor_get_property),
(clutter_actor_class_init): Implement the "visible" property; add
signals.
(clutter_actor_finalize): Do not leak the actor's name, if it is
set.
(clutter_actor_dispose): Emit the "destroy" signal here.
(clutter_actor_init): Sink the initial floating flag if needed.
(clutter_actor_destroy): Add a function to explicitely destroy
a ClutterActor.
(clutter_actor_set_parent), (clutter_actor_get_parent),
(clutter_actor_unparent): Make set_parent require a valid parent;
add unparent; check on get_parent; ref_sink the actor when
setting its parent and unref it when unsetting it. Probably we'll
need a function that does reparenting as unparent+set_parent in
a single shot.
* clutter/clutter-group.h:
* clutter/clutter-group.c (clutter_group_dispose),
(clutter_group_finalize), (clutter_group_add),
(clutter_group_remove): Make the group destroy its children when
disposing it; clean up, and use the newly-available
clutter_actor_unparent().
* clutter/clutter-stage.h:
* clutter/clutter-stage.c (clutter_stage_init): ClutterStage is
a top-level actor; clean up.
* clutter/clutter-video-texture.h:
* clutter/clutter-video-texture.c: Clean up.
* examples/super-oh.c:
* examples/test.c:
* examples/video-player.c:
* examples/test-text.c:
* examples/video-cube.c: Remove the g_object_unref() call, as the
ClutterStage object is destroyed on clutter_main_quit().
2006-06-23 Matthew Allum <mallum@openedhand.com> 2006-06-23 Matthew Allum <mallum@openedhand.com>
* examples/super-oh.c: * examples/super-oh.c:

View File

@ -34,12 +34,17 @@
#include "clutter-actor.h" #include "clutter-actor.h"
#include "clutter-main.h" #include "clutter-main.h"
#include "clutter-enum-types.h"
#include "clutter-marshal.h"
#include "clutter-private.h" #include "clutter-private.h"
G_DEFINE_ABSTRACT_TYPE (ClutterActor, clutter_actor, G_TYPE_OBJECT); G_DEFINE_ABSTRACT_TYPE (ClutterActor,
clutter_actor,
G_TYPE_INITIALLY_UNOWNED);
static guint32 __id = 0; static guint32 __id = 0;
#define CLUTTER_ACTOR_GET_PRIVATE(obj) \ #define CLUTTER_ACTOR_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_ACTOR, ClutterActorPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_ACTOR, ClutterActorPrivate))
@ -48,15 +53,18 @@ struct _ClutterActorPrivate
ClutterActorBox coords; ClutterActorBox coords;
ClutterGeometry clip; ClutterGeometry clip;
gboolean has_clip; guint has_clip : 1;
gfloat rxang, ryang, rzang; /* Rotation foo. */ gfloat rxang, ryang, rzang; /* Rotation foo. */
gint rzx, rzy, rxy, rxz, ryx, ryz; gint rzx, rzy, rxy, rxz, ryx, ryz;
gint z; /* to actor box ? */ gint z; /* to actor box ? */
guint8 opacity; guint8 opacity;
ClutterActor *parent_actor; /* This should always be a group */ ClutterActor *parent_actor; /* This should always be a group */
gchar *name; gchar *name;
guint32 id; /* Unique ID */ guint32 id; /* Unique ID */
}; };
@ -67,11 +75,24 @@ enum
PROP_Y, PROP_Y,
PROP_WIDTH, PROP_WIDTH,
PROP_HEIGHT, PROP_HEIGHT,
/* PROP_CLIP FIXME: add */ PROP_CLIP,
PROP_HAS_CLIP,
PROP_OPACITY, PROP_OPACITY,
PROP_NAME, PROP_NAME,
PROP_VISIBLE
}; };
enum
{
SHOW,
HIDE,
DESTROY,
LAST_SIGNAL
};
static guint actor_signals[LAST_SIGNAL] = { 0, };
static gboolean static gboolean
redraw_update_idle (gpointer data) redraw_update_idle (gpointer data)
{ {
@ -102,10 +123,11 @@ redraw_update_idle (gpointer data)
void void
clutter_actor_show (ClutterActor *self) clutter_actor_show (ClutterActor *self)
{ {
if (!CLUTTER_ACTOR_IS_VISIBLE (self))
{
ClutterActorClass *klass; ClutterActorClass *klass;
if (CLUTTER_ACTOR_IS_VISIBLE (self)) g_object_ref (self);
return;
if (!CLUTTER_ACTOR_IS_REALIZED (self)) if (!CLUTTER_ACTOR_IS_REALIZED (self))
clutter_actor_realize(self); clutter_actor_realize(self);
@ -113,12 +135,17 @@ clutter_actor_show (ClutterActor *self)
CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_MAPPED); CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_MAPPED);
klass = CLUTTER_ACTOR_GET_CLASS (self); klass = CLUTTER_ACTOR_GET_CLASS (self);
if (klass->show) if (klass->show)
(klass->show) (self); (klass->show) (self);
if (CLUTTER_ACTOR_IS_VISIBLE (self)) if (CLUTTER_ACTOR_IS_VISIBLE (self))
clutter_actor_queue_redraw (self); clutter_actor_queue_redraw (self);
g_signal_emit (self, actor_signals[SHOW], 0);
g_object_notify (G_OBJECT (self), "visible");
g_object_unref (self);
}
} }
/** /**
@ -131,19 +158,25 @@ clutter_actor_show (ClutterActor *self)
void void
clutter_actor_hide (ClutterActor *self) clutter_actor_hide (ClutterActor *self)
{ {
if (CLUTTER_ACTOR_IS_VISIBLE (self))
{
ClutterActorClass *klass; ClutterActorClass *klass;
if (!CLUTTER_ACTOR_IS_VISIBLE (self)) g_object_ref (self);
return;
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_MAPPED); CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_MAPPED);
klass = CLUTTER_ACTOR_GET_CLASS (self); klass = CLUTTER_ACTOR_GET_CLASS (self);
if (klass->hide) if (klass->hide)
(klass->hide) (self); (klass->hide) (self);
clutter_actor_queue_redraw (self); clutter_actor_queue_redraw (self);
g_signal_emit (self, actor_signals[HIDE], 0);
g_object_notify (G_OBJECT (self), "visible");
g_object_unref (self);
}
} }
/** /**
@ -324,7 +357,7 @@ clutter_actor_request_coords (ClutterActor *self,
/* FIXME: Kludgy see allocate co-ords */ /* FIXME: Kludgy see allocate co-ords */
if (klass->request_coords) if (klass->request_coords)
klass->request_coords(self, box); klass->request_coords (self, box);
x_change = (self->priv->coords.x1 != box->x1); x_change = (self->priv->coords.x1 != box->x1);
y_change = (self->priv->coords.y1 != box->y1); y_change = (self->priv->coords.y1 != box->y1);
@ -437,6 +470,12 @@ clutter_actor_set_property (GObject *object,
case PROP_NAME: case PROP_NAME:
clutter_actor_set_name (actor, g_value_get_string (value)); clutter_actor_set_name (actor, g_value_get_string (value));
break; break;
case PROP_VISIBLE:
if (g_value_get_boolean (value) == TRUE)
clutter_actor_show (actor);
else
clutter_actor_hide (actor);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -475,6 +514,10 @@ clutter_actor_get_property (GObject *object,
case PROP_NAME: case PROP_NAME:
g_value_set_string (value, priv->name); g_value_set_string (value, priv->name);
break; break;
case PROP_VISIBLE:
g_value_set_boolean (value,
(CLUTTER_ACTOR_IS_VISIBLE (actor) != FALSE));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -484,11 +527,19 @@ clutter_actor_get_property (GObject *object,
static void static void
clutter_actor_dispose (GObject *object) clutter_actor_dispose (GObject *object)
{ {
ClutterActor *self = CLUTTER_ACTOR(object); ClutterActor *self = CLUTTER_ACTOR (object);
if (self->priv->parent_actor) CLUTTER_DBG ("Disposing of object (id=%d) of type `%s'",
self->priv->id,
g_type_name (G_OBJECT_TYPE (self)));
if (!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IN_DESTRUCTION))
{ {
clutter_group_remove (CLUTTER_GROUP(self->priv->parent_actor), self); CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_DESTRUCTION);
g_signal_emit (self, actor_signals[DESTROY], 0);
CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_DESTRUCTION);
} }
G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object); G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object);
@ -497,6 +548,10 @@ clutter_actor_dispose (GObject *object)
static void static void
clutter_actor_finalize (GObject *object) clutter_actor_finalize (GObject *object)
{ {
ClutterActor *actor = CLUTTER_ACTOR (object);
g_free (actor->priv->name);
G_OBJECT_CLASS (clutter_actor_parent_class)->finalize (object); G_OBJECT_CLASS (clutter_actor_parent_class)->finalize (object);
} }
@ -512,8 +567,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
g_type_class_add_private (klass, sizeof (ClutterActorPrivate)); g_type_class_add_private (klass, sizeof (ClutterActorPrivate));
g_object_class_install_property g_object_class_install_property (object_class, PROP_X,
(object_class, PROP_X,
g_param_spec_int ("x", g_param_spec_int ("x",
"X co-ord", "X co-ord",
"X co-ord of actor", "X co-ord of actor",
@ -522,8 +576,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
0, 0,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property g_object_class_install_property (object_class, PROP_Y,
(object_class, PROP_Y,
g_param_spec_int ("y", g_param_spec_int ("y",
"Y co-ord", "Y co-ord",
"Y co-ord of actor", "Y co-ord of actor",
@ -532,8 +585,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
0, 0,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property g_object_class_install_property (object_class, PROP_WIDTH,
(object_class, PROP_WIDTH,
g_param_spec_int ("width", g_param_spec_int ("width",
"Width", "Width",
"Width of actor in pixels", "Width of actor in pixels",
@ -542,8 +594,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
0, 0,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property g_object_class_install_property (object_class, PROP_HEIGHT,
(object_class, PROP_HEIGHT,
g_param_spec_int ("height", g_param_spec_int ("height",
"Height", "Height",
"Height of actor in pixels", "Height of actor in pixels",
@ -552,8 +603,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
0, 0,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property g_object_class_install_property (object_class, PROP_OPACITY,
(object_class, PROP_OPACITY,
g_param_spec_uchar ("opacity", g_param_spec_uchar ("opacity",
"Opacity", "Opacity",
"Opacity of actor", "Opacity of actor",
@ -562,11 +612,49 @@ clutter_actor_class_init (ClutterActorClass *klass)
0xff, 0xff,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_VISIBLE,
g_param_spec_boolean ("visible",
"Visible",
"Whether the actor is visible or not",
FALSE,
G_PARAM_READABLE));
actor_signals[DESTROY] =
g_signal_new ("destroy",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
G_STRUCT_OFFSET (ClutterActorClass, destroy),
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
actor_signals[SHOW] =
g_signal_new ("show",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ClutterActorClass, show),
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
actor_signals[HIDE] =
g_signal_new ("hide",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ClutterActorClass, hide),
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
} }
static void static void
clutter_actor_init (ClutterActor *self) clutter_actor_init (ClutterActor *self)
{ {
gboolean was_floating;
/* sink the GInitiallyUnowned floating flag */
was_floating = g_object_is_floating (G_OBJECT (self));
if (was_floating)
g_object_force_floating (G_OBJECT (self));
self->priv = CLUTTER_ACTOR_GET_PRIVATE (self); self->priv = CLUTTER_ACTOR_GET_PRIVATE (self);
self->priv->parent_actor = NULL; self->priv->parent_actor = NULL;
@ -578,6 +666,25 @@ clutter_actor_init (ClutterActor *self)
clutter_actor_set_size (self, 0, 0); clutter_actor_set_size (self, 0, 0);
} }
/**
* clutter_actor_destroy:
* @self: a #ClutterActor
*
* Destroys an actor. When an actor is destroyed, it will break any
* references it holds to other objects. If the actor is inside a
* group, the actor will be removed from the group.
*
* When you destroy a group its children will be destroyed as well.
*/
void
clutter_actor_destroy (ClutterActor *self)
{
g_return_if_fail (CLUTTER_IS_ACTOR (self));
if (!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IN_DESTRUCTION))
g_object_run_dispose (G_OBJECT (self));
}
/** /**
* clutter_actor_queue_redraw: * clutter_actor_queue_redraw:
* @self: A #ClutterActor * @self: A #ClutterActor
@ -615,7 +722,7 @@ clutter_actor_queue_redraw (ClutterActor *self)
*/ */
void void
clutter_actor_set_geometry (ClutterActor *self, clutter_actor_set_geometry (ClutterActor *self,
ClutterGeometry *geom) const ClutterGeometry *geom)
{ {
ClutterActorBox box; ClutterActorBox box;
@ -906,10 +1013,10 @@ clutter_actor_set_name (ClutterActor *self,
{ {
g_return_if_fail (CLUTTER_IS_ACTOR (self)); g_return_if_fail (CLUTTER_IS_ACTOR (self));
if (name || name[0] != '\0')
{
g_free (self->priv->name); g_free (self->priv->name);
if (name || name[0] != '\0')
{
self->priv->name = g_strdup(name); self->priv->name = g_strdup(name);
} }
} }
@ -924,7 +1031,7 @@ clutter_actor_set_name (ClutterActor *self,
* returned string is owned by the actor and should not * returned string is owned by the actor and should not
* be modified or freed. * be modified or freed.
*/ */
const gchar* G_CONST_RETURN gchar *
clutter_actor_get_name (ClutterActor *self) clutter_actor_get_name (ClutterActor *self)
{ {
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL);
@ -1088,7 +1195,7 @@ clutter_actor_set_clip (ClutterActor *self,
g_return_if_fail (CLUTTER_IS_ACTOR (self)); g_return_if_fail (CLUTTER_IS_ACTOR (self));
clip = &self->priv->clip; clip = &(self->priv->clip);
clip->x = xoff; clip->x = xoff;
clip->y = yoff; clip->y = yoff;
@ -1115,9 +1222,11 @@ clutter_actor_remove_clip (ClutterActor *self)
/** /**
* clutter_actor_set_parent: * clutter_actor_set_parent:
* @self: A #ClutterActor * @self: A #ClutterActor
* @parent: A new #ClutterActor parent or NULL * @parent: A new #ClutterActor parent
*
* Sets the parent of @self to @parent. The opposite function is
* clutter_actor_unparent().
* *
* Sets the parent of @self to @parent.
* This function should not be used by applications. * This function should not be used by applications.
*/ */
void void
@ -1125,18 +1234,30 @@ clutter_actor_set_parent (ClutterActor *self,
ClutterActor *parent) ClutterActor *parent)
{ {
g_return_if_fail (CLUTTER_IS_ACTOR (self)); g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail ((parent == NULL) || CLUTTER_IS_ACTOR (parent)); g_return_if_fail (CLUTTER_IS_ACTOR (parent));
g_return_if_fail (self != parent);
if (self->priv->parent_actor != NULL)
{
g_warning ("Cannot set a parent on an actor which has a parent.\n"
"You must use clutter_actor_unparent() first.\n");
if (self->priv->parent_actor == parent)
return; return;
}
if (self->priv->parent_actor && self->priv->parent_actor != parent) if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IS_TOPLEVEL)
g_object_unref (self->priv->parent_actor); {
g_warning ("Cannot set a parent on a toplevel actor\n");
return;
}
g_object_ref_sink (self);
self->priv->parent_actor = parent; self->priv->parent_actor = parent;
if (self->priv->parent_actor) if (CLUTTER_ACTOR_IS_VISIBLE (self->priv->parent_actor) &&
g_object_ref (self->priv->parent_actor); CLUTTER_ACTOR_IS_VISIBLE (self))
clutter_actor_queue_redraw (self);
} }
/** /**
@ -1147,12 +1268,33 @@ clutter_actor_set_parent (ClutterActor *self,
* *
* Return Value: The #ClutterActor parent or NULL * Return Value: The #ClutterActor parent or NULL
*/ */
ClutterActor* ClutterActor *
clutter_actor_get_parent (ClutterActor *self) clutter_actor_get_parent (ClutterActor *self)
{ {
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL);
return self->priv->parent_actor; return self->priv->parent_actor;
} }
/**
* clutter_actor_unparent:
* @self: a #ClutterActor
*
* This function should not be used in applications. It should be called by
* implementations of group actors, to dissociate a child from the container.
*/
void
clutter_actor_unparent (ClutterActor *self)
{
g_return_if_fail (CLUTTER_IS_ACTOR (self));
if (self->priv->parent_actor == NULL)
return;
self->priv->parent_actor = NULL;
g_object_unref (self);
}
/** /**
* clutter_actor_raise: * clutter_actor_raise:
* @self: A #ClutterActor * @self: A #ClutterActor

View File

@ -63,6 +63,7 @@ typedef struct _ClutterActorPrivate ClutterActorPrivate;
typedef struct _ClutterGeometry ClutterGeometry; typedef struct _ClutterGeometry ClutterGeometry;
typedef void (*ClutterCallback) (ClutterActor *actor, gpointer data); typedef void (*ClutterCallback) (ClutterActor *actor, gpointer data);
#define CLUTTER_CALLBACK(f) ((ClutterCallback) (f))
struct _ClutterGeometry struct _ClutterGeometry
{ {
@ -87,10 +88,12 @@ GType clutter_actor_box_get_type (void) G_GNUC_CONST;
struct _ClutterActor struct _ClutterActor
{ {
/*< public >*/ /*< public >*/
GObject parent; GObject parent_instance;
guint32 flags; guint32 flags;
/*< private >*/ /*< private >*/
guint32 private_flags;
ClutterActorPrivate *priv; ClutterActorPrivate *priv;
}; };
@ -111,6 +114,8 @@ struct _ClutterActorClass
gint depth); gint depth);
gint (* get_depth) (ClutterActor *actor); gint (* get_depth) (ClutterActor *actor);
void (*destroy) (ClutterActor *actor);
/* to go ? */ /* to go ? */
void (* show_all) (ClutterActor *actor); void (* show_all) (ClutterActor *actor);
void (* hide_all) (ClutterActor *actor); void (* hide_all) (ClutterActor *actor);
@ -125,145 +130,80 @@ struct _ClutterActorClass
void (*_clutter_actor_6) (void); void (*_clutter_actor_6) (void);
}; };
GType clutter_actor_get_type (void); GType clutter_actor_get_type (void) G_GNUC_CONST;
void clutter_actor_show (ClutterActor *self);
void void clutter_actor_hide (ClutterActor *self);
clutter_actor_show (ClutterActor *self); void clutter_actor_realize (ClutterActor *self);
void clutter_actor_unrealize (ClutterActor *self);
void void clutter_actor_paint (ClutterActor *self);
clutter_actor_hide (ClutterActor *self); void clutter_actor_queue_redraw (ClutterActor *self);
void clutter_actor_destroy (ClutterActor *self);
void void clutter_actor_request_coords (ClutterActor *self,
clutter_actor_realize (ClutterActor *self);
void
clutter_actor_unrealize (ClutterActor *self);
void
clutter_actor_paint (ClutterActor *self);
void
clutter_actor_queue_redraw (ClutterActor *self);
void
clutter_actor_request_coords (ClutterActor *self,
ClutterActorBox *box); ClutterActorBox *box);
void clutter_actor_allocate_coords (ClutterActor *self,
void
clutter_actor_allocate_coords (ClutterActor *self,
ClutterActorBox *box); ClutterActorBox *box);
void clutter_actor_set_geometry (ClutterActor *self,
void const ClutterGeometry *geometry);
clutter_actor_set_geometry (ClutterActor *self, void clutter_actor_get_geometry (ClutterActor *self,
ClutterGeometry *geom); ClutterGeometry *geometry);
void clutter_actor_get_coords (ClutterActor *self,
void
clutter_actor_get_geometry (ClutterActor *self,
ClutterGeometry *geom);
void
clutter_actor_get_coords (ClutterActor *self,
gint *x1, gint *x1,
gint *y1, gint *y1,
gint *x2, gint *x2,
gint *y2); gint *y2);
void clutter_actor_set_size (ClutterActor *self,
void
clutter_actor_set_position (ClutterActor *self,
gint x,
gint y);
void
clutter_actor_set_size (ClutterActor *self,
gint width, gint width,
gint height); gint height);
void clutter_actor_set_position (ClutterActor *self,
void
clutter_actor_get_abs_position (ClutterActor *self,
gint *x,
gint *y);
guint
clutter_actor_get_width (ClutterActor *self);
guint
clutter_actor_get_height (ClutterActor *self);
gint
clutter_actor_get_x (ClutterActor *self);
gint
clutter_actor_get_y (ClutterActor *self);
void
clutter_actor_rotate_z (ClutterActor *self,
gfloat angle,
gint x, gint x,
gint y); gint y);
void clutter_actor_get_abs_position (ClutterActor *self,
void gint *x,
clutter_actor_rotate_x (ClutterActor *self, gint *y);
guint clutter_actor_get_width (ClutterActor *self);
guint clutter_actor_get_height (ClutterActor *self);
gint clutter_actor_get_x (ClutterActor *self);
gint clutter_actor_get_y (ClutterActor *self);
void clutter_actor_rotate_x (ClutterActor *self,
gfloat angle, gfloat angle,
gint y, gint y,
gint z); gint z);
void clutter_actor_rotate_y (ClutterActor *self,
void
clutter_actor_rotate_y (ClutterActor *self,
gfloat angle, gfloat angle,
gint x, gint x,
gint z); gint z);
void clutter_actor_rotate_z (ClutterActor *self,
void gfloat angle,
clutter_actor_set_opacity (ClutterActor *self, gint x,
gint y);
void clutter_actor_set_opacity (ClutterActor *self,
guint8 opacity); guint8 opacity);
guint8 clutter_actor_get_opacity (ClutterActor *self);
guint8 void clutter_actor_set_name (ClutterActor *self,
clutter_actor_get_opacity (ClutterActor *self); const gchar *name);
G_CONST_RETURN gchar *clutter_actor_get_name (ClutterActor *self);
void guint32 clutter_actor_get_id (ClutterActor *self);
clutter_actor_set_name (ClutterActor *self, void clutter_actor_set_clip (ClutterActor *self,
const gchar *id);
const gchar*
clutter_actor_get_name (ClutterActor *self);
guint32
clutter_actor_get_id (ClutterActor *self);
void
clutter_actor_set_clip (ClutterActor *self,
gint xoff, gint xoff,
gint yoff, gint yoff,
gint width, gint width,
gint height); gint height);
void clutter_actor_remove_clip (ClutterActor *self);
void void clutter_actor_set_parent (ClutterActor *self,
clutter_actor_remove_clip (ClutterActor *self); ClutterActor *parent);
ClutterActor * clutter_actor_get_parent (ClutterActor *self);
void void clutter_actor_reparent (ClutterActor *self,
clutter_actor_set_parent (ClutterActor *self, ClutterActor *parent); ClutterActor *new_parent);
void clutter_actor_unparent (ClutterActor *self);
ClutterActor* void clutter_actor_raise (ClutterActor *self,
clutter_actor_get_parent (ClutterActor *self); ClutterActor *below);
void clutter_actor_lower (ClutterActor *self,
void ClutterActor *above);
clutter_actor_raise (ClutterActor *self, ClutterActor *below); void clutter_actor_raise_top (ClutterActor *self);
void clutter_actor_lower_bottom (ClutterActor *self);
void void clutter_actor_set_depth (ClutterActor *self,
clutter_actor_lower (ClutterActor *self, ClutterActor *above);
void
clutter_actor_raise_top (ClutterActor *self);
void
clutter_actor_lower_bottom (ClutterActor *self);
void
clutter_actor_set_depth (ClutterActor *self,
gint depth); gint depth);
gint clutter_actor_get_depth (ClutterActor *self);
gint
clutter_actor_get_depth (ClutterActor *self);
G_END_DECLS G_END_DECLS

View File

@ -200,15 +200,11 @@ clutter_group_allocate_coords (ClutterActor *self,
static void static void
clutter_group_dispose (GObject *object) clutter_group_dispose (GObject *object)
{ {
ClutterGroup *self = CLUTTER_GROUP(object); ClutterGroup *self = CLUTTER_GROUP (object);
if (self->priv) clutter_group_foreach (self,
{ CLUTTER_CALLBACK (clutter_actor_destroy),
/* FIXME: Do we need to actually free anything here ? NULL);
* Children ref us so this wont get called till
* they are all removed.
*/
}
G_OBJECT_CLASS (clutter_group_parent_class)->dispose (object); G_OBJECT_CLASS (clutter_group_parent_class)->dispose (object);
} }
@ -217,17 +213,6 @@ clutter_group_dispose (GObject *object)
static void static void
clutter_group_finalize (GObject *object) clutter_group_finalize (GObject *object)
{ {
ClutterGroup *group = CLUTTER_GROUP (object);
/* XXX - if something survives ::dispose then there's something
* wrong; but, at least, we won't leak stuff around.
*/
if (group->priv->children)
{
g_list_foreach (group->priv->children, (GFunc) g_object_unref, NULL);
g_list_free (group->priv->children);
}
G_OBJECT_CLASS (clutter_group_parent_class)->finalize (object); G_OBJECT_CLASS (clutter_group_parent_class)->finalize (object);
} }
@ -285,7 +270,7 @@ clutter_group_init (ClutterGroup *self)
* *
* returns a new #ClutterGroup * returns a new #ClutterGroup
**/ **/
ClutterGroup* ClutterActor *
clutter_group_new (void) clutter_group_new (void)
{ {
return g_object_new (CLUTTER_TYPE_GROUP, NULL); return g_object_new (CLUTTER_TYPE_GROUP, NULL);
@ -405,14 +390,16 @@ clutter_group_add (ClutterGroup *self,
return; return;
} }
self->priv->children = g_list_append (self->priv->children, actor);
/* below refs */
clutter_actor_set_parent (actor, CLUTTER_ACTOR(self));
g_object_ref (actor); g_object_ref (actor);
self->priv->children = g_list_append (self->priv->children, actor);
clutter_actor_set_parent (actor, CLUTTER_ACTOR (self));
clutter_group_sort_depth_order (self); clutter_group_sort_depth_order (self);
g_signal_emit (self, group_signals[ADD], 0, actor); g_signal_emit (self, group_signals[ADD], 0, actor);
g_object_unref (actor);
} }
/** /**
@ -479,6 +466,8 @@ clutter_group_remove (ClutterGroup *self,
g_return_if_fail (CLUTTER_IS_GROUP (self)); g_return_if_fail (CLUTTER_IS_GROUP (self));
g_return_if_fail (CLUTTER_IS_ACTOR (actor)); g_return_if_fail (CLUTTER_IS_ACTOR (actor));
g_object_ref (actor);
parent = clutter_actor_get_parent (actor); parent = clutter_actor_get_parent (actor);
if (parent != CLUTTER_ACTOR (self)) if (parent != CLUTTER_ACTOR (self))
{ {
@ -490,10 +479,16 @@ clutter_group_remove (ClutterGroup *self,
return; return;
} }
g_object_ref (actor);
self->priv->children = g_list_remove (self->priv->children, actor); self->priv->children = g_list_remove (self->priv->children, actor);
clutter_actor_set_parent (actor, NULL); clutter_actor_unparent (actor);
g_signal_emit (self, group_signals[REMOVE], 0, actor); g_signal_emit (self, group_signals[REMOVE], 0, actor);
if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (self)))
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
g_object_unref (actor); g_object_unref (actor);
} }

View File

@ -59,7 +59,7 @@ typedef struct _ClutterGroupPrivate ClutterGroupPrivate;
struct _ClutterGroup struct _ClutterGroup
{ {
ClutterActor parent; ClutterActor parent_instance;
/*< private >*/ /*< private >*/
ClutterGroupPrivate *priv; ClutterGroupPrivate *priv;
@ -84,57 +84,33 @@ struct _ClutterGroupClass
void (*_clutter_group_6) (void); void (*_clutter_group_6) (void);
}; };
GType clutter_group_get_type (void); GType clutter_group_get_type (void) G_GNUC_CONST;
ClutterActor *clutter_group_new (void);
ClutterGroup *clutter_group_new (void); GList * clutter_group_get_children (ClutterGroup *self);
void clutter_group_foreach (ClutterGroup *self,
GList*
clutter_group_get_children (ClutterGroup *self);
void
clutter_group_foreach (ClutterGroup *self,
ClutterCallback callback, ClutterCallback callback,
gpointer user_data); gpointer user_data);
void clutter_group_add (ClutterGroup *self,
void
clutter_group_add (ClutterGroup *self,
ClutterActor *actor); ClutterActor *actor);
void clutter_group_add_many_valist (ClutterGroup *self,
void
clutter_group_add_many_valist (ClutterGroup *self,
ClutterActor *first_actor, ClutterActor *first_actor,
va_list args); va_list args);
void clutter_group_add_many (ClutterGroup *self,
void
clutter_group_add_many (ClutterGroup *self,
ClutterActor *first_actor, ClutterActor *first_actor,
...) G_GNUC_NULL_TERMINATED; ...) G_GNUC_NULL_TERMINATED;
void clutter_group_remove (ClutterGroup *self,
void
clutter_group_remove (ClutterGroup *self,
ClutterActor *actor); ClutterActor *actor);
void clutter_group_show_all (ClutterGroup *self);
void void clutter_group_hide_all (ClutterGroup *self);
clutter_group_show_all (ClutterGroup *self); ClutterActor *clutter_group_find_child_by_id (ClutterGroup *self,
guint id);
void void clutter_group_raise (ClutterGroup *self,
clutter_group_hide_all (ClutterGroup *self);
ClutterActor *
clutter_group_find_child_by_id (ClutterGroup *self, guint id);
void
clutter_group_raise (ClutterGroup *self,
ClutterActor *actor, ClutterActor *actor,
ClutterActor *sibling); ClutterActor *sibling);
void clutter_group_lower (ClutterGroup *self,
void
clutter_group_lower (ClutterGroup *self,
ClutterActor *actor, ClutterActor *actor,
ClutterActor *sibling); ClutterActor *sibling);
void clutter_group_sort_depth_order (ClutterGroup *self);
void
clutter_group_sort_depth_order (ClutterGroup *self);
G_END_DECLS G_END_DECLS

View File

@ -26,8 +26,6 @@
#ifndef _HAVE_CLUTTER_PRIVATE_H #ifndef _HAVE_CLUTTER_PRIVATE_H
#define _HAVE_CLUTTER_PRIVATE_H #define _HAVE_CLUTTER_PRIVATE_H
#include <config.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -45,6 +43,8 @@
#include <pango/pangoft2.h> #include <pango/pangoft2.h>
G_BEGIN_DECLS
typedef struct _ClutterMainContext ClutterMainContext; typedef struct _ClutterMainContext ClutterMainContext;
struct _ClutterMainContext struct _ClutterMainContext
@ -70,4 +70,18 @@ struct _ClutterMainContext
#define CLUTTER_CONTEXT() (clutter_context_get_default ()) #define CLUTTER_CONTEXT() (clutter_context_get_default ())
ClutterMainContext *clutter_context_get_default (void); ClutterMainContext *clutter_context_get_default (void);
typedef enum {
CLUTTER_ACTOR_UNUSED_FLAG = 0,
CLUTTER_ACTOR_IN_DESTRUCTION = 1 << 0,
CLUTTER_ACTOR_IS_TOPLEVEL = 1 << 1
} ClutterPrivateFlags;
#define CLUTTER_PRIVATE_FLAGS(a) (CLUTTER_ACTOR ((a))->private_flags)
#define CLUTTER_SET_PRIVATE_FLAGS(a,f) G_STMT_START{ (CLUTTER_PRIVATE_FLAGS (a) |= (f)); }G_STMT_END
#define CLUTTER_UNSET_PRIVATE_FLAGS(a,f) G_STMT_START{ (CLUTTER_PRIVATE_FLAGS (a) &= ~(f)); }G_STMT_END
G_END_DECLS
#endif #endif

View File

@ -731,6 +731,9 @@ clutter_stage_init (ClutterStage *self)
{ {
ClutterStagePrivate *priv; ClutterStagePrivate *priv;
/* a stage is a top-level object */
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IS_TOPLEVEL);
self->priv = priv = CLUTTER_STAGE_GET_PRIVATE (self); self->priv = priv = CLUTTER_STAGE_GET_PRIVATE (self);
priv->want_offscreen = FALSE; priv->want_offscreen = FALSE;

View File

@ -39,7 +39,7 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define CLUTTER_TYPE_STAGE clutter_stage_get_type() #define CLUTTER_TYPE_STAGE (clutter_stage_get_type())
#define CLUTTER_STAGE_WIDTH() \ #define CLUTTER_STAGE_WIDTH() \
clutter_actor_get_width(CLUTTER_ACTOR(clutter_stage_get_default())) clutter_actor_get_width(CLUTTER_ACTOR(clutter_stage_get_default()))
@ -106,25 +106,18 @@ struct _ClutterStageClass
void (*_clutter_stage6) (void); void (*_clutter_stage6) (void);
}; };
GType clutter_stage_get_type (void); GType clutter_stage_get_type (void) G_GNUC_CONST;
ClutterActor *clutter_stage_get_default (void); ClutterActor *clutter_stage_get_default (void);
Window clutter_stage_get_xwindow (ClutterStage *stage); Window clutter_stage_get_xwindow (ClutterStage *stage);
gboolean clutter_stage_set_xwindow_foreign (ClutterStage *stage, gboolean clutter_stage_set_xwindow_foreign (ClutterStage *stage,
Window xid); Window xid);
void clutter_stage_set_color (ClutterStage *stage, void clutter_stage_set_color (ClutterStage *stage,
const ClutterColor *color); const ClutterColor *color);
void clutter_stage_get_color (ClutterStage *stage, void clutter_stage_get_color (ClutterStage *stage,
ClutterColor *color); ClutterColor *color);
ClutterActor *clutter_stage_get_actor_at_pos (ClutterStage *stage, ClutterActor *clutter_stage_get_actor_at_pos (ClutterStage *stage,
gint x, gint x,
gint y); gint y);
GdkPixbuf * clutter_stage_snapshot (ClutterStage *stage, GdkPixbuf * clutter_stage_snapshot (ClutterStage *stage,
gint x, gint x,
gint y, gint y,

View File

@ -44,7 +44,7 @@
#include <glib.h> #include <glib.h>
struct ClutterVideoTexturePrivate struct _ClutterVideoTexturePrivate
{ {
GstElement *playbin; GstElement *playbin;
char *uri; char *uri;
@ -101,7 +101,6 @@ set_uri (ClutterMedia *media,
if (!priv->playbin) if (!priv->playbin)
return; return;
if (priv->uri)
g_free (priv->uri); g_free (priv->uri);
if (uri) if (uri)

View File

@ -58,7 +58,7 @@ G_BEGIN_DECLS
typedef struct _ClutterVideoTexture ClutterVideoTexture; typedef struct _ClutterVideoTexture ClutterVideoTexture;
typedef struct _ClutterVideoTextureClass ClutterVideoTextureClass; typedef struct _ClutterVideoTextureClass ClutterVideoTextureClass;
typedef struct ClutterVideoTexturePrivate ClutterVideoTexturePrivate; typedef struct _ClutterVideoTexturePrivate ClutterVideoTexturePrivate;
/* #define CLUTTER_VIDEO_TEXTURE_ERROR clutter_video_texture_error_quark() */ /* #define CLUTTER_VIDEO_TEXTURE_ERROR clutter_video_texture_error_quark() */
@ -88,10 +88,8 @@ struct _ClutterVideoTextureClass
void (* _clutter_reserved6) (void); void (* _clutter_reserved6) (void);
}; };
GType clutter_video_texture_get_type (void); GType clutter_video_texture_get_type (void) G_GNUC_CONST;
ClutterActor *clutter_video_texture_new (void);
ClutterActor*
clutter_video_texture_new (void);
G_END_DECLS G_END_DECLS

View File

@ -72,6 +72,7 @@ clutter-main
@a...: @a...:
@a...: @a...:
@a...: @a...:
@a...:
<!-- ##### MACRO CLUTTER_GLERR ##### --> <!-- ##### MACRO CLUTTER_GLERR ##### -->

View File

@ -10,7 +10,7 @@
typedef struct SuperOH typedef struct SuperOH
{ {
ClutterActor *hand[NHANDS], *bgtex; ClutterActor *hand[NHANDS], *bgtex;
ClutterGroup *group; ClutterActor *group;
GdkPixbuf *bgpixb; GdkPixbuf *bgpixb;
} SuperOH; } SuperOH;
@ -183,14 +183,14 @@ main (int argc, char *argv[])
clutter_actor_set_position (oh->hand[i], x, y); clutter_actor_set_position (oh->hand[i], x, y);
/* Add to our group group */ /* Add to our group group */
clutter_group_add (oh->group, oh->hand[i]); clutter_group_add (CLUTTER_GROUP (oh->group), oh->hand[i]);
} }
/* Add the group to the stage */ /* Add the group to the stage */
clutter_group_add (CLUTTER_GROUP (stage), CLUTTER_ACTOR(oh->group)); clutter_group_add (CLUTTER_GROUP (stage), CLUTTER_ACTOR(oh->group));
/* Show everying ( and map window ) */ /* Show everying ( and map window ) */
clutter_group_show_all (oh->group); clutter_group_show_all (CLUTTER_GROUP (oh->group));
clutter_group_show_all (CLUTTER_GROUP (stage)); clutter_group_show_all (CLUTTER_GROUP (stage));
g_signal_connect (stage, "button-press-event", g_signal_connect (stage, "button-press-event",
@ -212,7 +212,5 @@ main (int argc, char *argv[])
clutter_main(); clutter_main();
g_object_unref (stage);
return 0; return 0;
} }

View File

@ -50,8 +50,6 @@ main (int argc, char *argv[])
g_signal_connect (stage, "key-press-event", g_signal_connect (stage, "key-press-event",
G_CALLBACK (clutter_main_quit), NULL); G_CALLBACK (clutter_main_quit), NULL);
g_object_unref (stage);
clutter_main(); clutter_main();
return 0; return 0;

View File

@ -119,7 +119,5 @@ main (int argc, char *argv[])
clutter_main(); clutter_main();
g_object_unref (stage);
return 0; return 0;
} }

View File

@ -268,9 +268,5 @@ main (int argc, char *argv[])
clutter_main(); clutter_main();
g_object_unref (stage);
return 0; return 0;
} }

View File

@ -377,7 +377,5 @@ main (int argc, char *argv[])
clutter_main(); clutter_main();
g_object_unref (stage);
return 0; return 0;
} }