From a30b8f070e3eac05bed14a7396a497b22e56d5d3 Mon Sep 17 00:00:00 2001 From: Pierre-Luc Beaudoin Date: Sun, 15 Feb 2009 21:07:59 +0200 Subject: [PATCH] GObject-ify ChamplainTile As ChamplainTile will be publicly visible for custom map sources, it needs to be a Gobject. --- champlain/champlain-map.c | 23 +- champlain/champlain-map.h | 4 +- champlain/champlain-private.h | 1 - champlain/champlain-tile.c | 542 +++++++++++++++++++++++++++---- champlain/champlain-tile.h | 65 +++- champlain/champlain-view.c | 8 +- champlain/champlain-zoom-level.c | 4 +- champlain/sources/mffrelief.c | 18 +- champlain/sources/oam.c | 18 +- champlain/sources/osmmapnik.c | 18 +- 10 files changed, 587 insertions(+), 114 deletions(-) diff --git a/champlain/champlain-map.c b/champlain/champlain-map.c index 7a7505c..c7cb504 100644 --- a/champlain/champlain-map.c +++ b/champlain/champlain-map.c @@ -18,6 +18,8 @@ #include "champlain-map.h" +#define DEBUG_FLAG CHAMPLAIN_DEBUG_LOADING +#include "champlain-debug.h" #include "champlain-zoom-level.h" #include "sources/osmmapnik.h" #include "sources/mffrelief.h" @@ -88,7 +90,7 @@ map_load_visible_tiles (Map *map, ChamplainRectangle viewport, gboolean offline) if(y_count > map->current_level->column_count) y_count = map->current_level->column_count; - //g_print("Tiles: %d, %d to %d, %d\n", x_first, y_first, x_count, y_count); + DEBUG ("Range %d, %d to %d, %d", x_first, y_first, x_count, y_count); int i, j; guint k; @@ -96,11 +98,14 @@ map_load_visible_tiles (Map *map, ChamplainRectangle viewport, gboolean offline) // Get rid of old tiles first for (k = 0; k < map->current_level->tiles->len; k++) { - Tile *tile = g_ptr_array_index(map->current_level->tiles, k); - if (tile->x < x_first || tile->x > x_count || tile->y < y_first || tile->y > y_count) + ChamplainTile *tile = g_ptr_array_index(map->current_level->tiles, 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); - tile_free(tile); + g_object_unref (tile); } } @@ -112,14 +117,18 @@ map_load_visible_tiles (Map *map, ChamplainRectangle viewport, gboolean offline) gboolean exist = FALSE; for (k = 0; k < map->current_level->tiles->len && !exist; k++) { - Tile *tile = g_ptr_array_index(map->current_level->tiles, k); - if ( tile->x == i && tile->y == j) + ChamplainTile *tile = g_ptr_array_index(map->current_level->tiles, k); + gint tile_x = champlain_tile_get_x (tile); + gint tile_y = champlain_tile_get_y (tile); + + if ( tile_x == i && tile_y == j) exist = TRUE; } if(!exist) { - Tile *tile = tile_load(map, map->current_level->level, i, j, offline); + 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); } } diff --git a/champlain/champlain-map.h b/champlain/champlain-map.h index e011d8b..2fea5d4 100644 --- a/champlain/champlain-map.h +++ b/champlain/champlain-map.h @@ -47,8 +47,8 @@ struct _Map gdouble (* x_to_longitude) (Map *map, gint x, guint zoom_level); gdouble (* y_to_latitude) (Map *map, gint y, guint zoom_level); - gchar *(* get_tile_filename) (Map *map, Tile *tile); - gchar *(* get_tile_uri) (Map *map, Tile *tile); + gchar *(* get_tile_filename) (Map *map, ChamplainTile *tile); + gchar *(* get_tile_uri) (Map *map, ChamplainTile *tile); }; Map *map_new (ChamplainMapSource source); diff --git a/champlain/champlain-private.h b/champlain/champlain-private.h index 3da8526..e476778 100644 --- a/champlain/champlain-private.h +++ b/champlain/champlain-private.h @@ -24,7 +24,6 @@ #define CHAMPLAIN_MARKER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), CHAMPLAIN_TYPE_MARKER, ChamplainMarkerPrivate)) typedef struct _Map Map; -typedef struct _Tile Tile; typedef struct { diff --git a/champlain/champlain-tile.c b/champlain/champlain-tile.c index 94bda02..9aaf1e8 100644 --- a/champlain/champlain-tile.c +++ b/champlain/champlain-tile.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Pierre-Luc Beaudoin +* Copyright (C) 2008 Pierre-Luc Beaudoin * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,6 +18,7 @@ #include "champlain-tile.h" +#include "champlain-enum-types.h" #include "champlain-map.h" #include "champlain-private.h" @@ -27,43 +28,469 @@ #include #include +G_DEFINE_TYPE (ChamplainTile, champlain_tile, G_TYPE_OBJECT) + +#define GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), CHAMPLAIN_TYPE_TILE, ChamplainTilePrivate)) + +enum +{ + PROP_0, + PROP_X, + PROP_Y, + PROP_ZOOM_LEVEL, + PROP_SIZE, + PROP_URI, + PROP_FILENAME, + PROP_STATE, + PROP_ACTOR +}; + +typedef struct _ChamplainTilePrivate ChamplainTilePrivate; + +struct _ChamplainTilePrivate { + gint x; + gint y; + gint size; + gint zoom_level; + + gchar * uri; + gpointer data; + ChamplainStateEnum state; + gchar *filename; + ClutterActor *actor; +}; + +static void +champlain_tile_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + ChamplainTile *self = CHAMPLAIN_TILE (object); + switch (property_id) + { + case PROP_X: + g_value_set_int (value, champlain_tile_get_x (self)); + break; + case PROP_Y: + g_value_set_int (value, champlain_tile_get_y (self)); + break; + case PROP_ZOOM_LEVEL: + g_value_set_int (value, champlain_tile_get_zoom_level (self)); + break; + case PROP_SIZE: + g_value_set_uint (value, champlain_tile_get_size (self)); + break; + case PROP_STATE: + g_value_set_enum (value, champlain_tile_get_state (self)); + break; + case PROP_URI: + g_value_set_string (value, champlain_tile_get_uri (self)); + break; + case PROP_FILENAME: + g_value_set_string (value, champlain_tile_get_filename (self)); + break; + case PROP_ACTOR: + g_value_set_object (value, champlain_tile_get_actor (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +champlain_tile_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + ChamplainTile *self = CHAMPLAIN_TILE (object); + switch (property_id) + { + case PROP_X: + champlain_tile_set_x (self, g_value_get_int (value)); + break; + case PROP_Y: + champlain_tile_set_y (self, g_value_get_int (value)); + break; + case PROP_ZOOM_LEVEL: + champlain_tile_set_zoom_level (self, g_value_get_int (value)); + break; + case PROP_SIZE: + champlain_tile_set_size (self, g_value_get_uint (value)); + break; + case PROP_STATE: + champlain_tile_set_state (self, g_value_get_enum (value)); + break; + case PROP_URI: + champlain_tile_set_uri (self, g_value_dup_string (value)); + break; + case PROP_FILENAME: + champlain_tile_set_filename (self, g_value_dup_string (value)); + break; + case PROP_ACTOR: + champlain_tile_set_actor (self, g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +champlain_tile_dispose (GObject *object) +{ + ChamplainTilePrivate *priv = GET_PRIVATE (object); + /* We call destroy here as an actor should not survive its tile */ + if (priv->actor != NULL) + clutter_actor_destroy (priv->actor); + + G_OBJECT_CLASS (champlain_tile_parent_class)->dispose (object); +} + +static void +champlain_tile_finalize (GObject *object) +{ + G_OBJECT_CLASS (champlain_tile_parent_class)->finalize (object); +} + +static void +champlain_tile_class_init (ChamplainTileClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (ChamplainTilePrivate)); + + object_class->get_property = champlain_tile_get_property; + object_class->set_property = champlain_tile_set_property; + object_class->dispose = champlain_tile_dispose; + object_class->finalize = champlain_tile_finalize; + + + g_object_class_install_property (object_class, + PROP_X, + g_param_spec_int ("x", + "x", + "The X position of the tile", + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_Y, + g_param_spec_int ("y", + "y", + "The Y position of the tile", + G_MININT, + 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 zoom level of the tile", + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_SIZE, + g_param_spec_uint ("size", + "Size", + "The size of the tile", + 0, + G_MAXINT, + 256, + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_STATE, + g_param_spec_enum ("state", + "State", + "The state of the tile", + CHAMPLAIN_TYPE_STATE_ENUM, + CHAMPLAIN_STATE_NONE, + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_URI, + g_param_spec_string ("uri", + "URI", + "The URI of the tile", + "", + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_FILENAME, + g_param_spec_string ("filename", + "Filename", + "The filename of the tile", + "", + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_ACTOR, + g_param_spec_object ("actor", + "Actor", + "The tile's actor", + CLUTTER_TYPE_ACTOR, + G_PARAM_READWRITE)); +} + +static void +champlain_tile_init (ChamplainTile *self) +{ + champlain_tile_set_state (self, CHAMPLAIN_STATE_INIT); + champlain_tile_set_x (self, 0); + champlain_tile_set_y (self, 0); + champlain_tile_set_zoom_level (self, 0); + champlain_tile_set_size (self, 0); + champlain_tile_set_uri (self, ""); + champlain_tile_set_filename (self, ""); +} + +ChamplainTile* +champlain_tile_new (void) +{ + return g_object_new (CHAMPLAIN_TYPE_TILE, NULL); +} + +gint +champlain_tile_get_x (ChamplainTile *self) +{ + g_return_val_if_fail(CHAMPLAIN_TILE(self), 0); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + return priv->x; +} + +gint +champlain_tile_get_y (ChamplainTile *self) +{ + g_return_val_if_fail(CHAMPLAIN_TILE(self), 0); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + return priv->y; +} + +gint +champlain_tile_get_zoom_level (ChamplainTile *self) +{ + g_return_val_if_fail(CHAMPLAIN_TILE(self), 0); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + return priv->zoom_level; +} + +guint +champlain_tile_get_size (ChamplainTile *self) +{ + g_return_val_if_fail(CHAMPLAIN_TILE(self), 0); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + return priv->size; +} + +ChamplainStateEnum +champlain_tile_get_state (ChamplainTile *self) +{ + g_return_val_if_fail(CHAMPLAIN_TILE(self), CHAMPLAIN_STATE_NONE); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + return priv->state; +} + +gchar * +champlain_tile_get_uri (ChamplainTile *self) +{ + g_return_val_if_fail(CHAMPLAIN_TILE(self), NULL); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + return priv->uri; +} + +gchar * +champlain_tile_get_filename (ChamplainTile *self) +{ + g_return_val_if_fail(CHAMPLAIN_TILE(self), NULL); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + return priv->filename; +} + +ClutterActor * +champlain_tile_get_actor (ChamplainTile *self) +{ + g_return_val_if_fail(CHAMPLAIN_TILE(self), NULL); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + return priv->actor; +} + +void +champlain_tile_set_x (ChamplainTile *self, gint x) +{ + g_return_if_fail(CHAMPLAIN_TILE(self)); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + priv->x = x; + g_object_notify (G_OBJECT (self), "x"); +} + +void +champlain_tile_set_y (ChamplainTile *self, gint y) +{ + g_return_if_fail(CHAMPLAIN_TILE(self)); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + priv->y = y; + g_object_notify (G_OBJECT (self), "y"); +} + +void +champlain_tile_set_zoom_level (ChamplainTile *self, gint zoom_level) +{ + g_return_if_fail(CHAMPLAIN_TILE(self)); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + priv->zoom_level = zoom_level; + g_object_notify (G_OBJECT (self), "zoom-level"); +} + +void +champlain_tile_set_size (ChamplainTile *self, guint size) +{ + g_return_if_fail(CHAMPLAIN_TILE(self)); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + priv->size = size; + g_object_notify (G_OBJECT (self), "size"); +} + +void +champlain_tile_set_state (ChamplainTile *self, ChamplainStateEnum state) +{ + g_return_if_fail(CHAMPLAIN_TILE(self)); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + priv->state = state; + g_object_notify (G_OBJECT (self), "state"); +} + +ChamplainTile* +champlain_tile_new_full (gint x, + gint y, + guint size, + gint zoom_level) +{ + return g_object_new (CHAMPLAIN_TYPE_TILE, "x", x, "y", y, "zoom-level", + zoom_level, "size", size, NULL); +} + +void +champlain_tile_set_uri (ChamplainTile *self, gchar *uri) +{ + g_return_if_fail(CHAMPLAIN_TILE(self)); + g_return_if_fail(uri != NULL); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + priv->uri = uri; + g_object_notify (G_OBJECT (self), "uri"); +} + +void +champlain_tile_set_filename (ChamplainTile *self, gchar *filename) +{ + g_return_if_fail(CHAMPLAIN_TILE(self)); + g_return_if_fail(filename != NULL); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + priv->filename = filename; + g_object_notify (G_OBJECT (self), "filename"); +} + +void +champlain_tile_set_actor (ChamplainTile *self, ClutterActor *actor) +{ + g_return_if_fail(CHAMPLAIN_TILE(self)); + g_return_if_fail(actor != NULL); + + ChamplainTilePrivate *priv = GET_PRIVATE (self); + + priv->actor = g_object_ref (actor); + g_object_notify (G_OBJECT (self), "actor"); +} + +/* The code below this point is to be refactored */ + typedef struct { Map* map; - Tile* tile; + ChamplainTile* tile; } TwoPtr; #define CACHE_DIR "champlain" static SoupSession * soup_session; void -tile_set_position(Map* map, Tile* tile) +tile_set_position(Map* map, ChamplainTile* tile) { - clutter_actor_set_position (tile->actor, - (tile->x * tile->size) - map->current_level->anchor.x, - (tile->y * tile->size) - map->current_level->anchor.y); - clutter_actor_set_size (tile->actor, tile->size, tile->size); - clutter_actor_show (tile->actor); + ClutterActor *actor; + gint x; + gint y; + guint size; + g_object_get (G_OBJECT (tile), "actor", &actor, + "x", &x, "y", &y, + "size", &size, NULL); + clutter_actor_set_position (actor, + (x * size) - map->current_level->anchor.x, + (y * size) - map->current_level->anchor.y); + clutter_actor_set_size (actor, size, size); //XXX Move elsewhere + clutter_actor_show (actor); } void -tile_setup_animation(Tile* tile) +tile_setup_animation (ChamplainTile* tile) { + ClutterActor *actor = champlain_tile_get_actor (tile); ClutterEffectTemplate *etemplate = clutter_effect_template_new_for_duration (250, CLUTTER_ALPHA_SINE_INC); - clutter_actor_set_opacity(tile->actor, 0); - clutter_effect_fade (etemplate, tile->actor, 255, NULL, NULL); + clutter_actor_set_opacity(actor, 0); + clutter_effect_fade (etemplate, actor, 255, NULL, NULL); } static void -create_error_tile(Map* map, Tile* tile) +create_error_tile(Map* map, ChamplainTile* tile) { - tile->actor = clutter_texture_new_from_file(DATADIR "/champlain/error.svg", NULL); - if (!tile->actor) + ClutterActor *actor; + actor = clutter_texture_new_from_file (DATADIR "/champlain/error.svg", NULL); + if (!actor) return; - tile_set_position(map, tile); + champlain_tile_set_actor (tile, actor); + tile_set_position (map, tile); + + clutter_container_add (CLUTTER_CONTAINER (map->current_level->group), actor, NULL); + tile_setup_animation (tile); - clutter_container_add (CLUTTER_CONTAINER (map->current_level->group), tile->actor, NULL); - tile_setup_animation(tile); + champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE); } static void @@ -75,17 +502,21 @@ file_loaded_cb (SoupSession *session, GError *error = NULL; gchar* path, *filename, *map_filename; - Tile* tile = ptr->tile; + ChamplainTile* tile = ptr->tile; Map* map = ptr->map; if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) { - g_warning ("Unable to download tile %d, %d: %s", tile->x, tile->y, soup_status_get_phrase(msg->status_code)); - create_error_tile(map, tile); + g_warning ("Unable to download tile %d, %d: %s", + champlain_tile_get_x (tile), + champlain_tile_get_y (tile), + soup_status_get_phrase (msg->status_code)); + create_error_tile (map, tile); + g_object_unref (tile); return; } - loader = gdk_pixbuf_loader_new(); + loader = gdk_pixbuf_loader_new (); if (!gdk_pixbuf_loader_write (loader, (const guchar *) msg->response_body->data, msg->response_body->length, @@ -95,7 +526,8 @@ file_loaded_cb (SoupSession *session, { g_warning ("Unable to load the pixbuf: %s", error->message); g_error_free (error); - create_error_tile(map, tile); + create_error_tile (map, tile); + g_object_unref (tile); return; } @@ -109,6 +541,7 @@ file_loaded_cb (SoupSession *session, g_error_free (error); g_object_unref (loader); create_error_tile(map, tile); + g_object_unref (tile); return; } else @@ -139,33 +572,26 @@ file_loaded_cb (SoupSession *session, msg->response_body->data, msg->response_body->length, NULL); - // If the tile has been marked to be deleted, don't go any further - if(tile->to_destroy) - { - g_object_unref (loader); - g_free (filename); - g_free (map_filename); - g_free (tile); - return; - } GdkPixbuf* pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); - tile->actor = clutter_texture_new(); - clutter_texture_set_from_rgb_data(CLUTTER_TEXTURE(tile->actor), + ClutterActor *actor = clutter_texture_new(); + clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (actor), gdk_pixbuf_get_pixels (pixbuf), gdk_pixbuf_get_has_alpha (pixbuf), - gdk_pixbuf_get_width(pixbuf), - gdk_pixbuf_get_height(pixbuf), + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), gdk_pixbuf_get_rowstride (pixbuf), 3, 0, NULL); + champlain_tile_set_actor (tile, actor); - tile_set_position(map, tile); + tile_set_position (map, tile); - clutter_container_add (CLUTTER_CONTAINER (map->current_level->group), tile->actor, NULL); - tile_setup_animation(tile); + clutter_container_add (CLUTTER_CONTAINER (map->current_level->group), actor, NULL); + tile_setup_animation (tile); - tile->loading = FALSE; + champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE); + g_object_unref (tile); g_object_unref (loader); g_free (filename); @@ -174,23 +600,20 @@ file_loaded_cb (SoupSession *session, g_free (ptr); } -Tile* -tile_load (Map* map, guint zoom_level, guint x, guint y, gboolean offline) +ChamplainTile* +tile_load (Map* map, gint zoom_level, gint x, gint y, gboolean offline) { gchar* filename, *map_filename; - Tile* tile = g_new0(Tile, 1); + ChamplainTile* tile = champlain_tile_new (); + g_object_set (G_OBJECT (tile), "x", x, "y" , y, "zoom-level", zoom_level, + "size", map->tile_size, NULL); - tile->x = x; - tile->y = y; - tile->level = zoom_level; - tile->size = map->tile_size; - - TwoPtr* ptr = g_new0(TwoPtr, 1); + TwoPtr* ptr = g_new0 (TwoPtr, 1); ptr->map = map; ptr->tile = tile; // Try the cached version first - map_filename = map->get_tile_filename(map, tile); + map_filename = map->get_tile_filename (map, tile); filename = g_build_filename (g_get_user_cache_dir (), CACHE_DIR, map->name, @@ -199,10 +622,11 @@ tile_load (Map* map, guint zoom_level, guint x, guint y, gboolean offline) if (g_file_test (filename, G_FILE_TEST_EXISTS)) { - tile->actor = clutter_texture_new_from_file(filename, NULL); - tile_set_position(map, tile); + ClutterActor *actor = clutter_texture_new_from_file(filename, NULL); + champlain_tile_set_actor (tile, actor); + tile_set_position (map, tile); - clutter_container_add (CLUTTER_CONTAINER (map->current_level->group), tile->actor, NULL); + clutter_container_add (CLUTTER_CONTAINER (map->current_level->group), actor, NULL); // Do not animate since it is local and fast } else if (!offline) @@ -216,7 +640,8 @@ tile_load (Map* map, guint zoom_level, guint x, guint y, gboolean offline) soup_session_queue_message (soup_session, msg, file_loaded_cb, ptr); - tile->loading = TRUE; + champlain_tile_set_state (tile, CHAMPLAIN_STATE_LOADING); + g_object_ref (tile); //Unref when loading done } // If a tile is neither in cache or can be fetched, do nothing, it'll show up as empty @@ -224,14 +649,3 @@ tile_load (Map* map, guint zoom_level, guint x, guint y, gboolean offline) g_free (map_filename); return tile; } - -void -tile_free(Tile* tile) -{ - if(tile->actor) - clutter_actor_destroy(tile->actor); - if(tile->loading) - tile->to_destroy = TRUE; - else - g_free(tile); -} diff --git a/champlain/champlain-tile.h b/champlain/champlain-tile.h index a74146d..dd44439 100644 --- a/champlain/champlain-tile.h +++ b/champlain/champlain-tile.h @@ -19,27 +19,64 @@ #ifndef CHAMPLAIN_MAP_TILE_H #define CHAMPLAIN_MAP_TILE_H +#include #include #include #include -struct _Tile -{ - ClutterActor* actor; - int x; - int y; - int size; - int level; +G_BEGIN_DECLS - gboolean loading; // TRUE when a callback exist to load the tile, FALSE otherwise - gboolean to_destroy; // TRUE when a tile struct should be deleted when loading is done, FALSE otherwise -}; +#define CHAMPLAIN_TYPE_TILE champlain_tile_get_type() -void tile_free(Tile* tile); +#define CHAMPLAIN_TILE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), CHAMPLAIN_TYPE_TILE, ChamplainTile)) -void tile_set_position(Map* map, Tile* tile); +#define CHAMPLAIN_TILE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), CHAMPLAIN_TYPE_TILE, ChamplainTileClass)) -Tile* tile_load (Map* map, guint zoom_level, guint x, guint y, gboolean offline); +#define CHAMPLAIN_IS_TILE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CHAMPLAIN_TYPE_TILE)) + +#define CHAMPLAIN_IS_TILE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), CHAMPLAIN_TYPE_TILE)) + +#define CHAMPLAIN_TILE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), CHAMPLAIN_TYPE_TILE, ChamplainTileClass)) + +typedef struct { + GObject parent; +} ChamplainTile; + +typedef struct { + GObjectClass parent_class; +} ChamplainTileClass; + +GType champlain_tile_get_type (void); + +ChamplainTile* champlain_tile_new (void); +ChamplainTile* champlain_tile_new_full (gint x, gint y, guint size, gint zoom_level); + +gint champlain_tile_get_x (ChamplainTile *self); +gint champlain_tile_get_y (ChamplainTile *self); +gint champlain_tile_get_zoom_level (ChamplainTile *self); +guint champlain_tile_get_size (ChamplainTile *self); +ChamplainStateEnum champlain_tile_get_state (ChamplainTile *self); +gchar * champlain_tile_get_uri (ChamplainTile *self); +gchar * champlain_tile_get_filename (ChamplainTile *self); +ClutterActor * champlain_tile_get_actor (ChamplainTile *self); + +void champlain_tile_set_x (ChamplainTile *self, gint x); +void champlain_tile_set_y (ChamplainTile *self, gint y); +void champlain_tile_set_zoom_level (ChamplainTile *self, gint zoom_level); +void champlain_tile_set_size (ChamplainTile *self, guint size); +void champlain_tile_set_state (ChamplainTile *self, ChamplainStateEnum state); +void champlain_tile_set_uri (ChamplainTile *self, gchar* uri); +void champlain_tile_set_filename (ChamplainTile *self, gchar* filename); +void champlain_tile_set_actor (ChamplainTile *self, ClutterActor* actor); + +ChamplainTile* tile_load (Map* map, gint zoom_level, gint x, gint y, gboolean offline); +G_END_DECLS + +#endif /* CHAMPLAIN_MAP_TILE_H */ -#endif diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c index 474d7a2..7b6e4e3 100644 --- a/champlain/champlain-view.c +++ b/champlain/champlain-view.c @@ -733,8 +733,10 @@ champlain_view_init (ChamplainView *view) { ChamplainViewPrivate *priv = GET_PRIVATE (view); + champlain_debug_set_flags (g_getenv ("CHAMPLAIN_DEBUG")); + priv->map_source = CHAMPLAIN_MAP_SOURCE_OPENSTREETMAP; - priv->zoom_level = 3; + priv->zoom_level = 0; priv->offline = FALSE; priv->keep_center_on_resize = TRUE; priv->show_license = TRUE; @@ -988,8 +990,8 @@ champlain_view_center_on (ChamplainView *view, for (i = 0; i < priv->map->current_level->tiles->len; i++) { - Tile *tile = g_ptr_array_index (priv->map->current_level->tiles, i); - if (!tile->loading) + ChamplainTile *tile = g_ptr_array_index (priv->map->current_level->tiles, i); + if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_DONE) tile_set_position (priv->map, tile); } diff --git a/champlain/champlain-zoom-level.c b/champlain/champlain-zoom-level.c index 1d1ffe1..3da8d06 100644 --- a/champlain/champlain-zoom-level.c +++ b/champlain/champlain-zoom-level.c @@ -51,8 +51,8 @@ zoom_level_free(ZoomLevel *level) guint i; for (i = 0; i < level->tiles->len; i++) { - Tile *tile = g_ptr_array_index(level->tiles, i); - tile_free(tile); + ChamplainTile *tile = g_ptr_array_index(level->tiles, i); + g_object_unref (tile); } } diff --git a/champlain/sources/mffrelief.c b/champlain/sources/mffrelief.c index cbac1e3..8f7c3ee 100644 --- a/champlain/sources/mffrelief.c +++ b/champlain/sources/mffrelief.c @@ -29,15 +29,15 @@ guint mff_relief_row_count(Map *map, guint zoom_level); guint mff_relief_column_count(Map *map, guint zoom_level); -Tile *mff_relief_get_tile (Map *map, guint zoom_level, guint x, guint y); +ChamplainTile *mff_relief_get_tile (Map *map, guint zoom_level, guint x, guint y); gint mff_relief_longitude_to_x (Map *map, gdouble longitude, guint zoom_level); gint mff_relief_latitude_to_y (Map *map, gdouble latitude, guint zoom_level); gdouble mff_relief_x_to_longitude (Map *map, gint x, guint zoom_level); gdouble mff_relief_y_to_latitude (Map *map, gint y, guint zoom_level); -gchar *mff_relief_get_tile_filename(Map *map, Tile *tile); -gchar *mff_relief_get_tile_uri(Map *map, Tile *tile); +gchar *mff_relief_get_tile_filename(Map *map, ChamplainTile *tile); +gchar *mff_relief_get_tile_uri(Map *map, ChamplainTile *tile); void mff_relief_init(Map *map) @@ -98,12 +98,16 @@ mff_relief_y_to_latitude (Map *map, gint y, guint zoom_level) return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))); } -gchar *mff_relief_get_tile_filename(Map *map, Tile *tile) +gchar *mff_relief_get_tile_filename(Map *map, ChamplainTile *tile) { - return g_build_filename (g_strdup_printf("%d_%d_%d.png", tile->level, tile->y, tile->x), NULL); + gint x, y, level; + g_object_get (G_OBJECT (tile), "x", &x, "y", &y, "zoom-level", &level, NULL); + return g_build_filename (g_strdup_printf("%d_%d_%d.png", level, y, x), NULL); } -gchar *mff_relief_get_tile_uri(Map *map, Tile *tile) +gchar *mff_relief_get_tile_uri(Map *map, ChamplainTile *tile) { - return g_strdup_printf("http://maps-for-free.com/layer/relief/z%d/row%d/%d_%d-%d.jpg", tile->level, tile->y, tile->level, tile->x, tile->y); + gint x, y, level; + g_object_get (G_OBJECT (tile), "x", &x, "y", &y, "zoom-level", &level, NULL); + return g_strdup_printf("http://maps-for-free.com/layer/relief/z%d/row%d/%d_%d-%d.jpg", level, y, level, x, y); } diff --git a/champlain/sources/oam.c b/champlain/sources/oam.c index 2a5f3a7..0c8bb97 100644 --- a/champlain/sources/oam.c +++ b/champlain/sources/oam.c @@ -26,15 +26,15 @@ guint oam_row_count(Map *map, guint zoom_level); guint oam_column_count(Map *map, guint zoom_level); -Tile *oam_get_tile (Map *map, guint zoom_level, guint x, guint y); +ChamplainTile *oam_get_tile (Map *map, guint zoom_level, guint x, guint y); gint oam_longitude_to_x (Map *map, gdouble longitude, guint zoom_level); gint oam_latitude_to_y (Map *map, gdouble latitude, guint zoom_level); gdouble oam_x_to_longitude (Map *map, gint x, guint zoom_level); gdouble oam_y_to_latitude (Map *map, gint y, guint zoom_level); -gchar *oam_get_tile_filename(Map *map, Tile *tile); -gchar *oam_get_tile_uri(Map *map, Tile *tile); +gchar *oam_get_tile_filename(Map *map, ChamplainTile *tile); +gchar *oam_get_tile_uri(Map *map, ChamplainTile *tile); void oam_init(Map *map) @@ -95,12 +95,16 @@ oam_y_to_latitude (Map *map, gint y, guint zoom_level) return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))); } -gchar *oam_get_tile_filename(Map *map, Tile *tile) +gchar *oam_get_tile_filename(Map *map, ChamplainTile *tile) { - return g_build_filename (g_strdup_printf("%d_%d_%d.png", tile->level, tile->y, tile->x), NULL); + gint x, y, level; + g_object_get (G_OBJECT (tile), "x", &x, "y", &y, "zoom-level", &level, NULL); + return g_build_filename (g_strdup_printf("%d_%d_%d.png", level, y, x), NULL); } -gchar *oam_get_tile_uri(Map *map, Tile *tile) +gchar *oam_get_tile_uri(Map *map, ChamplainTile *tile) { - return g_strdup_printf("http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/%d/%d/%d.jpg", tile->level, tile->x, tile->y); + gint x, y, level; + g_object_get (G_OBJECT (tile), "x", &x, "y", &y, "zoom-level", &level, NULL); + return g_strdup_printf("http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/%d/%d/%d.jpg", level, x, y); } diff --git a/champlain/sources/osmmapnik.c b/champlain/sources/osmmapnik.c index f700ee0..51f7588 100644 --- a/champlain/sources/osmmapnik.c +++ b/champlain/sources/osmmapnik.c @@ -29,15 +29,15 @@ guint osm_mapnik_row_count(Map *map, guint zoom_level); guint osm_mapnik_column_count(Map *map, guint zoom_level); -Tile *osm_mapnik_get_tile (Map *map, guint zoom_level, guint x, guint y); +ChamplainTile *osm_mapnik_get_tile (Map *map, guint zoom_level, guint x, guint y); gint osm_mapnik_longitude_to_x (Map *map, gdouble longitude, guint zoom_level); gint osm_mapnik_latitude_to_y (Map *map, gdouble latitude, guint zoom_level); gdouble osm_mapnik_x_to_longitude (Map *map, gint x, guint zoom_level); gdouble osm_mapnik_y_to_latitude (Map *map, gint y, guint zoom_level); -gchar *osm_mapnik_get_tile_filename(Map *map, Tile *tile); -gchar *osm_mapnik_get_tile_uri(Map *map, Tile *tile); +gchar *osm_mapnik_get_tile_filename(Map *map, ChamplainTile *tile); +gchar *osm_mapnik_get_tile_uri(Map *map, ChamplainTile *tile); void osm_mapnik_init(Map *map) @@ -98,12 +98,16 @@ osm_mapnik_y_to_latitude (Map *map, gint y, guint zoom_level) return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))); } -gchar *osm_mapnik_get_tile_filename(Map *map, Tile *tile) +gchar *osm_mapnik_get_tile_filename(Map *map, ChamplainTile *tile) { - return g_build_filename (g_strdup_printf("%d_%d_%d.png", tile->level, tile->y, tile->x), NULL); + gint x, y, level; + g_object_get (G_OBJECT (tile), "x", &x, "y", &y, "zoom-level", &level, NULL); + return g_build_filename (g_strdup_printf("%d_%d_%d.png", level, y, x), NULL); } -gchar *osm_mapnik_get_tile_uri(Map *map, Tile *tile) +gchar *osm_mapnik_get_tile_uri(Map *map, ChamplainTile *tile) { - return g_strdup_printf("http://tile.openstreetmap.org/%d/%d/%d.png", tile->level, tile->x, tile->y); + gint x, y, level; + g_object_get (G_OBJECT (tile), "x", &x, "y", &y, "zoom-level", &level, NULL); + return g_strdup_printf("http://tile.openstreetmap.org/%d/%d/%d.png", level, x, y); } -- 2.39.5