]> err.no Git - libchamplain/commitdiff
GObject-ify ChamplainTile
authorPierre-Luc Beaudoin <pierre-luc@pierlux.com>
Sun, 15 Feb 2009 19:07:59 +0000 (21:07 +0200)
committerPierre-Luc Beaudoin <pierre-luc@pierlux.com>
Sun, 15 Feb 2009 19:07:59 +0000 (21:07 +0200)
As ChamplainTile will be publicly visible for custom map sources,
it needs to be a Gobject.

champlain/champlain-map.c
champlain/champlain-map.h
champlain/champlain-private.h
champlain/champlain-tile.c
champlain/champlain-tile.h
champlain/champlain-view.c
champlain/champlain-zoom-level.c
champlain/sources/mffrelief.c
champlain/sources/oam.c
champlain/sources/osmmapnik.c

index 7a7505c66dfe17cfcfb746e928c1cc32e515bd0d..c7cb504ae04c98923074fca3002b0c96929274c0 100644 (file)
@@ -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);
             }
         }
index e011d8bd7b21bccc710063bc4c0ab572ba7de96f..2fea5d456e489e53db5e090c14010af16efa8fdc 100644 (file)
@@ -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);
index 3da8526a4d190ed157c8e7284948a831b22f96d3..e47677863a9996129716d5c3ee567413e9822e69 100644 (file)
@@ -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 
 {
index 94bda028b54278746baa4a73f7a925b3635498e0..9aaf1e82d2bb09e09dcd646a0ec2e5a6b1fd996f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
+* Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
  *
  * 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"
 
 #include <libsoup/soup.h>
 #include <gio/gio.h>
 
+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);
-}
index a74146d37d8a970234717005e15eed869b8ecd0a..dd44439a4611b56460a5a3c6b4402f642747c1db 100644 (file)
 #ifndef CHAMPLAIN_MAP_TILE_H
 #define CHAMPLAIN_MAP_TILE_H
 
+#include <champlain/champlain-defines.h>
 #include <champlain/champlain-private.h>
 
 #include <glib.h>
 #include <clutter/clutter.h>
 
-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
index 474d7a2021074bc445b7b4231a00885e67825136..7b6e4e3f849eadc2c81df9ab11b2dcb520b53d0e 100644 (file)
@@ -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);
     }
 
index 1d1ffe1c0664460775f2d5bbaa2d2d167a465dd9..3da8d06eaa4a070476d979094233e81fe2ace54f 100644 (file)
@@ -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);
     }
 }
 
index cbac1e352002f556fc81806a6b0f20e67fc42b3c..8f7c3eeb7ed8c497ae5643ff6190b1fe8464c28e 100644 (file)
 
 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);
 }
index 2a5f3a75ae09b8b1956de8e3d2d75f97a224cda6..0c8bb977c18992746169fe66b2044ad888b1aad4 100644 (file)
 
 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);
 }
index f700ee011f898937f847adeff7bd13f06f3ecfbf..51f758882b6b2bfffa3dee3e153c046eb9e5cfd8 100644 (file)
 
 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);
 }