]> err.no Git - libchamplain/commitdiff
GObjectify ChamplainZoomLevel
authorPierre-Luc Beaudoin <pierre-luc@pierlux.com>
Fri, 27 Feb 2009 20:51:49 +0000 (22:51 +0200)
committerPierre-Luc Beaudoin <pierre-luc@pierlux.com>
Wed, 4 Mar 2009 21:05:37 +0000 (23:05 +0200)
champlain/champlain-map.c
champlain/champlain-map.h
champlain/champlain-tile.c
champlain/champlain-view.c
champlain/champlain-zoom-level.c
champlain/champlain-zoom-level.h

index c7cb504ae04c98923074fca3002b0c96929274c0..800a6b6c35db6543d8d9bf57d8385823709bcaf8 100644 (file)
@@ -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
index 2fea5d456e489e53db5e090c14010af16efa8fdc..d8451e3ab5479d4538483e30c3390935c19611dd 100644 (file)
@@ -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);
index 2e6a3a8e45b49fe1a7d2c90fb38b1ec0aef6c18c..5f83180bac5af31d7beb920eda1c655238b62d17 100644 (file)
@@ -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)
index 262303283ca484ad4dd96d564fe557f4303e1be9..b98a5bc0f36dc73233fff47d10dfc9ca848a4d05 100644 (file)
@@ -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;
 }
index 3da8d06eaa4a070476d979094233e81fe2ace54f..0f346a98876f38bf19fe162b8583e43b98cf1941 100644 (file)
 
 #include <clutter/clutter.h>
 
-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;
 }
index 75bee9572d1a83a166153c5d17e2642d97940b71..032e0d9eaedf2f1e84c6aff0275c2275173abad4 100644 (file)
  * 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 <glib.h>
 #include <clutter/clutter.h>
 
-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