[libchamplain] Merge ChamplainLayer and ChamplainSelectionLayer



commit 7d80054aa5a8fd6dad6f8a2186fbcc3b22432ab2
Author: JiÅ?í Techet <techet gmail com>
Date:   Sun Jan 16 23:16:06 2011 +0100

    Merge ChamplainLayer and ChamplainSelectionLayer
    
    There is no need for the user to distinguish between these two layers -
    he either uses the selection features or not.

 champlain/Makefile.am                 |    2 -
 champlain/champlain-layer.c           |  429 +++++++++++++++++++++++---
 champlain/champlain-layer.h           |   44 +++-
 champlain/champlain-polygon.c         |   28 +-
 champlain/champlain-polygon.h         |    7 +-
 champlain/champlain-selection-layer.c |  548 ---------------------------------
 champlain/champlain-selection-layer.h |  108 -------
 champlain/champlain-tile.c            |    2 +-
 champlain/champlain-view.c            |  314 +++++++++----------
 champlain/champlain-view.h            |   30 ++-
 champlain/champlain.h                 |    1 -
 demos/animated-marker.c               |    2 +-
 demos/markers.c                       |    6 +-
 demos/url-marker.c                    |    2 +-
 14 files changed, 616 insertions(+), 907 deletions(-)
---
diff --git a/champlain/Makefile.am b/champlain/Makefile.am
index 66a1642..442bbd2 100644
--- a/champlain/Makefile.am
+++ b/champlain/Makefile.am
@@ -17,7 +17,6 @@ libchamplain_headers_public = 				\
 	$(srcdir)/champlain-point.h			\
 	$(srcdir)/champlain-view.h			\
 	$(srcdir)/champlain-layer.h 			\
-	$(srcdir)/champlain-selection-layer.h 		\
 	$(srcdir)/champlain-base-marker.h		\
 	$(srcdir)/champlain-marker.h			\
 	$(srcdir)/champlain-tile.h			\
@@ -54,7 +53,6 @@ libchamplain_sources =					\
 	$(srcdir)/champlain-debug.c 			\
 	$(srcdir)/champlain-view.c 			\
 	$(srcdir)/champlain-layer.c 			\
-	$(srcdir)/champlain-selection-layer.c 		\
 	$(srcdir)/champlain-base-marker.c 		\
 	$(srcdir)/champlain-marker.c 			\
 	$(srcdir)/champlain-tile.c			\
diff --git a/champlain/champlain-layer.c b/champlain/champlain-layer.c
index 65598ad..2ba69e0 100644
--- a/champlain/champlain-layer.c
+++ b/champlain/champlain-layer.c
@@ -33,17 +33,37 @@
 
 #include "champlain-defines.h"
 #include "champlain-base-marker.h"
+#include "champlain-enum-types.h"
+#include "champlain-private.h"
 
 #include <clutter/clutter.h>
 #include <glib.h>
 
 G_DEFINE_TYPE (ChamplainLayer, champlain_layer, CLUTTER_TYPE_GROUP)
 
+#define GET_PRIVATE(obj)    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CHAMPLAIN_TYPE_LAYER, ChamplainLayerPrivate))
+
 enum
 {
-  PROP_0
+  /* normal signals */
+  CHANGED,
+  LAST_SIGNAL
 };
 
