mutter/doc/cookbook/clutter-cookbook.xml
Emmanuele Bassi 26b35e657f Add the first recipe to the Actors chapter
The first recipe shows how to be notified when the relative position
and size of an actor changes using the notify:: signal on the actor's
dimensional and positional properties.
2009-11-30 21:31:19 +00:00

365 lines
12 KiB
XML

<?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 version SYSTEM "version.xml">
]>
<book lang="en">
<bookinfo> <!-- {{{ -->
<author>
<firstname>Emmanuele</firstname>
<surname>Bassi</surname>
<address><email>&author_mail;</email></address>
</author>
<copyright>
<year>2008</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 &version;</title>
</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 sometimes 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, or a specific area. Each chapter starts with a short
introduction, followed by different <emphasis>recipes</emphasis>. Each
recipe has a problem, as 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 usefule, 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,
text and PDF. 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>
or perhaps from your distributor.</para>
</section>
<section>
<title>License</title>
<para>Clutter is distributed under the terms of the GNU Lesser 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>
</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 is either the parent of another actor or a
child of another actor.</para>
<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-recipe-1"> <!-- recipe 1 {{{ -->
<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</emphasis> detailt for
the notify signal:</para>
<informalexample>
<programlisting>
g_signal_connect (actor, "notify::allocation",
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>
</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;
g_object_get (gobject, pspec->name, &amp;x_value, NULL);
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 (GObject *gobject,
GParamSpec *pspec,
gpointer user_data)
{
ClutterActor *actor = CLUTTER_ACTOR (gobject);
g_print ("The bounding box is now: (%d, %d) (%d x %d)\n",
clutter_actor_get_x (actor),
clutter_actor_get_y (actor),
clutter_actor_get_width (actor),
clutter_actor_get_height (actor));
}
</programlisting>
</informalexample>
<para>All actors will update these properties when their size
or position change.</para>
<para>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 }}} -->
</chapter> <!-- actors }}} -->
<chapter id="textures"> <!-- 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> <!-- recipe 1 {{{ -->
<title>Maintaining the aspect ratio when loading a texture</title>
<section>
<title>Problem</title>
<para></para>
</section>
<section>
<title>Solution</title>
<para></para>
</section>
<section>
<title>Discussion</title>
<para></para>
</section>
</section> <!-- recipe 1 }}} -->
</chapter> <!-- textures }}} -->
<chapter id="animations"> <!-- 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> <!-- recipe 1 {{{ -->
<title>Inverting Animations</title>
<section>
<title>Problem</title>
<para></para>
</section>
<section>
<title>Solution</title>
<para></para>
</section>
<section>
<title>Discussion</title>
<para></para>
</section>
</section> <!-- recipe 1 }}} -->
</chapter> <!-- animations }}} -->
<appendix id="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 }}} -->
</book>