]> err.no Git - libchamplain/commitdiff
Revert "Get rid of Anchor"
authorPierre-Luc Beaudoin <pierre-luc@pierlux.com>
Fri, 11 Sep 2009 21:14:12 +0000 (17:14 -0400)
committerPierre-Luc Beaudoin <pierre-luc@pierlux.com>
Fri, 11 Sep 2009 21:14:12 +0000 (17:14 -0400)
This reverts commit 5eeadcfb6b6f3ad59881958c7b2cf18b964de438.

champlain/champlain-view.c

index db092dc409870244e13ff6fe89be2d117acfd4b6..6356bde7cdab719661c5c1933428fb9e6ab688a1 100644 (file)
@@ -134,6 +134,12 @@ struct _ChamplainViewPrivate
   gdouble longitude;
   gdouble latitude;
 
+  /* Hack to get smaller x,y coordinates as the clutter limit is G_MAXINT16 */
+  ChamplainFloatPoint anchor;
+
+  gdouble anchor_zoom_level; /* the zoom_level for which the current anchor has
+                                been computed for */
+
   Map *map; /* Contains the current map model */
 
   ClutterActor *finger_scroll; /* Contains the viewport */
@@ -200,6 +206,7 @@ static void view_load_visible_tiles (ChamplainView *view);
 static void view_position_tile (ChamplainView* view, ChamplainTile* tile);
 static void view_tiles_reposition (ChamplainView* view);
 static void view_update_state (ChamplainView *view);
+static void view_update_anchor (ChamplainView *view, gint x, gint y);
 static gboolean view_set_zoom_level_at (ChamplainView *view,
     gint zoom_level,
     gint x,
@@ -232,7 +239,7 @@ viewport_get_current_longitude (ChamplainViewPrivate *priv)
   if (!priv->map)
     return 0.0;
 
-  return viewport_get_longitude_at (priv,
+  return viewport_get_longitude_at (priv, priv->anchor.x +
       priv->viewport_size.x + priv->viewport_size.width / 2.0);
 }
 
@@ -253,7 +260,8 @@ viewport_get_current_latitude (ChamplainViewPrivate *priv)
     return 0.0;
 
   return viewport_get_latitude_at (priv,
-      priv->viewport_size.y + priv->viewport_size.height / 2.0);
+      priv->anchor.y + priv->viewport_size.y +
+      priv->viewport_size.height / 2.0);
 }
 
 static gboolean
@@ -287,7 +295,9 @@ marker_reposition_cb (ChamplainMarker *marker,
       x = champlain_map_source_get_x (priv->map_source, priv->zoom_level, marker_priv->lon);
       y = champlain_map_source_get_y (priv->map_source, priv->zoom_level, marker_priv->lat);
 
-      clutter_actor_set_position (CLUTTER_ACTOR (marker), x, y);
+      clutter_actor_set_position (CLUTTER_ACTOR (marker),
+        x - priv->anchor.x,
+        y - priv->anchor.y);
     }
 }
 
@@ -477,17 +487,33 @@ resize_viewport (ChamplainView *view)
   tidy_scrollable_get_adjustments (TIDY_SCROLLABLE (priv->viewport), &hadjust,
       &vadjust);
 
-  lower = -priv->viewport_size.width / 2.0;
-  upper = champlain_zoom_level_get_width (priv->map->current_level) *
-      champlain_map_source_get_tile_size (priv->map_source) -
-      priv->viewport_size.width / 2.0;
+  if (priv->zoom_level < 8)
+    {
+      lower = -priv->viewport_size.width / 2.0;
+      upper = champlain_zoom_level_get_width (priv->map->current_level) *
+          champlain_map_source_get_tile_size (priv->map_source) -
+          priv->viewport_size.width / 2.0;
+    }
+  else
+    {
+      lower = 0;
+      upper = G_MAXINT16;
+    }
   g_object_set (hadjust, "lower", lower, "upper", upper,
       "page-size", 1.0, "step-increment", 1.0, "elastic", TRUE, NULL);
 