+enum
+{
+  PROP_0,
+  PROP_SELECTION_MODE
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+struct _ChamplainLayerPrivate
+{
+  ChamplainSelectionMode mode;
+  GList *selection;
+  ChamplainView *view;
+};
 
 static void
 champlain_layer_get_property (GObject *object,
@@ -51,9 +71,14 @@ champlain_layer_get_property (GObject *object,
     G_GNUC_UNUSED GValue *value,
     GParamSpec *pspec)
 {
-  /* ChamplainLayer *self = CHAMPLAIN_LAYER (object); */
+  ChamplainLayer *self = CHAMPLAIN_LAYER (object);
+  ChamplainLayerPrivate *priv = self->priv;
+  
   switch (property_id)
     {
+    case PROP_SELECTION_MODE:
+      g_value_set_enum (value, priv->mode);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
     }
@@ -66,9 +91,13 @@ champlain_layer_set_property (GObject *object,
     G_GNUC_UNUSED const GValue *value,
     GParamSpec *pspec)
 {
-  /* ChamplainLayer *self = CHAMPLAIN_LAYER (object); */
+  ChamplainLayer *self = CHAMPLAIN_LAYER (object);
+  
   switch (property_id)
     {
+    case PROP_SELECTION_MODE:
+      champlain_layer_set_selection_mode (self, g_value_get_enum (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
     }
@@ -78,6 +107,14 @@ champlain_layer_set_property (GObject *object,
 static void
 champlain_layer_dispose (GObject *object)
 {
+  ChamplainLayer *self = CHAMPLAIN_LAYER (object);
+  ChamplainLayerPrivate *priv = self->priv;
+  
+  if (priv->selection != NULL)
+    {
+      champlain_layer_unselect_all (self);
+    }
+
   G_OBJECT_CLASS (champlain_layer_parent_class)->dispose (object);
 }
 
@@ -94,21 +131,57 @@ champlain_layer_class_init (ChamplainLayerClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  g_type_class_add_private (klass, sizeof (ChamplainLayerPrivate));
+  
   object_class->finalize = champlain_layer_finalize;
   object_class->dispose = champlain_layer_dispose;
   object_class->get_property = champlain_layer_get_property;
   object_class->set_property = champlain_layer_set_property;
+  
+  /**
+   * ChamplainLayer:selection-mode:
+   *
+   * Determines the type of selection that will be performed.
+   *
+   * Since: 0.10
+   */
+  g_object_class_install_property (object_class,
+      PROP_SELECTION_MODE,
+      g_param_spec_enum ("selection-mode",
+          "Selection Mode",
+          "Determines the type of selection that will be performed.",
+          CHAMPLAIN_TYPE_SELECTION_MODE,
+          CHAMPLAIN_SELECTION_NONE,
+          CHAMPLAIN_PARAM_READWRITE));
+
+  /**
+   * ChamplainLayer::changed
+   *
+   * The changed signal is emitted when the selected marker(s) change.
+   *
+   * Since: 0.4.1
+   */
+  signals[CHANGED] =
+    g_signal_new ("changed", G_OBJECT_CLASS_TYPE (object_class),
+        G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+        g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
 }
 
 
 static void
 champlain_layer_init (ChamplainLayer *self)
 {
+  self->priv = GET_PRIVATE (self);
+  self->priv->mode = CHAMPLAIN_SELECTION_NONE;
+  self->priv->selection = NULL;
+  self->priv->view = NULL;
 }
 
 
 /**
- * champlain_layer_new:
+ * champlain_layer_new_full:
+ * @mode: Selection mode
  *
  * Creates a new instance of #ChamplainLayer.
  *
@@ -117,9 +190,64 @@ champlain_layer_init (ChamplainLayer *self)
  * Since: 0.2.2
  */
 ChamplainLayer *
-champlain_layer_new ()
+champlain_layer_new_full (ChamplainSelectionMode mode)
+{
+  return g_object_new (CHAMPLAIN_TYPE_LAYER, "selection-mode", mode, NULL);
+}
+
+
+static void
+marker_select (ChamplainLayer *layer,
+    ChamplainBaseMarker *marker)
+{
+  /* Add selection */
+  g_object_ref (marker);
+  champlain_base_marker_set_highlighted (marker, TRUE);
+  layer->priv->selection = g_list_prepend (layer->priv->selection, marker);
+
+  g_signal_emit_by_name (layer, "changed", NULL);
+}
+
+
+static void
+select (ChamplainLayer *layer,
+    ChamplainBaseMarker *marker,
+    gboolean mouse,
+    gboolean append)
+{
+  if (layer->priv->mode == CHAMPLAIN_SELECTION_NONE)
+    return;
+
+  if (layer->priv->mode == CHAMPLAIN_SELECTION_SINGLE || (mouse && !append))
+    {
+      /* Clear previous selection */
+      champlain_layer_unselect_all (layer);
+      marker_select (layer, marker);
+    }
+  else if (layer->priv->mode == CHAMPLAIN_SELECTION_MULTIPLE)
+    {
+      if (champlain_layer_marker_is_selected (layer, marker))
+        {
+          if (mouse)
+            champlain_layer_unselect (layer, marker);
+        }
+      else
+        marker_select (layer, marker);
+    }
+}
+
+
+static gboolean
+marker_clicked_cb (ClutterActor *actor,
+    ClutterButtonEvent *event,
+    gpointer user_data)
 {
-  return g_object_new (CHAMPLAIN_TYPE_LAYER, NULL);
+  select (CHAMPLAIN_LAYER (user_data),
+      CHAMPLAIN_BASE_MARKER (actor),
+      TRUE,
+      (event->modifier_state & CLUTTER_CONTROL_MASK));
+
+  return TRUE;
 }
 
 
@@ -136,9 +264,16 @@ void
 champlain_layer_add_marker (ChamplainLayer *layer,
     ChamplainBaseMarker *marker)
 {
+  ClutterActor *actor = CLUTTER_ACTOR (marker);
+    
   g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
   g_return_if_fail (CHAMPLAIN_IS_BASE_MARKER (marker));
 
+  clutter_actor_set_reactive (actor, TRUE);
+
+  g_signal_connect (G_OBJECT (marker), "button-release-event",
+      G_CALLBACK (marker_clicked_cb), layer);
+
   clutter_container_add_actor (CLUTTER_CONTAINER (layer), CLUTTER_ACTOR (marker));
 }
 
@@ -159,41 +294,10 @@ champlain_layer_remove_marker (ChamplainLayer *layer,
   g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
   g_return_if_fail (CHAMPLAIN_IS_BASE_MARKER (marker));
 
-  clutter_container_remove_actor (CLUTTER_CONTAINER (layer), CLUTTER_ACTOR (marker));
-}
+  g_signal_handlers_disconnect_by_func (G_OBJECT (marker),
+      G_CALLBACK (marker_clicked_cb), layer);
 
-
-/**
- * champlain_layer_show:
- * @layer: a #ChamplainLayer
- *
- * Makes the layer and its markers visible.
- *
- * Since: 0.4
- */
-void
-champlain_layer_show (ChamplainLayer *layer)
-{
-  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
-
-  clutter_actor_show (CLUTTER_ACTOR (layer));
-}
-
-
-/**
- * champlain_layer_hide:
- * @layer: a #ChamplainLayer
- *
- * Makes the layer and its markers invisible.
- *
- * Since: 0.4
- */
-void
-champlain_layer_hide (ChamplainLayer *layer)
-{
-  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
-
-  clutter_actor_hide (CLUTTER_ACTOR (layer));
+  clutter_container_remove_actor (CLUTTER_CONTAINER (layer), CLUTTER_ACTOR (marker));
 }
 
 
@@ -249,6 +353,7 @@ champlain_layer_animate_out_all_markers (ChamplainLayer *layer)
 }
 
 
+//TODO: do we need it? (we can hide the whole layer)
 /**
  * champlain_layer_show_all_markers:
  * @layer: a #ChamplainLayer
@@ -272,7 +377,7 @@ champlain_layer_show_all_markers (ChamplainLayer *layer)
     }
 }
 
-
+//TODO: do we need it? (we can hide the whole layer)
 /**
  * champlain_layer_hide_all_markers:
  * @layer: a #ChamplainLayer
@@ -295,3 +400,245 @@ champlain_layer_hide_all_markers (ChamplainLayer *layer)
       clutter_actor_hide (marker);
     }
 }
+
+
+/**
+ * champlain_layer_get_selected_markers:
+ * @layer: a #ChamplainLayer
+ *
+ * Gets the list of selected markers.
+ *
+ * Returns: (transfer none) (element-type ChamplainBaseMarker): the list of selected #ChamplainBaseMarker or NULL if none is selected.
+ * You shouldn't free that list.
+ *
+ * Since: 0.4
+ */
+const GList *
+champlain_layer_get_selected_markers (ChamplainLayer *layer)
+{
+  return layer->priv->selection;
+}
+
+
+/**
+ * champlain_layer_select:
+ * @layer: a #ChamplainLayer
+ * @marker: a #ChamplainBaseMarker
+ *
+ * Selects the marker.
+ *
+ * Since: 0.4
+ */
+void
+champlain_layer_select (ChamplainLayer *layer,
+    ChamplainBaseMarker *marker)
+{
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
+  g_return_if_fail (CHAMPLAIN_IS_BASE_MARKER (marker));
+
+  select (layer, marker, FALSE, FALSE);
+}
+
+
+/**
+ * champlain_layer_unselect:
+ * @layer: a #ChamplainLayer
+ * @marker: a #ChamplainBaseMarker
+ *
+ * Unselect the marker.
+ *
+ * Since: 0.4
+ */
+void
+champlain_layer_unselect (ChamplainLayer *layer,
+    ChamplainBaseMarker *marker)
+{
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
+  g_return_if_fail (CHAMPLAIN_IS_BASE_MARKER (marker));
+
+  GList *selection;
+
+  selection = g_list_find (layer->priv->selection, marker);
+  if (selection != NULL)
+    {
+      champlain_base_marker_set_highlighted (marker, FALSE);
+      g_object_unref (selection->data);
+      layer->priv->selection = g_list_delete_link (layer->priv->selection, selection);
+
+      g_signal_emit_by_name (layer, "changed", NULL);
+    }
+}
+
+
+/**
+ * champlain_layer_marker_is_selected:
+ * @layer: a #ChamplainLayer
+ * @marker: a #ChamplainBaseMarker
+ *
+ * Checks whether the marker is selected.
+ *
+ * Returns: whether the marker is selected or not.
+ *
+ * Since: 0.4
+ */
+gboolean
+champlain_layer_marker_is_selected (ChamplainLayer *layer,
+    ChamplainBaseMarker *marker)
+{
+  g_return_val_if_fail (CHAMPLAIN_IS_LAYER (layer), FALSE);
+  g_return_val_if_fail (CHAMPLAIN_IS_BASE_MARKER (marker), FALSE);
+
+  GList *selection;
+
+  selection = g_list_find (layer->priv->selection, marker);
+  return selection != NULL;
+}
+
+
+/**
+ * champlain_layer_unselect_all:
+ * @layer: a #ChamplainLayer
+ *
+ * Unselects all markers.
+ *
+ * Since: 0.4
+ */
+void
+champlain_layer_unselect_all (ChamplainLayer *layer)
+{
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
+
+  GList *selection = layer->priv->selection;
+  
+  if (selection == NULL)
+    return;
+
+  while (selection != NULL)
+    {
+      champlain_base_marker_set_highlighted (selection->data, FALSE);
+      g_object_unref (selection->data);
+      selection = g_list_delete_link (selection, selection);
+    }
+  layer->priv->selection = NULL;
+
+  g_signal_emit_by_name (layer, "changed", NULL);
+}
+
+
+/**
+ * champlain_layer_select_all:
+ * @layer: a #ChamplainLayer
+ *
+ * Selects all markers in the layer. This call will only work if the selection
+ * mode is set CHAMPLAIN_SELETION_MULTIPLE.
+ *
+ * Since: 0.4
+ */
+void
+champlain_layer_select_all (ChamplainLayer *layer)
+{
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
+
+  gint n_children;
+  gint i;
+
+  if (layer->priv->mode == CHAMPLAIN_SELECTION_NONE)
+    return;
+
+  if (layer->priv->mode == CHAMPLAIN_SELECTION_SINGLE)
+    return;
+
+  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);
+          select (layer, marker, FALSE, FALSE);
+        }
+    }
+}
+
+
+/**
+ * champlain_layer_set_selection_mode:
+ * @layer: a #ChamplainLayer
+ * @mode: a #ChamplainSelectionMode value
+ *
+ * Sets the selection mode of the layer.
+ *
+ * NOTE: changing selection mode to CHAMPLAIN_SELECTION_NONE or
+ * CHAMPLAIN_SELECTION_SINGLE will clear all previously selected markers.
+ *
+ * Since: 0.4
+ */
+void
+champlain_layer_set_selection_mode (ChamplainLayer *layer,
+    ChamplainSelectionMode mode)
+{
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
+
+  if (layer->priv->mode == mode)
+    return;
+  layer->priv->mode = mode;
+
+  /* Switching to single mode shouldn't keep the selection */
+  if (mode == CHAMPLAIN_SELECTION_NONE ||
+      mode == CHAMPLAIN_SELECTION_SINGLE)
+    champlain_layer_unselect_all (layer);
+
+  g_object_notify (G_OBJECT (layer), "selection-mode");
+}
+
+
+/**
+ * champlain_layer_get_selection_mode:
+ * @layer: a #ChamplainLayer
+ *
+ * Gets the selection mode of the layer.
+ *
+ * Returns: the selection mode of the layer.
+ *
+ * Since: 0.4
+ */
+ChamplainSelectionMode
+champlain_layer_get_selection_mode (ChamplainLayer *layer)
+{
+  g_return_val_if_fail (
+      CHAMPLAIN_IS_LAYER (layer),
+      CHAMPLAIN_SELECTION_SINGLE);
+  return layer->priv->mode;
+}
+
+
+void champlain_layer_set_view (ChamplainLayer *layer,
+    ChamplainView *view)
+{
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer) && (CHAMPLAIN_IS_VIEW (view) || view == NULL));
+  
+  if (layer->priv->view != NULL)
+    {
+      g_object_unref (layer->priv->view);
+    }
+  
+  layer->priv->view = view;
+
+  if (view != NULL)
+    {
+      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_after (layer, "actor-added",
+      G_CALLBACK (layer_add_marker_cb), view);
+
+  clutter_container_foreach (CLUTTER_CONTAINER (layer),
+      CLUTTER_CALLBACK (connect_marker_notify_cb), view);
+    }
+}
+
diff --git a/champlain/champlain-layer.h b/champlain/champlain-layer.h
index 326de5e..7b97622 100644
--- a/champlain/champlain-layer.h
+++ b/champlain/champlain-layer.h
@@ -48,12 +48,31 @@ G_BEGIN_DECLS
 #define CHAMPLAIN_LAYER_GET_CLASS(obj) \
   (G_TYPE_INSTANCE_GET_CLASS ((obj), CHAMPLAIN_TYPE_LAYER, ChamplainLayerClass))
 
+typedef struct _ChamplainLayerPrivate ChamplainLayerPrivate;
+
 typedef struct _ChamplainLayer ChamplainLayer;
 typedef struct _ChamplainLayerClass ChamplainLayerClass;
 
+/**
+ * ChamplainSelectionMode:
+ * @CHAMPLAIN_SELECTION_NONE: No marker can be selected.
+ * @CHAMPLAIN_SELECTION_SINGLE: Only one marker can be selected.
+ * @CHAMPLAIN_SELECTION_MULTIPLE: Multiple marker can be selected.
+ *
+ * Selection mode
+ */
+typedef enum
+{
+  CHAMPLAIN_SELECTION_NONE,
+  CHAMPLAIN_SELECTION_SINGLE,
+  CHAMPLAIN_SELECTION_MULTIPLE
+} ChamplainSelectionMode;
+
 struct _ChamplainLayer
 {
   ClutterGroup parent;
+  
+  ChamplainLayerPrivate *priv;
 };
 
 struct _ChamplainLayerClass
@@ -63,22 +82,39 @@ struct _ChamplainLayerClass
 
 GType champlain_layer_get_type (void);
 
-ChamplainLayer *champlain_layer_new (void);
-
-void champlain_layer_show (ChamplainLayer *layer);
-void champlain_layer_hide (ChamplainLayer *layer);
+ChamplainLayer *champlain_layer_new_full (ChamplainSelectionMode mode);
 
 void champlain_layer_add_marker (ChamplainLayer *layer,
     ChamplainBaseMarker *marker);
 void champlain_layer_remove_marker (ChamplainLayer *layer,
     ChamplainBaseMarker *marker);
 
+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);
 
 void champlain_layer_show_all_markers (ChamplainLayer *layer);
 void champlain_layer_hide_all_markers (ChamplainLayer *layer);
 
+void champlain_layer_select (ChamplainLayer *layer,
+    ChamplainBaseMarker *marker);
+void champlain_layer_unselect (ChamplainLayer *layer,
+    ChamplainBaseMarker *marker);
+gboolean champlain_layer_marker_is_selected (ChamplainLayer *layer,
+    ChamplainBaseMarker *marker);
+
+void champlain_layer_select_all (ChamplainLayer *layer);
+void champlain_layer_unselect_all (ChamplainLayer *layer);
+const GList *champlain_layer_get_selected_markers (ChamplainLayer *layer);
+
+void champlain_layer_set_selection_mode (ChamplainLayer *layer,
+    ChamplainSelectionMode mode);
+ChamplainSelectionMode champlain_layer_get_selection_mode (
+    ChamplainLayer *layer);
+
 G_END_DECLS
 
 #endif
diff --git a/champlain/champlain-polygon.c b/champlain/champlain-polygon.c
index 5504be3..dd9fa51 100644
--- a/champlain/champlain-polygon.c
+++ b/champlain/champlain-polygon.c
@@ -28,7 +28,7 @@
 #include "champlain-polygon.h"
 
 #include "champlain-private.h"
-#include "champlain-map-source.h"
+#include "champlain-view.h"
 
 #include <clutter/clutter.h>
 #include <glib.h>
@@ -782,18 +782,16 @@ champlain_polygon_hide (ChamplainPolygon *polygon)
 
 void
 champlain_polygon_draw_polygon (ChamplainPolygon *polygon,
-    ChamplainMapSource *map_source,
-    guint zoom_level,
-    gfloat width,
-    gfloat height,
-    gfloat shift_x,
-    gfloat shift_y)
+    ChamplainView *view)
 {
   ChamplainPolygonPrivate *priv = polygon->priv;
   ClutterActor *cairo_texture;
   cairo_t *cr;
+  gfloat width, height;
+  
+  clutter_actor_get_size (CLUTTER_ACTOR (view), &width, &height);
 
-  if (!priv->visible || width == 0 || height == 0)
+  if (!priv->visible || width == 0.0 || height == 0.0)
     return;
 
   clutter_group_remove_all (CLUTTER_GROUP (polygon));
@@ -814,11 +812,8 @@ champlain_polygon_draw_polygon (ChamplainPolygon *polygon,
       ChamplainPoint *point = (ChamplainPoint *) list->data;
       gfloat x, y;
 
-      x = champlain_map_source_get_x (map_source, zoom_level, point->lon);
-      y = champlain_map_source_get_y (map_source, zoom_level, point->lat);
-
-      x -= shift_x;
-      y -= shift_y;
+      x = champlain_view_longitude_to_x (view, point->lon);
+      y = champlain_view_latitude_to_y (view, point->lat);
 
       cairo_line_to (cr, x, y);
 
@@ -857,11 +852,8 @@ champlain_polygon_draw_polygon (ChamplainPolygon *polygon,
           ChamplainPoint *point = (ChamplainPoint *) list->data;
           gfloat x, y;
 
-          x = champlain_map_source_get_x (map_source, zoom_level, point->lon);
-          y = champlain_map_source_get_y (map_source, zoom_level, point->lat);
-
-          x -= shift_x;
-          y -= shift_y;
+          x = champlain_view_longitude_to_x (view, point->lon);
+          y = champlain_view_latitude_to_y (view, point->lat);
 
           cairo_arc (cr, x, y, priv->stroke_width * 1.5, 0, 2 * M_PI);
           cairo_fill (cr);
diff --git a/champlain/champlain-polygon.h b/champlain/champlain-polygon.h
index e991a72..04f6cff 100644
--- a/champlain/champlain-polygon.h
+++ b/champlain/champlain-polygon.h
@@ -105,12 +105,7 @@ void champlain_polygon_show (ChamplainPolygon *polygon);
 void champlain_polygon_hide (ChamplainPolygon *polygon);
 
 void champlain_polygon_draw_polygon (ChamplainPolygon *polygon,
-    ChamplainMapSource *map_source,
-    guint zoom_level,
-    gfloat width,
-    gfloat height,
-    gfloat shift_x,
-    gfloat shift_y);
+    ChamplainView *view);
 
 G_END_DECLS
 
diff --git a/champlain/champlain-tile.c b/champlain/champlain-tile.c
index 395da01..355d635 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_POINTER);
+        1, G_TYPE_OBJECT);
 }
 
 
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index 83a4aaf..88843ce 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -207,12 +207,6 @@ struct _ChamplainViewPrivate
 
 G_DEFINE_TYPE (ChamplainView, champlain_view, CLUTTER_TYPE_GROUP);
 
