Clutter Learning (14th): review with a large example

Source: Internet
Author: User


We have learned the basic usage of clutter, with a large example to review, example Source: http://www.openismus.com/documents/clutter_tutorial/0.9/docs/tutorial/html/sec-full-example.html

. This tutorial is based on clutter0.9 and requires minor changes on clutter1.0. The following is an example of rewriting in clutter1.0:

# Include <clutter/clutter. h>

# Include <stdlib. h>

Const gint maid = 390;

Const gint ELLIPSE_HEIGHT = 450;

Const gint IMAGE_HEIGHT = 100;

Double angle_step = 30;

ClutterTimeline * timeline_rotation = NULL, * timeline_moveup = NULL;

ClutterActor * label_filename = NULL;

ClutterBehaviour * behaviour_scale = NULL, * behaviour_path = NULL,

* Behaviour_opacity = NULL;

Typedef struct Item {

ClutterActor * actor;

ClutterBehaviour * ellipse_behaviour;

Gchar * filepath;

} Item;

Item * item_at_front = NULL;

GSList * list_items = 0;

Void rotate_all_until_item_is_at_front (Item * item );

Gdouble angle_in_360 (gdouble angle ){

Gdouble result = angle;

While (result >=360)

Result-= 360;

Return result;

}

Void on_foreach_clear_list_items (gpointer data, gpointer user_data)

{

If (data = NULL)

Return;

Item * item = (Item *) data;

/* We don't need to unref the actor because the floating reference was taken by the stage .*/

G_object_unref (item-> ellipse_behaviour );

G_free (item-> filepath );

G_free (item );

}

Void scale_texture_default (ClutterActor * texture ){

Int pixbuf_height = 0;

Clutter_texture_get_base_size (clutter_texture (texture), null,

& Pixbuf_height );

Const gdouble scale = pixbuf_height? Image_height/(gdouble) pixbuf_height: 0;

Clutter_actor_set_scale (texture, scale, scale );

}

Void load_images (const gchar * directory_path ){

G_return_if_fail (directory_path );

/* Clear any existing images :*/

G_slist_foreach (list_items, on_foreach_clear_list_items, null );

G_slist_free (list_items );

/* Create a new list :*/

List_items = NULL;

Gerror * error = NULL;

Gdir * dir = g_dir_open (directory_path, 0, & error );

If (error ){

G_warning ("g_dir_open () failed: % s/n", error-> message );

G_clear_error (& error );

Return;

}

Int I = 0;

Const gchar * filename = NULL;

While (filename = g_dir_read_name (dir ))! = NULL ){

Gchar * path = g_build_filename (directory_path, filename, NULL );

Printf ("% 2d % s/n", ++ I, path );

ClutterActor * actor = clutter_texture_new_from_file (path, NULL );

If (actor ){

Item * item = g_new0 (Item, 1 );

Item-> actor = actor;

Item-> filepath = g_strdup (path );

Scale_texture_default (item-> actor );

List_items = g_slist_append (list_items, item );

}

G_free (path );

}

Angle_step = 360.0/I;

Printf ("total % d image, angel step is %. 1f/n", I, angle_step );

}

Gboolean on_texture_button_press (ClutterActor * actor, ClutterEvent * event,

Gpointer user_data ){

If (timeline_rotation & clutter_timeline_is_playing (timeline_rotation )){

Printf ("on_texture_button_press (): ignoring/n ");

Return FALSE;

} Else {

Printf ("on_texture_button_press (): handling/n ");

}

Item * item = (Item *) user_data;

Rotate_all_until_item_is_at_front (item );

Return TRUE;

}

Void add_to_ellipse_behaviour (ClutterTimeline * timeline_rotation, gdouble start_angle, Item * item ){

G_return_if_fail (timeline_rotation );

Clutteralpha * alpha = clutter_alpha_new_full (timeline_rotation,

Clutter_ease_out_sine );

/* If start is equal to end, the behaviour will rotate by exacly 360 degrees .*/

Item-> ellipse_behaviour = clutter_behaviour_ellipse_new (alpha, 320, ellipse_y,/* x, y */

Ellipse_height, ellipse_height/* width, height */

, Clutter_rotate_cw,

Start_angle, start_angle );

Clutter_behaviour_ellipse_set_angle_tilt (clutter_behaviour_ellipse (item-> ellipse_behaviour ),

Clutter_x_axis,-90.0 );

Clutter_behaviour_apply (item-> ellipse_behaviour, item-> actor );

}

