test-scrolling: Animate intermediate positions
authorEmmanuele Bassi <ebassi@linux.intel.com>
Thu, 27 May 2010 11:32:45 +0000 (12:32 +0100)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Thu, 27 May 2010 11:32:45 +0000 (12:32 +0100)
Animating intermediate positions in the viewport panning is a neat
effect.

tests/interactive/test-scrolling.c

index 6d646ca..e5923c5 100644 (file)
@@ -1,9 +1,10 @@
 #include <stdlib.h>
+#include <math.h>
 #include <gmodule.h>
 #include <clutter/clutter.h>
 
-#define RECT_WIDTH      300
-#define RECT_HEIGHT     200
+#define RECT_WIDTH      400
+#define RECT_HEIGHT     300
 #define N_RECTS         7
 
 static const gchar *rect_color[N_RECTS] = {
@@ -28,7 +29,10 @@ on_drag_end (ClutterDragAction   *action,
              ClutterModifierType  modifiers)
 {
   gfloat viewport_x = clutter_actor_get_x (viewport);
+  gfloat offset_x;
+  gint child_visible;
 
+  /* check if we're at the viewport edges */
   if (viewport_x > 0)
     {
       clutter_actor_animate (viewport, CLUTTER_EASE_OUT_QUAD, 250,
@@ -44,6 +48,22 @@ on_drag_end (ClutterDragAction   *action,
                              NULL);
       return;
     }
+
+  /* animate the viewport to fully show the child once we pass
+   * a certain threshold with the dragging action
+   */
+  offset_x = fabsf (viewport_x) / RECT_WIDTH + 0.5f;
+  if (offset_x > (RECT_WIDTH * 0.33))
+    child_visible = (int) offset_x + 1;
+  else
+    child_visible = (int) offset_x;
+
+  /* sanity check on the children number */
+  child_visible = CLAMP (child_visible, 0, N_RECTS);
+
+  clutter_actor_animate (viewport, CLUTTER_EASE_OUT_QUAD, 250,
+                         "x", (-1.0f * RECT_WIDTH * child_visible),
+                         NULL);
 }
 
 G_MODULE_EXPORT int
@@ -66,11 +86,11 @@ test_scrolling_main (int argc, char *argv[])
    * the stage and set it to clip its contents to the allocated size
    */
   scroll = clutter_group_new ();
+  clutter_container_add_actor (CLUTTER_CONTAINER (stage), scroll);
   clutter_actor_set_size (scroll, RECT_WIDTH, RECT_HEIGHT);
   clutter_actor_add_constraint (scroll, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5));
   clutter_actor_add_constraint (scroll, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5));
   clutter_actor_set_clip_to_allocation (scroll, TRUE);
-  clutter_container_add_actor (CLUTTER_CONTAINER (stage), scroll);
 
   /* viewport: the actual container for the children; we scroll it using
    * the Drag action constrained to the horizontal axis, and every time
@@ -80,11 +100,15 @@ test_scrolling_main (int argc, char *argv[])
   viewport = clutter_box_new (clutter_box_layout_new ());
   clutter_container_add_actor (CLUTTER_CONTAINER (scroll), viewport);
 
+  /* add dragging capabilities to the viewport; the heavy lifting is
+   * all done by the DragAction itself, plus the ::drag-end signal
+   * handler in our code
+   */
   action = clutter_drag_action_new ();
+  clutter_actor_add_action (viewport, action);
   clutter_drag_action_set_drag_axis (CLUTTER_DRAG_ACTION (action),
                                      CLUTTER_DRAG_X_AXIS);
   g_signal_connect (action, "drag-end", G_CALLBACK (on_drag_end), NULL);
-  clutter_actor_add_action (viewport, action);
   clutter_actor_set_reactive (viewport, TRUE);
 
   /* children of the viewport */