update to 1.10.4
[profile/ivi/clutter.git] / tests / interactive / test-transitions.c
1 #include <stdlib.h>
2 #include <gmodule.h>
3 #include <clutter/clutter.h>
4
5 /* all the easing modes provided by Clutter */
6 static const struct {
7   const gchar *name;
8   ClutterAnimationMode mode;
9 } easing_modes[] = {
10   { "linear", CLUTTER_LINEAR },
11   { "easeInQuad", CLUTTER_EASE_IN_QUAD },
12   { "easeOutQuad", CLUTTER_EASE_OUT_QUAD },
13   { "easeInOutQuad", CLUTTER_EASE_IN_OUT_QUAD },
14   { "easeInCubic", CLUTTER_EASE_IN_CUBIC },
15   { "easeOutCubic", CLUTTER_EASE_OUT_CUBIC },
16   { "easeInOutCubic", CLUTTER_EASE_IN_OUT_CUBIC },
17   { "easeInQuart", CLUTTER_EASE_IN_QUART },
18   { "easeOutQuart", CLUTTER_EASE_OUT_QUART },
19   { "easeInOutQuart", CLUTTER_EASE_IN_OUT_QUART },
20   { "easeInQuint", CLUTTER_EASE_IN_QUINT },
21   { "easeOutQuint", CLUTTER_EASE_OUT_QUINT },
22   { "easeInOutQuint", CLUTTER_EASE_IN_OUT_QUINT },
23   { "easeInSine", CLUTTER_EASE_IN_SINE },
24   { "easeOutSine", CLUTTER_EASE_OUT_SINE },
25   { "easeInOutSine", CLUTTER_EASE_IN_OUT_SINE },
26   { "easeInExpo", CLUTTER_EASE_IN_EXPO },
27   { "easeOutExpo", CLUTTER_EASE_OUT_EXPO },
28   { "easeInOutExpo", CLUTTER_EASE_IN_OUT_EXPO },
29   { "easeInCirc", CLUTTER_EASE_IN_CIRC },
30   { "easeOutCirc", CLUTTER_EASE_OUT_CIRC },
31   { "easeInOutCirc", CLUTTER_EASE_IN_OUT_CIRC },
32   { "easeInElastic", CLUTTER_EASE_IN_ELASTIC },
33   { "easeOutElastic", CLUTTER_EASE_OUT_ELASTIC },
34   { "easeInOutElastic", CLUTTER_EASE_IN_OUT_ELASTIC },
35   { "easeInBack", CLUTTER_EASE_IN_BACK },
36   { "easeOutBack", CLUTTER_EASE_OUT_BACK },
37   { "easeInOutBack", CLUTTER_EASE_IN_OUT_BACK },
38   { "easeInBounce", CLUTTER_EASE_IN_BOUNCE },
39   { "easeOutBounce", CLUTTER_EASE_OUT_BOUNCE },
40   { "easeInOutBounce", CLUTTER_EASE_IN_OUT_BOUNCE },
41 };
42
43 #define HELP_TEXT       "Easing mode: %s (%d of %d)\n" \
44                         "Left click to tween\n" \
45                         "Right click to change the easing mode"
46
47 static const gint n_easing_modes = G_N_ELEMENTS (easing_modes);
48 static gint current_mode = 0;
49
50 static gint duration = 1;
51
52 static ClutterActor *main_stage = NULL;
53 static ClutterActor *easing_mode_label = NULL;
54
55 static gboolean
56 on_button_press (ClutterActor       *actor,
57                  ClutterButtonEvent *event,
58                  ClutterActor       *rectangle)
59 {
60   if (event->button == CLUTTER_BUTTON_SECONDARY)
61     {
62       gchar *text;
63
64       /* cycle through the various easing modes */
65       current_mode = (current_mode + 1 < n_easing_modes)
66                    ? current_mode + 1
67                    : 0;
68
69       /* update the text of the label */
70       text = g_strdup_printf (HELP_TEXT,
71                               easing_modes[current_mode].name,
72                               current_mode + 1,
73                               n_easing_modes);
74
75       clutter_text_set_text (CLUTTER_TEXT (easing_mode_label), text);
76       g_free (text);
77     }
78   else if (event->button == CLUTTER_BUTTON_PRIMARY)
79     {
80       ClutterAnimationMode cur_mode;
81
82       cur_mode = easing_modes[current_mode].mode;
83
84       clutter_actor_save_easing_state (rectangle);
85
86       /* tween the actor using the current easing mode */
87       clutter_actor_set_easing_mode (rectangle, cur_mode);
88       clutter_actor_set_easing_duration (rectangle, duration * 1000);
89
90       clutter_actor_set_position (rectangle, event->x, event->y);
91
92       clutter_actor_restore_easing_state (rectangle);
93     }
94
95   return TRUE;
96 }
97
98 static gboolean
99 draw_bouncer (ClutterCairoTexture *texture,
100               cairo_t             *cr)
101 {
102   const ClutterColor *bouncer_color;
103   cairo_pattern_t *pattern;
104   guint width, height;
105   float radius;
106
107   clutter_cairo_texture_get_surface_size (texture, &width, &height);
108
109   radius = MAX (width, height);
110
111   clutter_cairo_texture_clear (texture);
112
113   cairo_arc (cr, radius / 2, radius / 2, radius / 2, 0.0, 2.0 * G_PI);
114
115   bouncer_color = CLUTTER_COLOR_DarkScarletRed;
116
117   pattern = cairo_pattern_create_radial (radius / 2, radius / 2, 0,
118                                          radius, radius, radius);
119   cairo_pattern_add_color_stop_rgba (pattern,
120                                      0,
121                                      bouncer_color->red / 255.0,
122                                      bouncer_color->green / 255.0,
123                                      bouncer_color->blue / 255.0,
124                                      bouncer_color->alpha / 255.0);
125   cairo_pattern_add_color_stop_rgba (pattern,
126                                      0.85,
127                                      bouncer_color->red / 255.0,
128                                      bouncer_color->green / 255.0,
129                                      bouncer_color->blue / 255.0,
130                                      0.25);
131
132   cairo_set_source (cr, pattern);
133   cairo_fill_preserve (cr);
134
135   cairo_pattern_destroy (pattern);
136
137   return TRUE;
138 }
139
140 static ClutterActor *
141 make_bouncer (gfloat width,
142               gfloat height)
143 {
144   ClutterActor *retval;
145
146   retval = clutter_cairo_texture_new (width, height);
147   g_signal_connect (retval, "draw", G_CALLBACK (draw_bouncer), NULL);
148
149   clutter_actor_set_name (retval, "bouncer");
150   clutter_actor_set_size (retval, width, height);
151   clutter_actor_set_anchor_point (retval, width / 2, height / 2);
152   clutter_actor_set_reactive (retval, TRUE);
153
154   /* make sure we draw the bouncer immediately */
155   clutter_cairo_texture_invalidate (CLUTTER_CAIRO_TEXTURE (retval));
156
157   return retval;
158 }
159
160 static GOptionEntry test_easing_entries[] = {
161   {
162     "duration", 'd',
163     0,
164     G_OPTION_ARG_INT, &duration,
165     "Duration of the animation",
166     "SECONDS"
167   },
168
169   { NULL }
170 };
171
172 G_MODULE_EXPORT int
173 test_transitions_main (int argc, char *argv[])
174 {
175   ClutterActor *stage, *rect, *label;
176   gchar *text;
177   gfloat stage_width, stage_height;
178   GError *error = NULL;
179
180   if (clutter_init_with_args (&argc, &argv,
181                               NULL,
182                               test_easing_entries,
183                               NULL,
184                               &error) != CLUTTER_INIT_SUCCESS)
185     return 1;
186
187   stage = clutter_stage_new ();
188   clutter_stage_set_title (CLUTTER_STAGE (stage), "Easing Modes");
189   clutter_actor_set_background_color (stage, CLUTTER_COLOR_LightSkyBlue);
190   g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
191   main_stage = stage;
192
193   clutter_actor_get_size (stage, &stage_width, &stage_height);
194
195   /* create the actor that we want to tween */
196   rect = make_bouncer (50, 50);
197   clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
198   clutter_actor_set_position (rect, stage_width / 2, stage_height / 2);
199
200   text = g_strdup_printf (HELP_TEXT,
201                           easing_modes[current_mode].name,
202                           current_mode + 1,
203                           n_easing_modes);
204
205   label = clutter_text_new ();
206   clutter_container_add_actor (CLUTTER_CONTAINER (stage), label);
207   clutter_text_set_text (CLUTTER_TEXT (label), text);
208   clutter_actor_add_constraint (label, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.95));
209   clutter_actor_add_constraint (label, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.95));
210   easing_mode_label = label;
211
212   g_free (text);
213
214   g_signal_connect (stage,
215                     "button-press-event", G_CALLBACK (on_button_press),
216                     rect);
217
218   clutter_actor_show (stage);
219
220   clutter_main ();
221
222   return EXIT_SUCCESS;
223 }
224
225 G_MODULE_EXPORT const char *
226 test_transitions_describe (void)
227 {
228   return "Visualize all easing modes provided by Clutter";
229 }