2007-06-16 20:56:40 +00:00
|
|
|
<chapter id="clutter-subclassing-ClutterActor">
|
|
|
|
<chapterinfo>
|
|
|
|
<author>
|
|
|
|
<firstname>Emmanuele</firstname>
|
|
|
|
<surname>Bassi</surname>
|
|
|
|
<affiliation>
|
|
|
|
<address>
|
|
|
|
<email>ebassi@openedhand.com</email>
|
|
|
|
</address>
|
|
|
|
</affiliation>
|
|
|
|
</author>
|
|
|
|
</chapterinfo>
|
|
|
|
|
|
|
|
<title>Implementing a new actor</title>
|
|
|
|
|
|
|
|
<para>In order to implement a new #ClutterActor subclass the usual
|
|
|
|
machinery for subclassing a GObject should be used. After that, the
|
|
|
|
ClutterActor::query_coords() and ClutterActor::request_coords() virtual
|
|
|
|
functions should be overidden. Optionally, also the ClutterActor::paint()
|
|
|
|
virtual functions should be overridden.</para>
|
|
|
|
|
|
|
|
<para>The ClutterActor::query_coords() method of a #ClutterActor is
|
|
|
|
invoked when clutter_actor_query_coords() is called on an instance
|
|
|
|
of that actor class. It is used to return a #ClutterActorBox containing
|
|
|
|
the coordinates of the bounding box for the actor (the coordinates
|
|
|
|
of the top left corner and of the bottom right corner of the rectangle
|
|
|
|
that fully contains the actor). Container actors, or composite actors
|
|
|
|
with internal children, should call clutter_actor_query_coords() on
|
|
|
|
each visible child. Remember: the returned coordinates must be relative
|
|
|
|
to the parent actor.</para>
|
|
|
|
|
|
|
|
<example id="clutter-actor-query-coords-example">
|
|
|
|
<para>This example shows how an actor class should override the
|
|
|
|
query_coords() virtual function of #ClutterActor. In this case,
|
|
|
|
the returned bounding box is the sum of the bounding boxes of all
|
|
|
|
the <structname>FooActor</structname> children.</para>
|
|
|
|
|
|
|
|
<programlisting>
|
|
|
|
static void
|
|
|
|
foo_actor_query_coords (ClutterActor *actor,
|
|
|
|
ClutterActorBox *box)
|
|
|
|
{
|
|
|
|
FooActor *foo_actor = FOO_ACTOR (actor);
|
|
|
|
GList *child;
|
|
|
|
guint width, height;
|
|
|
|
|
|
|
|
/* initialize our size */
|
|
|
|
width = height = 0;
|
|
|
|
|
|
|
|
for (l = foo_actor->children; l != NULL; l = l->next)
|
|
|
|
{
|
|
|
|
ClutterActor *child_actor = child->data;
|
|
|
|
|
|
|
|
/* we return only visible actors */
|
|
|
|
if (CLUTTER_ACTOR_IS_VISIBLE (child_actor))
|
|
|
|
{
|
|
|
|
ClutterActorBox child_box;
|
|
|
|
|
|
|
|
clutter_actor_query_coords (child_actor, &child_box);
|
|
|
|
|
|
|
|
width += child_box.x2 - child_box.x2;
|
|
|
|
height += child_box.y2 - child_box.y1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* internally, the coordinates are all expressed in generic
|
|
|
|
* "units", but the public API converts them into pixels,
|
|
|
|
* so we need to juggle around with conversions
|
|
|
|
*/
|
|
|
|
box->x2 = box->x1 + CLUTTER_UNITS_FROM_INT (width);
|
|
|
|
box->y2 = box->y1 + CLUTTER_UNITS_FROM_INT (height);
|
|
|
|
}
|
|
|
|
</programlisting>
|
|
|
|
</example>
|
|
|
|
|
|
|
|
<para>The ClutterActor::request_coords() method of a #ClutterActor
|
|
|
|
is invoked when clutter_actor_request_coords() is called on an instance
|
|
|
|
of that actor class. It is used to set the coordinates of the bounding
|
|
|
|
box for the actor. Container actors, or composite actors with internal
|
2007-11-23 17:12:27 +00:00
|
|
|
children, should override the request_coords() virtual function and call
|
|
|
|
clutter_actor_request_coords() on each visible child. Every actor class
|
|
|
|
overriding the request_coords() virtual function must chain up to the
|
|
|
|
parent class request_coords() method.</para>
|
2007-06-16 20:56:40 +00:00
|
|
|
|
|
|
|
<para>The ClutterActor::paint() method should be overridden if the
|
|
|
|
actor needs to control its drawing process, by using the GL API
|
|
|
|
directly. Actors performing transformations should push the GL matrix
|
|
|
|
first and then pop the GL matrix before returning. Container actors
|
|
|
|
or composite actors with internal children should do the same, and call
|
|
|
|
clutter_actor_paint() on every visible child:</para>
|
|
|
|
|
|
|
|
<example id="clutter-actor-paint-example">
|
|
|
|
<programlisting>
|
|
|
|
static void
|
|
|
|
foo_actor_paint (ClutterActor *actor)
|
|
|
|
{
|
|
|
|
FooActor *foo_actor = FOO_ACTOR (actor);
|
|
|
|
GList *child;
|
|
|
|
|
|
|
|
glPushMatrix ();
|
|
|
|
|
|
|
|
for (child = foo_actor->children; child != NULL; child = child->next)
|
|
|
|
{
|
|
|
|
ClutterActor *child_actor = child->data;
|
|
|
|
|
|
|
|
clutter_actor_paint (child_actor);
|
|
|
|
}
|
|
|
|
|
|
|
|
glPopMatrix ();
|
|
|
|
}
|
|
|
|
</programlisting>
|
|
|
|
</example>
|
|
|
|
|
|
|
|
</chapter>
|