-static gdouble viewport_get_current_longitude (ChamplainViewPrivate *priv);
-static gdouble viewport_get_current_latitude (ChamplainViewPrivate *priv);
-static gdouble viewport_get_longitude_at (ChamplainViewPrivate *priv,
-    gint x);
-static gdouble viewport_get_latitude_at (ChamplainViewPrivate *priv,
-    gint y);
 static gboolean scroll_event (ClutterActor *actor,
     ClutterScrollEvent *event,
     ChamplainView *view);
@@ -277,54 +271,6 @@ static gboolean fill_tile_cb (FillTileCallbackData *data);
 #define SCALE_INSIDE_PADDING 10
 #define SCALE_LINE_WIDTH 2
 
-static gdouble
-viewport_get_longitude_at (ChamplainViewPrivate *priv,
-    gint x)
-{
-  DEBUG_LOG ()
-
-  if (!priv->map_source)
-    return 0.0;
-
-  return champlain_map_source_get_longitude (priv->map_source,
-      priv->zoom_level, x);
-}
-
-
-static gdouble
-viewport_get_current_longitude (ChamplainViewPrivate *priv)
-{
-  DEBUG_LOG ()
-
-  return viewport_get_longitude_at (priv, priv->anchor.x +
-      priv->viewport_size.x + priv->viewport_size.width / 2.0);
-}
-
-
-static gdouble
-viewport_get_latitude_at (ChamplainViewPrivate *priv,
-    gint y)
-{
-  DEBUG_LOG ()
-
-  if (!priv->map_source)
-    return 0.0;
-
-  return champlain_map_source_get_latitude (priv->map_source,
-      priv->zoom_level, y);
-}
-
-
-static gdouble
-viewport_get_current_latitude (ChamplainViewPrivate *priv)
-{
-  DEBUG_LOG ()
-
-  return viewport_get_latitude_at (priv,
-      priv->anchor.y + priv->viewport_size.y +
-      priv->viewport_size.height / 2.0);
-}
-
 
 /* Updates the internals after the viewport changed */
 static void
