From: Pierre-Luc Beaudoin Date: Tue, 4 Aug 2009 01:23:50 +0000 (-0400) Subject: Introduce the new Marker animation API X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ea9dfb56c15ff44e4c9863667434fe1145ac96a2;p=libchamplain 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. --- 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 */