docs: Update the Actor API reference
Given the size and scope of the changes in ClutterActor, we ought to rewrite the overall description of what an actor is, what it does, and how are you supposed to use it and subclass it.
This commit is contained in:
parent
5959099473
commit
86152f478d
@ -26,107 +26,105 @@
|
|||||||
* SECTION:clutter-actor
|
* SECTION:clutter-actor
|
||||||
* @short_description: Base abstract class for all visual stage actors.
|
* @short_description: Base abstract class for all visual stage actors.
|
||||||
*
|
*
|
||||||
* #ClutterActor is a base abstract class for all visual elements on the
|
* The ClutterActor class is the basic element of the scene graph in Clutter,
|
||||||
* stage. Every object that must appear on the main #ClutterStage must also
|
* and it encapsulates the position, size, and transformations of a node in
|
||||||
* be a #ClutterActor, either by using one of the classes provided by
|
* the graph.
|
||||||
* Clutter, or by implementing a new #ClutterActor subclass.
|
|
||||||
*
|
*
|
||||||
* Every actor is a 2D surface positioned and optionally transformed
|
* <refsect2 id="ClutterActor-transformations">
|
||||||
* in 3D space. The actor is positioned relative to top left corner of
|
* <title>Actor transformations</title>
|
||||||
* it parent with the childs origin being its anchor point (also top
|
* <para>Each actor can be transformed using methods like
|
||||||
* left by default).
|
* clutter_actor_set_scale() or clutter_actor_set_rotation(). The order
|
||||||
*
|
* in which the transformations are applied is decided by Clutter and it is
|
||||||
* <refsect2 id="ClutterActor-box">
|
* the following:</para>
|
||||||
* <title>Actor bounding box and transformations</title>
|
|
||||||
* <para>Any actor's 2D surface is contained inside its bounding box,
|
|
||||||
* as described by the #ClutterActorBox structure:</para>
|
|
||||||
* <figure id="actor-box">
|
|
||||||
* <title>Bounding box of an Actor</title>
|
|
||||||
* <graphic fileref="actor-box.png" format="PNG"/>
|
|
||||||
* </figure>
|
|
||||||
* <para>The actor box represents the untransformed area occupied by an
|
|
||||||
* actor. Each visible actor that has been put on a #ClutterStage also
|
|
||||||
* has a transformed area, depending on the actual transformations
|
|
||||||
* applied to it by the developer (scale, rotation). Tranforms will
|
|
||||||
* also be applied to any child actors. Also applied to all actors by
|
|
||||||
* the #ClutterStage is a perspective transformation. API is provided
|
|
||||||
* for both tranformed and untransformed actor geometry information.</para>
|
|
||||||
* <para>The GL 'modelview' transform matrix for the actor is constructed
|
|
||||||
* from the actor settings by the following order of operations:</para>
|
|
||||||
* <orderedlist>
|
* <orderedlist>
|
||||||
* <listitem><para>Translation by actor x, y coords,</para></listitem>
|
* <listitem><para>translation by the origin of the #ClutterActor:allocation;</para></listitem>
|
||||||
* <listitem><para>Translation by actor depth (z),</para></listitem>
|
* <listitem><para>translation by the actor's #ClutterActor:depth;</para></listitem>
|
||||||
* <listitem><para>Scaling by scale_x, scale_y,</para></listitem>
|
* <listitem><para>scaling by the #ClutterActor:scale-x and #ClutterActor:scale-y factors;</para></listitem>
|
||||||
* <listitem><para>Rotation around z axis,</para></listitem>
|
* <listitem><para>rotation around the #ClutterActor:rotation-z-angle and #ClutterActor:rotation-z-center;</para></listitem>
|
||||||
* <listitem><para>Rotation around y axis,</para></listitem>
|
* <listitem><para>rotation around the #ClutterActor:rotation-y-angle and #ClutterActor:rotation-y-center;</para></listitem>
|
||||||
* <listitem><para>Rotation around x axis,</para></listitem>
|
* <listitem><para>rotation around the #ClutterActor:rotation-x-angle and #ClutterActor:rotation-x-center;</para></listitem>
|
||||||
* <listitem><para>Negative translation by anchor point x,
|
* <listitem><para>negative translation by the #ClutterActor:anchor-x and #ClutterActor:anchor-y point.</para></listitem>
|
||||||
* y,</para></listitem>
|
|
||||||
* <listitem><para>Rectangular Clip is applied (this is not an operation
|
|
||||||
* on the matrix as such, but it is done as part of the transform set
|
|
||||||
* up).</para></listitem>
|
|
||||||
* </orderedlist>
|
* </orderedlist>
|
||||||
* <para>An actor can either be explicitly sized and positioned, using the
|
|
||||||
* various size and position accessors, like clutter_actor_set_x() or
|
|
||||||
* clutter_actor_set_width(); or it can have a preferred width and
|
|
||||||
* height, which then allows a layout manager to implicitly size and
|
|
||||||
* position it by "allocating" an area for an actor. This allows for
|
|
||||||
* actors to be manipulated in both a fixed (or static) parent container
|
|
||||||
* (i.e. children of #ClutterGroup) and a more automatic (or dynamic)
|
|
||||||
* layout based parent container.</para>
|
|
||||||
* <para>When accessing the position and size of an actor, the simple
|
|
||||||
* accessors like clutter_actor_get_width() and clutter_actor_get_x()
|
|
||||||
* will return a value depending on whether the actor has been explicitly
|
|
||||||
* sized and positioned by the developer or implicitly by the layout
|
|
||||||
* manager.</para>
|
|
||||||
* <para>Depending on whether you are querying an actor or implementing a
|
|
||||||
* layout manager, you should either use the simple accessors or use the
|
|
||||||
* size negotiation API.</para>
|
|
||||||
* </refsect2>
|
* </refsect2>
|
||||||
*
|
*
|
||||||
* <refsect2 id="ClutterActor-event-handling">
|
* <refsect2 id="ClutterActor-geometry">
|
||||||
* <title>Event Handling</title>
|
* <title>Modifying an actor's geometry</title>
|
||||||
* <para>Clutter actors are also able to receive input events and react to
|
* <para>Each actor has a bounding box, called #ClutterActor:allocation
|
||||||
* them. Events are handled in the following ways:</para>
|
* which is either set by its parent or explicitly through the
|
||||||
* <orderedlist>
|
* clutter_actor_set_position() and clutter_actor_set_size() methods.
|
||||||
* <listitem><para>Actors emit pointer events if set reactive, see
|
* Each actor also has an implicit preferred size.</para>
|
||||||
* clutter_actor_set_reactive()</para></listitem>
|
* <para>An actor’s preferred size can be defined by any subclass by
|
||||||
* <listitem><para>The stage is always reactive</para></listitem>
|
* overriding the #ClutterActorClass.get_preferred_width() and the
|
||||||
* <listitem><para>Events are handled by connecting signal handlers to
|
* #ClutterActorClass.get_preferred_height() virtual functions, or it can
|
||||||
* the numerous event signal types.</para></listitem>
|
* be explicitly set by using clutter_actor_set_width() and
|
||||||
* <listitem><para>Event handlers must return %TRUE if they handled
|
* clutter_actor_set_height().</para>
|
||||||
* the event and wish to block the event emission chain, or %FALSE
|
* <para>An actor’s position can be set explicitly by using
|
||||||
* if the emission chain must continue</para></listitem>
|
* clutter_actor_set_x() and clutter_actor_set_y(); the coordinates are
|
||||||
* <listitem><para>Keyboard events are emitted if actor has focus, see
|
* relative to the origin of the actor’s parent.</para>
|
||||||
* clutter_stage_set_key_focus()</para></listitem>
|
* </refsect2>
|
||||||
* <listitem><para>Motion events (motion, enter, leave) are not emitted
|
*
|
||||||
* if clutter_set_motion_events_enabled() is called with %FALSE.
|
* <refsect2 id="ClutterActor-children">
|
||||||
* See clutter_set_motion_events_enabled() documentation for more
|
* <title>Managing actor children</title>
|
||||||
* information.</para></listitem>
|
* <para>Each actor can have multiple children, by calling
|
||||||
* <listitem><para>Once emitted, an event emission chain has two
|
* clutter_actor_add_child() to add a new child actor, and
|
||||||
* phases: capture and bubble. An emitted event starts in the capture
|
* clutter_actor_remove_child() to remove an existing child. #ClutterActor
|
||||||
* phase (see ClutterActor::captured-event) beginning at the stage and
|
* will hold a reference on each child actor, which will be released when
|
||||||
* traversing every child actor until the event source actor is reached.
|
* the child is removed from its parent, or destroyed using
|
||||||
* The emission then enters the bubble phase, traversing back up the
|
* clutter_actor_destroy().</para>
|
||||||
* chain via parents until it reaches the stage. Any event handler can
|
* <para>Children can be inserted at a given index, or above and below
|
||||||
* abort this chain by returning %TRUE (meaning "event handled").
|
* another child actor. The order of insertion determines the order of the
|
||||||
* </para></listitem>
|
* children when iterating over them. Iterating over children is performed
|
||||||
* <listitem><para>Pointer events will 'pass through' non reactive
|
* by using clutter_actor_get_first_child(), clutter_actor_get_previous_sibling(),
|
||||||
* overlapping actors.</para></listitem>
|
* clutter_actor_get_next_child(), and clutter_actor_get_last_child(). It is
|
||||||
* </orderedlist>
|
* also possible to retrieve a list of children by using
|
||||||
* <figure id="event-flow">
|
* clutter_actor_get_children(), as well as retrieving a specific child at a
|
||||||
* <title>Event flow in Clutter</title>
|
* given index by using clutter_actor_get_child_at_index().</para>
|
||||||
* <graphic fileref="event-flow.png" format="PNG"/>
|
* <para>If you need to track additions of children to a #ClutterActor, use
|
||||||
* </figure>
|
* the #ClutterContainer::actor-added signal; similarly, to track removals
|
||||||
* <para>Every '?' box in the diagram above is an entry point for
|
* of children from a ClutterActor, use the #ClutterContainer::actor-removed
|
||||||
* application code.</para>
|
* signal.</para>
|
||||||
|
* </refsect2>
|
||||||
|
*
|
||||||
|
* <refsect2 id="ClutterActor-events">
|
||||||
|
* <title>Handling events on an actor</title>
|
||||||
|
* <para>A #ClutterActor can receive and handle input device events, for
|
||||||
|
* instance pointer events and key events, as long as its
|
||||||
|
* #ClutterActor:reactive property is set to %TRUE.</para>
|
||||||
|
* <para>Once an actor has been determined to be the source of an event,
|
||||||
|
* Clutter will traverse the scene graph from the top-level actor towards the
|
||||||
|
* event source, emitting the #ClutterActor::captured-event signal on each
|
||||||
|
* ancestor until it reaches the source; this phase is also called
|
||||||
|
* <emphasis>the capture phase</emphasis>. If the event propagation was not
|
||||||
|
* stopped, the graph is walked backwards, from the source actor to the
|
||||||
|
* top-level, and the #ClutterActor::event signal, along with other event
|
||||||
|
* signals if needed, is emitted; this phase is also called <emphasis>the
|
||||||
|
* bubble phase</emphasis>. At any point of the signal emission, signal
|
||||||
|
* handlers can stop the propagation through the scene graph by returning
|
||||||
|
* %CLUTTER_EVENT_STOP; otherwise, they can continue the propagation by
|
||||||
|
* returning %CLUTTER_EVENT_PROPAGATE.</para>
|
||||||
* </refsect2>
|
* </refsect2>
|
||||||
*
|
*
|
||||||
* <refsect2 id="ClutterActor-subclassing">
|
* <refsect2 id="ClutterActor-subclassing">
|
||||||
* <title>Implementing a ClutterActor</title>
|
* <title>Implementing an actor</title>
|
||||||
* <para>For implementing a new custom actor class, please read <link
|
* <para>Careful consideration should be given when deciding to implement
|
||||||
* linkend="clutter-subclassing-ClutterActor">the corresponding
|
* a #ClutterActor sub-class. It is generally recommended to implement a
|
||||||
* section</link> of the API reference.</para>
|
* sub-class of #ClutterActor only for actors that should be used as leaf
|
||||||
|
* nodes of a scene graph.</para>
|
||||||
|
* <para>If your actor should be painted in a custom way, you should
|
||||||
|
* override the #ClutterActor::paint signal class handler. You can either
|
||||||
|
* opt to chain up to the parent class implementation or decide to fully
|
||||||
|
* override the default paint implementation; Clutter will set up the
|
||||||
|
* transformations and clip regions prior to emitting the #ClutterActor::paint
|
||||||
|
* signal.</para>
|
||||||
|
* <para>By overriding the #ClutterActorClass.get_preferred_width() and
|
||||||
|
* #ClutterActorClass.get_preferred_height() virtual functions it is
|
||||||
|
* possible to change or provide the preferred size of an actor; similarly,
|
||||||
|
* by overriding the #ClutterActorClass.allocate() virtual function it is
|
||||||
|
* possible to control the layout of the children of an actor. Make sure to
|
||||||
|
* always chain up to the parent implementation of the
|
||||||
|
* #ClutterActorClass.allocate() virtual function.</para>
|
||||||
|
* <para>In general, it is strongly encouraged to use delegation and
|
||||||
|
* composition instead of direct subclassing.</para>
|
||||||
* </refsect2>
|
* </refsect2>
|
||||||
*
|
*
|
||||||
* <refsect2 id="ClutterActor-script">
|
* <refsect2 id="ClutterActor-script">
|
||||||
@ -178,14 +176,12 @@
|
|||||||
* property.</para>
|
* property.</para>
|
||||||
* <para>The <emphasis>property-name</emphasis> fragment is the name of the
|
* <para>The <emphasis>property-name</emphasis> fragment is the name of the
|
||||||
* action or constraint property to be animated.</para>
|
* action or constraint property to be animated.</para>
|
||||||
* <example id="example-ClutterActor-animating-meta">
|
* <para>The example below animates a #ClutterBindConstraint applied to an
|
||||||
* <title>Animating a constraint property</title>
|
* actor using clutter_actor_animate(). The <emphasis>rect</emphasis> has
|
||||||
* <para>The example below animates a #ClutterBindConstraint applied to an
|
* a binding constraint for the <emphasis>origin</emphasis> actor, and in
|
||||||
* actor using clutter_actor_animate(). The <emphasis>rect</emphasis> has
|
* its initial state is fully transparent and overlapping the actor to
|
||||||
* a binding constraint for the <emphasis>origin</emphasis> actor, and in
|
* which is bound to. </para>
|
||||||
* its initial state is fully transparent and overlapping the actor to
|
* <informalexample><programlisting>
|
||||||
* which is bound to. </para>
|
|
||||||
* <programlisting>
|
|
||||||
* constraint = clutter_bind_constraint_new (origin, CLUTTER_BIND_X, 0.0);
|
* constraint = clutter_bind_constraint_new (origin, CLUTTER_BIND_X, 0.0);
|
||||||
* clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "bind-x");
|
* clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "bind-x");
|
||||||
* clutter_actor_add_constraint (rect, constraint);
|
* clutter_actor_add_constraint (rect, constraint);
|
||||||
@ -200,19 +196,18 @@
|
|||||||
* g_signal_connect (rect, "button-press-event",
|
* g_signal_connect (rect, "button-press-event",
|
||||||
* G_CALLBACK (on_button_press),
|
* G_CALLBACK (on_button_press),
|
||||||
* NULL);
|
* NULL);
|
||||||
* </programlisting>
|
* </programlisting></informalexample>
|
||||||
* <para>On button press, the rectangle "slides" from behind the actor to
|
* <para>On button press, the rectangle "slides" from behind the actor to
|
||||||
* which is bound to, using the #ClutterBindConstraint:offset property and
|
* which is bound to, using the #ClutterBindConstraint:offset property and
|
||||||
* the #ClutterActor:opacity property.</para>
|
* the #ClutterActor:opacity property.</para>
|
||||||
* <programlisting>
|
* <informalexample><programlisting>
|
||||||
* float new_offset = clutter_actor_get_width (origin) + h_padding;
|
* float new_offset = clutter_actor_get_width (origin) + h_padding;
|
||||||
*
|
*
|
||||||
* clutter_actor_animate (rect, CLUTTER_EASE_OUT_CUBIC, 500,
|
* clutter_actor_animate (rect, CLUTTER_EASE_OUT_CUBIC, 500,
|
||||||
* "opacity", 255,
|
* "opacity", 255,
|
||||||
* "@constraints.bind-x.offset", new_offset,
|
* "@constraints.bind-x.offset", new_offset,
|
||||||
* NULL);
|
* NULL);
|
||||||
* </programlisting>
|
* </programlisting></informalexample>
|
||||||
* </example>
|
|
||||||
* </refsect2>
|
* </refsect2>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -56,7 +56,9 @@ HFILE_GLOB=\
|
|||||||
$(top_srcdir)/clutter/egl/clutter-egl.h \
|
$(top_srcdir)/clutter/egl/clutter-egl.h \
|
||||||
$(top_srcdir)/clutter/cex100/clutter-cex100.h \
|
$(top_srcdir)/clutter/cex100/clutter-cex100.h \
|
||||||
$(top_srcdir)/clutter/win32/clutter-win32.h \
|
$(top_srcdir)/clutter/win32/clutter-win32.h \
|
||||||
$(top_srcdir)/clutter/gdk/clutter-gdk.h
|
$(top_srcdir)/clutter/gdk/clutter-gdk.h \
|
||||||
|
$(top_srcdir)/clutter/wayland/clutter-wayland-compositor.h \
|
||||||
|
$(top_srcdir)/clutter/wayland/clutter-wayland-surface.h
|
||||||
|
|
||||||
CFILE_GLOB=\
|
CFILE_GLOB=\
|
||||||
$(top_srcdir)/clutter/*.c \
|
$(top_srcdir)/clutter/*.c \
|
||||||
@ -65,7 +67,8 @@ CFILE_GLOB=\
|
|||||||
$(top_srcdir)/clutter/win32/*.c \
|
$(top_srcdir)/clutter/win32/*.c \
|
||||||
$(top_srcdir)/clutter/gdk/*.c \
|
$(top_srcdir)/clutter/gdk/*.c \
|
||||||
$(top_srcdir)/clutter/cex100/*.c \
|
$(top_srcdir)/clutter/cex100/*.c \
|
||||||
$(top_srcdir)/clutter/egl/*.c
|
$(top_srcdir)/clutter/egl/*.c \
|
||||||
|
$(top_srcdir)/clutter/wayland/*.c
|
||||||
|
|
||||||
# Header files to ignore when scanning.
|
# Header files to ignore when scanning.
|
||||||
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
|
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
|
||||||
@ -116,9 +119,10 @@ EXTRA_HFILES=\
|
|||||||
$(top_srcdir)/clutter/x11/clutter-glx-texture-pixmap.h \
|
$(top_srcdir)/clutter/x11/clutter-glx-texture-pixmap.h \
|
||||||
$(top_srcdir)/clutter/egl/clutter-egl.h \
|
$(top_srcdir)/clutter/egl/clutter-egl.h \
|
||||||
$(top_srcdir)/clutter/cex100/clutter-cex100.h \
|
$(top_srcdir)/clutter/cex100/clutter-cex100.h \
|
||||||
$(top_srcdir)/clutter/wayland/clutter-wayland.h \
|
|
||||||
$(top_srcdir)/clutter/win32/clutter-win32.h \
|
$(top_srcdir)/clutter/win32/clutter-win32.h \
|
||||||
$(top_srcdir)/clutter/gdk/clutter-gdk.h
|
$(top_srcdir)/clutter/gdk/clutter-gdk.h \
|
||||||
|
$(top_srcdir)/clutter/wayland/clutter-wayland-compositor.h \
|
||||||
|
$(top_srcdir)/clutter/wayland/clutter-wayland-surface.h
|
||||||
|
|
||||||
# Images to copy into HTML directory.
|
# Images to copy into HTML directory.
|
||||||
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
|
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
|
||||||
@ -139,9 +143,7 @@ HTML_IMAGES=\
|
|||||||
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
|
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
|
||||||
content_files= \
|
content_files= \
|
||||||
glossary.xml \
|
glossary.xml \
|
||||||
subclassing-ClutterActor.xml \
|
|
||||||
clutter-animation-tutorial.xml \
|
clutter-animation-tutorial.xml \
|
||||||
creating-behaviours.xml \
|
|
||||||
clutter-overview.xml \
|
clutter-overview.xml \
|
||||||
building-clutter.xml \
|
building-clutter.xml \
|
||||||
running-clutter.xml \
|
running-clutter.xml \
|
||||||
@ -154,9 +156,7 @@ content_files= \
|
|||||||
# e.g. expand_content_files=running.sgml
|
# e.g. expand_content_files=running.sgml
|
||||||
expand_content_files= \
|
expand_content_files= \
|
||||||
glossary.xml \
|
glossary.xml \
|
||||||
subclassing-ClutterActor.xml \
|
|
||||||
clutter-animation-tutorial.xml \
|
clutter-animation-tutorial.xml \
|
||||||
creating-behaviours.xml \
|
|
||||||
clutter-overview.xml \
|
clutter-overview.xml \
|
||||||
building-clutter.xml \
|
building-clutter.xml \
|
||||||
running-clutter.xml \
|
running-clutter.xml \
|
||||||
|
@ -210,8 +210,9 @@
|
|||||||
<xi:include href="xml/clutter-win32.xml"/>
|
<xi:include href="xml/clutter-win32.xml"/>
|
||||||
<xi:include href="xml/clutter-egl.xml"/>
|
<xi:include href="xml/clutter-egl.xml"/>
|
||||||
<xi:include href="xml/clutter-cex100.xml"/>
|
<xi:include href="xml/clutter-cex100.xml"/>
|
||||||
<xi:include href="xml/clutter-wayland.xml"/>
|
|
||||||
<xi:include href="xml/clutter-gdk.xml"/>
|
<xi:include href="xml/clutter-gdk.xml"/>
|
||||||
|
<xi:include href="xml/clutter-wayland-compositor.xml"/>
|
||||||
|
<xi:include href="xml/clutter-wayland-surface.xml"/>
|
||||||
</part>
|
</part>
|
||||||
|
|
||||||
<part id="additionaldocs">
|
<part id="additionaldocs">
|
||||||
@ -222,9 +223,7 @@
|
|||||||
developing with Clutter.</para>
|
developing with Clutter.</para>
|
||||||
</partintro>
|
</partintro>
|
||||||
|
|
||||||
<xi:include href="xml/subclassing-ClutterActor.xml"/>
|
|
||||||
<xi:include href="xml/clutter-animation-tutorial.xml"/>
|
<xi:include href="xml/clutter-animation-tutorial.xml"/>
|
||||||
<xi:include href="xml/creating-behaviours.xml"/>
|
|
||||||
</part>
|
</part>
|
||||||
|
|
||||||
<part id="migration">
|
<part id="migration">
|
||||||
|
@ -348,6 +348,35 @@ clutter_actor_get_offscreen_redirect
|
|||||||
clutter_actor_set_name
|
clutter_actor_set_name
|
||||||
clutter_actor_get_name
|
clutter_actor_get_name
|
||||||
clutter_actor_get_gid
|
clutter_actor_get_gid
|
||||||
|
ClutterActorAlign
|
||||||
|
clutter_actor_set_x_align
|
||||||
|
clutter_actor_get_x_align
|
||||||
|
clutter_actor_set_y_align
|
||||||
|
clutter_actor_get_y_align
|
||||||
|
clutter_actor_set_x_expand
|
||||||
|
clutter_actor_get_x_expand
|
||||||
|
clutter_actor_set_y_expand
|
||||||
|
clutter_actor_get_y_expand
|
||||||
|
clutter_actor_needs_x_expand
|
||||||
|
clutter_actor_needs_y_expand
|
||||||
|
clutter_actor_queue_compute_expand
|
||||||
|
ClutterMargin
|
||||||
|
clutter_margin_copy
|
||||||
|
clutter_margin_free
|
||||||
|
clutter_margin_get_type
|
||||||
|
clutter_margin_new
|
||||||
|
clutter_actor_set_margin_top
|
||||||
|
clutter_actor_get_margin_top
|
||||||
|
clutter_actor_set_margin_right
|
||||||
|
clutter_actor_get_margin_right
|
||||||
|
clutter_actor_set_margin_bottom
|
||||||
|
clutter_actor_get_margin_bottom
|
||||||
|
clutter_actor_set_margin_left
|
||||||
|
clutter_actor_get_margin_left
|
||||||
|
clutter_actor_set_layout_manager
|
||||||
|
clutter_actor_get_layout_manager
|
||||||
|
clutter_actor_set_background_color
|
||||||
|
clutter_actor_get_background_color
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_actor_set_clip
|
clutter_actor_set_clip
|
||||||
@ -358,18 +387,33 @@ clutter_actor_set_clip_to_allocation
|
|||||||
clutter_actor_get_clip_to_allocation
|
clutter_actor_get_clip_to_allocation
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_actor_set_parent
|
clutter_actor_new
|
||||||
|
clutter_actor_add_child
|
||||||
|
clutter_actor_insert_child_above
|
||||||
|
clutter_actor_insert_child_at_index
|
||||||
|
clutter_actor_insert_child_below
|
||||||
|
clutter_actor_replace_child
|
||||||
|
clutter_actor_remove_all_children
|
||||||
|
clutter_actor_remove_child
|
||||||
|
clutter_actor_get_first_child
|
||||||
|
clutter_actor_get_next_sibling
|
||||||
|
clutter_actor_get_previous_sibling
|
||||||
|
clutter_actor_get_last_child
|
||||||
|
clutter_actor_get_child_at_index
|
||||||
|
clutter_actor_get_children
|
||||||
|
clutter_actor_get_n_children
|
||||||
clutter_actor_get_parent
|
clutter_actor_get_parent
|
||||||
clutter_actor_reparent
|
|
||||||
clutter_actor_unparent
|
|
||||||
clutter_actor_contains
|
|
||||||
clutter_actor_raise
|
clutter_actor_raise
|
||||||
clutter_actor_lower
|
clutter_actor_lower
|
||||||
clutter_actor_raise_top
|
clutter_actor_raise_top
|
||||||
clutter_actor_lower_bottom
|
clutter_actor_lower_bottom
|
||||||
|
clutter_actor_contains
|
||||||
clutter_actor_get_stage
|
clutter_actor_get_stage
|
||||||
clutter_actor_push_internal
|
clutter_actor_push_internal
|
||||||
clutter_actor_pop_internal
|
clutter_actor_pop_internal
|
||||||
|
clutter_actor_set_parent
|
||||||
|
clutter_actor_reparent
|
||||||
|
clutter_actor_unparent
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_actor_set_depth
|
clutter_actor_set_depth
|
||||||
@ -502,6 +546,7 @@ CLUTTER_TYPE_GEOMETRY
|
|||||||
CLUTTER_TYPE_ACTOR_BOX
|
CLUTTER_TYPE_ACTOR_BOX
|
||||||
CLUTTER_TYPE_VERTEX
|
CLUTTER_TYPE_VERTEX
|
||||||
CLUTTER_TYPE_PAINT_VOLUME
|
CLUTTER_TYPE_PAINT_VOLUME
|
||||||
|
CLUTTER_TYPE_MARGIN
|
||||||
CLUTTER_ACTOR
|
CLUTTER_ACTOR
|
||||||
CLUTTER_IS_ACTOR
|
CLUTTER_IS_ACTOR
|
||||||
CLUTTER_TYPE_ACTOR
|
CLUTTER_TYPE_ACTOR
|
||||||
@ -601,6 +646,7 @@ clutter_stage_ensure_current
|
|||||||
clutter_stage_ensure_viewport
|
clutter_stage_ensure_viewport
|
||||||
clutter_stage_ensure_redraw
|
clutter_stage_ensure_redraw
|
||||||
clutter_stage_queue_redraw
|
clutter_stage_queue_redraw
|
||||||
|
clutter_actor_queue_redraw_with_clip
|
||||||
clutter_stage_event
|
clutter_stage_event
|
||||||
clutter_stage_set_key_focus
|
clutter_stage_set_key_focus
|
||||||
clutter_stage_get_key_focus
|
clutter_stage_get_key_focus
|
||||||
@ -1352,11 +1398,22 @@ clutter_wayland_set_compositor_display
|
|||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>clutter-wayland-surface</FILE>
|
<FILE>clutter-wayland-surface</FILE>
|
||||||
|
<TITLE>ClutterWaylandSurface</TITLE>
|
||||||
ClutterWaylandSurface
|
ClutterWaylandSurface
|
||||||
ClutterWaylandSurfaceClass
|
ClutterWaylandSurfaceClass
|
||||||
clutter_wayland_surface_new
|
clutter_wayland_surface_new
|
||||||
clutter_wayland_surface_attach_buffer
|
clutter_wayland_surface_attach_buffer
|
||||||
clutter_wayland_surface_damage_buffer
|
clutter_wayland_surface_damage_buffer
|
||||||
|
<SUBSECTION Standard>
|
||||||
|
CLUTTER_WAYLAND_IS_SURFACE
|
||||||
|
CLUTTER_WAYLAND_IS_SURFACE_CLASS
|
||||||
|
CLUTTER_WAYLAND_SURFACE
|
||||||
|
CLUTTER_WAYLAND_SURFACE_CLASS
|
||||||
|
CLUTTER_WAYLAND_SURFACE_GET_CLASS
|
||||||
|
CLUTTER_WAYLAND_TYPE_SURFACE
|
||||||
|
<SUBSECTION Private>
|
||||||
|
ClutterWaylandSurfacePrivate
|
||||||
|
clutter_wayland_surface_get_type
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
<chapter id="creating-your-own-behaviours">
|
|
||||||
<chapterinfo>
|
|
||||||
<author>
|
|
||||||
<firstname>Matthew</firstname>
|
|
||||||
<surname>Allum</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>mallum@openedhand.com</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
</chapterinfo>
|
|
||||||
|
|
||||||
<title>Creating You Own Behaviours</title>
|
|
||||||
<para>Clutter comes with a number of fairly generic prebuilt behaviour
|
|
||||||
classes which provide a basis for transitions, animations and other
|
|
||||||
visual effects. However even with the ability to combine a number of
|
|
||||||
these behaviours sometimes they are not enough and a custom behaviour
|
|
||||||
is needed to create a spcific animation.</para>
|
|
||||||
|
|
||||||
<para>In order to implement a new #ClutterBehaviour subclass the usual
|
|
||||||
machinery for subclassing a GObject should be used. The new subclass
|
|
||||||
then just overides the #ClutterBehaviour::alpha_notify() method. This
|
|
||||||
method is passed an alpha value which is then used to compute
|
|
||||||
modifications to any actors the behaviour is applied to.</para>
|
|
||||||
|
|
||||||
<example id="clutter-behaviour-alpha-notify-example">
|
|
||||||
<title>Implementing the alpha-notify virtual function</title>
|
|
||||||
<para>This example demonstrates a behaviour that produces a vertical
|
|
||||||
'wipe' like affect by modifying the actors clip region</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
static void
|
|
||||||
clutter_behaviour_foo_alpha_notify (ClutterBehaviour *behaviour,
|
|
||||||
gdouble factor)
|
|
||||||
{
|
|
||||||
ClutterActor *actor
|
|
||||||
gint i, n;
|
|
||||||
|
|
||||||
n = clutter_behaviour_get_n_actors (behaviour);
|
|
||||||
|
|
||||||
/* Change clip height of each applied actor. Note that it is
|
|
||||||
* usually better to use clutter_behaviour_actors_foreach()
|
|
||||||
* to avoid iterating multiple times
|
|
||||||
*/
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
gfloat clip_height;
|
|
||||||
|
|
||||||
actor = clutter_behaviour_get_nth_actor (behaviour, i);
|
|
||||||
|
|
||||||
clip_height = clutter_actor_get_height (actor)
|
|
||||||
- (clutter_actor_get_height (actor) * factor);
|
|
||||||
|
|
||||||
clutter_actor_set_clip (actor,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
clutter_actor_get_width (actor),
|
|
||||||
clip_height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<para>If the new behaviour is meant to set an initial state on the
|
|
||||||
actors to which its applied to, then the ClutterBehaviour::applied
|
|
||||||
signal class handler should be overridden.</para>
|
|
||||||
</chapter>
|
|
@ -1,672 +0,0 @@
|
|||||||
<chapter id="clutter-subclassing-ClutterActor">
|
|
||||||
<chapterinfo>
|
|
||||||
<author>
|
|
||||||
<firstname>Emmanuele</firstname>
|
|
||||||
<surname>Bassi</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>ebassi@linux.intel.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:</para>
|
|
||||||
|
|
||||||
<informalexample>
|
|
||||||
<programlisting>
|
|
||||||
#define FOO_TYPE_ACTOR (foo_actor_get_type ())
|
|
||||||
#define FOO_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_ACTOR, FooActor))
|
|
||||||
#define FOO_IS_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_ACTOR))
|
|
||||||
#define FOO_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_ACTOR, FooActorClass))
|
|
||||||
#define FOO_IS_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_ACTOR))
|
|
||||||
#define FOO_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_ACTOR, FooActorClass))
|
|
||||||
|
|
||||||
typedef struct _FooActor
|
|
||||||
{
|
|
||||||
ClutterActor parent_instance;
|
|
||||||
} FooActor;
|
|
||||||
|
|
||||||
typedef struct _FooActorClass
|
|
||||||
{
|
|
||||||
ClutterActorClass parent_class;
|
|
||||||
} FooActorClass;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (FooActor, foo_actor, CLUTTER_TYPE_ACTOR);
|
|
||||||
|
|
||||||
static void
|
|
||||||
foo_actor_class_init (FooActorClass *klass)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
foo_actor_init (FooActor *actor)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
</informalexample>
|
|
||||||
|
|
||||||
<para>The implementation of an actor roughly depends on what kind
|
|
||||||
of actor the class should display.</para>
|
|
||||||
|
|
||||||
<para>The implementation process can be broken down into sections:
|
|
||||||
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term>size requisition</term>
|
|
||||||
<listitem><para>used by containers to know how much space
|
|
||||||
an actor requires for itself and its eventual
|
|
||||||
children.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>size allocation</term>
|
|
||||||
<listitem><para>used by containers to define how much space
|
|
||||||
an actor should have for itself and its eventual
|
|
||||||
children.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>painting and picking</term>
|
|
||||||
<listitem><para>the actual actor painting and the "picking"
|
|
||||||
done to determine the actors that received events</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>realization and visibility</term>
|
|
||||||
<listitem><para>used by containers and composite actors to
|
|
||||||
determine whether their children should allocate (and deallocate)
|
|
||||||
specific resources associated with being added to the #ClutterStage,
|
|
||||||
and whether their children should be painted or not.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
</variablelist>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>Container actors should also implement the #ClutterContainer
|
|
||||||
interface to provide a consistent API for adding, removing and iterating
|
|
||||||
over their children.</para>
|
|
||||||
|
|
||||||
<refsect1 id="actor-size-requisition">
|
|
||||||
<title>Size requisition</title>
|
|
||||||
|
|
||||||
<para>Actors should usually implement the size requisition virtual
|
|
||||||
functions unless they depend on explicit sizing by the developer,
|
|
||||||
using the clutter_actor_set_width() and clutter_actor_set_height()
|
|
||||||
functions and their wrappers.</para>
|
|
||||||
|
|
||||||
<note><para>For instance, an actor that depends on the explicit
|
|
||||||
sizing is the #ClutterRectangle actor.</para></note>
|
|
||||||
|
|
||||||
<para>The size requisition is split into two different phases: width
|
|
||||||
requisition and height requisition.</para>
|
|
||||||
|
|
||||||
<para>The <classname>ClutterActor</classname>::<function>get_preferred_width</function> and
|
|
||||||
<classname>ClutterActor</classname>::<function>get_preferred_height</function> methods of a
|
|
||||||
#ClutterActor are invoked when clutter_actor_get_preferred_width() and
|
|
||||||
clutter_actor_get_preferred_height() are respectively called on an instance
|
|
||||||
of that actor class. They are used to return the preferred size of the
|
|
||||||
actor. Container actors, or composite actors with internal children,
|
|
||||||
should call clutter_actor_get_preferred_width() and
|
|
||||||
clutter_actor_get_preferred_height() on each visible child inside
|
|
||||||
their implementation of the <function>get_preferred_width</function> and
|
|
||||||
<function>get_preferred_height</function> virtual functions.</para>
|
|
||||||
|
|
||||||
<para>The <function>get_preferred_width</function> and <function>get_preferred_height</function>
|
|
||||||
virtual functions return both the minimum size of the actor and its natural
|
|
||||||
size. The minimum size is defined as the amount of space an actor must
|
|
||||||
occupy to be useful; the natural size is defined as the amount of space an
|
|
||||||
actor would occupy if nothing would constrain it.</para>
|
|
||||||
|
|
||||||
<note><para>The natural size must always be greater than, or equal
|
|
||||||
to the minimum size. #ClutterActor will just ignore a natural size
|
|
||||||
lesser than a minimum size.</para></note>
|
|
||||||
|
|
||||||
<para>The height request may be computed for a specific width, which
|
|
||||||
is passed to the implementation, thus allowing height-for-width
|
|
||||||
geometry management. Similarly, the width request may be computed
|
|
||||||
for a specific height, allowing width-for-height geometry management.
|
|
||||||
By default, every #ClutterActor uses the height-for-width geometry
|
|
||||||
management, but the setting can be changed by using the
|
|
||||||
#ClutterActor:request-mode property.</para>
|
|
||||||
|
|
||||||
<note><para>The clutter_actor_get_preferred_size() function will
|
|
||||||
automatically check the geometry management preferred by the actor
|
|
||||||
and return its preferred size depending on the value of the request-mode
|
|
||||||
property and on the natural size of the actor. The
|
|
||||||
clutter_actor_get_preferred_size() method, though, will ignore any
|
|
||||||
notion of "available size" so it should not be used inside a
|
|
||||||
<classname>ClutterActor</classname>::<function>allocate</function>
|
|
||||||
implementation.</para></note>
|
|
||||||
|
|
||||||
<para>The size requisition starts from the #ClutterStage and it is
|
|
||||||
performed on every child of the stage following down the hierarchy
|
|
||||||
of the scene graph.</para>
|
|
||||||
|
|
||||||
<note><para>The size requisition should not take into account the
|
|
||||||
actor's scale, rotation or anchor point unless an actor is performing
|
|
||||||
layout management depending on those properties.</para></note>
|
|
||||||
|
|
||||||
<note><para>All the sizes are expressed using pixels with subpixel
|
|
||||||
precision. The sub-pixel precision is useful when animating actors
|
|
||||||
but it can produce odd results on screen, so you might want to
|
|
||||||
truncate the precision of the computed values.</para></note>
|
|
||||||
|
|
||||||
<example id="clutter-actor-get-width-request-example">
|
|
||||||
<title>Width requisition implementation of a container</title>
|
|
||||||
|
|
||||||
<para>This example shows how an actor class should override the
|
|
||||||
<function>get_preferred_width</function> virtual function of
|
|
||||||
#ClutterActor. In this case, the returned widths are the union of
|
|
||||||
the extents of all the <classname>FooActor</classname> children.</para>
|
|
||||||
|
|
||||||
<para>The <function>get_preferred_height</function> implementation
|
|
||||||
would be similar to the <function>get_preferred_width</function>
|
|
||||||
implementation, so it is omitted.</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
static void
|
|
||||||
foo_actor_get_preferred_width (ClutterActor *actor,
|
|
||||||
gfloat for_height,
|
|
||||||
gfloat *min_width_p,
|
|
||||||
gfloat *natural_width_p)
|
|
||||||
{
|
|
||||||
GList *l;
|
|
||||||
ClutterUnit min_left, min_right;
|
|
||||||
ClutterUnit natural_left, natural_right;
|
|
||||||
|
|
||||||
min_left = 0;
|
|
||||||
min_right = 0;
|
|
||||||
natural_left = 0;
|
|
||||||
natural_right = 0;
|
|
||||||
|
|
||||||
for (l = children; l != NULL; l = l->next)
|
|
||||||
{
|
|
||||||
ClutterActor *child = l->data;
|
|
||||||
gfloat child_x, child_min, child_natural;
|
|
||||||
|
|
||||||
child_x = clutter_actor_get_xu (child);
|
|
||||||
|
|
||||||
clutter_actor_get_preferred_width (child, for_height,
|
|
||||||
&child_min,
|
|
||||||
&child_natural);
|
|
||||||
|
|
||||||
if (l == children)
|
|
||||||
{
|
|
||||||
/* First child */
|
|
||||||
min_left = child_x;
|
|
||||||
natural_left = child_x;
|
|
||||||
min_right = min_left + child_min;
|
|
||||||
natural_right = natural_left + child_natural;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (child_x < min_left)
|
|
||||||
min_left = child_x;
|
|
||||||
|
|
||||||
if (child_x < natural_left)
|
|
||||||
natural_left = child_x;
|
|
||||||
|
|
||||||
if (child_x + child_min > min_right)
|
|
||||||
min_right = child_x + child_min;
|
|
||||||
|
|
||||||
if (child_x + child_natural > natural_right)
|
|
||||||
natural_right = child_x + child_natural;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The request is defined as the width and height we want starting from
|
|
||||||
* our origin, since our allocation will set the origin; so we now need
|
|
||||||
* to remove any part of the request that is to the left of the origin.
|
|
||||||
*/
|
|
||||||
if (min_left < 0)
|
|
||||||
min_left = 0;
|
|
||||||
|
|
||||||
if (natural_left < 0)
|
|
||||||
natural_left = 0;
|
|
||||||
|
|
||||||
if (min_right < 0)
|
|
||||||
min_right = 0;
|
|
||||||
|
|
||||||
if (natural_right < 0)
|
|
||||||
natural_right = 0;
|
|
||||||
|
|
||||||
g_assert (min_right >= min_left);
|
|
||||||
g_assert (natural_right >= natural_left);
|
|
||||||
|
|
||||||
if (min_width_p)
|
|
||||||
*min_width_p = min_right - min_left;
|
|
||||||
|
|
||||||
if (natural_width_p)
|
|
||||||
*natural_width_p = natural_right - min_left;
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
</refsect1> <!-- actor-size-requisition -->
|
|
||||||
|
|
||||||
<refsect1 id="actor-size-allocation">
|
|
||||||
<title>Size allocation</title>
|
|
||||||
|
|
||||||
<para>The <classname>ClutterActor</classname>::<function>allocate</function>
|
|
||||||
virtual function of a #ClutterActor is invoked when clutter_actor_allocate()
|
|
||||||
is called on an instance of that actor class. It is used by a parent actor
|
|
||||||
to set the coordinates of the bounding box for its children actors. Hence,
|
|
||||||
container actors, or composite actors with internal children, should
|
|
||||||
override the <function>allocate</function> virtual function and call
|
|
||||||
clutter_actor_allocate() on each visible child.</para>
|
|
||||||
|
|
||||||
<para>Each actor can know from their allocation box whether they
|
|
||||||
have been moved with respect to their parent actor. Each child will
|
|
||||||
also be able to tell whether their parent has been moved with respect
|
|
||||||
to the stage.</para>
|
|
||||||
|
|
||||||
<note><para>The <function>allocate</function> virtual function implementation
|
|
||||||
will be notified whether the actor has been moved, while clutter_actor_allocate()
|
|
||||||
will usually be invoked with the %CLUTTER_ABSOLUTE_ORIGIN_CHANGED flag,
|
|
||||||
meaning that the parent has been moved.</para></note>
|
|
||||||
|
|
||||||
<example id="container-allocate-example">
|
|
||||||
<title>Allocation of a container</title>
|
|
||||||
<para>In this example, <classname>FooActor</classname> acts like a
|
|
||||||
horizontal box with overflowing, like a toolbar which will display
|
|
||||||
more children as it expands. The children falling outside of the
|
|
||||||
allocated area will not be allocated.</para>
|
|
||||||
<programlisting language="C">
|
|
||||||
static void
|
|
||||||
foo_actor_allocate (ClutterActor *actor,
|
|
||||||
const ClutterActorBox *box,
|
|
||||||
ClutterAllocationFlags flags)
|
|
||||||
{
|
|
||||||
FooActor *foo_actor = FOO_ACTOR (actor);
|
|
||||||
gfloat available_width, available_height;
|
|
||||||
gfloat current_width, current_height;
|
|
||||||
gfloat row_height;
|
|
||||||
GList *l;
|
|
||||||
|
|
||||||
/* chain up to store the allocation of the actor */
|
|
||||||
CLUTTER_ACTOR_CLASS (foo_actor_parent_class)->allocate (actor, box, flags);
|
|
||||||
|
|
||||||
clutter_actor_box_get_size (box,
|
|
||||||
&available_width,
|
|
||||||
&available_height);
|
|
||||||
|
|
||||||
current_width = 0;
|
|
||||||
current_height = 0;
|
|
||||||
|
|
||||||
row_height = 0;
|
|
||||||
|
|
||||||
for (l = foo_actor->children;
|
|
||||||
l != NULL;
|
|
||||||
l = l->next)
|
|
||||||
{
|
|
||||||
ClutterActor *child = l->data;
|
|
||||||
ClutterActorBox child_box = { 0, };
|
|
||||||
gfloat child_width, child_height;
|
|
||||||
ClutterRequestMode mode;
|
|
||||||
|
|
||||||
/* do not allocate invisible children */
|
|
||||||
if (!CLUTTER_ACTOR_IS_VISIBLE (child))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
g_object_get (G_OBJECT (child), "request-mode", &mode, NULL);
|
|
||||||
if (mode == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH)
|
|
||||||
{
|
|
||||||
gfloat min, natural;
|
|
||||||
|
|
||||||
clutter_actor_get_preferred_width (child, available_height,
|
|
||||||
&min, &natural);
|
|
||||||
child_width = MAX (min, MIN (natural, available_width));
|
|
||||||
|
|
||||||
clutter_actor_get_preferred_height (child, child_width,
|
|
||||||
&min, &natural);
|
|
||||||
child_height = MAX (min, MIN (natural, available_height));
|
|
||||||
}
|
|
||||||
else (mode == CLUTTER_REQUEST_WIDTH_FOR_HEIGHT)
|
|
||||||
{
|
|
||||||
gfloat min, natural;
|
|
||||||
|
|
||||||
clutter_actor_get_preferred_height (child, available_width,
|
|
||||||
&min, &natural);
|
|
||||||
child_height = MAX (min, MIN (natural, available_height));
|
|
||||||
|
|
||||||
clutter_actor_get_preferred_width (child, child_height,
|
|
||||||
&min, &natural);
|
|
||||||
child_width = MAX (min, MIN (natural, available_width));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_assert_not_reached ();
|
|
||||||
|
|
||||||
/* overflow */
|
|
||||||
if (current_width + child_width > available_width)
|
|
||||||
{
|
|
||||||
current_width = 0;
|
|
||||||
current_height += row_height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
current_width += child_width;
|
|
||||||
|
|
||||||
/* stop allocating if we are overflowing the available height */
|
|
||||||
if (current_height + child_height > available_height)
|
|
||||||
break;
|
|
||||||
|
|
||||||
child_box.x1 = current_width;
|
|
||||||
child_box.y1 = current_height;
|
|
||||||
child_box.x2 = child_box.x1 + child_width;
|
|
||||||
child_box.y2 = child_box.y1 + child_height;
|
|
||||||
|
|
||||||
/* update the allocation */
|
|
||||||
clutter_actor_allocate (child,
|
|
||||||
&child_box,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
row_height = MAX (row_height, child_height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<para>The allocation is also the "paint area", that is the area where
|
|
||||||
the paint operations should be performed.</para>
|
|
||||||
|
|
||||||
</refsect1> <!-- actor-size-allocation -->
|
|
||||||
|
|
||||||
<refsect1 id="actor-painting-and-picking">
|
|
||||||
<title>Painting and picking</title>
|
|
||||||
|
|
||||||
<para>The <classname>ClutterActor</classname>::<function>paint</function>
|
|
||||||
virtual function should be overridden if the actor needs to control its
|
|
||||||
drawing process, by painting other child actors or drawing with the Cogl
|
|
||||||
3D graphics
|
|
||||||
API.</para>
|
|
||||||
|
|
||||||
<example id="simple-actor-paint-example">
|
|
||||||
<title>Paint implementation of a simple actor</title>
|
|
||||||
<para>In this example, the <classname>FooActor</classname>
|
|
||||||
implementation of the <function>paint</function> virtual function is
|
|
||||||
drawing a rectangle with rounded corners with a custom color using the
|
|
||||||
Cogl API.</para>
|
|
||||||
<programlisting>
|
|
||||||
static void
|
|
||||||
foo_actor_paint (ClutterActor *actor)
|
|
||||||
{
|
|
||||||
FooActor *foo_actor = FOO_ACTOR (actor);
|
|
||||||
ClutterActorBox allocation = { 0, };
|
|
||||||
gfloat width, height;
|
|
||||||
|
|
||||||
/* FooActor has a specific background color
|
|
||||||
*
|
|
||||||
* the alpha component must take into account the absolute
|
|
||||||
* opacity of the actor on the screen at this point in the
|
|
||||||
* scenegraph; this value is obtained by calling
|
|
||||||
* clutter_actor_get_paint_opacity().
|
|
||||||
*/
|
|
||||||
cogl_set_source_color4ub (priv->fgcol.red,
|
|
||||||
priv->fgcol.green,
|
|
||||||
priv->fgcol.blue,
|
|
||||||
clutter_actor_get_paint_opacity (actor));
|
|
||||||
|
|
||||||
clutter_actor_get_allocation_box (actor, &allocation);
|
|
||||||
clutter_actor_box_get_size (&allocation &width, &height);
|
|
||||||
|
|
||||||
/* paint a rounded rectangle using GL primitives; the area of
|
|
||||||
* paint is (0, 0) - (width, height), which means the whole
|
|
||||||
* allocation or, if the actor has a fixed size, the size that
|
|
||||||
* has been set.
|
|
||||||
*/
|
|
||||||
cogl_path_round_rectangle (0, 0, width, height, foo_actor->radius, 5);
|
|
||||||
|
|
||||||
/* and fill it with the current color */
|
|
||||||
cogl_path_fill ();
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<note><para>When inside the <classname>ClutterActor</classname>::<function>paint</function>
|
|
||||||
virtual function the actor is already positioned at the coordinates specified by
|
|
||||||
its parent; all the paint operations should take place from the (0, 0)
|
|
||||||
coordinates.</para></note>
|
|
||||||
|
|
||||||
<para>Container actors or composite actors with internal children should
|
|
||||||
also override the paint method, and call clutter_actor_paint() on every
|
|
||||||
visible child:</para>
|
|
||||||
|
|
||||||
<example id="container-actor-paint-example">
|
|
||||||
<title>Paint implementation of a container</title>
|
|
||||||
<para>In this example, <classname>FooActor</classname> is a simple
|
|
||||||
container invoking clutter_actor_paint() on every visible child.</para>
|
|
||||||
<programlisting>
|
|
||||||
static void
|
|
||||||
foo_actor_paint (ClutterActor *actor)
|
|
||||||
{
|
|
||||||
FooActor *foo_actor = FOO_ACTOR (actor);
|
|
||||||
GList *child;
|
|
||||||
|
|
||||||
for (child = foo_actor->children;
|
|
||||||
child != NULL;
|
|
||||||
child = child->next)
|
|
||||||
{
|
|
||||||
ClutterActor *child_actor = child->data;
|
|
||||||
|
|
||||||
clutter_actor_paint (child_actor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<para>If the actor has a non-rectangular shape, or it has internal
|
|
||||||
children that need to be distinguished by the events delivery mechanism,
|
|
||||||
the <classname>ClutterActor</classname>::<function>pick</function> virtual
|
|
||||||
function should also be overridden. The <function>pick</function> virtual
|
|
||||||
function works exactly like the <function>paint</function> virtual
|
|
||||||
function, but the actor should paint just its shape with the passed
|
|
||||||
colour:</para>
|
|
||||||
|
|
||||||
<example id="simple-actor-pick-example">
|
|
||||||
<title>Pick implementation of a simple actor</title>
|
|
||||||
<para>In this example, <classname>FooActor</classname> overrides the
|
|
||||||
<function>pick</function> virtual function default implementation to
|
|
||||||
paint itself with a shaped silhouette, to allow events only on the
|
|
||||||
actual shape of the actor instead of the whole paint area.</para>
|
|
||||||
<programlisting>
|
|
||||||
static void
|
|
||||||
foo_actor_pick (ClutterActor *actor,
|
|
||||||
const ClutterColor *pick_color)
|
|
||||||
{
|
|
||||||
FooActor *foo_actor = FOO_ACTOR (actor);
|
|
||||||
ClutterActorBox allocation = { 0, };
|
|
||||||
gfloat width, height;
|
|
||||||
|
|
||||||
/* it is possible to avoid a costly paint by checking whether the
|
|
||||||
* actor should really be painted in pick mode
|
|
||||||
*/
|
|
||||||
if (!clutter_actor_should_pick_paint (actor))
|
|
||||||
return;
|
|
||||||
|
|
||||||
clutter_actor_get_allocation_box (actor, &allocation);
|
|
||||||
clutter_actor_box_get_size (&allocation, &width, &height);
|
|
||||||
|
|
||||||
/* use the passed color to paint ourselves */
|
|
||||||
cogl_set_source_color4ub (pick_color->red,
|
|
||||||
pick_color->green,
|
|
||||||
pick_color->blue,
|
|
||||||
pick_color->alpha);
|
|
||||||
|
|
||||||
/* paint a round rectangle */
|
|
||||||
cogl_path_round_rectangle (0, 0, width, height, foo_actor->radius, 5);
|
|
||||||
|
|
||||||
/* and fill it with the current color */
|
|
||||||
cogl_path_fill ();
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<para>Containers should simply chain up to the parent class'
|
|
||||||
<function>pick</function> implementation to get their silhouette painted
|
|
||||||
and then paint their children:</para>
|
|
||||||
|
|
||||||
<example id="container-actor-pick-example">
|
|
||||||
<title>Pick implementation of a container</title>
|
|
||||||
<para>In this example, <classname>FooActor</classname> allows the
|
|
||||||
picking of each child it contains, as well as itself.</para>
|
|
||||||
<programlisting>
|
|
||||||
static void
|
|
||||||
foo_actor_pick (ClutterActor *actor,
|
|
||||||
const ClutterColor *pick_color)
|
|
||||||
{
|
|
||||||
FooActor *foo_actor = FOO_ACTOR (actor);
|
|
||||||
|
|
||||||
/* this will paint a silhouette corresponding to the paint box */
|
|
||||||
CLUTTER_ACTOR_CLASS (foo_actor_parent_class)->pick (actor, pick_color);
|
|
||||||
|
|
||||||
/* clutter_actor_paint() is context-sensitive, and will perform
|
|
||||||
* a pick paint if the scene graph is in pick mode
|
|
||||||
*/
|
|
||||||
clutter_actor_paint (foo_actor->child);
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
</refsect1> <!-- actor-painting-and-picking -->
|
|
||||||
|
|
||||||
<refsect1 id="implementing-clutter-container">
|
|
||||||
<title>Implementing Containers</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The #ClutterContainer interface should be implemented by subclasses
|
|
||||||
of #ClutterActor who wants to provide a general API for adding child
|
|
||||||
actors.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
If the #ClutterActor subclass only handles internal children, or it's
|
|
||||||
not suitable for having generic actors added to it, it should not
|
|
||||||
implement the #ClutterContainer interface, but simply use
|
|
||||||
clutter_actor_set_parent():
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<example id="clutter-actor-set-parent-example">
|
|
||||||
<title>Parenting an actor</title>
|
|
||||||
<para>In this example, <classname>FooActor</classname> has an internal
|
|
||||||
child of type <classname>BazActor</classname> which is assigned using a
|
|
||||||
specific function called foo_actor_add_baz(). The
|
|
||||||
<classname>FooActor</classname> instance takes ownership of the
|
|
||||||
<classname>BazActor</classname> instance and sets the parent-child
|
|
||||||
relationship using clutter_actor_set_parent().</para>
|
|
||||||
<programlisting>
|
|
||||||
void
|
|
||||||
foo_actor_add_baz (FooActor *foo_actor,
|
|
||||||
BazActor *baz_actor)
|
|
||||||
{
|
|
||||||
g_return_if_fail (FOO_IS_ACTOR (foo_actor));
|
|
||||||
g_return_if_fail (BAZ_IS_ACTOR (baz_actor));
|
|
||||||
|
|
||||||
/* unparent the previous BazActor; this will automatically call
|
|
||||||
* g_object_unref() on the actor
|
|
||||||
*/
|
|
||||||
if (foo_actor->baz)
|
|
||||||
clutter_actor_unparent (foo_actor->baz);
|
|
||||||
|
|
||||||
foo_actor->baz = baz_actor;
|
|
||||||
|
|
||||||
/* this will cause the initial floating reference of ClutterActor to
|
|
||||||
* disappear, and add a new reference on baz_actor. foo_actor has now
|
|
||||||
* taken ownership of baz_actor, so that:
|
|
||||||
*
|
|
||||||
* foo_actor_add_baz (foo_actor, baz_actor_new ());
|
|
||||||
*
|
|
||||||
* is a safe statement (no reference is leaked).
|
|
||||||
*/
|
|
||||||
clutter_actor_set_parent (CLUTTER_ACTOR (baz_actor),
|
|
||||||
CLUTTER_ACTOR (foo_actor));
|
|
||||||
|
|
||||||
/* a container should queue a change in the layout */
|
|
||||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (foo_actor));
|
|
||||||
|
|
||||||
/* emit a signal and notification */
|
|
||||||
g_signal_emit (foo_actor, foo_actor_signals[BAZ_CHANGED], 0, baz_actor);
|
|
||||||
g_object_notify (G_OBJECT (foo_actor), "baz");
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
In order to implement the #ClutterContainer interface, these virtual
|
|
||||||
functions must be defined:
|
|
||||||
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term>ClutterContainer::add</term>
|
|
||||||
<listitem>
|
|
||||||
<para>The container actor should hold a pointer to the passed
|
|
||||||
#ClutterActor, call clutter_actor_set_parent() on it, queue
|
|
||||||
a relayout on itself and then emit the
|
|
||||||
#ClutterContainer::actor-added signal to notify
|
|
||||||
handlers of the newly added actor.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>ClutterContainer::remove</term>
|
|
||||||
<listitem>
|
|
||||||
<para>The container actor should increase the reference count
|
|
||||||
of the passed #ClutterActor, remove the pointer held on the
|
|
||||||
child and call clutter_actor_unparent() on it; then, emit the
|
|
||||||
#ClutterContainer::actor-removed signal and decrease the
|
|
||||||
reference count.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>ClutterContainer::foreach</term>
|
|
||||||
<listitem>
|
|
||||||
<para>The container should invoke the callback on every
|
|
||||||
child it is holding.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>ClutterContainer::foreach_with_internals</term>
|
|
||||||
<listitem>
|
|
||||||
<para>The container should invoke the callback on every
|
|
||||||
child it is holding, including eventual private children
|
|
||||||
that should not be handled by the #ClutterContainer API.
|
|
||||||
This method can be ignored if the container does not
|
|
||||||
have internal children.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>ClutterContainer::raise</term>
|
|
||||||
<listitem>
|
|
||||||
<para>The container should move the passed child on top
|
|
||||||
of the given sibling, or on top of the paint stack in
|
|
||||||
case the sibling is NULL. This method can be ignored if the
|
|
||||||
container does not have overlapping children.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>ClutterContainer::lower</term>
|
|
||||||
<listitem>
|
|
||||||
<para>The container should move the passed child below
|
|
||||||
the given sibling, or on the bottom of the paint stack
|
|
||||||
in case the sibling is NULL. This method can be ignored
|
|
||||||
if the container does not have overlapping children.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>ClutterContainer::sort_depth_order</term>
|
|
||||||
<listitem>
|
|
||||||
<para>The container should sort the paint stack depending
|
|
||||||
on the relative depths of each child. This method can
|
|
||||||
be ignored if the container does not have overlapping
|
|
||||||
children.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</refsect1> <!-- implementing-clutter-container -->
|
|
||||||
|
|
||||||
</chapter>
|
|
Loading…
Reference in New Issue
Block a user