@@ -364,12 +310,17 @@ update_viewport (ChamplainView *view,
   priv->viewport_size.y = y;
 
   view_load_visible_tiles (view);
-  marker_reposition (view);
+  g_signal_emit_by_name (view, "layer-relocated", NULL);
   update_scale (view);
   view_update_polygons (view);
 
-  priv->longitude = viewport_get_current_longitude (priv);
-  priv->latitude = viewport_get_current_latitude (priv);
+  priv->longitude = champlain_map_source_get_longitude (priv->map_source,
+      priv->zoom_level, 
+      priv->anchor.x + priv->viewport_size.x + priv->viewport_size.width / 2.0);
+
+  priv->latitude = champlain_map_source_get_latitude (priv->map_source,
+      priv->zoom_level,
+      priv->anchor.y + priv->viewport_size.y + priv->viewport_size.height / 2.0);
 
   g_object_notify (G_OBJECT (view), "longitude");
   g_object_notify (G_OBJECT (view), "latitude");
@@ -503,11 +454,7 @@ redraw_polygon_on_idle (PolygonRedrawContext *ctx)
   ChamplainViewPrivate *priv = ctx->view->priv;
 
   if (ctx->polygon)
-    champlain_polygon_draw_polygon (ctx->polygon,
-        priv->map_source, priv->zoom_level,
-        priv->viewport_size.width, priv->viewport_size.height,
-        priv->viewport_size.x + priv->anchor.x,
-        priv->viewport_size.y + priv->anchor.y);
+    champlain_polygon_draw_polygon (ctx->polygon, ctx->view);
 
   priv->polygon_redraw_id = 0;
 
@@ -546,7 +493,6 @@ resize_viewport (ChamplainView *view)
   DEBUG_LOG ()
 
   gdouble lower, upper;
-  gint i;
   TidyAdjustment *hadjust, *vadjust;
 
   ChamplainViewPrivate *priv = view->priv;
@@ -595,21 +541,6 @@ resize_viewport (ChamplainView *view)
 
   /* no more updates of TidyAdjustment, we can unblock the signal again */
   g_signal_handlers_unblock_by_func (priv->viewport, G_CALLBACK (viewport_pos_changed_cb), view);
-
-  /* Resize polygon actors */
-  if (priv->viewport_size.width == 0 ||
-      priv->viewport_size.height == 0)
-    return;
-
-  for (i = 0; i < clutter_group_get_n_children (CLUTTER_GROUP (priv->polygon_layer)); i++)
-    {
-      ChamplainPolygon *polygon = CHAMPLAIN_POLYGON (clutter_group_get_nth_child (CLUTTER_GROUP (priv->polygon_layer), i));
-
-      clutter_actor_set_position (CLUTTER_ACTOR (polygon), 0, 0);
-      champlain_polygon_draw_polygon (polygon, priv->map_source, priv->zoom_level,
-          priv->viewport_size.width, priv->viewport_size.height,
-          priv->viewport_size.x + priv->anchor.x, priv->viewport_size.y + priv->anchor.y);
-    }
 }
 
 