-  lower = -priv->viewport_size.height / 2.0;
-  upper = champlain_zoom_level_get_height (priv->map->current_level) *
-      champlain_map_source_get_tile_size (priv->map_source) -
-      priv->viewport_size.height / 2.0;
+  if (priv->zoom_level < 8)
+    {
+      lower = -priv->viewport_size.height / 2.0;
+      upper = champlain_zoom_level_get_height (priv->map->current_level) *
+          champlain_map_source_get_tile_size (priv->map_source) -
+          priv->viewport_size.height / 2.0;
+    }
+  else
+    {
+      lower = 0;
+      upper = G_MAXINT16;
+    }
   g_object_set (vadjust, "lower", lower, "upper", upper,
       "page-size", 1.0, "step-increment", 1.0, "elastic", TRUE, NULL);
 
@@ -962,6 +988,9 @@ champlain_view_init (ChamplainView *view)
   priv->viewport_size.y = 0;
   priv->viewport_size.width = 0;
   priv->viewport_size.height = 0;
+  priv->anchor.x = 0;
+  priv->anchor.y = 0;
+  priv->anchor_zoom_level = 0;
   priv->state = CHAMPLAIN_STATE_INIT;
   priv->latitude = 0.0f;
   priv->longitude = 0.0f;
@@ -1040,6 +1069,7 @@ viewport_pos_changed_cb (GObject *gobject,
   ChamplainViewPrivate *priv = view->priv;
 
   ChamplainFloatPoint rect;
+  ChamplainFloatPoint old_anchor;
 
   tidy_viewport_get_origin (TIDY_VIEWPORT (priv->viewport), &rect.x, &rect.y,
       NULL);
@@ -1048,6 +1078,26 @@ viewport_pos_changed_cb (GObject *gobject,
       rect.y == priv->viewport_size.y)
       return;
 
+  old_anchor.x = priv->anchor.x;
+  old_anchor.y = priv->anchor.y;
+
+  view_update_anchor (view,
+      rect.x + priv->anchor.x + priv->viewport_size.width / 2.0,
+      rect.y + priv->anchor.y + priv->viewport_size.height / 2.0);
+
+  if (priv->anchor.x - old_anchor.x != 0)
+    {
+      ChamplainFloatPoint diff;
+
+      diff.x = priv->anchor.x - old_anchor.x;
+      diff.y = priv->anchor.y - old_anchor.y;
+
+      DEBUG("Relocating the viewport by %f, %f", diff.x, diff.y);
+      tidy_viewport_set_origin (TIDY_VIEWPORT (priv->viewport),
+          rect.x - diff.x, rect.y - diff.y, 0);
+      return;
+    }
+
   priv->viewport_size.x = rect.x;
   priv->viewport_size.y = rect.y;
 
@@ -1267,6 +1317,55 @@ champlain_view_new (void)
   return g_object_new (CHAMPLAIN_TYPE_VIEW, NULL);
 }
 