Void add_image_actors (ClutterActor * stage ){

Int x = 20;

Int y = 0;

Gdouble angle = 0;

GSList * list = list_items;

While (list ){

Item * item = (Item *) list-> data;

ClutterActor * actor = item-> actor;

Clutter_actor_set_position (actor, x, y );

Y + = 100;

Clutter_container_add_actor (clutter_container (stage), actor );

/* Allow the actor to emit events. By default only the stage does this .*/

Clutter_actor_set_reactive (actor, true );

G_signal_connect (actor, "button-press-Event ",

G_CALLBACK (on_texture_button_press), item );

While (angle >=360)

Angle-= 360;

Add_to_ellipse_behaviour (timeline_rotation, angle, item );

Angle + = angle_step;

List = g_slist_next (list );

}

}

Void on_timeline_moveup_completed (cluttertimeline * timeline, gpointer user_data)

{

/* Unref this timeline because we have now finished with it :*/

G_object_unref (timeline_moveup );

Timeline_moveup = NULL;

G_object_unref (behaviour_scale );

Behaviour_scale = NULL;

G_object_unref (behaviour_path );

Behaviour_path = NULL;

G_object_unref (behaviour_opacity );

Behaviour_opacity = NULL;

}

Void on_timeline_rotation_completed (ClutterTimeline * timeline, gpointer user_data ){

ClutterActor * actor = item_at_front-> actor;

Timeline_moveup = clutter_timeline_new (1200/* milliseconds */);

/* For Scaling */

ClutterAlpha * alpha = clutter_alpha_new_full (timeline_moveup, CLUTTER_EASE_OUT_SINE );

Gdouble scale_start = 0;

Clutter_actor_get_scale (actor, & scale_start, NULL );

Const gdouble scale_end = scale_start * 1.80;

Behaviour_scale = clutter_behaviour_scale_new (alpha, scale_start, scale_start, scale_end, scale_end );

Clutter_behaviour_apply (behaviour_scale, actor );

/* Move the item up the y axis :*/

ClutterKnot knots [2];

Knots [0]. x = clutter_actor_get_x (actor );

Knots [0]. y = clutter_actor_get_y (actor );

Knots [1]. x = knots [0]. x-80;

Knots [1]. y = knots [0]. y-255;

Printf ("move from (% d, % d) to (% d, % d)/n", knots [0]. x, knots [0]. y, knots [1]. x, knots [1]. y );

Behaviour_path = clutter_behaviour_path_new_with_knots (alpha, knots, G_N_ELEMENTS (knots ));

Clutter_behaviour_apply (behaviour_path, actor );

/* Show the file name */

Clutter_text_set_text (CLUTTER_TEXT (label_filename), item_at_front-> filepath );

Behaviour_opacity = clutter_behaviour_opacity_new (alpha, 0,255 );

Clutter_behaviour_apply (behaviour_opacity, label_filename );

/* After it complete unref the param */

G_signal_connect (timeline_moveup, "completed", G_CALLBACK (on_timeline_moveup_completed), NULL );

Clutter_timeline_start (timeline_moveup );

}