@@ -1328,12 +1259,12 @@ button_release_cb (G_GNUC_UNUSED ClutterActor *actor,
     {
       ClutterActor *actor = CLUTTER_ACTOR (clutter_group_get_nth_child (CLUTTER_GROUP (priv->user_layers), i));
 
-      if (actor && CHAMPLAIN_IS_SELECTION_LAYER (actor))
+      if (actor && CHAMPLAIN_IS_LAYER (actor))
         {
-          ChamplainSelectionLayer *layer = CHAMPLAIN_SELECTION_LAYER (actor);
-          if (champlain_selection_layer_count_selected_markers (layer) > 0)
+          ChamplainLayer *layer = CHAMPLAIN_LAYER (actor);
+          if (champlain_layer_get_selected_markers (layer) != NULL)
             {
-              champlain_selection_layer_unselect_all (layer);
+              champlain_layer_unselect_all (layer);
               found = TRUE;
             }
         }
@@ -1668,29 +1599,6 @@ viewport_pos_changed_cb (G_GNUC_UNUSED GObject *gobject,
 }
 
 
-/**
- * champlain_view_set_size:
- * @view: a #ChamplainView
- * @width: the width in pixels
- * @height: the height in pixels
- *
- * Sets the size of the view.  This function is deprecated and should not be used in new code
- * Use #clutter_actor_set_size instead.
- *
- * Since: 0.1
- */
-/* FIXME: move to an handler of actor size change */
-void
-champlain_view_set_size (ChamplainView *view,
-    guint width,
-    guint height)
-{
-  DEBUG_LOG ()
-
-  clutter_actor_set_size (CLUTTER_ACTOR (view), width, height);
-}
-
-
 static void
 update_license (ChamplainView *view)
 {
@@ -2312,21 +2220,12 @@ 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));
   clutter_actor_raise_top (CLUTTER_ACTOR (layer));
-
-  g_idle_add_full (G_PRIORITY_DEFAULT,
-      (GSourceFunc) marker_reposition,
-      g_object_ref (view),
-      (GDestroyNotify) g_object_unref);
-
-  g_signal_connect_after (layer, "actor-added",
-      G_CALLBACK (layer_add_marker_cb), view);
-
-  clutter_container_foreach (CLUTTER_CONTAINER (layer),
-      CLUTTER_CALLBACK (connect_marker_notify_cb), view);
 }
 
 
