<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
               "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY appurl "http://clutter-project.org">
<!ENTITY docurl "http://clutter-project.org/docs/">
<!ENTITY author_mail "ebassi@linux.intel.com">
<!ENTITY apiversion "@CLUTTER_API_VERSION@">
]>

<book lang="en">

  <bookinfo> <!-- {{{ -->
    <author>
      <firstname>Emmanuele</firstname>
      <surname>Bassi</surname>
      <address><email>&author_mail;</email></address>
    </author>

    <copyright>
      <year>2009</year>
      <holder>Intel Corporation</holder>
    </copyright>

    <legalnotice>
      <para>This document is distributed under the terms of the GNU General
      Public License as published by the Free Software Foundation; either
      version 2 of the License, or (at your option) any later version. A copy
      of this license can be found in the file COPYING included with the
      source code of this program.</para>
    </legalnotice>

    <title>The Clutter Cookbook</title>
    <releaseinfo>for Clutter &apiversion;</releaseinfo>
  </bookinfo> <!-- }}} -->

  <chapter id="introduction"> <!-- {{{ -->
    <title>Preface</title>

    <epigraph>
      <attribution>The Perl Cookbook</attribution>
      <para>Let me show you that easy way, so others may easily follow.</para>
    </epigraph>

    <para>There is a wonderful simile in the preface of the <emphasis>Perl
    Cookbook</emphasis>: approaching a programming problem is oftentimes
    similar to balancing Columbus's egg. The initial difficulties of dealing
    with, and more importantly solving, problems in the computer programming
    field sometimes can only be overcome if somebody shows you how to use a
    new tool. This is true for programming languages but also for programming
    libraries.</para>

    <para>This book has been written to try and give you a reference on
    how to solve common issues that you might have to face when using
    the Clutter toolkit.</para>

    <para>This book is not meant to be a replacement for the API reference,
    even though there will be descriptions of how Clutter works and how
    its API looks like. We will require knowledge of the Clutter API, but
    we will also point out where to find more information on the API that
    examples have used.</para>

    <para>Indeed, this book should be used as a companion to the API reference,
    expanding the examples and showing how to achieve a specific result.</para>

    <para>This is not a book for learning Clutter. This is also not a book
    for learning C, or GObject or even GUI development.</para>

    <para>Above all, this is a book for learning <emphasis>more</emphasis>
    about Clutter, and about how to use it in the most efficient and easiest
    way. It is meant to help you move past the basic usage of Clutter.</para>

    <para>This book is divided into chapters. Each chapter is dedicated to
    a specific class, like ClutterTexture, or a specific area, like animations.
    Each chapter starts with a short introduction, followed by different
    <emphasis>recipes</emphasis>. Each recipe starts with a problem, or a short
    statement describing what we want to achieve; a solution, containing the
    source code; and a discussion section, where the code is explained, where
    alternative approaches might be useful, caveats and references to the
    Clutter API for furher studying.</para>

    <para>This book, in the cookbook spirit, can be accessed mostly at
    random.</para>

    <section>
      <title>About Clutter</title>

      <para>Clutter is an free and open source software library for creating
      fast, visually rich and animated graphical user interfaces.</para>

      <para>Clutter uses OpenGL (and, optionally, OpenGL ES on mobile and
      embedded platforms) for rendering the user interface elements, but
      at the same time it exposes an application program interface that hides
      the underlying complexity of the OpenGL state machine from the
      developer.</para>

      <para>The program interface of Clutter is intended to be easy to use,
      efficient, flexible and as self-documenting as possible.</para>
    </section>

    <section>
      <title>About this document</title>

      <para>This document is available in various formats like HTML, and
      PDF.</para>

      <para>The latest version is always available at
      <ulink url="&docurl;">&docurl;</ulink>.</para>

    </section>

    <section>
      <title>Where to get Clutter</title>

      <para>You can obtain Clutter from <ulink url="&appurl;">&appurl;</ulink>.</para>

      <para>Clutter is also available on all major GNU/Linux distributions,
      in various package formats.</para>

      <para>On OSX, Clutter is available with both Fink and MacPorts.</para>

      <para>Binaries for Microsoft Windows are also available.</para>
    </section>

  </chapter> <!-- introduction }}} -->

  <chapter id="actors"> <!-- actors {{{ -->
    <title>Actors</title>

    <epigraph>
      <attribution>Edmon Gween, actor, on his deathbed</attribution>
      <para>An actor's a guy who if you ain't talkin' about him, ain't
      listening.</para>
    </epigraph>

    <section id="actors-introduction">
      <title>Introduction</title>

      <para>When building a User Interface with Clutter, the visible part
      of the UI &mdash; that is, what is displayed on the screen &mdash; is
      commonly referred to as "the scene graph". Like every graph, a scene
      graph is composed by nodes.</para>

      <para>Every node on the Clutter scene graph is an
      <emphasis>actor</emphasis>. Every actor has a single relationship
      with the others: it can be the parent of another actor, or a child of
      another actor.</para>

      <note><para>The Stage is an actor that can have children but cannot have
      any parent.</para></note>

      <para>Actors have different attributes: a position, a size, a
      scale factor, a rotation angle on each axis (relative to a specific
      center on the normal plane for that axis), an opacity factor.</para>

      <para>The scene graph is not fixed: it can be changed, not only
      by adding or removing actors, but also by changing the parent-child
      relationship: it is possible, for instance, to move an entire
      section of the scene graph from one parent actor to another.</para>

    </section>

    <section id="actors-allocation-notify"> <!-- {{{ -->
      <title>Knowing when an actor position or size change</title>

      <section>
        <title>Problem</title>

        <para>You want to know when the position or the size, or
        both, of an actor change, for instance to update an unrelated
        actor or some internal state.</para>
      </section>

      <section>
        <title>Solution</title>

        <para>You can use the <emphasis>notify</emphasis> signal,
        detailed with the coordinate or the dimension you want
        to know has changed:</para>

        <informalexample>
          <programlisting>
g_signal_connect (actor, "notify::x",
                  G_CALLBACK (on_x_changed),
                  NULL);
g_signal_connect (actor, "notify::height",
                  G_CALLBACK (on_height_changed),
                  NULL);
g_signal_connect (actor, "notify::depth",
                  G_CALLBACK (on_depth_changed),
                  NULL);
          </programlisting>
        </informalexample>

        <para>If you want to know if any of the coordinates or dimensions of
        an actor have been changed, except for depth, you can use the
        <emphasis>allocation-changed</emphasis> signal:</para>

        <informalexample>
          <programlisting>
g_signal_connect (actor, "allocation-changed",
                  G_CALLBACK (on_allocation_changed),
                  NULL);
          </programlisting>
        </informalexample>

        <para>The signature for the handler of the "notify" signal is:</para>

        <informalexample>
          <programlisting>
void
on_notify (GObject    *gobject,
           GParamSpec *pspec,
           gpointer    user_data);
          </programlisting>
        </informalexample>

        <para>While the signature for the handler of the "allocation-changed"
        signal is:</para>

        <informalexample>
          <programlisting>
void
on_allocation_changed (ClutterActor           *actor,
                       const ClutterActorBox  *allocation,
                       ClutterAllocationFlags  flags,
                       gpointer                user_data);
          </programlisting>
        </informalexample>

      </section>

      <section>
        <title>Discussion</title>

        <para>Any change the position and size of an actor will cause a
        change in the allocation of the actor itself. This will update the
        values of the :x, :y, :width and :height properties as well.</para>

        <para>The first technique allows a greater deal of granularity,
        allowing you to know what exactly changed. Inside the callback
        for the signal you can query the value of the property:</para>

        <informalexample>
          <programlisting>
void
on_x_changed (GObject    *gobject,
              GParamSpec *pspec,
              gpointer    user_data)
{
  gint x_value = 0;

  /* Round the X coordinate to the nearest pixel */
  x_value = floorf (clutter_actor_get_x (CLUTTER_ACTOR (gobject))) + 0.5;

  g_print ("The new X coordinate is '%d' pixels\n", x_value);
}
          </programlisting>
        </informalexample>

        <para>The second technique is more indicated if you want to
        get notification that any of the positional or dimensional
        attributes changed, except for the depth:</para>

        <informalexample>
          <programlisting>
void
on_allocation_changed (ClutterActor           *actor,
                       const ClutterActorBox  *allocation,
                       ClutterAllocationFlags  flags,
                       gpointer                user_data)
{
  ClutterActor *actor = CLUTTER_ACTOR (gobject);

  g_print ("The bounding box is now: (%.2f, %.2f) (%.2f x %.2f)\n",
           clutter_actor_box_get_x (allocation),
           clutter_actor_box_get_y (allocation),
           clutter_actor_box_get_width (allocation),
           clutter_actor_box_get_height (allocation));
}
          </programlisting>
        </informalexample>

        <para>All actors will update these properties when their size
        or position change.</para>

        <para>Note that the Stage, on the other hand, will not notify on
        position changes, so it is not possible to use the :x and :y
        properties to know that the platform-specific window embedding the
        stage has been moved &mdash; if the platform supports a windowing
        system. In order to achieve that you will have to use backend-specific
        API to extract the surface used by the Stage and then platform-specific
        API to retrieve its coordinates.</para>

      </section>

    </section> <!-- recipe 1 }}} -->

    <section id="actors-paint-wrappers"> <!-- {{{ -->
      <title>Overriding the paint sequence</title>

      <section>
        <title>Problem</title>

        <para>You want to override the way an actor paints itself
        without creating a subclass.</para>
      </section>

      <section>
        <title>Solution</title>

        <para>You can use the <emphasis>paint</emphasis> signal to
        invoke a callback that will be executed before the actor's
        paint implementation:</para>

        <informalexample>
          <programlisting>
g_signal_connect (actor, "paint",
                  G_CALLBACK (on_paint),
                  NULL);
          </programlisting>
        </informalexample>

        <para>You can paint something after the actor's paint implementation
        by using the <function>g_signal_connect_after()</function> function
        instead of <function>g_signal_connect()</function>:</para>

        <informalexample>
          <programlisting>
g_signal_connect_after (actor, "paint",
                        G_CALLBACK (on_paint_after),
                        NULL);
          </programlisting>
        </informalexample>

        <para>The signature for the handler of the "paint" signal is:</para>

        <informalexample>
          <programlisting>
void
on_paint (ClutterActor *actor,
          gpointer      user_data);
          </programlisting>
        </informalexample>

      </section>

      <section>
        <title>Discussion</title>

        <para>The paint cycle in Clutter works its way recursively from the
        Stage through every child.</para>

        <para>Whenever an Actor is going to be painted it will be positioned in
        a new frame of reference according to the list of transformations
        (scaling, rotation and additional traslations). After that, the "paint"
        signal will be emitted.</para>

        <para>The "paint" signal is defined as <emphasis>run-last</emphasis>,
        that is the signal handlers connected to it using
        <function>g_signal_connetc()</function> will be called first; then the
        default handler defined by the Actor's sub-class will be called;
        finally, all the signal handlers connected to the signal using
        <function>g_signal_connect_after()</function> will be called.</para>

        <para>This allows pre- and post-default paint handlers, and it also
        allows completely overriding the way an Actor draws itself by default;
        for instance:</para>

        <informalexample>
          <programlisting>
void
on_paint (ClutterActor *actor)
{
  do_my_paint (actor);

  g_signal_stop_emission_by_name (actor, "paint");
}
          </programlisting>
        </informalexample>

        <para>The code above will prevent the default paint implementation of
        the actor from running.</para>
      </section>

    </section> <!-- }}} -->

  </chapter> <!-- actors }}} -->

