mirror of
https://github.com/brl/mutter.git
synced 2024-12-26 04:42:14 +00:00
113 lines
3.8 KiB
Plaintext
113 lines
3.8 KiB
Plaintext
|
<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
|
||
|
children, should call clutter_actor_request_coords() on each visible
|
||
|
child.</para>
|
||
|
|
||
|
<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>
|