@@ -2422,55 +2321,144 @@ champlain_view_get_coords_from_event (ChamplainView *view,
       return FALSE;
     }
 
-  return champlain_view_get_coords_at (view, x, y, lat, lon);
+  *lon = champlain_view_x_to_longitude (view, x);
+  *lat = champlain_view_y_to_latitude (view, y);
+  
+  return TRUE;
 }
 
 
-/**
- * champlain_view_get_coords_at:
- * @view: a #ChamplainView
- * @x: the x position in the view
- * @y: the y position in the view
- * @lat: (out): a variable where to put the latitude of the event
- * @lon: (out): a variable where to put the longitude of the event
- *
- * Gets latitude and longitude for the given x, y position in
- * the view. Use if you get coordinates from GtkEvents for example.
- *
- * Returns: TRUE when successful.
- *
- * Since: 0.4
- */
-gboolean
-champlain_view_get_coords_at (ChamplainView *view,
-    guint x,
-    guint y,
-    gdouble *lat,
-    gdouble *lon)
+gdouble
+champlain_view_x_to_longitude (ChamplainView *view,
+    gdouble x)
 {
   DEBUG_LOG ()
 
-  g_return_val_if_fail (CHAMPLAIN_IS_VIEW (view), FALSE);
+  g_return_val_if_fail (CHAMPLAIN_IS_VIEW (view), 0.0);
+  
   ChamplainViewPrivate *priv = view->priv;
-  gfloat actor_x, actor_y;
-  gdouble rel_x, rel_y;
 
-  clutter_actor_get_transformed_position (priv->finger_scroll, &actor_x, &actor_y);
+  return champlain_view_layer_x_to_longitude (view, priv->viewport_size.x + x);
+}
 