Void rotate_all_until_item_is_at_front (Item * item ){

G_return_if_fail (item );

Clutter_timeline_stop (timeline_rotation );

If (timeline_moveup! = NULL)

Clutter_timeline_stop (timeline_moveup );

Clutter_actor_set_opacity (label_filename, 0 );
/* Get the item's position in the list :*/

Const gint pos = g_slist_index (list_items, item );

Printf ("We want to show pos = % d/n", pos );

G_assert (pos! =-1 );

If (! Item_at_front & list_items)

Item_at_front = (Item *) list_items-> data;

Gint pos_front = 0;

If (item_at_front)

Pos_front = g_slist_index (list_items, item_at_front );

Printf ("Current front pos is % d/n", pos_front );

G_assert (pos_front! =-1 );
/* Calculate the end angle of the first item :*/

Const gdouble angle_front = 90;

Gdouble angle_start = angle_front-(angle_step * pos_front );

Angle_start = angle_in_360 (angle_start );

Gdouble angle_end = angle_front-(angle_step * pos );

Printf ("angle (%. 0f %. 0f)/n", angle_start, angle_end );

Gdouble angle_diff = 0;

GSList * list = list_items;

Gint I = 0;

While (list ){

Item * this_item = (item *) List-> data;
/* Reset its size :*/

Scale_texture_default (this_item-> actor );

Angle_start = angle_in_360 (angle_start );

Angle_end = angle_in_360 (angle_end );

If (item_at_front = item)

Angle_end plus = 360;

Angle_end = angle_in_360 (angle_end );

Clutter_behaviour_ellipse_set_angle_start (

CLUTTER_BEHAVIOUR_ELLIPSE (this_item-> ellipse_behaviour), angle_start );

Clutter_behaviour_ellipse_set_angle_end (

CLUTTER_BEHAVIOUR_ELLIPSE (this_item-> ellipse_behaviour), angle_end );

If (this_item = item ){

If (angle_start <angle_end)

Angle_diff = angle_end-angle_start;

Else

Angle_diff = 360-(angle_start-angle_end );

Printf ("debug: angle diff = % f/n", angle_diff );

}

// Printf ("% 2d angle %. 0f, %. 0f/n", ++ I, angle_start, angle_end );

Angle_end + = angle_step;

Angle_start + = angle_step;

List = g_slist_next (list );

}

Const Gint COUNT = g_slist_length (list_items );

Gint pos_to_move = count + pos_front-Pos;

If (pos_to_move> count)

Pos_to_move-= count;

Int duration = (INT) (5000.0/count * pos_to_move );

Printf ("old is % d want % d POs to move = % d duration = % d/N", pos_front, POs, pos_to_move, duration );

Clutter_timeline_set_duration (timeline_rotation, duration );

Item_at_front = item;

Clutter_timeline_start (timeline_rotation );

}

Int main (int argc, char * argv []) {

Clutter_init (& argc, & argv );

ClutterColor stage_color = {0xB0, 0xB0, 0xB0, 0xff };

ClutterActor * stage = clutter_stage_get_default ();

Clutter_actor_set_size (stage, 800,600 );

Clutter_stage_set_color (CLUTTER_STAGE (stage), & stage_color );

/* Create and add a label actor, hidden at first :*/

Label_filename = clutter_text_new ();

ClutterColor label_color = {0x00,0x00,0x00, 0xff };

Clutter_text_set_color (CLUTTER_TEXT (label_filename), & label_color );

Clutter_text_set_font_name (CLUTTER_TEXT (label_filename), "18 18 ");

Clutter_actor_set_position (label_filename, 10, 10 );

Clutter_actor_set_opacity (label_filename, 0 );

Clutter_container_add_actor (CLUTTER_CONTAINER (stage), label_filename );

/* Add a plane under the ellipse of images :*/

ClutterColor rect_color = {0xff, 0xff, 0xdf, 0xff};/* white */

ClutterActor * rect = clutter_rectangle_new_with_color (& rect_color );

Clutter_actor_set_height (rect, ELLIPSE_HEIGHT + 20 );

Clutter_actor_set_width (rect, clutter_actor_get_width (stages) + 100 );

Clutter_actor_set_position (rect,-(clutter_actor_get_width (rect)-clutter_actor_get_width (stage)/2,

ELLIPSE_Y + IMAGE_HEIGHT-(clutter_actor_get_height (rect)/2 ));

Clutter_actor_set_rotation (rect, CLUTTER_X_AXIS, 90.0, 0.0, (clutter_actor_get_height (rect)/2.0), 0.0 );

Clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect );

Timeline_rotation = clutter_timeline_new (5000 );

G_signal_connect (timeline_rotation, "completed", G_CALLBACK (on_timeline_rotation_completed), NULL );

/* Add an actor for each image :*/

Load_images ("./images /");

Add_image_actors (stage );

If (list_items)

Rotate_all_until_item_is_at_front (Item *) list_items-> data );

Clutter_actor_show_all (stage );

Clutter_main ();

G_object_unref (timeline_rotation );

Return exit_success;

}

Link: My Clutter blog

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.