update to 1.10.4
[profile/ivi/clutter.git] / tests / interactive / test-bin-layout.c
1 #include <stdlib.h>
2 #include <gmodule.h>
3 #include <cairo.h>
4 #include <clutter/clutter.h>
5
6 static const ClutterColor bg_color = { 0xcc, 0xcc, 0xcc, 0x99 };
7
8 static gboolean is_expanded = FALSE;
9
10 static gboolean
11 draw_background (ClutterCairoTexture *texture,
12                  cairo_t             *cr)
13 {
14   cairo_pattern_t *pat;
15   gfloat x, y;
16   guint width, height;
17
18   clutter_cairo_texture_get_surface_size (texture, &width, &height);
19
20 #define BG_ROUND_RADIUS         12
21
22   x = y = 0;
23
24   cairo_move_to (cr, BG_ROUND_RADIUS, y);
25   cairo_line_to (cr, width - BG_ROUND_RADIUS, y);
26   cairo_curve_to (cr, width, y, width, y, width, BG_ROUND_RADIUS);
27   cairo_line_to (cr, width, height - BG_ROUND_RADIUS);
28   cairo_curve_to (cr, width, height, width, height, width - BG_ROUND_RADIUS, height);
29   cairo_line_to (cr, BG_ROUND_RADIUS, height);
30   cairo_curve_to (cr, x, height, x, height, x, height - BG_ROUND_RADIUS);
31   cairo_line_to (cr, x, BG_ROUND_RADIUS);
32   cairo_curve_to (cr, x, y, x, y, BG_ROUND_RADIUS, y);
33
34   cairo_close_path (cr);
35
36   clutter_cairo_set_source_color (cr, &bg_color);
37   cairo_stroke (cr);
38
39   x += 4;
40   y += 4;
41   width -= 4;
42   height -= 4;
43
44   cairo_move_to (cr, BG_ROUND_RADIUS, y);
45   cairo_line_to (cr, width - BG_ROUND_RADIUS, y);
46   cairo_curve_to (cr, width, y, width, y, width, BG_ROUND_RADIUS);
47   cairo_line_to (cr, width, height - BG_ROUND_RADIUS);
48   cairo_curve_to (cr, width, height, width, height, width - BG_ROUND_RADIUS, height);
49   cairo_line_to (cr, BG_ROUND_RADIUS, height);
50   cairo_curve_to (cr, x, height, x, height, x, height - BG_ROUND_RADIUS);
51   cairo_line_to (cr, x, BG_ROUND_RADIUS);
52   cairo_curve_to (cr, x, y, x, y, BG_ROUND_RADIUS, y);
53
54   cairo_close_path (cr);
55
56   pat = cairo_pattern_create_linear (0, 0, 0, height);
57   cairo_pattern_add_color_stop_rgba (pat, 1, .85, .85, .85, 1);
58   cairo_pattern_add_color_stop_rgba (pat, .95, 1, 1, 1, 1);
59   cairo_pattern_add_color_stop_rgba (pat, .05, 1, 1, 1, 1);
60   cairo_pattern_add_color_stop_rgba (pat, 0, .85, .85, .85, 1);
61
62   cairo_set_source (cr, pat);
63   cairo_fill (cr);
64
65   cairo_pattern_destroy (pat);
66
67 #undef BG_ROUND_RADIUS
68
69   return TRUE;
70 }
71
72 static gboolean
73 on_box_enter (ClutterActor *box,
74               ClutterEvent *event,
75               ClutterActor *emblem)
76 {
77   clutter_actor_save_easing_state (emblem);
78   clutter_actor_set_easing_duration (emblem, 150);
79   clutter_actor_set_easing_mode (emblem, CLUTTER_LINEAR);
80   clutter_actor_set_opacity (emblem, 255);
81   clutter_actor_restore_easing_state (emblem);
82
83   return CLUTTER_EVENT_STOP;
84 }
85
86 static gboolean
87 on_box_leave (ClutterActor *box,
88               ClutterEvent *event,
89               ClutterActor *emblem)
90 {
91   clutter_actor_save_easing_state (emblem);
92   clutter_actor_set_easing_duration (emblem, 150);
93   clutter_actor_set_easing_mode (emblem, CLUTTER_LINEAR);
94   clutter_actor_set_opacity (emblem, 0);
95   clutter_actor_restore_easing_state (emblem);
96
97   return CLUTTER_EVENT_STOP;
98 }
99
100 static void
101 on_rect_clicked (ClutterClickAction *action,
102                  ClutterActor       *rect,
103                  ClutterActor       *box)
104 {
105   clutter_actor_save_easing_state (box);
106   clutter_actor_set_easing_mode (box, CLUTTER_EASE_OUT_BOUNCE);
107   clutter_actor_set_easing_duration (box, 500);
108
109   if (!is_expanded)
110     clutter_actor_set_size (box, 400, 400);
111   else
112     clutter_actor_set_size (box, 200, 200);
113
114   clutter_actor_restore_easing_state (box);
115
116   is_expanded = !is_expanded;
117 }
118
119 static gboolean
120 on_rect_long_press (ClutterClickAction    *action,
121                     ClutterActor          *rect,
122                     ClutterLongPressState  state,
123                     ClutterActor          *box)
124 {
125   switch (state)
126     {
127     case CLUTTER_LONG_PRESS_QUERY:
128       g_print ("*** long press: query ***\n");
129       return is_expanded;
130
131     case CLUTTER_LONG_PRESS_CANCEL:
132       g_print ("*** long press: cancel ***\n");
133       break;
134
135     case CLUTTER_LONG_PRESS_ACTIVATE:
136       g_print ("*** long press: activate ***\n");
137       break;
138     }
139
140   return TRUE;
141 }
142
143 static void
144 on_box_allocation_changed (ClutterActor           *box,
145                            const ClutterActorBox  *allocation,
146                            ClutterAllocationFlags  flags,
147                            ClutterActor           *background)
148 {
149   gfloat new_width, new_height;
150
151   clutter_actor_box_get_size (allocation, &new_width, &new_height);
152   clutter_cairo_texture_set_surface_size (CLUTTER_CAIRO_TEXTURE (background),
153                                           new_width,
154                                           new_height);
155   clutter_cairo_texture_invalidate (CLUTTER_CAIRO_TEXTURE (background));
156 }
157
158 G_MODULE_EXPORT int
159 test_bin_layout_main (int argc, char *argv[])
160 {
161   ClutterActor *stage, *box, *rect;
162   ClutterLayoutManager *layout;
163   ClutterColor stage_color = { 0xe0, 0xf2, 0xfc, 0xff };
164   ClutterColor *color;
165   ClutterAction *action;
166
167   if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
168     return 1;
169
170   stage = clutter_stage_new ();
171   clutter_stage_set_title (CLUTTER_STAGE (stage), "BinLayout");
172   clutter_actor_set_background_color (stage, &stage_color);
173   clutter_actor_set_size (stage, 640, 480);
174   g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
175
176   layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
177                                    CLUTTER_BIN_ALIGNMENT_CENTER);
178
179   box = clutter_box_new (layout);
180   clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
181   clutter_actor_set_anchor_point_from_gravity (box, CLUTTER_GRAVITY_CENTER);
182   clutter_actor_set_position (box, 320, 240);
183   clutter_actor_set_reactive (box, TRUE);
184   clutter_actor_set_name (box, "box");
185
186   /* the contents of the texture are created every time the allocation
187    * of the box changes, to keep the background's size the same as the
188    * box's size
189    */
190   rect = clutter_cairo_texture_new (100, 100);
191   g_signal_connect (rect, "draw", G_CALLBACK (draw_background), NULL);
192
193   /* first method: use clutter_box_pack() */
194   clutter_box_pack (CLUTTER_BOX (box), rect,
195                     "x-align", CLUTTER_BIN_ALIGNMENT_FILL,
196                     "y-align", CLUTTER_BIN_ALIGNMENT_FILL,
197                     NULL);
198
199   clutter_actor_lower_bottom (rect);
200   clutter_actor_set_name (rect, "background");
201   g_signal_connect (box, "allocation-changed",
202                     G_CALLBACK (on_box_allocation_changed),
203                     rect);
204
205   {
206     ClutterActor *tex;
207     GError *error;
208     gchar *file;
209
210     error = NULL;
211     file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL);
212     tex = clutter_texture_new_from_file (file, &error);
213     if (error)
214       g_error ("Unable to create texture: %s", error->message);
215
216     clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (tex), TRUE);
217
218     /* second method: use clutter_bin_layout_add() */
219     clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (layout), tex,
220                             CLUTTER_BIN_ALIGNMENT_CENTER,
221                             CLUTTER_BIN_ALIGNMENT_CENTER);
222
223     clutter_actor_raise (tex, rect);
224     clutter_actor_set_width (tex, 175);
225     clutter_actor_set_name (tex, "texture");
226
227     g_free (file);
228   }
229
230   color = clutter_color_new (g_random_int_range (0, 255),
231                              g_random_int_range (0, 255),
232                              g_random_int_range (0, 255),
233                              224);
234
235   rect = clutter_rectangle_new_with_color (color);
236
237   /* third method: container_add() and set_alignment() */
238   clutter_container_add_actor (CLUTTER_CONTAINER (box), rect);
239   clutter_bin_layout_set_alignment (CLUTTER_BIN_LAYOUT (layout), rect,
240                                     CLUTTER_BIN_ALIGNMENT_END,
241                                     CLUTTER_BIN_ALIGNMENT_END);
242
243   clutter_actor_set_size (rect, 50, 50);
244   clutter_actor_set_opacity (rect, 0);
245   clutter_actor_set_reactive (rect, TRUE);
246   clutter_actor_raise_top (rect);
247   clutter_actor_set_name (rect, "emblem");
248
249   action = clutter_click_action_new ();
250   clutter_actor_add_action (rect, action);
251   g_signal_connect (action, "clicked", G_CALLBACK (on_rect_clicked), box);
252   g_signal_connect (action, "long-press", G_CALLBACK (on_rect_long_press), box);
253   g_signal_connect (box,
254                     "enter-event", G_CALLBACK (on_box_enter),
255                     rect);
256   g_signal_connect (box,
257                     "leave-event", G_CALLBACK (on_box_leave),
258                     rect);
259
260   rect = clutter_text_new ();
261   clutter_text_set_text (CLUTTER_TEXT (rect), "A simple test");
262   clutter_container_add_actor (CLUTTER_CONTAINER (box), rect);
263   clutter_bin_layout_set_alignment (CLUTTER_BIN_LAYOUT (layout), rect,
264                                     CLUTTER_BIN_ALIGNMENT_CENTER,
265                                     CLUTTER_BIN_ALIGNMENT_START);
266   clutter_actor_raise_top (rect);
267   clutter_actor_set_name (rect, "text");
268
269   clutter_actor_show_all (stage);
270
271   clutter_main ();
272
273   clutter_color_free (color);
274
275   return EXIT_SUCCESS;
276 }
277
278 G_MODULE_EXPORT const char *
279 test_bin_layout_describe (void)
280 {
281   return "BinLayout layout manager example";
282 }