-  rel_x = x - actor_x;
-  rel_y = y - actor_y;
 
-  if (lat)
-    *lat = viewport_get_latitude_at (priv,
-          priv->viewport_size.y + rel_y + priv->anchor.y);
-  if (lon)
-    *lon = viewport_get_longitude_at (priv,
-          priv->viewport_size.x + rel_x + priv->anchor.x);
+gdouble
+champlain_view_y_to_latitude (ChamplainView *view,
+    gdouble y)
+{
+  DEBUG_LOG ()
 
-  return TRUE;
+  g_return_val_if_fail (CHAMPLAIN_IS_VIEW (view), 0.0);
+  
+  ChamplainViewPrivate *priv = view->priv;
+
+  return champlain_view_layer_y_to_latitude (view, priv->viewport_size.y + y);
+}
+
+gdouble
+champlain_view_longitude_to_x (ChamplainView *view, 
+    gdouble longitude)
+{
+  DEBUG_LOG ()
+
+  g_return_val_if_fail (CHAMPLAIN_IS_VIEW (view), 0);
+
+  ChamplainViewPrivate *priv = view->priv;
+
+  return champlain_view_longitude_to_layer_x (view, longitude) - priv->viewport_size.x;
+}
+
+
+gdouble
+champlain_view_latitude_to_y (ChamplainView *view, 
+    gdouble latitude)
+{
+  DEBUG_LOG ()
+
+  g_return_val_if_fail (CHAMPLAIN_IS_VIEW (view), 0);
+
+  ChamplainViewPrivate *priv = view->priv;
+
+  return champlain_view_latitude_to_layer_y (view, latitude) - priv->viewport_size.y;
+}
+
+
+
+gdouble
+champlain_view_layer_x_to_longitude (ChamplainView *view,
+    gdouble x)
+{
+  DEBUG_LOG ()
+
+  g_return_val_if_fail (CHAMPLAIN_IS_VIEW (view), 0.0);
+  ChamplainViewPrivate *priv = view->priv;
+  
+  gdouble longitude;
+
+  longitude = champlain_map_source_get_longitude (priv->map_source,
+      priv->zoom_level, 
+      x + priv->anchor.x);
+
+  return longitude;
+}
+
+
+gdouble
+champlain_view_layer_y_to_latitude (ChamplainView *view,
+    gdouble y)
+{
+  DEBUG_LOG ()
+
+  g_return_val_if_fail (CHAMPLAIN_IS_VIEW (view), 0.0);
+  ChamplainViewPrivate *priv = view->priv;
+  
+  gdouble latitude;
+
+  latitude = champlain_map_source_get_longitude (priv->map_source,
+      priv->zoom_level, 
+      y + priv->anchor.y);
+
+  return latitude;
 }
 
 