+static void
+view_update_anchor (ChamplainView *view,
+    gint x,
+    gint y)
+{
+  ChamplainViewPrivate *priv = view->priv;
+  gboolean need_anchor = FALSE;
+  gboolean need_update = FALSE;
+
+  if (priv->zoom_level >= 8)
+    need_anchor = TRUE;
+
+  if (priv->anchor_zoom_level != priv->zoom_level ||
+      x - priv->anchor.x + priv->viewport_size.width >= G_MAXINT16 ||
+      y - priv->anchor.y + priv->viewport_size.height >= G_MAXINT16)
+    need_update = TRUE;
+
+  if (need_anchor && need_update)
+    {
+      gdouble max;
+
+      priv->anchor.x = x - G_MAXINT16 / 2;
+      priv->anchor.y = y - G_MAXINT16 / 2;
+
+      if ( priv->anchor.x < 0 )
+        priv->anchor.x = 0;
+      if ( priv->anchor.y < 0 )
+        priv->anchor.y = 0;
+
+      max = champlain_zoom_level_get_width (priv->map->current_level) *
+          champlain_map_source_get_tile_size (priv->map_source) -
+          (G_MAXINT16 / 2);
+      if (priv->anchor.x > max)
+        priv->anchor.x = max;
+      if (priv->anchor.y > max)
+        priv->anchor.y = max;
+
+      priv->anchor_zoom_level = priv->zoom_level;
+    }
+
+  if (need_anchor == FALSE)
+    {
+      priv->anchor.x = 0;
+      priv->anchor.y = 0;
+      priv->anchor_zoom_level = priv->zoom_level;
+    }
+  DEBUG ("New Anchor (%f, %f) for (%d, %d)", priv->anchor.x, priv->anchor.y, x, y);
+}
+
 /**
  * champlain_view_center_on:
  * @view: a #ChamplainView
@@ -1298,6 +1397,11 @@ champlain_view_center_on (ChamplainView *view,
   x = champlain_map_source_get_x (priv->map_source, priv->zoom_level, longitude);
   y = champlain_map_source_get_y (priv->map_source, priv->zoom_level, latitude);
 
+  view_update_anchor (view, x, y);
+
+  x -= priv->anchor.x;
+  y -= priv->anchor.y;
+
   tidy_viewport_set_origin (TIDY_VIEWPORT (priv->viewport),
     x - priv->viewport_size.width / 2.0,
     y - priv->viewport_size.height / 2.0,
@@ -1703,10 +1807,10 @@ gboolean champlain_view_get_coords_at (ChamplainView *view,
 
   if (latitude)
     *latitude = viewport_get_latitude_at (priv,
-        priv->viewport_size.y + rel_y);
+        priv->viewport_size.y + rel_y + priv->anchor.y);
   if (longitude)
     *longitude = viewport_get_longitude_at (priv,
-        priv->viewport_size.x + rel_x);
+        priv->viewport_size.x + rel_x + priv->anchor.x);
 
   return TRUE;
 }
@@ -1719,6 +1823,9 @@ view_load_visible_tiles (ChamplainView *view)
   gint size;
   ChamplainZoomLevel *level;
 
+  viewport.x += priv->anchor.x;
+  viewport.y += priv->anchor.y;
+
   size = champlain_map_source_get_tile_size (priv->map_source);
   level = priv->map->current_level;
 
@@ -1803,8 +1910,7 @@ view_load_visible_tiles (ChamplainView *view)
             {
               DEBUG ("Loading tile %d, %d, %d", champlain_zoom_level_get_zoom_level (level), i, j);
               ChamplainTile *tile = champlain_tile_new ();
-              g_object_set (G_OBJECT (tile), "x", i, "y", j, "zoom-level",
-                  champlain_zoom_level_get_zoom_level (level), NULL);
+              g_object_set (G_OBJECT (tile), "x", i, "y", j, "zoom-level", champlain_zoom_level_get_zoom_level (level), NULL);
 
               g_signal_connect (tile, "notify::state", G_CALLBACK (tile_state_notify), view);
               clutter_container_add (CLUTTER_CONTAINER (champlain_zoom_level_get_actor (level)),
@@ -1824,17 +1930,25 @@ static void
 view_position_tile (ChamplainView* view,
     ChamplainTile* tile)
 {
+  ChamplainViewPrivate *priv = view->priv;
+
   ClutterActor *actor;
   gint x;
   gint y;
   guint size;
 
   actor = champlain_tile_get_actor (tile);
+
+  if (actor == NULL)
+    return;
+
   x = champlain_tile_get_x (tile);
   y = champlain_tile_get_y (tile);
   size = champlain_tile_get_size (tile);
 
-  clutter_actor_set_position (actor, (x * size), (y * size));
+  clutter_actor_set_position (actor,
+    (x * size) - priv->anchor.x,
+    (y * size) - priv->anchor.y);
 }
 
 static void
@@ -1842,7 +1956,6 @@ view_tiles_reposition (ChamplainView* view)
 {
   ChamplainViewPrivate *priv = view->priv;
   gint i;
-  return;
 
   for (i = 0; i < champlain_zoom_level_tile_count (priv->map->current_level); i++)
     {
@@ -2230,9 +2343,9 @@ view_set_zoom_level_at (ChamplainView *view,
 
   /* Keep the lon, lat where the mouse is */
   lon = viewport_get_longitude_at (priv,
-    priv->viewport_size.x + rel_x);
+    priv->viewport_size.x + rel_x + priv->anchor.x);
   lat = viewport_get_latitude_at (priv,
-    priv->viewport_size.y + rel_y);
+    priv->viewport_size.y + rel_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;