[libchamplain] Introduce the new Marker animation API



commit ea9dfb56c15ff44e4c9863667434fe1145ac96a2
Author: Pierre-Luc Beaudoin <pierre-luc pierlux com>
Date:   Mon Aug 3 21:23:50 2009 -0400

    Introduce the new Marker animation API
    
    With this API you can have the markers fall from the sky on the map
    and get drawn back.  It also introduces helper functions in
    ChamplainLayer to animation many markers at once.

 champlain/champlain-base-marker.c |  115 +++++++++++++++++++++++++++++++++++++
 champlain/champlain-base-marker.h |    7 ++
 champlain/champlain-layer.c       |   98 +++++++++++++++++++++++++++++++
 champlain/champlain-layer.h       |    6 ++
 demos/launcher-gtk.c              |    7 +-
 5 files changed, 230 insertions(+), 3 deletions(-)
---
diff --git a/champlain/champlain-base-marker.c b/champlain/champlain-base-marker.c
index a1dc670..7fa087a 100644
--- a/champlain/champlain-base-marker.c
+++ b/champlain/champlain-base-marker.c
@@ -281,3 +281,118 @@ champlain_base_marker_get_highlighted (ChamplainBaseMarker *champlainBaseMarker)
 
   return priv->highlighted;
 }
+
+/**
+ * champlain_base_marker_animate_in:
+ * @marker: The marker
+ *
+ * Animates the marker as if it were falling from the sky onto the map.
+ *
+ * Since: 0.4
+ */
+void
+champlain_base_marker_animate_in (ChamplainBaseMarker *marker)
+{
+  champlain_base_marker_animate_in_with_delay (marker, 0);
+}
+
+/**
+ * champlain_base_marker_animate_in_with_delay :
+ * @marker: The marker
+ * @delay: The delay in milliseconds
+ *
+ * Animates the marker as if it were falling from the sky onto the map after
+ * delay.
+ *
+ * Since: 0.4
+ */
+void
+champlain_base_marker_animate_in_with_delay (ChamplainBaseMarker *marker,
+    guint delay)
+{
+  ClutterAnimation *animation;
+  ClutterTimeline *timeline;
+  gfloat y;
+
+  g_return_if_fail (CHAMPLAIN_IS_BASE_MARKER (marker));
+
+  clutter_actor_show (CLUTTER_ACTOR (marker));
+  clutter_actor_set_opacity (CLUTTER_ACTOR (marker), 0);
+  clutter_actor_set_scale (CLUTTER_ACTOR (marker), 1.5, 1.5);
+  clutter_actor_get_position (CLUTTER_ACTOR (marker), NULL, &y);
+  clutter_actor_move_by (CLUTTER_ACTOR (marker), 0, -100);
+
+  timeline = clutter_timeline_new (1000);
+  clutter_timeline_set_delay (timeline, delay);
+  animation = clutter_actor_animate_with_timeline (CLUTTER_ACTOR (marker),
+      CLUTTER_EASE_OUT_BOUNCE, timeline, "opacity", 255, "y", y,
+      "scale-x", 1.0, "scale-y", 1.0, NULL);
+  timeline = clutter_animation_get_timeline (animation);
+}
+
+/**
+ * champlain_base_marker_animate_out:
+ * @marker: The marker
+ *
+ * Animates the marker as if it were drawn through the sky.
+ *
+ * Since: 0.4
+ */
+void
+champlain_base_marker_animate_out (ChamplainBaseMarker *marker)
+{
+  champlain_base_marker_animate_in_with_delay (marker, 0);
+}
+
+static gboolean
+on_idle (ChamplainBaseMarker* marker)
+{
+  /* Notify the view that the position changed so that the marker's
+   * position is reset, it has to happen on idle as Clutter seems to
+   * set actors position after calling animation_completed */
+  clutter_actor_hide (CLUTTER_ACTOR (marker));
+
+  g_object_notify (G_OBJECT (marker), "latitude");
+  g_object_notify (G_OBJECT (marker), "longitude");
+  return FALSE;
+}
+
+static void
+on_animation_completed (ClutterAnimation* animation,
+    ChamplainBaseMarker *marker)
+{
+  g_idle_add ((GSourceFunc) on_idle, marker);
+}
+
+/**
+ * champlain_base_marker_animate_out_with_delay :
+ * @marker: The marker
+ * @delay: The delay in milliseconds
+ *
+ * Animates the marker as if it were drawn through the sky after
+ * delay.
+ *
+ * Since: 0.4
+ */
+void
+champlain_base_marker_animate_out_with_delay (ChamplainBaseMarker *marker,
+    guint delay)
+{
+  ClutterAnimation *animation;
+  ClutterTimeline *timeline;
+  gfloat y;
+
+  g_return_if_fail (CHAMPLAIN_IS_BASE_MARKER (marker));
+
+  clutter_actor_get_position (CLUTTER_ACTOR (marker), NULL, &y);
+  clutter_actor_set_opacity (CLUTTER_ACTOR (marker), 200);
+
+  timeline = clutter_timeline_new (750);
+  clutter_timeline_set_delay (timeline, delay);
+  animation = clutter_actor_animate_with_timeline (CLUTTER_ACTOR (marker),
+      CLUTTER_EASE_IN_BACK, timeline, "opacity", 0, "y", y - 100,
+      "scale-x", 2.0, "scale-y", 2.0, NULL);
+  timeline = clutter_animation_get_timeline (animation);
+  g_signal_connect (animation, "completed",
+      G_CALLBACK (on_animation_completed), marker);
+}
diff --git a/champlain/champlain-base-marker.h b/champlain/champlain-base-marker.h
index 79cf533..d27677b 100644
--- a/champlain/champlain-base-marker.h
+++ b/champlain/champlain-base-marker.h
@@ -66,6 +66,13 @@ void champlain_base_marker_set_highlighted (ChamplainBaseMarker *marker,
     gboolean value);
 gboolean champlain_base_marker_get_highlighted (ChamplainBaseMarker *marker);
 