+gdouble
+champlain_view_longitude_to_layer_x (ChamplainView *view, 
+    gdouble longitude)
+{
+  DEBUG_LOG ()
+
+  g_return_val_if_fail (CHAMPLAIN_IS_VIEW (view), 0);
+
+  ChamplainViewPrivate *priv = view->priv;
+  gdouble x;
+
+  x = champlain_map_source_get_x (priv->map_source, priv->zoom_level, longitude);
+  x -= priv->anchor.x;
+  
+  return x;
+}
+
+
+gdouble
+champlain_view_latitude_to_layer_y (ChamplainView *view, 
+    gdouble latitude)
+{
+  DEBUG_LOG ()
+
+  g_return_val_if_fail (CHAMPLAIN_IS_VIEW (view), 0);
+
+  ChamplainViewPrivate *priv = view->priv;
+  gdouble y;
+
+  y = champlain_map_source_get_y (priv->map_source, priv->zoom_level, latitude);
+  y -= priv->anchor.y;
+
+  return y;
+}
+
+
+
 static void
 view_load_visible_tiles (ChamplainView *view)
 {
@@ -3133,8 +3121,6 @@ view_set_zoom_level_at (ChamplainView *view,
 
   gdouble lon, lat;
   gint x_diff, y_diff;
-  gfloat actor_x, actor_y;
-  gdouble rel_x, rel_y;
   gfloat x2, y2;
   gdouble lat2, lon2;
 
@@ -3143,19 +3129,17 @@ view_set_zoom_level_at (ChamplainView *view,
 
   champlain_view_stop_go_to (view);
 
-  clutter_actor_get_transformed_position (priv->finger_scroll, &actor_x, &actor_y);
-  rel_x = x - actor_x;
-  rel_y = y - actor_y;
-
   /* Keep the lon, lat where the mouse is */
-  lon = viewport_get_longitude_at (priv,
-    priv->viewport_size.x + rel_x + priv->anchor.x);
-  lat = viewport_get_latitude_at (priv,
-    priv->viewport_size.y + rel_y + priv->anchor.y);
+  lon = champlain_map_source_get_longitude (priv->map_source,
+    priv->zoom_level, 
+    priv->viewport_size.x + x + priv->anchor.x);
+  lat = champlain_map_source_get_latitude (priv->map_source,
+      priv->zoom_level,
+      priv->viewport_size.y + y + priv->anchor.y);
 
   /* How far was it from the center of the viewport (in px) */
-  x_diff = priv->viewport_size.width / 2 - rel_x;
-  y_diff = priv->viewport_size.height / 2 - rel_y;
+  x_diff = priv->viewport_size.width / 2 - x;
+  y_diff = priv->viewport_size.height / 2 - y;
 
   priv->zoom_level = zoom_level;
 
@@ -3472,9 +3456,7 @@ view_update_polygons (ChamplainView *view)
     {
       ChamplainPolygon *polygon = CHAMPLAIN_POLYGON (clutter_group_get_nth_child (polygon_layer_group, i));
 
-      champlain_polygon_draw_polygon (polygon, priv->map_source, priv->zoom_level,
-          priv->viewport_size.width, priv->viewport_size.height,
-          priv->viewport_size.x + priv->anchor.x, priv->viewport_size.y + priv->anchor.y);
+      champlain_polygon_draw_polygon (polygon, view);
     }
 
   /* Position the layer in the viewport */
diff --git a/champlain/champlain-view.h b/champlain/champlain-view.h
index 88a031d..dc4f3d1 100644
--- a/champlain/champlain-view.h
+++ b/champlain/champlain-view.h
@@ -127,9 +127,6 @@ void champlain_view_ensure_markers_visible (ChamplainView *view,
 
 void champlain_view_set_map_source (ChamplainView *view,
     ChamplainMapSource *map_source);
-void champlain_view_set_size (ChamplainView *view,
-    guint width,
-    guint height);
 void champlain_view_set_decel_rate (ChamplainView *view,
     gdouble rate);
 void champlain_view_set_scroll_mode (ChamplainView *view,
@@ -159,11 +156,6 @@ gboolean champlain_view_get_coords_from_event (ChamplainView *view,
     gdouble *lat,
     gdouble *lon);
 
-gboolean champlain_view_get_coords_at (ChamplainView *view,
-    guint x,
-    guint y,
-    gdouble *lat,
-    gdouble *lon);
 
 gint champlain_view_get_zoom_level (ChamplainView *view);
 gint champlain_view_get_min_zoom_level (ChamplainView *view);
@@ -186,6 +178,28 @@ void champlain_view_remove_polygon (ChamplainView *view,
 
 void champlain_view_reload_tiles (ChamplainView *view);
 
+
+
+gdouble champlain_view_layer_x_to_longitude (ChamplainView *view,
+    gdouble x);
+gdouble champlain_view_layer_y_to_latitude (ChamplainView *view,
+    gdouble y);
+gdouble champlain_view_longitude_to_layer_x (ChamplainView *viev, 
+    gdouble longitude);
+gdouble champlain_view_latitude_to_layer_y (ChamplainView *viev, 
+    gdouble latitude);
+
+gdouble champlain_view_x_to_longitude (ChamplainView *view,
+    gdouble x);
+gdouble champlain_view_y_to_latitude (ChamplainView *view,
+    gdouble y);
+gdouble champlain_view_longitude_to_x (ChamplainView *view, 
+    gdouble longitude);
+gdouble champlain_view_latitude_to_y (ChamplainView *view, 
+    gdouble latitude);
+
+
+
 G_END_DECLS
 
 #endif
diff --git a/champlain/champlain.h b/champlain/champlain.h
index 2e11284..4acc6f0 100644
--- a/champlain/champlain.h
+++ b/champlain/champlain.h
@@ -30,7 +30,6 @@
 #include "champlain/champlain-version.h"
 
 #include "champlain/champlain-layer.h"
-#include "champlain/champlain-selection-layer.h"
 #include "champlain/champlain-point.h"
 #include "champlain/champlain-base-marker.h"
 #include "champlain/champlain-marker.h"
diff --git a/demos/animated-marker.c b/demos/animated-marker.c
index ebcbe72..a592bb0 100644
--- a/demos/animated-marker.c
+++ b/demos/animated-marker.c
@@ -135,7 +135,7 @@ main (int argc, char *argv[])
   clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
 
   /* Create the marker layer */
-  layer = champlain_layer_new ();
+  layer = champlain_layer_new_full (CHAMPLAIN_SELECTION_SINGLE);
   clutter_actor_show (CLUTTER_ACTOR (layer));
   champlain_view_add_layer (CHAMPLAIN_VIEW (actor), layer);
 
diff --git a/demos/markers.c b/demos/markers.c
index b3e4932..00bd1c1 100644
--- a/demos/markers.c
+++ b/demos/markers.c
@@ -45,9 +45,11 @@ create_marker_layer (G_GNUC_UNUSED ChamplainView *view)
 {
   ClutterActor *marker;
   ChamplainLayer *layer;
+  ClutterActor *layer_actor;
   ClutterColor orange = { 0xf3, 0x94, 0x07, 0xbb };
 
-  layer = champlain_selection_layer_new ();
+  layer = champlain_layer_new_full (CHAMPLAIN_SELECTION_SINGLE);
+  layer_actor = CLUTTER_ACTOR (layer);
 
   marker = champlain_marker_new_with_text ("Montréal\n<span size=\"xx-small\">Québec</span>",
         "Serif 14", NULL, NULL);
@@ -84,6 +86,6 @@ create_marker_layer (G_GNUC_UNUSED ChamplainView *view)
       -71.918907);
   champlain_layer_add_marker (layer, CHAMPLAIN_BASE_MARKER (marker));
 
-  champlain_layer_show (layer);
+  clutter_actor_show (layer_actor);
   return layer;
 }
diff --git a/demos/url-marker.c b/demos/url-marker.c
index 6fbbfb0..3440b10 100644
--- a/demos/url-marker.c
+++ b/demos/url-marker.c
@@ -256,7 +256,7 @@ main (int argc, char *argv[])
   clutter_container_add_actor (CLUTTER_CONTAINER (stage), view);
 
   /* Create the markers and marker layer */
-  layer = champlain_layer_new ();
+  layer = champlain_layer_new_full (CHAMPLAIN_SELECTION_SINGLE);
   champlain_view_add_layer (CHAMPLAIN_VIEW (view), layer);
   session = soup_session_async_new ();
   create_marker_from_url (layer, session, 48.218611, 17.146397,



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