[libchamplain] Add relocation signal to view and use it by the layers



commit 6a60606ac4d0830f3c603115484358dc7e7a18b2
Author: JiÅ?í Techet <techet gmail com>
Date:   Mon Jan 17 21:51:42 2011 +0100

    Add relocation signal to view and use it by the layers
    
    ChamplainView should have to know nothing about the layers and markers -
    add a signal to the view to inform about its relocation and let
    the layers redraw themselves when the signal is emitted.

 champlain/champlain-layer.c |  129 ++++++++++++++++++++++++++--
 champlain/champlain-layer.h |    4 +-
 champlain/champlain-tile.c  |    2 +-
 champlain/champlain-view.c  |  199 ++++---------------------------------------
 champlain/champlain-view.h  |    3 -
 5 files changed, 141 insertions(+), 196 deletions(-)
---
diff --git a/champlain/champlain-layer.c b/champlain/champlain-layer.c
index 2ba69e0..3e3e3a0 100644
--- a/champlain/champlain-layer.c
+++ b/champlain/champlain-layer.c
@@ -35,6 +35,7 @@
 #include "champlain-base-marker.h"
 #include "champlain-enum-types.h"
 #include "champlain-private.h"
+#include "champlain-view.h"
 
 #include <clutter/clutter.h>
 #include <glib.h>
@@ -115,6 +116,11 @@ champlain_layer_dispose (GObject *object)
       champlain_layer_unselect_all (self);
     }
 
+  if (priv->view != NULL)
+    {
+      champlain_layer_set_view (self, NULL);
+    }
+
   G_OBJECT_CLASS (champlain_layer_parent_class)->dispose (object);
 }
 
@@ -613,6 +619,61 @@ champlain_layer_get_selection_mode (ChamplainLayer *layer)
 }
 
 
