mirror of
https://github.com/brl/mutter.git
synced 2024-11-10 07:56:14 -05:00
2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-sections.txt: Update with the new API. * clutter/subclassing-ClutterActor.sgml: Update with the new size negotiation API.
This commit is contained in:
parent
4a788a6df7
commit
d93c7d1f85
@ -1,3 +1,10 @@
|
|||||||
|
2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
|
||||||
|
* clutter/clutter-sections.txt: Update with the new API.
|
||||||
|
|
||||||
|
* clutter/subclassing-ClutterActor.sgml: Update with the new
|
||||||
|
size negotiation API.
|
||||||
|
|
||||||
2008-06-09 Chris Lord <chris@openedhand.com>
|
2008-06-09 Chris Lord <chris@openedhand.com>
|
||||||
|
|
||||||
* cogl/cogl-sections.txt:
|
* cogl/cogl-sections.txt:
|
||||||
|
@ -255,15 +255,15 @@ clutter_container_lower_child
|
|||||||
clutter_container_sort_depth_order
|
clutter_container_sort_depth_order
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_container_find_child_property
|
clutter_container_class_find_child_property
|
||||||
clutter_container_list_child_properties
|
clutter_container_class_list_child_properties
|
||||||
clutter_container_child_set_property
|
clutter_container_child_set_property
|
||||||
clutter_container_child_get_property
|
clutter_container_child_get_property
|
||||||
clutter_container_child_set
|
clutter_container_child_set
|
||||||
clutter_container_child_get
|
clutter_container_child_get
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_container_get_child_data
|
clutter_container_get_child_meta
|
||||||
|
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
CLUTTER_TYPE_CONTAINER
|
CLUTTER_TYPE_CONTAINER
|
||||||
@ -275,21 +275,21 @@ clutter_container_get_type
|
|||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>clutter-child-data</FILE>
|
<FILE>clutter-child-meta</FILE>
|
||||||
<TITLE>ClutterChildData<TITLE>
|
<TITLE>ClutterChildMeta</TITLE>
|
||||||
ClutterChildData
|
ClutterChildMeta
|
||||||
ClutterChildDataClass
|
ClutterChildMetaClass
|
||||||
clutter_child_data_get_container
|
clutter_child_meta_get_container
|
||||||
clutter_child_data_get_actor
|
clutter_child_meta_get_actor
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
CLUTTER_TYPE_CHILD_DATA
|
CLUTTER_TYPE_CHILD_META
|
||||||
CLUTTER_CHILD_DATA
|
CLUTTER_CHILD_META
|
||||||
CLUTTER_IS_CHILD_DATA
|
CLUTTER_IS_CHILD_META
|
||||||
CLUTTER_CHILD_DATA_CLASS
|
CLUTTER_CHILD_META_CLASS
|
||||||
CLUTTER_IS_CHILD_DATA_CLASS
|
CLUTTER_IS_CHILD_META_CLASS
|
||||||
CLUTTER_CHILD_DATA_GET_CLASS
|
CLUTTER_CHILD_META_GET_CLASS
|
||||||
<SUBSECTION Private>
|
<SUBSECTION Private>
|
||||||
clutter_child_data_get_type
|
clutter_child_meta_get_type
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
@ -330,6 +330,7 @@ CLUTTER_ACTOR_IS_REACTIVE
|
|||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
ClutterActorBox
|
ClutterActorBox
|
||||||
ClutterActorFlags
|
ClutterActorFlags
|
||||||
|
ClutterRequestMode
|
||||||
ClutterGeometry
|
ClutterGeometry
|
||||||
CLUTTER_CALLBACK
|
CLUTTER_CALLBACK
|
||||||
ClutterCallback
|
ClutterCallback
|
||||||
@ -343,22 +344,32 @@ clutter_actor_realize
|
|||||||
clutter_actor_unrealize
|
clutter_actor_unrealize
|
||||||
clutter_actor_paint
|
clutter_actor_paint
|
||||||
clutter_actor_queue_redraw
|
clutter_actor_queue_redraw
|
||||||
|
clutter_actor_queue_relayout
|
||||||
clutter_actor_destroy
|
clutter_actor_destroy
|
||||||
clutter_actor_request_coords
|
|
||||||
clutter_actor_query_coords
|
|
||||||
clutter_actor_event
|
clutter_actor_event
|
||||||
clutter_actor_pick
|
clutter_actor_pick
|
||||||
clutter_actor_should_pick_paint
|
clutter_actor_should_pick_paint
|
||||||
|
|
||||||
|
<SUBSECTION>
|
||||||
|
clutter_actor_allocate
|
||||||
|
clutter_actor_get_allocation_coords
|
||||||
|
clutter_actor_get_allocation_box
|
||||||
|
clutter_actor_get_allocation_geometry
|
||||||
|
clutter_actor_get_allocation_vertices
|
||||||
|
clutter_actor_get_preferred_size
|
||||||
|
clutter_actor_get_preferred_width
|
||||||
|
clutter_actor_get_preferred_height
|
||||||
|
clutter_actor_get_paint_area
|
||||||
|
clutter_actor_set_fixed_position_set
|
||||||
|
clutter_actor_get_fixed_position_set
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_actor_set_geometry
|
clutter_actor_set_geometry
|
||||||
clutter_actor_get_geometry
|
clutter_actor_get_geometry
|
||||||
clutter_actor_get_coords
|
|
||||||
clutter_actor_set_size
|
clutter_actor_set_size
|
||||||
clutter_actor_get_size
|
clutter_actor_get_size
|
||||||
clutter_actor_set_position
|
clutter_actor_set_position
|
||||||
clutter_actor_get_position
|
clutter_actor_get_position
|
||||||
clutter_actor_get_abs_position
|
|
||||||
clutter_actor_set_width
|
clutter_actor_set_width
|
||||||
clutter_actor_get_width
|
clutter_actor_get_width
|
||||||
clutter_actor_set_height
|
clutter_actor_set_height
|
||||||
@ -392,6 +403,7 @@ 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_get_stage
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_actor_set_depth
|
clutter_actor_set_depth
|
||||||
@ -399,15 +411,16 @@ clutter_actor_get_depth
|
|||||||
clutter_actor_set_scale
|
clutter_actor_set_scale
|
||||||
clutter_actor_get_scale
|
clutter_actor_get_scale
|
||||||
clutter_actor_is_scaled
|
clutter_actor_is_scaled
|
||||||
clutter_actor_get_abs_size
|
|
||||||
clutter_actor_apply_transform_to_point
|
clutter_actor_apply_transform_to_point
|
||||||
clutter_actor_transform_stage_point
|
clutter_actor_transform_stage_point
|
||||||
clutter_actor_apply_relative_transform_to_point
|
clutter_actor_apply_relative_transform_to_point
|
||||||
|
clutter_actor_get_transformed_position
|
||||||
|
clutter_actor_get_transformed_size
|
||||||
|
clutter_actor_get_paint_opacity
|
||||||
|
clutter_actor_get_abs_allocation_vertices
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
ClutterVertex
|
ClutterVertex
|
||||||
clutter_actor_get_vertices
|
|
||||||
clutter_actor_get_relative_vertices
|
|
||||||
clutter_actor_box_get_from_vertices
|
clutter_actor_box_get_from_vertices
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
@ -444,7 +457,11 @@ clutter_actor_get_anchor_pointu
|
|||||||
clutter_actor_move_anchor_pointu
|
clutter_actor_move_anchor_pointu
|
||||||
clutter_actor_set_clipu
|
clutter_actor_set_clipu
|
||||||
clutter_actor_get_clipu
|
clutter_actor_get_clipu
|
||||||
|
clutter_actor_set_rotationu
|
||||||
|
clutter_actor_get_rotationu
|
||||||
clutter_actor_move_byu
|
clutter_actor_move_byu
|
||||||
|
clutter_actor_get_transformed_positionu
|
||||||
|
clutter_actor_get_transformed_sizeu
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_actor_set_scalex
|
clutter_actor_set_scalex
|
||||||
@ -516,8 +533,9 @@ ClutterStage
|
|||||||
ClutterStageClass
|
ClutterStageClass
|
||||||
CLUTTER_STAGE_WIDTH
|
CLUTTER_STAGE_WIDTH
|
||||||
CLUTTER_STAGE_HEIGHT
|
CLUTTER_STAGE_HEIGHT
|
||||||
clutter_stage_new
|
|
||||||
clutter_stage_get_default
|
clutter_stage_get_default
|
||||||
|
clutter_stage_new
|
||||||
|
clutter_stage_is_default
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_stage_set_color
|
clutter_stage_set_color
|
||||||
@ -528,6 +546,7 @@ clutter_stage_show_cursor
|
|||||||
clutter_stage_hide_cursor
|
clutter_stage_hide_cursor
|
||||||
clutter_stage_get_actor_at_pos
|
clutter_stage_get_actor_at_pos
|
||||||
clutter_stage_ensure_current
|
clutter_stage_ensure_current
|
||||||
|
clutter_stage_queue_redraw
|
||||||
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
|
||||||
@ -564,9 +583,9 @@ CLUTTER_TYPE_STAGE
|
|||||||
CLUTTER_STAGE_CLASS
|
CLUTTER_STAGE_CLASS
|
||||||
CLUTTER_IS_STAGE_CLASS
|
CLUTTER_IS_STAGE_CLASS
|
||||||
CLUTTER_STAGE_GET_CLASS
|
CLUTTER_STAGE_GET_CLASS
|
||||||
|
CLUTTER_STAGE_TYPE
|
||||||
CLUTTER_TYPE_PERSPECTIVE
|
CLUTTER_TYPE_PERSPECTIVE
|
||||||
CLUTTER_TYPE_FOG
|
CLUTTER_TYPE_FOG
|
||||||
CLUTTER_STAGE_TYPE
|
|
||||||
<SUBSECTION Private>
|
<SUBSECTION Private>
|
||||||
ClutterStagePrivate
|
ClutterStagePrivate
|
||||||
clutter_stage_get_type
|
clutter_stage_get_type
|
||||||
@ -821,6 +840,8 @@ clutter_backend_get_double_click_time
|
|||||||
clutter_backend_set_double_click_time
|
clutter_backend_set_double_click_time
|
||||||
clutter_backend_get_double_click_distance
|
clutter_backend_get_double_click_distance
|
||||||
clutter_backend_set_double_click_distance
|
clutter_backend_set_double_click_distance
|
||||||
|
clutter_backend_set_font_options
|
||||||
|
clutter_backend_get_font_options
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
CLUTTER_BACKEND
|
CLUTTER_BACKEND
|
||||||
CLUTTER_IS_BACKEND
|
CLUTTER_IS_BACKEND
|
||||||
@ -1014,6 +1035,7 @@ clutter_key_event_symbol
|
|||||||
clutter_key_event_code
|
clutter_key_event_code
|
||||||
clutter_key_event_unicode
|
clutter_key_event_unicode
|
||||||
clutter_keysym_to_unicode
|
clutter_keysym_to_unicode
|
||||||
|
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
CLUTTER_TYPE_EVENT
|
CLUTTER_TYPE_EVENT
|
||||||
<SUBSECTION Private>
|
<SUBSECTION Private>
|
||||||
@ -1028,6 +1050,7 @@ ClutterInitError
|
|||||||
clutter_init
|
clutter_init
|
||||||
clutter_init_with_args
|
clutter_init_with_args
|
||||||
clutter_get_option_group
|
clutter_get_option_group
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_main
|
clutter_main
|
||||||
clutter_main_quit
|
clutter_main_quit
|
||||||
@ -1044,6 +1067,9 @@ clutter_set_motion_events_enabled
|
|||||||
clutter_get_motion_events_enabled
|
clutter_get_motion_events_enabled
|
||||||
clutter_set_motion_events_frequency
|
clutter_set_motion_events_frequency
|
||||||
clutter_get_motion_events_frequency
|
clutter_get_motion_events_frequency
|
||||||
|
clutter_clear_glyph_cache
|
||||||
|
clutter_set_use_mipmapped_text
|
||||||
|
clutter_get_use_mipmapped_text
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_threads_set_lock_functions
|
clutter_threads_set_lock_functions
|
||||||
@ -1102,10 +1128,10 @@ clutter_x11_remove_filter
|
|||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>clutter-win32</FILE>
|
<FILE>clutter-win32</FILE>
|
||||||
<TITLE>Win32 Specific Support</TITLE>
|
<TITLE>Win32 Specific Support</TITLE>
|
||||||
clutter_win32_get_stage_from_window
|
|
||||||
clutter_win32_get_stage_window
|
|
||||||
clutter_win32_disable_event_retrieval
|
clutter_win32_disable_event_retrieval
|
||||||
clutter_win32_set_stage_foreign
|
clutter_win32_set_stage_foreign
|
||||||
|
clutter_win32_get_stage_from_window
|
||||||
|
clutter_win32_get_stage_window
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
|
@ -14,135 +14,524 @@
|
|||||||
<title>Implementing a new actor</title>
|
<title>Implementing a new actor</title>
|
||||||
|
|
||||||
<para>In order to implement a new #ClutterActor subclass the usual
|
<para>In order to implement a new #ClutterActor subclass the usual
|
||||||
machinery for subclassing a GObject should be used. After that, the
|
machinery for subclassing a #GObject should be used:</para>
|
||||||
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>
|
|
||||||
|
|
||||||
<note>All the coordinates are expressed using #ClutterUnit<!-- -->s,
|
|
||||||
the internal high-precision unit type, which guarantee sub-pixel
|
|
||||||
precision. #ClutterUnit has the same limitation that #ClutterFixed
|
|
||||||
has, see the <link linkend="clutter-Fixed-Point-Support">fixed point page</link>.</note>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|
||||||
|
<informalexample>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
static void
|
#define FOO_TYPE_ACTOR (foo_actor_get_type ())
|
||||||
foo_actor_query_coords (ClutterActor *actor,
|
#define FOO_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_ACTOR, FooActor))
|
||||||
ClutterActorBox *box)
|
#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
|
||||||
{
|
{
|
||||||
FooActor *foo_actor = FOO_ACTOR (actor);
|
ClutterActor parent_instance;
|
||||||
GList *child;
|
} FooActor;
|
||||||
|
|
||||||
/* Clutter uses high-precision units which can be converted from
|
typedef struct _FooActorClass
|
||||||
* and into pixels, typographic points, percentages, etc.
|
{
|
||||||
*/
|
ClutterActorClass parent_class;
|
||||||
ClutterUnit width, height;
|
} FooActorClass;
|
||||||
|
|
||||||
/* initialize our size */
|
G_DEFINE_TYPE (FooActor, foo_actor, CLUTTER_TYPE_ACTOR);
|
||||||
width = height = 0;
|
|
||||||
|
|
||||||
for (l = foo_actor->children; l != NULL; l = l->next)
|
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>
|
||||||
|
|
||||||
|
</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>
|
||||||
|
|
||||||
|
<para>The size requisition is split into two different phases: width
|
||||||
|
requisition and height requisition.</para>
|
||||||
|
|
||||||
|
<para>The <classname>ClutterActor</classname>::get_preferred_width() and
|
||||||
|
<classname>ClutterActor</classname>::get_preferred_height() 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 get_preferred_width() and get_preferred_height()
|
||||||
|
virtual functions.</para>
|
||||||
|
|
||||||
|
<para>The get_preferred_width() and get_preferred_height() 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 warn in case this assumption
|
||||||
|
is not respected by an implementation.</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 it and on the natural
|
||||||
|
size.</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 #ClutterUnit<!-- -->s, the
|
||||||
|
internal high-precision unit type, which guarantees sub-pixel precision.
|
||||||
|
#ClutterUnit currently has the same limitations that #ClutterFixed has,
|
||||||
|
see the <link linkend="clutter-Fixed-Point-Support">fixed point page</link>.
|
||||||
|
</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
|
||||||
|
get_preferred_width() 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 get_preferred_height() implementation would be similar to the
|
||||||
|
get_preferred_width() implementation, so it is omitted.</para>
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
static void
|
||||||
|
foo_actor_get_preferred_width (ClutterActor *actor,
|
||||||
|
ClutterUnit for_height,
|
||||||
|
ClutterUnit *min_width_p,
|
||||||
|
ClutterUnit *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_actor = child->data;
|
ClutterActor *child = l->data;
|
||||||
|
ClutterUnit child_x, child_min, child_natural;
|
||||||
|
|
||||||
/* we consider only visible actors */
|
child_x = clutter_actor_get_xu (child);
|
||||||
if (CLUTTER_ACTOR_IS_VISIBLE (child_actor))
|
|
||||||
|
clutter_actor_get_preferred_width (child, for_height,
|
||||||
|
&child_min,
|
||||||
|
&child_natural);
|
||||||
|
|
||||||
|
if (l == children)
|
||||||
{
|
{
|
||||||
ClutterActorBox child_box = { 0, };
|
/* 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;
|
||||||
|
|
||||||
clutter_actor_query_coords (child_actor, &child_box);
|
if (child_x < natural_left)
|
||||||
|
natural_left = child_x;
|
||||||
width += child_box.x2 - child_box.x2;
|
|
||||||
height += child_box.y2 - child_box.y1;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
box->x2 = box->x1 + width
|
/* The request is defined as the width and height we want starting from
|
||||||
box->y2 = box->y1 + height;
|
* 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>
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
|
</refsect1> <!-- actor-size-requisition -->
|
||||||
|
|
||||||
|
<refsect1 id="actor-size-allocation">
|
||||||
|
<title>Size allocation</title>
|
||||||
|
|
||||||
|
<para>The <classname>ClutterActor</classname>::allocate() method 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 allocate() 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 allocate() virtual function implementation will be
|
||||||
|
notified whether the actor has been moved, while clutter_actor_allocate()
|
||||||
|
will usually be invoked with a boolean 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 fade out; the children falling inside the
|
||||||
|
same area will fade in.</para>
|
||||||
|
<programlisting language="C">
|
||||||
|
static void
|
||||||
|
foo_actor_allocate (ClutterActor *actor,
|
||||||
|
const ClutterActorBox *box,
|
||||||
|
gboolean absolute_origin_changed)
|
||||||
|
{
|
||||||
|
FooActor *foo_actor = FOO_ACTOR (actor);
|
||||||
|
ClutterUnit current_width;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
/* chain up to set the allocation of the actor */
|
||||||
|
CLUTTER_ACTOR_CLASS (foo_actor_parent_class)->allocate (actor, box, absolute_origin_changed);
|
||||||
|
|
||||||
|
current_width = foo_actor->padding;
|
||||||
|
|
||||||
|
for (l = foo_actor->children;
|
||||||
|
l != NULL;
|
||||||
|
l = l->next)
|
||||||
|
{
|
||||||
|
FooActorChild *child = l->data;
|
||||||
|
ClutterUnit natural_width, natural_height;
|
||||||
|
ClutterActorBox child_box = { 0, };
|
||||||
|
|
||||||
|
/* each child will get as much space as they require */
|
||||||
|
clutter_actor_get_preferred_size (CLUTTER_ACTOR (child),
|
||||||
|
NULL, NULL,
|
||||||
|
&natural_width, &natural_height);
|
||||||
|
|
||||||
|
/* if the child is overflowing, we just fade it out */
|
||||||
|
if (current_width + natual_width > box->x2 - box->x1)
|
||||||
|
foo_actor_fade_child (foo_actor, child, 0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current_width += natural_width + priv->padding;
|
||||||
|
|
||||||
|
child_box.x1 = current_width;
|
||||||
|
child_box.y1 = 0;
|
||||||
|
child_box.x2 = child_box.x1 + natural_width;
|
||||||
|
child_box.y2 = child_box.y1 + natural_height;
|
||||||
|
|
||||||
|
/* update the allocation */
|
||||||
|
clutter_actor_allocate (CLUTTER_ACTOR (child),
|
||||||
|
&child_box,
|
||||||
|
absolute_origin_changed);
|
||||||
|
|
||||||
|
/* fade the child in if it wasn't visible */
|
||||||
|
foo_actor_fade_child (foo_actor, child, 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<para>An actor should always paint inside its allocation. It is,
|
||||||
|
however, possible to paint outside the negotiated size by overriding
|
||||||
|
the <classname>ClutterActor</classname>::get_paint_area() virtual
|
||||||
|
function and setting the passed #ClutterActorBox with their
|
||||||
|
<emphasis>untransformed</emphasis> paint area. This allows writing
|
||||||
|
actors that can effectively paint on an area different in size and
|
||||||
|
position from the allocation area.</para>
|
||||||
|
|
||||||
|
<para>The <classname>ClutterActor</classname>::get_paint_area() method of
|
||||||
|
a #ClutterActor is internally invoked when clutter_actor_get_paint_area()
|
||||||
|
is called on an instance of that actor class. The get_paint_area()
|
||||||
|
virtual function must return the untransformed area used by the
|
||||||
|
actor to paint itself; clutter_actor_get_paint_area() will then
|
||||||
|
proceed to transform the area coordinates into the frame of reference
|
||||||
|
of the actor's parent (taking into account anchor point, scaling
|
||||||
|
and rotation).</para>
|
||||||
|
|
||||||
|
<note><para>The default paint area is the allocation area of the
|
||||||
|
actor.</para></note>
|
||||||
|
|
||||||
|
<example id="container-actor-paint-area-example">
|
||||||
|
<title>Implementation of get_paint_area()</title>
|
||||||
|
<para>In this example, <classname>FooActor</classname> implements
|
||||||
|
the get_paint_area() virtual function to return an area equivalent
|
||||||
|
to those of its children plus a border which is not taken into
|
||||||
|
account by the size negotiation process.</para>
|
||||||
|
<programlisting>
|
||||||
|
static void
|
||||||
|
foo_actor_get_paint_area (ClutterActor *actor,
|
||||||
|
ClutterActorBox *box)
|
||||||
|
{
|
||||||
|
FooActor *foo_actor = FOO_ACTOR (actor);
|
||||||
|
|
||||||
|
if (!foo_actor->children)
|
||||||
|
{
|
||||||
|
/* if we don't have any children we return the
|
||||||
|
* allocation given to us
|
||||||
|
*/
|
||||||
|
clutter_actor_get_allocation_box (actor, box);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClutterActorBox all_box = { 0, };
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
/* our paint area is the union of the children
|
||||||
|
* paint areas, plus a border
|
||||||
|
*/
|
||||||
|
for (l = foo_actor->children; l != NULL; l = l>next)
|
||||||
|
{
|
||||||
|
ClutterActor *child = l->data;
|
||||||
|
ClutterActorBox child_box = { 0, };
|
||||||
|
|
||||||
|
clutter_actor_get_paint_area (child, &child_box);
|
||||||
|
|
||||||
|
if (l == foo_actor->children)
|
||||||
|
all_box = child_box;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (child_box.x1 < all_box.x1)
|
||||||
|
all_box.x1 = child_box.x1;
|
||||||
|
|
||||||
|
if (child_box.y1 < all_box.y1)
|
||||||
|
all_box.y1 = child_box.y1;
|
||||||
|
|
||||||
|
if (child_box.x2 < all_box.x2)
|
||||||
|
all_box.x2 = child_box.x2;
|
||||||
|
|
||||||
|
if (child_box.y2 < all_box.y2)
|
||||||
|
all_box.y2 = child_box.y2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* apply the border width around the box */
|
||||||
|
all_box.x1 -= (foo_actor->border_width / 2);
|
||||||
|
all_box.y1 -= (foo_actor->border_width / 2);
|
||||||
|
all_box.x2 += (foo_actor->border_width / 2);
|
||||||
|
all_box.y2 += (foo_actor->border_width / 2);
|
||||||
|
|
||||||
|
*box = all_box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
</refsect1> <!-- actor-size-allocation -->
|
||||||
|
|
||||||
|
<refsect1 id="actor-painting-and-picking">
|
||||||
|
<title>Painting and picking</title>
|
||||||
|
|
||||||
|
<para>The <classname>ClutterActor</classname>::paint() method should be
|
||||||
|
overridden if the actor needs to control its drawing process, either by
|
||||||
|
using the Clutter GL and GLES abstraction library (COGL) or by directly
|
||||||
|
using the GL or GLES API.</para>
|
||||||
|
|
||||||
|
<note><para>Actors performing transformations should push the GL matrix
|
||||||
|
first and then pop the GL matrix before returning.</para></note>
|
||||||
|
|
||||||
<para>The ClutterActor::request_coords() method of a #ClutterActor
|
<example id="simple-actor-paint-example">
|
||||||
is invoked when clutter_actor_request_coords() is called on an instance
|
<title>Paint implementation of a simple actor</title>
|
||||||
of that actor class. It is used to set the coordinates of the bounding
|
<para>In this example, the <classname>FooActor</classname>
|
||||||
box for the actor. Container actors, or composite actors with internal
|
implementation of the paint() virtual function is drawing a rectangle
|
||||||
children, should override the request_coords() virtual function and call
|
with rounded corners with a custom color. The COGL API is used, to
|
||||||
clutter_actor_request_coords() on each visible child. Every actor class
|
allow portability between GL and GLES platforms.</para>
|
||||||
overriding the request_coords() virtual function must chain up to the
|
<programlisting>
|
||||||
parent class request_coords() method.</para>
|
static void
|
||||||
|
foo_actor_paint (ClutterActor *actor)
|
||||||
|
{
|
||||||
|
FooActor *foo_actor = FOO_ACTOR (actor);
|
||||||
|
ClutterColor color = { 0, };
|
||||||
|
ClutterUnit w, h, r;
|
||||||
|
|
||||||
<para>The ClutterActor::paint() method should be overridden if the
|
cogl_push_matrix ();
|
||||||
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>
|
|
||||||
|
|
||||||
<para>When inside the ClutterActor::paint() method the actor is already
|
/* FooActor has a specific background color */
|
||||||
positioned at the coordinates specified by its bounding box; all the
|
color.red = foo_actor->bg_color.red;
|
||||||
paint operations should then take place from the (0, 0) coordinates.</para>
|
color.green = foo_actor->bg_color.green;
|
||||||
|
color.blue = foo_actor->bg_color.blue;
|
||||||
|
|
||||||
<example id="clutter-actor-paint-example">
|
/* the alpha component must take into account the absolute
|
||||||
<programlisting>
|
* opacity of the actor on the screen at this point in the
|
||||||
|
* scenegraph; this value is obtained by calling
|
||||||
|
* clutter_actor_get_paint_opacity().
|
||||||
|
*/
|
||||||
|
color.alpha = clutter_actor_get_paint_opacity (actor);
|
||||||
|
|
||||||
|
/* set the color of the pen */
|
||||||
|
cogl_color (&color);
|
||||||
|
|
||||||
|
/* get the size of the actor with sub-pixel precision */
|
||||||
|
w = CLUTTER_UNITS_TO_FIXED (clutter_actor_get_widthu (actor));
|
||||||
|
h = CLUTTER_UNITS_TO_FIXED (clutter_actor_get_heightu (actor));
|
||||||
|
|
||||||
|
/* this is the arc radius for the rounded rectangle corners */
|
||||||
|
r = CLUTTER_UNITS_TO_FIXED (foo_actor->radius);
|
||||||
|
|
||||||
|
/* 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_round_rectangle (0, 0, w, h, r, 5);
|
||||||
|
|
||||||
|
/* and fill it with the current color */
|
||||||
|
cogl_fill ();
|
||||||
|
|
||||||
|
cogl_pop_matrix ();
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<note><para>When inside the <classname>ClutterActor</classname>::paint()
|
||||||
|
method 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. To
|
||||||
|
allow transformations on itself to affect the children, the GL modelview
|
||||||
|
matrix is pushed at the beginning of the paint sequence, and the popped
|
||||||
|
at the end.</para>
|
||||||
|
<programlisting>
|
||||||
static void
|
static void
|
||||||
foo_actor_paint (ClutterActor *actor)
|
foo_actor_paint (ClutterActor *actor)
|
||||||
{
|
{
|
||||||
FooActor *foo_actor = FOO_ACTOR (actor);
|
FooActor *foo_actor = FOO_ACTOR (actor);
|
||||||
GList *child;
|
GList *child;
|
||||||
|
|
||||||
/* by including <clutter/cogl.h> it's possible to use the internal
|
|
||||||
* COGL abstraction API, which is also used by Clutter itself and avoids
|
|
||||||
* changing the GL calls depending on the target platform (GL or GL/ES).
|
|
||||||
*/
|
|
||||||
cogl_push_matrix ();
|
cogl_push_matrix ();
|
||||||
|
|
||||||
for (child = foo_actor->children; child != NULL; child = child->next)
|
for (child = foo_actor->children;
|
||||||
|
child != NULL;
|
||||||
|
child = child->next)
|
||||||
{
|
{
|
||||||
ClutterActor *child_actor = child->data;
|
ClutterActor *child_actor = child->data;
|
||||||
|
|
||||||
if (CLUTTER_ACTOR_IS_MAPPED (child_actor))
|
/* paint only visible children */
|
||||||
|
if (CLUTTER_ACTOR_IS_VISIBLE (child_actor))
|
||||||
clutter_actor_paint (child_actor);
|
clutter_actor_paint (child_actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
cogl_pop_matrix ();
|
cogl_pop_matrix ();
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
<para>When painting a blended actor, cogl_enable() should be called with
|
<note><para>A container imposing a layout on its children may
|
||||||
the %CGL_BLEND flag; or, alternatively, glEnable() with %GL_BLEND on
|
opt to use the paint area as returned by clutter_actor_get_paint_area()
|
||||||
OpenGL.</para>
|
instead of the allocation.</para></note>
|
||||||
|
|
||||||
<para>If the actor has a non-rectangular shape, or it has internal childrens
|
<para>If the actor has a non-rectangular shape, or it has internal
|
||||||
that needs to be distinguished by the events delivery mechanism, the
|
children that need to be distinguished by the events delivery mechanism,
|
||||||
ClutterActor::pick() method should also be overridden. The ::pick() method
|
the <classname>ClutterActor</classname>::pick() method should also be
|
||||||
works exactly like the ::paint() method, but the actor should paint just
|
overridden. The pick() method works exactly like the paint() method, but
|
||||||
its shape with the passed colour:</para>
|
the actor should paint just its shape with the passed colour:</para>
|
||||||
|
|
||||||
<example id="clutter-actor-pick-example">
|
<example id="simple-actor-pick-example">
|
||||||
<programlisting>
|
<title>Pick implementation of a simple actor</title>
|
||||||
|
<para>In this example, <classname>FooActor</classname> overrides the
|
||||||
|
pick() 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 paint area.</para>
|
||||||
|
<programlisting>
|
||||||
static void
|
static void
|
||||||
foo_actor_pick (ClutterActor *actor,
|
foo_actor_pick (ClutterActor *actor,
|
||||||
const ClutterColor *pick_color)
|
const ClutterColor *pick_color)
|
||||||
{
|
{
|
||||||
FooActor *foo_actor = FOO_ACTOR (actor);
|
FooActor *foo_actor = FOO_ACTOR (actor);
|
||||||
guint width, height;
|
ClutterUnit w, h, r;
|
||||||
|
|
||||||
/* it is possible to avoid a costly paint by checking whether the
|
/* it is possible to avoid a costly paint by checking whether the
|
||||||
* actor should really be painted in pick mode
|
* actor should really be painted in pick mode
|
||||||
@ -150,32 +539,56 @@ foo_actor_pick (ClutterActor *actor,
|
|||||||
if (!clutter_actor_should_pick_paint (actor))
|
if (!clutter_actor_should_pick_paint (actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* by including <clutter/cogl.h> it's possible to use the internal
|
w = CLUTTER_UNITS_TO_FIXED (clutter_actor_get_widthu (actor));
|
||||||
* COGL abstraction API, which is also used by Clutter itself and avoids
|
h = CLUTTER_UNITS_TO_FIXED (clutter_actor_get_heightu (actor));
|
||||||
* changing the GL calls depending on the target platform (GL or GL/ES).
|
|
||||||
*/
|
/* this is the arc radius for the rounded rectangle corners */
|
||||||
|
r = CLUTTER_UNITS_TO_FIXED (foo_actor->radius);
|
||||||
|
|
||||||
|
/* use the passed color to paint ourselves */
|
||||||
cogl_color (pick_color);
|
cogl_color (pick_color);
|
||||||
|
|
||||||
clutter_actor_get_size (actor, &width, &height);
|
/* paint a round rectangle */
|
||||||
|
cogl_round_rectangle (0, 0, w, h, r, 5);
|
||||||
|
|
||||||
/* it is also possible to use raw GL calls, at the cost of losing
|
/* and fill it with the current color */
|
||||||
* portability
|
cogl_fill ();
|
||||||
*/
|
|
||||||
glEnable (GL_BLEND);
|
|
||||||
|
|
||||||
/* draw a triangular shape */
|
|
||||||
glBegin (GL_POLYGON);
|
|
||||||
glVertex2i (width / 2, 0 );
|
|
||||||
glVertex2i (width , height);
|
|
||||||
glVertex2i (0 , height);
|
|
||||||
glEnd ();
|
|
||||||
|
|
||||||
cogl_pop_matrix ();
|
cogl_pop_matrix ();
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
<section id="implementing-clutter-container">
|
<para>Containers should simply chain up to the parent class'
|
||||||
|
pick() 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
|
||||||
|
*/
|
||||||
|
if (CLUTTER_ACTOR_IS_VISIBLE (foo_actor->child))
|
||||||
|
clutter_actor_paint (foo_actor->child);
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
</refsect1> <!-- actor-painting-and-picking -->
|
||||||
|
|
||||||
|
<refsect1 id="implementing-clutter-container">
|
||||||
<title>Implementing Containers</title>
|
<title>Implementing Containers</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -192,6 +605,13 @@ foo_actor_pick (ClutterActor *actor,
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<example id="clutter-actor-set-parent-example">
|
<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>
|
<programlisting>
|
||||||
void
|
void
|
||||||
foo_actor_add_baz (FooActor *foo_actor,
|
foo_actor_add_baz (FooActor *foo_actor,
|
||||||
@ -208,14 +628,20 @@ foo_actor_add_baz (FooActor *foo_actor,
|
|||||||
|
|
||||||
foo_actor->baz = baz_actor;
|
foo_actor->baz = baz_actor;
|
||||||
|
|
||||||
/* this will cause the initial floating reference to disappear,
|
/* this will cause the initial floating reference of ClutterActor to
|
||||||
* and add a new reference on baz_actor. foo_actor has now taken
|
* disappear, and add a new reference on baz_actor. foo_actor has now
|
||||||
* ownership of baz_actor
|
* 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_set_parent (CLUTTER_ACTOR (baz_actor),
|
||||||
CLUTTER_ACTOR (foo_actor));
|
CLUTTER_ACTOR (foo_actor));
|
||||||
|
|
||||||
|
/* emit a signal and notification */
|
||||||
g_signal_emit (foo_actor, foo_actor_signals[BAZ_CHANGED], 0, baz_actor);
|
g_signal_emit (foo_actor, foo_actor_signals[BAZ_CHANGED], 0, baz_actor);
|
||||||
|
g_object_notify (G_OBJECT (foo_actor), "baz");
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
@ -228,43 +654,56 @@ foo_actor_add_baz (FooActor *foo_actor,
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>ClutterContainer::add</term>
|
<term>ClutterContainer::add</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para></para>
|
<para>The container actor should hold a pointer to the passed
|
||||||
|
#ClutterActor, call clutter_actor_set_parent() on it and then
|
||||||
|
emit the #ClutterContainer::actor-added signal to notify
|
||||||
|
handlers of the newly added actor.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>ClutterContainer::remove</term>
|
<term>ClutterContainer::remove</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para></para>
|
<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>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>ClutterContainer::foreach</term>
|
<term>ClutterContainer::foreach</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para></para>
|
<para>The container should invoke the callback on every
|
||||||
|
child it is holding.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>ClutterContainer::raise</term>
|
<term>ClutterContainer::raise</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para></para>
|
<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.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>ClutterContainer::lower</term>
|
<term>ClutterContainer::lower</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para></para>
|
<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.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>ClutterContainer::sort_depth_order</term>
|
<term>ClutterContainer::sort_depth_order</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para></para>
|
<para>The container should sort the paint stack depending
|
||||||
|
on the relative depths of each child.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</section>
|
</refsect1> <!-- implementing-clutter-container -->
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
Loading…
Reference in New Issue
Block a user