<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY version SYSTEM "version.xml">
+<!ENTITY clutter-SubclassingActor SYSTEM "xml/subclassing-ClutterActor.sgml">
]>
<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
<chapter>
<title>Container Actors</title>
+
+ <partintro>
+ <para>Actors containing other actors.</para>
+ </partintro>
<xi:include href="xml/clutter-group.xml"/>
<xi:include href="xml/clutter-hbox.xml"/>
<xi:include href="xml/clutter-vbox.xml"/>
<chapter>
<title>Base Classes</title>
+
+ <partintro>
+ <para>Clutter base animation objects</para>
+ </partintro>
+
<xi:include href="xml/clutter-timeline.xml"/>
<xi:include href="xml/clutter-alpha.xml"/>
<xi:include href="xml/clutter-behaviour.xml"/>
<chapter>
<title>Clutter Behaviours</title>
+
+ <partintro>
+ <para>Classes implementing ClutterBehaviour</para>
+ </partintro>
+
<xi:include href="xml/clutter-behaviour-bspline.xml"/>
<xi:include href="xml/clutter-behaviour-ellipse.xml"/>
<xi:include href="xml/clutter-behaviour-opacity.xml"/>
<chapter>
<title>Simple Effects</title>
+
+ <partintro>
+ <para>Simple animation API</para>
+ </partintro>
+
<xi:include href="xml/clutter-effects.xml"/>
</chapter>
<part>
<title>Clutter Backends</title>
+
+ <partintro>
+ <para>Clutter is usually compiled against a specific drawing backend.
+ All backends have a common API for querying the underlying platform,
+ and some of them might have specific API exposed by Clutter.</para>
+ </partintro>
<xi:include href="xml/clutter-backend.xml"/>
<xi:include href="xml/clutter-glx.xml"/>
</part>
+ <part>
+ <title>Additional Documentation</title>
+
+ <partintro>
+ <para>This section contains additional useful documentation for
+ developing with Clutter.</para>
+ </partintro>
+
+ &clutter-SubclassingActor;
+
+ </part>
+
<index>
<title>Index</title>
</index>
--- /dev/null
+<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>