From da9f4ffe8b38c5b7c4e4ff6d13e3b1b10f5e453f Mon Sep 17 00:00:00 2001 From: Pierre-Luc Beaudoin Date: Fri, 11 Sep 2009 17:14:12 -0400 Subject: [PATCH] Revert "Get rid of Anchor" This reverts commit 5eeadcfb6b6f3ad59881958c7b2cf18b964de438. --- champlain/champlain-view.c | 151 ++++++++++++++++++++++++++++++++----- 1 file changed, 132 insertions(+), 19 deletions(-) diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c index db092dc..6356bde 100644 --- a/champlain/champlain-view.c +++ b/champlain/champlain-view.c @@ -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; -- 2.39.5