<!--
  <chapter id="textures">
    <title>Textures</title>

    <epigraph>
      <attribution>the author of the epigraph</attribution>
      <para>a short epigraph</para>
    </epigraph>

    <section id="textures-introduction">
      <title>Introduction</title>

      <para>introduction</para>
    </section>

    <section id="textures-aspect-ratio">
      <title>Maintaining the aspect ratio when loading a texture</title>

      <section>
        <title>Problem</title>

        <para>You want to maintain the aspect ratio of a texture.</para>
      </section>

      <section>
        <title>Solution</title>

        <para></para>
      </section>

      <section>
        <title>Discussion</title>

        <para></para>
      </section>

    </section>

  </chapter>
-->

<!--
  <chapter id="animations">
    <title>Animations</title>

    <epigraph>
      <attribution>the author of the epigraph</attribution>
      <para>a short epigraph</para>
    </epigraph>

    <section id="animations-introduction">
      <title>Introduction</title>

      <para>introduction</para>
    </section>

    <section>
      <title>Inverting Animations</title>

      <section>
        <title>Problem</title>

        <para>You want to have an animation exactly mirroring another one
        that you just played.</para>
      </section>

      <section>
        <title>Solution</title>

        <para>...</para>
      </section>

      <section>
        <title>Discussion</title>

        <para>...</para>
      </section>

    </section>

  </chapter>
-->

  <appendix id="contributing"> <!-- contributing {{{ -->
    <title>Contributing to this document</title>

    <para>This document is written in Docbook XML. The source file for this
    document is located in the subdirectory "doc/cookbook" of the source
    directory of Clutter.</para>
  </appendix> <!-- contributing }}} -->

<!--
    <section id="recipe">
      <title>Recipe</title>

      <section>
        <title>Problem</title>

        <para>...</para>
      </section>

      <section>
        <title>Solution</title>

        <para>...</para>
      </section>

      <section>
        <title>Discussion</title>

        <para>...</para>
      </section>

    </section>
-->

</book>