+static void
+relocate_cb (G_GNUC_UNUSED GObject *gobject,
+    ChamplainLayer *layer)
+{
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
+    
+  ChamplainLayerPrivate *priv = layer->priv;
+  gint i, n_children;
+  
+  g_return_if_fail (CHAMPLAIN_IS_VIEW (priv->view));
+
+  n_children = clutter_group_get_n_children (CLUTTER_GROUP (layer));
+  for (i = 0; i < n_children; i++)
+    {
+      ClutterActor *actor = clutter_group_get_nth_child (
+          CLUTTER_GROUP (layer), i);
+      if (CHAMPLAIN_IS_BASE_MARKER (actor))
+        {
+          ChamplainBaseMarker *marker = CHAMPLAIN_BASE_MARKER (actor);
+          gint x, y;
+
+          x = champlain_view_longitude_to_layer_x (priv->view, 
+            champlain_base_marker_get_longitude (marker));
+          y = champlain_view_latitude_to_layer_y (priv->view, 
+            champlain_base_marker_get_latitude (marker));
+
+          clutter_actor_set_position (CLUTTER_ACTOR (marker), x, y);
+        }
+    }
+}
+
+
+static gboolean
+button_release_cb (G_GNUC_UNUSED ClutterActor *actor,
+    ClutterEvent *event,
+    ChamplainLayer *layer)
+{
+  gboolean found = FALSE;
+printf("FOOOOOO\n");
+  if (clutter_event_get_button (event) != 1)
+    return FALSE;
+
+  if (champlain_layer_get_selected_markers (layer) != NULL)
+    {
+      champlain_layer_unselect_all (layer);
+      found = TRUE;
+    }
+
+  return found;
+}
+
+
+
+
+
 void champlain_layer_set_view (ChamplainLayer *layer,
     ChamplainView *view)
 {
@@ -620,6 +681,8 @@ void champlain_layer_set_view (ChamplainLayer *layer,
   
   if (layer->priv->view != NULL)
     {
+      g_signal_handlers_disconnect_by_func (layer->priv->view,
+        G_CALLBACK (relocate_cb), layer);
       g_object_unref (layer->priv->view);
     }
   
@@ -629,16 +692,64 @@ void champlain_layer_set_view (ChamplainLayer *layer,
     {
       g_object_ref (view);
   
-    g_idle_add_full (G_PRIORITY_DEFAULT,
-      (GSourceFunc) marker_reposition,
-      g_object_ref (view),
-      (GDestroyNotify) g_object_unref);
+      g_signal_connect (view, "layer-relocated",
+        G_CALLBACK (relocate_cb), layer);
+        
+      g_signal_connect_after (view, "button-release-event",
+        G_CALLBACK (button_release_cb), layer);
+  
+    }
+}
+
+/**
+ * champlain_view_ensure_markers_visible:
+ * @view: a #ChamplainView
+ * @markers: (array zero-terminated=1): a NULL terminated array of #ChamplainMarker elements
+ * @animate: a #gboolean
+ *
+ * Changes the map's zoom level and center to make sure those markers are
+ * visible.
+ *
+ * FIXME: This doesn't take into account the marker's actor size yet
+ *
+ * Since: 0.4
+ */
+/*void
+champlain_view_ensure_markers_visible (ChamplainView *view,
+    ChamplainBaseMarker *markers[],
+    gboolean animate)
+{
+  DEBUG_LOG ()
+
+  gdouble min_lat, min_lon, max_lat, max_lon;
+  ChamplainBaseMarker *marker = NULL;
+  gint i = 0;
+
+  min_lat = min_lon = 200;
+  max_lat = max_lon = -200;
 
-  g_signal_connect_after (layer, "actor-added",
-      G_CALLBACK (layer_add_marker_cb), view);
+  marker = markers[i];
+  while (marker != NULL)
+    {
+      gdouble lat, lon;
+      g_object_get (G_OBJECT (marker), "latitude", &lat, "longitude", &lon,
+          NULL);
+
+      if (lon < min_lon)
+        min_lon = lon;
+
+      if (lat < min_lat)
+        min_lat = lat;
+
+      if (lon > max_lon)
+        max_lon = lon;
 
-  clutter_container_foreach (CLUTTER_CONTAINER (layer),
-      CLUTTER_CALLBACK (connect_marker_notify_cb), view);
+      if (lat > max_lat)
+        max_lat = lat;
+
+      marker = markers[i++];
     }
-}
+  champlain_view_ensure_visible (view, min_lat, min_lon, max_lat, max_lon, animate);
+}*/
+
 
diff --git a/champlain/champlain-layer.h b/champlain/champlain-layer.h
index 7b97622..ccffaa8 100644
--- a/champlain/champlain-layer.h
+++ b/champlain/champlain-layer.h
@@ -91,7 +91,6 @@ void champlain_layer_remove_marker (ChamplainLayer *layer,
 
 void champlain_layer_set_view (ChamplainLayer *layer,
     ChamplainView *view);
-void champlain_layer_clear_view (ChamplainLayer *layer);
 
 void champlain_layer_animate_in_all_markers (ChamplainLayer *layer);
 void champlain_layer_animate_out_all_markers (ChamplainLayer *layer);
@@ -114,6 +113,9 @@ void champlain_layer_set_selection_mode (ChamplainLayer *layer,
     ChamplainSelectionMode mode);
 ChamplainSelectionMode champlain_layer_get_selection_mode (
     ChamplainLayer *layer);
+//void champlain_view_ensure_markers_visible (ChamplainView *view,
+//    ChamplainBaseMarker *markers[],
+//    gboolean animate);
 
 G_END_DECLS
 
diff --git a/champlain/champlain-tile.c b/champlain/champlain-tile.c
index 355d635..395da01 100644
--- a/champlain/champlain-tile.c
+++ b/champlain/champlain-tile.c
@@ -393,7 +393,7 @@ champlain_tile_class_init (ChamplainTileClass *klass)
     g_signal_new ("render-complete", G_OBJECT_CLASS_TYPE (object_class),
         G_SIGNAL_RUN_LAST, 0, NULL, NULL,
         g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE,
-        1, G_TYPE_OBJECT);
+        1, G_TYPE_POINTER);
 }
 
 
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index 88843ce..48b0cb6 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -83,6 +83,7 @@ enum
 {
   /* normal signals */
   ANIMATION_COMPLETED,
+  LAYER_RELOCATED,
   LAST_SIGNAL
 };
 
@@ -210,11 +211,6 @@ G_DEFINE_TYPE (ChamplainView, champlain_view, CLUTTER_TYPE_GROUP);
 static gboolean scroll_event (ClutterActor *actor,
     ClutterScrollEvent *event,
     ChamplainView *view);
-static void marker_reposition_cb (ChamplainMarker *marker,
-    ChamplainView *view);
-static void layer_reposition_cb (ClutterActor *layer,
-    ChamplainView *view);
-static gboolean marker_reposition (gpointer data);
 static void resize_viewport (ChamplainView *view);
 static void champlain_view_get_property (GObject *object,
     guint prop_id,
@@ -230,14 +226,6 @@ static void champlain_view_init (ChamplainView *view);
 static void viewport_pos_changed_cb (GObject *gobject,
     GParamSpec *arg1,
     ChamplainView *view);
-static void notify_marker_reposition_cb (ChamplainMarker *marker,
-    GParamSpec *arg1,
-    ChamplainView *view);
-static void layer_add_marker_cb (ClutterGroup *layer,
-    ChamplainMarker *marker,
-    ChamplainView *view);
-static void connect_marker_notify_cb (ChamplainMarker *marker,
-    ChamplainView *view);
 static gboolean finger_scroll_button_press_cb (ClutterActor *actor,
     ClutterButtonEvent *event,
     ChamplainView *view);
@@ -291,7 +279,7 @@ update_viewport (ChamplainView *view,
       x + priv->anchor.x + priv->viewport_size.width / 2.0,
       y + priv->anchor.y + priv->viewport_size.height / 2.0);
 
-  if (priv->anchor.x - old_anchor.x != 0)
+  if (priv->anchor.x - old_anchor.x != 0 || priv->anchor.y - old_anchor.y != 0)
     {
       ChamplainFloatPoint diff;
 
@@ -362,90 +350,6 @@ scroll_event (G_GNUC_UNUSED ClutterActor *actor,
 }
 
 
-static void
-marker_reposition_cb (ChamplainMarker *marker,
-    ChamplainView *view)
-{
-  DEBUG_LOG ()
-
-  ChamplainViewPrivate *priv = view->priv;
-  ChamplainBaseMarker *base_marker = CHAMPLAIN_BASE_MARKER (marker);
-
-  gint x, y;
-
-  x = champlain_map_source_get_x (priv->map_source, priv->zoom_level,
-        champlain_base_marker_get_longitude (base_marker));
-  y = champlain_map_source_get_y (priv->map_source, priv->zoom_level,
-        champlain_base_marker_get_latitude (base_marker));
-
-  clutter_actor_set_position (CLUTTER_ACTOR (marker),
-      x - priv->anchor.x,
-      y - priv->anchor.y);
-}
-
-
-static void
-notify_marker_reposition_cb (ChamplainMarker *marker,
-    G_GNUC_UNUSED GParamSpec *arg1,
-    ChamplainView *view)
-{
-  DEBUG_LOG ()
-
-  marker_reposition_cb (marker, view);
-}
-
-
-static void
-layer_add_marker_cb (G_GNUC_UNUSED ClutterGroup *layer,
-    ChamplainMarker *marker,
-    ChamplainView *view)
-{
-  DEBUG_LOG ()
-
-  g_signal_connect (marker, "notify::longitude",
-      G_CALLBACK (notify_marker_reposition_cb), view);
-
-  g_idle_add_full (G_PRIORITY_DEFAULT,
-      (GSourceFunc) marker_reposition,
-      g_object_ref (view),
-      (GDestroyNotify) g_object_unref);
-}
-
-
-static void
-connect_marker_notify_cb (ChamplainMarker *marker,
-    ChamplainView *view)
-{
-  DEBUG_LOG ()
-
-  g_signal_connect (marker, "notify::longitude",
-      G_CALLBACK (notify_marker_reposition_cb), view);
-}
-
-
-static void
-layer_reposition_cb (ClutterActor *layer,
-    ChamplainView *view)
-{
-  DEBUG_LOG ()
-
-  clutter_container_foreach (CLUTTER_CONTAINER (layer),
-      CLUTTER_CALLBACK (marker_reposition_cb), view);
-}
-
-
-static gboolean
-marker_reposition (gpointer data)
-{
-  DEBUG_LOG ()
-
-  ChamplainView *view = CHAMPLAIN_VIEW (data);
-  clutter_container_foreach (CLUTTER_CONTAINER (view->priv->user_layers),
-      CLUTTER_CALLBACK (layer_reposition_cb), view);
-  return FALSE;
-}
-
-
 static gboolean
 redraw_polygon_on_idle (PolygonRedrawContext *ctx)
 {
@@ -1214,6 +1118,12 @@ champlain_view_class_init (ChamplainViewClass *champlainViewClass)
     g_signal_new ("animation-completed", G_OBJECT_CLASS_TYPE (object_class),
         G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL,
         g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 0);
+        
+  signals[LAYER_RELOCATED] =
+    g_signal_new ("layer-relocated", G_OBJECT_CLASS_TYPE (object_class),
+        G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+        g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+        
 }
 
 
@@ -1240,7 +1150,7 @@ create_license (ChamplainView *view)
   clutter_actor_raise_top (priv->license_actor);
 }
 
-
+/*
 static gboolean
 button_release_cb (G_GNUC_UNUSED ClutterActor *actor,
     ClutterEvent *event,
@@ -1248,31 +1158,9 @@ button_release_cb (G_GNUC_UNUSED ClutterActor *actor,
 {
   DEBUG_LOG ()
 
-  guint i;
-  gboolean found = FALSE;
-  ChamplainViewPrivate *priv = view->priv;
-
-  if (clutter_event_get_button (event) != 1)
-    return FALSE;
-
-  for (i = 0; i < clutter_group_get_n_children (CLUTTER_GROUP (priv->user_layers)); i++)
-    {
-      ClutterActor *actor = CLUTTER_ACTOR (clutter_group_get_nth_child (CLUTTER_GROUP (priv->user_layers), i));
-
-      if (actor && CHAMPLAIN_IS_LAYER (actor))
-        {
-          ChamplainLayer *layer = CHAMPLAIN_LAYER (actor);
-          if (champlain_layer_get_selected_markers (layer) != NULL)
-            {
-              champlain_layer_unselect_all (layer);
-              found = TRUE;
-            }
-        }
-    }
-
-  return found;
+  return TRUE;
 }
-
+*/
 
 static void
 update_scale (ChamplainView *view)
@@ -1543,8 +1431,8 @@ champlain_view_init (ChamplainView *view)
       G_CALLBACK (panning_completed), view);
   g_signal_connect (priv->finger_scroll, "button-press-event",
       G_CALLBACK (finger_scroll_button_press_cb), view);
-  g_signal_connect_after (priv->finger_scroll, "button-release-event",
-      G_CALLBACK (button_release_cb), view);
+//  g_signal_connect_after (priv->finger_scroll, "button-release-event",
+//      G_CALLBACK (button_release_cb), view);
 
   clutter_stage_set_key_focus (CLUTTER_STAGE (clutter_stage_get_default ()),
       priv->finger_scroll);
@@ -1921,7 +1809,7 @@ champlain_view_center_on (ChamplainView *view,
   view_load_visible_tiles (view);
   view_update_polygons (view);
   update_scale (view);
-  marker_reposition (view);
+  g_signal_emit_by_name (view, "layer-relocated", NULL);
 }
 
 
@@ -2221,10 +2109,9 @@ champlain_view_add_layer (ChamplainView *view,
   g_return_if_fail (CHAMPLAIN_IS_VIEW (view));
   g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
   
-  champlain_layer_set_view (layer, view);
-
   clutter_container_add_actor (CLUTTER_CONTAINER (view->priv->user_layers),
       CLUTTER_ACTOR (layer));
+  champlain_layer_set_view (layer, view);
   clutter_actor_raise_top (CLUTTER_ACTOR (layer));
 }
 
@@ -2247,8 +2134,8 @@ champlain_view_remove_layer (ChamplainView *view,
   g_return_if_fail (CHAMPLAIN_IS_VIEW (view));
   g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
 
-  g_signal_handlers_disconnect_by_func (layer,
-      G_CALLBACK (layer_add_marker_cb), view);
+  champlain_layer_set_view (layer, view);      
+
   clutter_container_remove_actor (CLUTTER_CONTAINER (view->priv->user_layers),
       CLUTTER_ACTOR (layer));
 }
@@ -3056,58 +2943,6 @@ champlain_view_ensure_visible (ChamplainView *view,
 }
 
 
-/**
- * champlain_view_ensure_markers_visible:
- * @view: a #ChamplainView
- * @markers: (array zero-terminated=1): a NULL terminated array of #ChamplainMarker elements
- * @animate: a #gboolean
- *
- * Changes the map's zoom level and center to make sure those markers are
- * visible.
- *
- * FIXME: This doesn't take into account the marker's actor size yet
- *
- * Since: 0.4
- */
-void
-champlain_view_ensure_markers_visible (ChamplainView *view,
-    ChamplainBaseMarker *markers[],
-    gboolean animate)
-{
-  DEBUG_LOG ()
-
-  gdouble min_lat, min_lon, max_lat, max_lon;
-  ChamplainBaseMarker *marker = NULL;
-  gint i = 0;
-
-  min_lat = min_lon = 200;
-  max_lat = max_lon = -200;
-
-  marker = markers[i];
-  while (marker != NULL)
-    {
-      gdouble lat, lon;
-      g_object_get (G_OBJECT (marker), "latitude", &lat, "longitude", &lon,
-          NULL);
-
-      if (lon < min_lon)
-        min_lon = lon;
-
-      if (lat < min_lat)
-        min_lat = lat;
-
-      if (lon > max_lon)
-        max_lon = lon;
-
-      if (lat > max_lat)
-        max_lat = lat;
-
-      marker = markers[i++];
-    }
-  champlain_view_ensure_visible (view, min_lat, min_lon, max_lat, max_lon, animate);
-}
-
-
 /* Sets the zoom level, leaving the (x, y) at the exact same point in the view */
 static gboolean
 view_set_zoom_level_at (ChamplainView *view,
diff --git a/champlain/champlain-view.h b/champlain/champlain-view.h
index dc4f3d1..d6fd729 100644
--- a/champlain/champlain-view.h
+++ b/champlain/champlain-view.h
@@ -121,9 +121,6 @@ void champlain_view_ensure_visible (ChamplainView *view,
     gdouble lat2,
     gdouble lon2,
     gboolean animate);
-void champlain_view_ensure_markers_visible (ChamplainView *view,
-    ChamplainBaseMarker *markers[],
-    gboolean animate);
 
 void champlain_view_set_map_source (ChamplainView *view,
     ChamplainMapSource *map_source);



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