From a345d0ef9c553debe7720f2a19d5b9c8552c7ca8 Mon Sep 17 00:00:00 2001 From: Pierre-Luc Beaudoin Date: Fri, 27 Feb 2009 22:51:49 +0200 Subject: [PATCH] GObjectify ChamplainZoomLevel --- champlain/champlain-map.c | 49 ++--- champlain/champlain-map.h | 4 +- champlain/champlain-tile.c | 13 +- champlain/champlain-view.c | 230 ++++++++++++----------- champlain/champlain-zoom-level.c | 306 ++++++++++++++++++++++++++++--- champlain/champlain-zoom-level.h | 65 +++++-- 6 files changed, 490 insertions(+), 177 deletions(-) diff --git a/champlain/champlain-map.c b/champlain/champlain-map.c index c7cb504..800a6b6 100644 --- a/champlain/champlain-map.c +++ b/champlain/champlain-map.c @@ -59,13 +59,18 @@ void map_load_level(Map *map, gint zoom_level) { if (map->previous_level) - zoom_level_free(map->previous_level); + g_object_unref (map->previous_level); map->previous_level = map->current_level; guint row_count = map->get_row_count(map, zoom_level); guint column_count = map->get_column_count(map, zoom_level); - map->current_level = zoom_level_new(zoom_level, row_count, column_count, map->tile_size); + map->current_level = champlain_zoom_level_new (); + g_object_set (G_OBJECT (map->current_level), + "zoom-level", zoom_level, + "width", row_count, + "height", column_count, + NULL); } void @@ -79,16 +84,19 @@ map_load_visible_tiles (Map *map, ChamplainRectangle viewport, gboolean offline) gint x_count = ceil((float)viewport.width / map->tile_size) + 1; gint y_count = ceil((float)viewport.height / map->tile_size) + 1; - gint x_first = (map->current_level->anchor.x + viewport.x) / map->tile_size; - gint y_first = (map->current_level->anchor.y + viewport.y) / map->tile_size; + ChamplainPoint anchor; //XXX + anchor.x = 0; + anchor.y = 0; + gint x_first = (anchor.x + viewport.x) / map->tile_size; + gint y_first = (anchor.y + viewport.y) / map->tile_size; x_count += x_first; y_count += y_first; - if(x_count > map->current_level->row_count) - x_count = map->current_level->row_count; - if(y_count > map->current_level->column_count) - y_count = map->current_level->column_count; + if(x_count > champlain_zoom_level_get_width (map->current_level)) + x_count = champlain_zoom_level_get_width (map->current_level); + if(y_count > champlain_zoom_level_get_height (map->current_level)) + y_count = champlain_zoom_level_get_height (map->current_level); DEBUG ("Range %d, %d to %d, %d", x_first, y_first, x_count, y_count); @@ -96,17 +104,14 @@ map_load_visible_tiles (Map *map, ChamplainRectangle viewport, gboolean offline) guint k; // Get rid of old tiles first - for (k = 0; k < map->current_level->tiles->len; k++) + for (k = 0; k < champlain_zoom_level_tile_count (map->current_level); k++) { - ChamplainTile *tile = g_ptr_array_index(map->current_level->tiles, k); + ChamplainTile *tile = champlain_zoom_level_get_nth_tile (map->current_level, k); gint tile_x = champlain_tile_get_x (tile); gint tile_y = champlain_tile_get_y (tile); if (tile_x < x_first || tile_x > x_count || tile_y < y_first || tile_y > y_count) - { - g_ptr_array_remove (map->current_level->tiles, tile); - g_object_unref (tile); - } + champlain_zoom_level_remove_tile (map->current_level, tile); } //Load new tiles if needed @@ -115,9 +120,9 @@ map_load_visible_tiles (Map *map, ChamplainRectangle viewport, gboolean offline) for (j = y_first; j < y_count; j++) { gboolean exist = FALSE; - for (k = 0; k < map->current_level->tiles->len && !exist; k++) + for (k = 0; k < champlain_zoom_level_tile_count (map->current_level) && !exist; k++) { - ChamplainTile *tile = g_ptr_array_index(map->current_level->tiles, k); + ChamplainTile *tile = champlain_zoom_level_get_nth_tile (map->current_level, k); gint tile_x = champlain_tile_get_x (tile); gint tile_y = champlain_tile_get_y (tile); @@ -127,9 +132,9 @@ map_load_visible_tiles (Map *map, ChamplainRectangle viewport, gboolean offline) if(!exist) { - DEBUG ("Loading tile %d, %d, %d", map->current_level->level, i, j); - ChamplainTile *tile = tile_load (map, map->current_level->level, i, j, offline); - g_ptr_array_add (map->current_level->tiles, tile); + DEBUG ("Loading tile %d, %d, %d", champlain_zoom_level_get_zoom_level (map->current_level), i, j); + ChamplainTile *tile = tile_load (map, champlain_zoom_level_get_zoom_level (map->current_level), i, j, offline); + champlain_zoom_level_add_tile (map->current_level, tile); } } } @@ -138,7 +143,7 @@ map_load_visible_tiles (Map *map, ChamplainRectangle viewport, gboolean offline) gboolean map_zoom_in (Map *map) { - guint new_level = map->current_level->level + 1; + guint new_level = champlain_zoom_level_get_zoom_level (map->current_level) + 1; if(new_level <= map->zoom_levels) { map_load_level(map, new_level); @@ -150,7 +155,7 @@ map_zoom_in (Map *map) gboolean map_zoom_out (Map *map) { - gint new_level = map->current_level->level - 1; + guint new_level = champlain_zoom_level_get_zoom_level (map->current_level) - 1; if(new_level >= 0) { map_load_level(map, new_level); @@ -162,7 +167,7 @@ map_zoom_out (Map *map) void map_free (Map *map) { - zoom_level_free(map->current_level); + g_object_unref (map->current_level); } gboolean diff --git a/champlain/champlain-map.h b/champlain/champlain-map.h index 2fea5d4..d8451e3 100644 --- a/champlain/champlain-map.h +++ b/champlain/champlain-map.h @@ -36,8 +36,8 @@ struct _Map const gchar *license_uri; int tile_size; - ZoomLevel *current_level; - ZoomLevel *previous_level; + ChamplainZoomLevel *current_level; + ChamplainZoomLevel *previous_level; guint (* get_row_count) (Map *map, guint zoom_level); guint (* get_column_count) (Map *map, guint zoom_level); diff --git a/champlain/champlain-tile.c b/champlain/champlain-tile.c index 2e6a3a8..5f83180 100644 --- a/champlain/champlain-tile.c +++ b/champlain/champlain-tile.c @@ -460,9 +460,12 @@ tile_set_position(Map* map, ChamplainTile* tile) g_object_get (G_OBJECT (tile), "actor", &actor, "x", &x, "y", &y, "size", &size, NULL); + ChamplainPoint anchor; //XXX + anchor.x = 0; + anchor.y = 0; clutter_actor_set_position (actor, - (x * size) - map->current_level->anchor.x, - (y * size) - map->current_level->anchor.y); + (x * size) - anchor.x, + (y * size) - anchor.y); clutter_actor_set_size (actor, size, size); //XXX Move elsewhere clutter_actor_show (actor); } @@ -487,7 +490,7 @@ create_error_tile(Map* map, ChamplainTile* tile) champlain_tile_set_actor (tile, actor); tile_set_position (map, tile); - clutter_container_add (CLUTTER_CONTAINER (map->current_level->group), actor, NULL); + clutter_container_add (CLUTTER_CONTAINER (champlain_zoom_level_get_actor (map->current_level)), actor, NULL); tile_setup_animation (tile); champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE); @@ -586,7 +589,7 @@ file_loaded_cb (SoupSession *session, tile_set_position (map, tile); - clutter_container_add (CLUTTER_CONTAINER (map->current_level->group), actor, NULL); + clutter_container_add (CLUTTER_CONTAINER (champlain_zoom_level_get_actor (map->current_level)), actor, NULL); tile_setup_animation (tile); champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE); @@ -624,7 +627,7 @@ tile_load (Map* map, gint zoom_level, gint x, gint y, gboolean offline) champlain_tile_set_actor (tile, actor); tile_set_position (map, tile); - clutter_container_add (CLUTTER_CONTAINER (map->current_level->group), actor, NULL); + clutter_container_add (CLUTTER_CONTAINER (champlain_zoom_level_get_actor (map->current_level)), actor, NULL); // Do not animate since it is local and fast } else if (!offline) diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c index 2623032..b98a5bc 100644 --- a/champlain/champlain-view.c +++ b/champlain/champlain-view.c @@ -99,8 +99,7 @@ struct _ChamplainViewPrivate ChamplainMapSource map_source; ChamplainScrollMode scroll_mode; - gint zoom_level; /* Only used when the zoom-level property is set before map - * is created */ + gint zoom_level; /* Represents the (lat, lon) at the center of the viewport */ gdouble longitude; @@ -157,11 +156,12 @@ static void license_set_position (ChamplainView *view); static gdouble viewport_get_longitude_at (ChamplainViewPrivate *priv, gint x) { + gint level; + if (!priv->map) return 0.0; - return priv->map->x_to_longitude (priv->map, x, - priv->map->current_level->level); + return priv->map->x_to_longitude (priv->map, x, priv->zoom_level); } static gdouble @@ -170,18 +170,22 @@ viewport_get_current_longitude (ChamplainViewPrivate *priv) if (!priv->map) return 0.0; - return viewport_get_longitude_at (priv, priv->map->current_level->anchor.x + + ChamplainPoint anchor; //XXX + anchor.x = 0; + anchor.y = 0; + return viewport_get_longitude_at (priv, anchor.x + priv->viewport_size.x + priv->viewport_size.width / 2.0); } static gdouble viewport_get_latitude_at (ChamplainViewPrivate *priv, gint y) { + gint level; + if (!priv->map) return 0.0; - return priv->map->y_to_latitude (priv->map, y, - priv->map->current_level->level); + return priv->map->y_to_latitude (priv->map, y, priv->zoom_level); } static gdouble @@ -190,8 +194,12 @@ viewport_get_current_latitude (ChamplainViewPrivate *priv) if (!priv->map) return 0.0; + ChamplainPoint anchor; //XXX + anchor.x = 0; + anchor.y = 0; + return viewport_get_latitude_at (priv, - priv->map->current_level->anchor.y + priv->viewport_size.y + + anchor.y + priv->viewport_size.y + priv->viewport_size.height / 2.0); } @@ -201,22 +209,27 @@ scroll_event (ClutterActor *actor, ChamplainView *view) { ChamplainViewPrivate *priv = GET_PRIVATE (view); - ClutterActor *group = priv->map->current_level->group; + + ClutterActor *group, *new_group; gboolean success = FALSE; gdouble lon, lat; gint x_diff, y_diff; gint actor_x, actor_y; gint rel_x, rel_y; + group = champlain_zoom_level_get_actor (priv->map->current_level); clutter_actor_get_transformed_position (priv->finger_scroll, &actor_x, &actor_y); rel_x = event->x - actor_x; rel_y = event->y - actor_y; /* Keep the lon, lat where the mouse is */ + ChamplainPoint anchor; //XXX + anchor.x = 0; + anchor.y = 0; lon = viewport_get_longitude_at (priv, - priv->viewport_size.x + rel_x + priv->map->current_level->anchor.x); + priv->viewport_size.x + rel_x + anchor.x); lat = viewport_get_latitude_at (priv, - priv->viewport_size.y + rel_y + priv->map->current_level->anchor.y); + priv->viewport_size.y + rel_y + anchor.y); /* How far was it from the center of the viewport (in px) */ x_diff = priv->viewport_size.width / 2 - rel_x; @@ -232,23 +245,22 @@ scroll_event (ClutterActor *actor, gint x2, y2; gdouble lat2, lon2; + priv->zoom_level = champlain_zoom_level_get_zoom_level (priv->map->current_level); + new_group = champlain_zoom_level_get_actor (priv->map->current_level); + /* Get the new x,y in the new zoom level */ - x2 = priv->map->longitude_to_x (priv->map, lon, - priv->map->current_level->level); - y2 = priv->map->latitude_to_y (priv->map, lat, - priv->map->current_level->level); + x2 = priv->map->longitude_to_x (priv->map, lon, priv->zoom_level); + y2 = priv->map->latitude_to_y (priv->map, lat, priv->zoom_level); /* Get the new lon,lat of these new x,y minus the distance from the * viewport center */ - lon2 = priv->map->x_to_longitude (priv->map, x2 + x_diff, - priv->map->current_level->level); - lat2 = priv->map->y_to_latitude (priv->map, y2 + y_diff, - priv->map->current_level->level); + lon2 = priv->map->x_to_longitude (priv->map, x2 + x_diff, priv->zoom_level); + lat2 = priv->map->y_to_latitude (priv->map, y2 + y_diff, priv->zoom_level); resize_viewport (view); clutter_container_remove_actor (CLUTTER_CONTAINER (priv->map_layer), group); clutter_container_add_actor (CLUTTER_CONTAINER (priv->map_layer), - priv->map->current_level->group); + new_group); champlain_view_center_on (view, lat2, lon2); g_object_notify (G_OBJECT (view), "zoom-level"); @@ -264,18 +276,20 @@ marker_reposition_cb (ChamplainMarker *marker, ChamplainViewPrivate *priv = GET_PRIVATE (view); ChamplainMarkerPrivate *marker_priv = CHAMPLAIN_MARKER_GET_PRIVATE (marker); + gint level; gint x, y; + ChamplainPoint anchor; //XXX + anchor.x = 0; + anchor.y = 0; if (priv->map) { - x = priv->map->longitude_to_x (priv->map, marker_priv->lon, - priv->map->current_level->level); - y = priv->map->latitude_to_y (priv->map, marker_priv->lat, - priv->map->current_level->level); + x = priv->map->longitude_to_x (priv->map, marker_priv->lon, priv->zoom_level); + y = priv->map->latitude_to_y (priv->map, marker_priv->lat, priv->zoom_level); clutter_actor_set_position (CLUTTER_ACTOR (marker), - x - priv->map->current_level->anchor.x, - y - priv->map->current_level->anchor.y); + x - anchor.x, + y - anchor.y); } } @@ -328,10 +342,12 @@ static void create_initial_map (ChamplainView *view) { ChamplainViewPrivate *priv = GET_PRIVATE (view); + ClutterActor *group; + priv->map = map_new (priv->map_source); map_load_level (priv->map, priv->zoom_level); - clutter_container_add_actor (CLUTTER_CONTAINER (priv->map_layer), - priv->map->current_level->group); + group = champlain_zoom_level_get_actor (priv->map->current_level); + clutter_container_add_actor (CLUTTER_CONTAINER (priv->map_layer), group); g_idle_add (marker_reposition, view); update_license (view); @@ -360,6 +376,7 @@ resize_viewport (ChamplainView *view) gdouble lower, upper; gboolean center = FALSE; TidyAdjustment *hadjust, *vadjust; + gint level; ChamplainViewPrivate *priv = GET_PRIVATE (view); @@ -372,14 +389,13 @@ resize_viewport (ChamplainView *view) clutter_actor_set_size (priv->finger_scroll, priv->viewport_size.width, priv->viewport_size.height); - tidy_scrollable_get_adjustments (TIDY_SCROLLABLE (priv->viewport), &hadjust, &vadjust); - if (priv->map->current_level->level < 8) + if (priv->zoom_level < 8) { lower = -priv->viewport_size.width / 2.0; - upper = zoom_level_get_width (priv->map->current_level) - + upper = champlain_zoom_level_get_width (priv->map->current_level)*256 - //XXX priv->viewport_size.width / 2.0; } else @@ -390,10 +406,10 @@ resize_viewport (ChamplainView *view) g_object_set (hadjust, "lower", lower, "upper", upper, "page-size", 1.0, "step-increment", 1.0, "elastic", TRUE, NULL); - if (priv->map->current_level->level < 8) + if (priv->zoom_level < 8) { lower = -priv->viewport_size.height / 2.0; - upper = zoom_level_get_height (priv->map->current_level) - + upper = champlain_zoom_level_get_height (priv->map->current_level)*256 - //XXX priv->viewport_size.height / 2.0; } else @@ -402,7 +418,7 @@ resize_viewport (ChamplainView *view) upper = G_MAXINT16; } g_object_set (vadjust, "lower", lower, "upper", upper, - "page-size", 1.0, "step-increment", 1.0, "elastic", TRUE, NULL); + "page-size", 1.0, "step-increment", 1.0, "elastic", TRUE, NULL); if (center) { @@ -428,17 +444,8 @@ champlain_view_get_property (GObject *object, g_value_set_double (value, viewport_get_current_latitude (priv)); break; case PROP_ZOOM_LEVEL: - { - if (priv->map) - { - g_value_set_int (value, priv->map->current_level->level); - } - else - { - g_value_set_int (value, 0); - } - break; - } + g_value_set_int (value, priv->zoom_level); + break; case PROP_MAP_SOURCE: g_value_set_int (value, priv->map_source); break; @@ -494,26 +501,23 @@ champlain_view_set_property (GObject *object, gint level = g_value_get_int (value); if (priv->map) { - if (level != priv->map->current_level->level) + if (level != priv->zoom_level) { - ClutterActor *group = priv->map->current_level->group; + priv->zoom_level = level; + ClutterActor *group = champlain_zoom_level_get_actor (priv->map->current_level); if (map_zoom_to (priv->map, level)) { + ClutterActor *new_group = champlain_zoom_level_get_actor (priv->map->current_level); resize_viewport (view); clutter_container_remove_actor ( CLUTTER_CONTAINER (priv->map_layer), group); clutter_container_add_actor ( - CLUTTER_CONTAINER (priv->map_layer), - priv->map->current_level->group); + CLUTTER_CONTAINER (priv->map_layer), new_group); champlain_view_center_on (view, priv->latitude, priv->longitude); } } } - else - { - priv->zoom_level = level; - } break; } case PROP_MAP_SOURCE: @@ -522,29 +526,31 @@ champlain_view_set_property (GObject *object, if (priv->map_source != source) { priv->map_source = source; - if (priv->map) { - guint currentLevel = priv->map->current_level->level; - map_free (priv->map); - priv->map = map_new (priv->map_source); - - /* Keep same zoom level if the new map supports it */ - if (currentLevel > priv->map->zoom_levels) - { - currentLevel = priv->map->zoom_levels; - g_object_notify (G_OBJECT (view), "zoom-level"); - } - - map_load_level (priv->map, currentLevel); - - map_load_visible_tiles (priv->map, priv->viewport_size, - priv->offline); - clutter_container_add_actor (CLUTTER_CONTAINER (priv->map_layer), - priv->map->current_level->group); - - update_license (view); - g_idle_add (marker_reposition, view); - champlain_view_center_on (view, priv->latitude, priv->longitude); - } + if (priv->map) + { + ClutterActor *group; + map_free (priv->map); + priv->map = map_new (priv->map_source); + + /* Keep same zoom level if the new map supports it */ + if (priv->zoom_level > priv->map->zoom_levels) + { + priv->zoom_level = priv->map->zoom_levels; + g_object_notify (G_OBJECT (view), "zoom-level"); + } + + map_load_level (priv->map, priv->zoom_level); + group = champlain_zoom_level_get_actor (priv->map->current_level); + + map_load_visible_tiles (priv->map, priv->viewport_size, + priv->offline); + clutter_container_add_actor (CLUTTER_CONTAINER (priv->map_layer), + group); + + update_license (view); + g_idle_add (marker_reposition, view); + champlain_view_center_on (view, priv->latitude, priv->longitude); + } } break; } @@ -743,6 +749,11 @@ champlain_view_init (ChamplainView *view) priv->license_actor = NULL; priv->stage = clutter_group_new (); priv->scroll_mode = CHAMPLAIN_SCROLL_MODE_PUSH; + priv->viewport_size.x = 0; + priv->viewport_size.y = 0; + priv->viewport_size.width = 0; + priv->viewport_size.height = 0; + /* Setup viewport */ priv->viewport = tidy_viewport_new (); @@ -810,6 +821,7 @@ viewport_x_changed_cb (GObject *gobject, g_object_notify (G_OBJECT (view), "latitude"); } +//FIXME: move to an handler of actor size change void champlain_view_set_size (ChamplainView *view, guint width, @@ -817,13 +829,8 @@ champlain_view_set_size (ChamplainView *view, { g_return_if_fail (CHAMPLAIN_IS_VIEW (view)); - gdouble lat, lon; - ChamplainViewPrivate *priv = GET_PRIVATE (view); - lat = priv->latitude; - lon = priv->longitude; - priv->viewport_size.width = width; priv->viewport_size.height = height; @@ -831,7 +838,7 @@ champlain_view_set_size (ChamplainView *view, resize_viewport (view); if (priv->keep_center_on_resize) - champlain_view_center_on (view, lat, lon); + champlain_view_center_on (view, priv->latitude, priv->longitude); else map_load_visible_tiles (priv->map, priv->viewport_size, priv->offline); } @@ -875,12 +882,15 @@ finger_scroll_button_press_cb (ClutterActor *actor, rel_x = event->x - actor_x; rel_y = event->y - actor_y; - ClutterActor *group = priv->map->current_level->group; + ClutterActor *group = champlain_zoom_level_get_actor (priv->map->current_level); /* Keep the lon, lat where the mouse is */ + ChamplainPoint anchor; //XXX + anchor.x = 0; + anchor.y = 0; gdouble lon = viewport_get_longitude_at (priv, - priv->viewport_size.x + rel_x + priv->map->current_level->anchor.x); - gdouble lat = viewport_get_latitude_at (priv, - priv->viewport_size.y + rel_y + priv->map->current_level->anchor.y); + priv->viewport_size.x + rel_x + anchor.x); + gdouble lat = viewport_get_latitude_at (priv, + priv->viewport_size.y + rel_y + anchor.y); /* How far was it from the center of the viewport (in px) */ gint x_diff = priv->viewport_size.width / 2 - rel_x; @@ -888,23 +898,25 @@ finger_scroll_button_press_cb (ClutterActor *actor, if (map_zoom_in (priv->map)) { + priv->zoom_level++; + ClutterActor *new_group = champlain_zoom_level_get_actor (priv->map->current_level); /* Get the new x,y in the new zoom level */ gint x2 = priv->map->longitude_to_x (priv->map, lon, - priv->map->current_level->level); + priv->zoom_level); gint y2 = priv->map->latitude_to_y (priv->map, lat, - priv->map->current_level->level); + priv->zoom_level); /* Get the new lon,lat of these new x,y minus the distance from the * viewport center */ gdouble lon2 = priv->map->x_to_longitude (priv->map, x2 + x_diff, - priv->map->current_level->level); + priv->zoom_level); gdouble lat2 = priv->map->y_to_latitude (priv->map, y2 + y_diff, - priv->map->current_level->level); + priv->zoom_level); resize_viewport (view); clutter_container_remove_actor (CLUTTER_CONTAINER (priv->map_layer), group); clutter_container_add_actor (CLUTTER_CONTAINER (priv->map_layer), - priv->map->current_level->group); + new_group); champlain_view_center_on (view, lat2, lon2); g_object_notify (G_OBJECT (view), "zoom-level"); @@ -954,13 +966,11 @@ champlain_view_center_on (ChamplainView *view, if (!priv->map) return; - x = priv->map->longitude_to_x (priv->map, longitude, - priv->map->current_level->level); - y = priv->map->latitude_to_y (priv->map, latitude, - priv->map->current_level->level); - ChamplainPoint* anchor = &priv->map->current_level->anchor; + x = priv->map->longitude_to_x (priv->map, longitude, priv->zoom_level); + y = priv->map->latitude_to_y (priv->map, latitude, priv->zoom_level); + ChamplainPoint* anchor = g_new0 (ChamplainPoint, 1); //XXX - if (priv->map->current_level->level >= 8) + if (priv->zoom_level >= 8) { gdouble max; @@ -972,7 +982,7 @@ champlain_view_center_on (ChamplainView *view, if ( anchor->y < 0 ) anchor->y = 0; - max = zoom_level_get_width (priv->map->current_level) - + max = champlain_zoom_level_get_width (priv->map->current_level)*256 - //XXX (G_MAXINT16 / 2); if (anchor->x > max) anchor->x = max; @@ -987,13 +997,14 @@ champlain_view_center_on (ChamplainView *view, anchor->x = 0; anchor->y = 0; } - - for (i = 0; i < priv->map->current_level->tiles->len; i++) +/* + for (i = 0; i < champlain_zoom_level_tile_count (priv->map->current_level); i++) { - ChamplainTile *tile = g_ptr_array_index (priv->map->current_level->tiles, i); + ChamplainTile *tile = champlain_zoom_level_get_nth_tile (priv->map->current_level, i); if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_DONE) tile_set_position (priv->map, tile); } +*/ tidy_viewport_set_origin (TIDY_VIEWPORT (priv->viewport), x - priv->viewport_size.width / 2.0, @@ -1021,15 +1032,16 @@ champlain_view_zoom_in (ChamplainView *view) g_return_if_fail (CHAMPLAIN_IS_VIEW (view)); ChamplainViewPrivate *priv = GET_PRIVATE (view); - ClutterActor *group = priv->map->current_level->group; + ClutterActor *group = champlain_zoom_level_get_actor (priv->map->current_level); if (map_zoom_in (priv->map)) { + priv->zoom_level++; resize_viewport (view); clutter_container_remove_actor (CLUTTER_CONTAINER (priv->map_layer), group); clutter_container_add_actor (CLUTTER_CONTAINER (priv->map_layer), - priv->map->current_level->group); + champlain_zoom_level_get_actor (priv->map->current_level)); champlain_view_center_on (view, priv->latitude, priv->longitude); g_object_notify (G_OBJECT (view), "zoom-level"); @@ -1050,15 +1062,16 @@ champlain_view_zoom_out (ChamplainView *view) g_return_if_fail (CHAMPLAIN_IS_VIEW (view)); ChamplainViewPrivate *priv = GET_PRIVATE (view); - ClutterActor *group = priv->map->current_level->group; + ClutterActor *group = champlain_zoom_level_get_actor (priv->map->current_level); if (map_zoom_out (priv->map)) { + priv->zoom_level--; resize_viewport (view); clutter_container_remove_actor (CLUTTER_CONTAINER (priv->map_layer), group); clutter_container_add_actor (CLUTTER_CONTAINER (priv->map_layer), - priv->map->current_level->group); + champlain_zoom_level_get_actor (priv->map->current_level)); champlain_view_center_on (view, priv->latitude, priv->longitude); g_object_notify (G_OBJECT (view), "zoom-level"); @@ -1163,12 +1176,15 @@ champlain_view_get_coords_from_event (ChamplainView *view, rel_x = x - actor_x; rel_y = y - actor_y; + ChamplainPoint anchor; //XXX + anchor.x = 0; + anchor.y = 0; if (latitude) *latitude = viewport_get_latitude_at (priv, - priv->viewport_size.y + rel_y + priv->map->current_level->anchor.y); + priv->viewport_size.y + rel_y + anchor.y); if (longitude) *longitude = viewport_get_longitude_at (priv, - priv->viewport_size.x + rel_x + priv->map->current_level->anchor.x); + priv->viewport_size.x + rel_x + anchor.x); return TRUE; } diff --git a/champlain/champlain-zoom-level.c b/champlain/champlain-zoom-level.c index 3da8d06..0f346a9 100644 --- a/champlain/champlain-zoom-level.c +++ b/champlain/champlain-zoom-level.c @@ -23,47 +23,303 @@ #include -ZoomLevel* -zoom_level_new(gint zoom_level, gint row, gint column, gint tile_size) +G_DEFINE_TYPE (ChamplainZoomLevel, champlain_zoom_level, G_TYPE_OBJECT) + +#define GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), CHAMPLAIN_TYPE_ZOOM_LEVEL, ChamplainZoomLevelPrivate)) + +enum { - ZoomLevel *level = g_new0(ZoomLevel, 1); + /* normal signals */ + SIGNAL_TILE_ADDED, + SIGNAL_TILE_REMOVED, + LAST_SIGNAL +}; - level->level = zoom_level; - level->row_count = row; - level->column_count = column; - level->tile_size = tile_size; +static guint signals[LAST_SIGNAL]; - //FIXME: this hard coded value means that there can't be more than 16x16 tiles displayed at once - level->tiles = g_ptr_array_sized_new (256); - level->group = clutter_group_new (); +enum +{ + PROP_0, + PROP_WIDTH, + PROP_HEIGHT, + PROP_ZOOM_LEVEL, + PROP_ACTOR +}; - g_object_ref(level->group); // so that the group isn't destroyed when removed from the viewport +typedef struct _ChamplainZoomLevelPrivate ChamplainZoomLevelPrivate; - level->anchor.x = 0; - level->anchor.y = 0; +struct _ChamplainZoomLevelPrivate { + guint width; + guint height; + gint zoom_level; + GPtrArray *tiles; + ClutterActor *actor; +}; - return level; +static void +champlain_zoom_level_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + ChamplainZoomLevel *self = CHAMPLAIN_ZOOM_LEVEL (object); + switch (property_id) + { + case PROP_WIDTH: + g_value_set_uint (value, champlain_zoom_level_get_width (self)); + break; + case PROP_HEIGHT: + g_value_set_uint (value, champlain_zoom_level_get_height (self)); + break; + case PROP_ZOOM_LEVEL: + g_value_set_int (value, champlain_zoom_level_get_zoom_level (self)); + break; + case PROP_ACTOR: + g_value_set_object (value, champlain_zoom_level_get_actor (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } } -void -zoom_level_free(ZoomLevel *level) +static void +champlain_zoom_level_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - guint i; - for (i = 0; i < level->tiles->len; i++) + ChamplainZoomLevel *self = CHAMPLAIN_ZOOM_LEVEL (object); + switch (property_id) { - ChamplainTile *tile = g_ptr_array_index(level->tiles, i); - g_object_unref (tile); + case PROP_WIDTH: + champlain_zoom_level_set_width (self, g_value_get_uint (value)); + break; + case PROP_HEIGHT: + champlain_zoom_level_set_height (self, g_value_get_uint (value)); + break; + case PROP_ZOOM_LEVEL: + champlain_zoom_level_set_zoom_level (self, g_value_get_int (value)); + break; + case PROP_ACTOR: + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } -guint -zoom_level_get_width(ZoomLevel *level) +static void +champlain_zoom_level_dispose (GObject *object) +{ + //FIXME: Get rid of tiles here? + ChamplainZoomLevelPrivate *priv = GET_PRIVATE (object); + + g_object_unref (priv->actor); + + G_OBJECT_CLASS (champlain_zoom_level_parent_class)->dispose (object); +} + +static void +champlain_zoom_level_finalize (GObject *object) +{ + G_OBJECT_CLASS (champlain_zoom_level_parent_class)->finalize (object); +} + +static void +champlain_zoom_level_class_init (ChamplainZoomLevelClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (ChamplainZoomLevelPrivate)); + + object_class->get_property = champlain_zoom_level_get_property; + object_class->set_property = champlain_zoom_level_set_property; + object_class->dispose = champlain_zoom_level_dispose; + object_class->finalize = champlain_zoom_level_finalize; + + signals[SIGNAL_TILE_ADDED] = + g_signal_new ("tile-added", G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, CHAMPLAIN_TYPE_TILE); + + signals[SIGNAL_TILE_REMOVED] = + g_signal_new ("tile-removed", G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, CHAMPLAIN_TYPE_TILE); + + g_object_class_install_property (object_class, + PROP_WIDTH, + g_param_spec_uint ("width", + "Width", + "The width of this zoom level", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_HEIGHT, + g_param_spec_uint ("height", + "height", + "The height of this zoom level", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_ZOOM_LEVEL, + g_param_spec_int ("zoom-level", + "zoom-level", + "The level of this zoom level", + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_ACTOR, + g_param_spec_object ("actor", + "Actor", + "The actor containing all the tiles", + CLUTTER_TYPE_ACTOR, + G_PARAM_READABLE)); +} + +static void +champlain_zoom_level_init (ChamplainZoomLevel *self) +{ + ChamplainZoomLevelPrivate *priv = GET_PRIVATE (self); + + priv->tiles = g_ptr_array_sized_new (64); + priv->actor = g_object_ref (clutter_group_new ()); +} + +ChamplainZoomLevel* +champlain_zoom_level_new (void) { - return (level->column_count) * level->tile_size; + return g_object_new (CHAMPLAIN_TYPE_ZOOM_LEVEL, NULL); +} + +void +champlain_zoom_level_add_tile (ChamplainZoomLevel *self, + ChamplainTile *tile) +{ + g_return_if_fail (CHAMPLAIN_ZOOM_LEVEL (self)); + + ChamplainZoomLevelPrivate *priv = GET_PRIVATE (self); + + g_ptr_array_add (priv->tiles, tile); + g_signal_emit (self, signals[SIGNAL_TILE_ADDED], 0, tile); +} + +void +champlain_zoom_level_remove_tile (ChamplainZoomLevel *self, + ChamplainTile *tile) +{ + g_return_if_fail (CHAMPLAIN_ZOOM_LEVEL (self)); + + ChamplainZoomLevelPrivate *priv = GET_PRIVATE (self); + + g_signal_emit (self, signals[SIGNAL_TILE_REMOVED], 0, tile); + g_ptr_array_remove_fast (priv->tiles, tile); } guint -zoom_level_get_height(ZoomLevel *level) +champlain_zoom_level_tile_count (ChamplainZoomLevel *self) { - return (level->row_count) * level->tile_size; + g_return_val_if_fail (CHAMPLAIN_ZOOM_LEVEL (self), 0); + + ChamplainZoomLevelPrivate *priv = GET_PRIVATE (self); + + return priv->tiles->len; +} + +ChamplainTile * +champlain_zoom_level_get_nth_tile (ChamplainZoomLevel *self, + guint index) +{ + g_return_val_if_fail (CHAMPLAIN_ZOOM_LEVEL (self), NULL); + + ChamplainZoomLevelPrivate *priv = GET_PRIVATE (self); + + return g_ptr_array_index (priv->tiles, index); +} + +gint +champlain_zoom_level_get_width (ChamplainZoomLevel *self) +{ + + g_return_val_if_fail (CHAMPLAIN_ZOOM_LEVEL (self), 0); + + ChamplainZoomLevelPrivate *priv = GET_PRIVATE (self); + + return priv->width; +} + +gint +champlain_zoom_level_get_height (ChamplainZoomLevel *self) +{ + g_return_val_if_fail (CHAMPLAIN_ZOOM_LEVEL (self), 0); + + ChamplainZoomLevelPrivate *priv = GET_PRIVATE (self); + + return priv->height; +} + +gint +champlain_zoom_level_get_zoom_level (ChamplainZoomLevel *self) +{ + g_return_val_if_fail (CHAMPLAIN_ZOOM_LEVEL (self), 0); + + ChamplainZoomLevelPrivate *priv = GET_PRIVATE (self); + + return priv->zoom_level; +} + +void +champlain_zoom_level_set_width (ChamplainZoomLevel *self, + guint width) +{ + g_return_if_fail (CHAMPLAIN_ZOOM_LEVEL (self)); + + ChamplainZoomLevelPrivate *priv = GET_PRIVATE (self); + + priv->width = width; + g_object_notify (G_OBJECT (self), "width"); +} + +void +champlain_zoom_level_set_height (ChamplainZoomLevel *self, + guint height) +{ + g_return_if_fail (CHAMPLAIN_ZOOM_LEVEL (self)); + + ChamplainZoomLevelPrivate *priv = GET_PRIVATE (self); + + priv->height = height; + g_object_notify (G_OBJECT (self), "height"); + +} + +void +champlain_zoom_level_set_zoom_level (ChamplainZoomLevel *self, + gint zoom_level) +{ + g_return_if_fail (CHAMPLAIN_ZOOM_LEVEL (self)); + + ChamplainZoomLevelPrivate *priv = GET_PRIVATE (self); + + priv->zoom_level = zoom_level; + g_object_notify (G_OBJECT (self), "zoom-level"); + +} + +ClutterActor * +champlain_zoom_level_get_actor (ChamplainZoomLevel *self) +{ + g_return_if_fail (CHAMPLAIN_ZOOM_LEVEL (self)); + + ChamplainZoomLevelPrivate *priv = GET_PRIVATE (self); + + return priv->actor; } diff --git a/champlain/champlain-zoom-level.h b/champlain/champlain-zoom-level.h index 75bee95..032e0d9 100644 --- a/champlain/champlain-zoom-level.h +++ b/champlain/champlain-zoom-level.h @@ -16,33 +16,66 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef CHAMPLAIN_MAP_ZOOM_LEVEL_H -#define CHAMPLAIN_MAP_ZOOM_LEVEL_H +#ifndef CHAMPLAIN_ZOOM_LEVEL_H +#define CHAMPLAIN_ZOOM_LEVEL_H #include "champlain-private.h" +#include "champlain-tile.h" #include #include -typedef struct -{ - int level; - int row_count; - int column_count; - int tile_size; +G_BEGIN_DECLS - GPtrArray *tiles; - ClutterActor* group; +#define CHAMPLAIN_TYPE_ZOOM_LEVEL champlain_zoom_level_get_type() - ChamplainPoint anchor; -} ZoomLevel; +#define CHAMPLAIN_ZOOM_LEVEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), CHAMPLAIN_TYPE_ZOOM_LEVEL, ChamplainZoomLevel)) -guint zoom_level_get_width(ZoomLevel *level); +#define CHAMPLAIN_ZOOM_LEVEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), CHAMPLAIN_TYPE_ZOOM_LEVEL, ChamplainZoomLevelClass)) -guint zoom_level_get_height(ZoomLevel *level); +#define CHAMPLAIN_IS_ZOOM_LEVEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CHAMPLAIN_TYPE_ZOOM_LEVEL)) -ZoomLevel* zoom_level_new(gint zoom_level, gint row, gint column, gint tile_size); +#define CHAMPLAIN_IS_ZOOM_LEVEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), CHAMPLAIN_TYPE_ZOOM_LEVEL)) -void zoom_level_free(ZoomLevel *level); +#define CHAMPLAIN_ZOOM_LEVEL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), CHAMPLAIN_TYPE_ZOOM_LEVEL, ChamplainZoomLevelClass)) + +typedef struct { + GObject parent; +} ChamplainZoomLevel; + +typedef struct { + GObjectClass parent_class; +} ChamplainZoomLevelClass; + +GType champlain_zoom_level_get_type (void); + +ChamplainZoomLevel* champlain_zoom_level_new (void); + +gint champlain_zoom_level_get_width (ChamplainZoomLevel *self); +gint champlain_zoom_level_get_height (ChamplainZoomLevel *self); +gint champlain_zoom_level_get_zoom_level (ChamplainZoomLevel *self); +ClutterActor* champlain_zoom_level_get_actor (ChamplainZoomLevel *self); + +void champlain_zoom_level_set_width (ChamplainZoomLevel *self, guint width); +void champlain_zoom_level_set_height (ChamplainZoomLevel *self, guint height); +void champlain_zoom_level_set_zoom_level (ChamplainZoomLevel *self, + gint zoom_level); +void champlain_zoom_level_set_actor (ChamplainZoomLevel *self, + ClutterActor *actor); + +void champlain_zoom_level_add_tile (ChamplainZoomLevel *self, + ChamplainTile *tile); +void champlain_zoom_level_remove_tile (ChamplainZoomLevel *self, + ChamplainTile *tile); +guint champlain_zoom_level_tile_count (ChamplainZoomLevel *self); +ChamplainTile* champlain_zoom_level_get_nth_tile (ChamplainZoomLevel *self, + guint index); + +G_END_DECLS #endif -- 2.39.5