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
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);
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
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);
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);
}
}
}
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);
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);
void
map_free (Map *map)
{
- zoom_level_free(map->current_level);
+ g_object_unref (map->current_level);
}
gboolean
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);
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);
}
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);
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);
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)
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;
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
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
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);
}
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;
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");
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);
}
}
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);
gdouble lower, upper;
gboolean center = FALSE;
TidyAdjustment *hadjust, *vadjust;
+ gint level;
ChamplainViewPrivate *priv = GET_PRIVATE (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
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
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)
{
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;
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:
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;
}
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 ();
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,
{
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;
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);
}
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;
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");
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;
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;
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,
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");
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");
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;
}
#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;
}
* 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