+void champlain_base_marker_animate_in (ChamplainBaseMarker *marker);
+void champlain_base_marker_animate_in_with_delay (ChamplainBaseMarker *marker,
+    guint delay);
+void champlain_base_marker_animate_out (ChamplainBaseMarker *marker);
+void champlain_base_marker_animate_out_with_delay (ChamplainBaseMarker *marker,
+    guint delay);
+
 G_END_DECLS
 
 #endif
diff --git a/champlain/champlain-layer.c b/champlain/champlain-layer.c
index b28295b..25cf61d 100644
--- a/champlain/champlain-layer.c
+++ b/champlain/champlain-layer.c
@@ -259,3 +259,101 @@ champlain_layer_hide (ChamplainLayer *layer)
 
   clutter_actor_hide (CLUTTER_ACTOR (layer));
 }
+
+/**
+ * champlain_layer_animate_in_all_markers:
+ * @layer: a #ChamplainLayer
+ *
+ * Fade in all markers with an animation
+ *
+ * Since: 0.4
+ */
+void
+champlain_layer_animate_in_all_markers (ChamplainLayer *layer)
+{
+  GList *children;
+  guint delay = 0;
+
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
+
+  children = clutter_container_get_children (CLUTTER_CONTAINER (layer));
+
+  for (; children != NULL; children = g_list_next (children))
+    {
+      champlain_base_marker_animate_in_with_delay (CHAMPLAIN_BASE_MARKER (children->data),
+          delay);
+      delay += 50;
+    }
+}
+
+/**
+ * champlain_layer_animate_out_all_markers:
+ * @layer: a #ChamplainLayer
+ *
+ * Fade out all markers with an animation
+ *
+ * Since: 0.4
+ */
+void
+champlain_layer_animate_out_all_markers (ChamplainLayer *layer)
+{
+  GList *children;
+  guint delay = 0;
+
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
+
+  children = clutter_container_get_children (CLUTTER_CONTAINER (layer));
+
+  for (; children != NULL; children = g_list_next (children))
+    {
+      champlain_base_marker_animate_out_with_delay (CHAMPLAIN_BASE_MARKER (children->data),
+          delay);
+      delay += 50;
+    }
+}
+
+/**
+ * champlain_layer_show_all_markers:
+ * @layer: a #ChamplainLayer
+ *
+ * Calls clutter_actor_show on all markers
+ *
+ * Since: 0.4
+ */
+void
+champlain_layer_show_all_markers (ChamplainLayer *layer)
+{
+  GList *children;
+
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
+
+  children = clutter_container_get_children (CLUTTER_CONTAINER (layer));
+
+  for (; children != NULL; children = g_list_next (children))
+    {
+      clutter_actor_show (CLUTTER_ACTOR (children->data));
+    }
+}
+
+/**
+ * champlain_layer_hide_all_markers:
+ * @layer: a #ChamplainLayer
+ *
+ * Calls clutter_actor_hide on all markers
+ *
+ * Since: 0.4
+ */
+void
+champlain_layer_hide_all_markers (ChamplainLayer *layer)
+{
+  GList *children;
+
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
+
+  children = clutter_container_get_children (CLUTTER_CONTAINER (layer));
+
+  for (; children != NULL; children = g_list_next (children))
+    {
+      clutter_actor_hide (CLUTTER_ACTOR (children->data));
+    }
+}
diff --git a/champlain/champlain-layer.h b/champlain/champlain-layer.h
index 54a5d5e..b8469f6 100644
--- a/champlain/champlain-layer.h
+++ b/champlain/champlain-layer.h
@@ -68,6 +68,12 @@ void champlain_layer_add_marker (ChamplainLayer *layer,
 void champlain_layer_remove_marker (ChamplainLayer *layer,
     ChamplainBaseMarker *marker);
 
+void champlain_layer_animate_in_all_markers (ChamplainLayer *layer);
+void champlain_layer_animate_out_all_markers (ChamplainLayer *layer);
+
+void champlain_layer_show_all_markers (ChamplainLayer *layer);
+void champlain_layer_hide_all_markers (ChamplainLayer *layer);
+
 G_END_DECLS
 
 #endif
diff --git a/demos/launcher-gtk.c b/demos/launcher-gtk.c
index eb31307..312b769 100644
--- a/demos/launcher-gtk.c
+++ b/demos/launcher-gtk.c
@@ -45,13 +45,14 @@ toggle_layer (GtkToggleButton *widget,
 {
   if(gtk_toggle_button_get_active(widget))
     {
+
       champlain_polygon_show (polygon);
-      clutter_actor_show_all (layer);
+      champlain_layer_animate_in_all_markers (layer);
     }
   else
     {
       champlain_polygon_hide (polygon);
-      clutter_actor_hide (layer);
+      champlain_layer_animate_out_all_markers (layer);
     }
 }
 
@@ -214,7 +215,7 @@ main (int argc,
       "zoom-level", 5, NULL);
   layer = create_marker_layer (view);
   champlain_view_add_layer(view, layer);
-  clutter_actor_hide (CLUTTER_ACTOR (layer));
+  champlain_layer_hide_all_markers (CLUTTER_ACTOR (layer));
 
   polygon = champlain_polygon_new ();
   /* Cheap approx of Highway 10 */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]