--- /dev/null
+/*
+ * Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc@squidy.info>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include "champlain_defines.h"
+#include "champlainmarker.h"
+#include "champlain_private.h"
+#include "champlain.h"
+#include "champlain-marshal.h"
+#include "map.h"
+#include "tile.h"
+#include "zoomlevel.h"
+
+#include <clutter/clutter.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk-clutter-embed.h>
+#include <math.h>
+
+enum
+{
+ /* normal signals */
+ LAST_SIGNAL
+};
+
+enum
+{
+ PROP_0,
+ PROP_LONGITUDE,
+ PROP_LATITUDE,
+ PROP_ANCHOR_X,
+ PROP_ANCHOR_Y,
+};
+
+static guint champlain_marker_signals[LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE (ChamplainMarker, champlain_marker, CLUTTER_TYPE_GROUP);
+
+static void
+champlain_marker_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
+{
+ ChamplainMarker* marker = CHAMPLAIN_MARKER(object);
+ ChamplainMarkerPrivate *priv = CHAMPLAIN_MARKER_GET_PRIVATE (marker);
+
+ switch(prop_id)
+ {
+ case PROP_LONGITUDE:
+ g_value_set_double(value, priv->lon);
+ break;
+ case PROP_LATITUDE:
+ g_value_set_double(value, priv->lat);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void
+champlain_marker_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec *pspec)
+{
+ ChamplainMarker* marker = CHAMPLAIN_MARKER(object);
+ ChamplainMarkerPrivate *priv = CHAMPLAIN_MARKER_GET_PRIVATE (marker);
+
+ switch(prop_id)
+ {
+ case PROP_LONGITUDE:
+ {
+ gdouble lon = g_value_get_double(value);
+ champlain_marker_set_position(marker, lon, priv->lat);
+ break;
+ }
+ case PROP_LATITUDE:
+ {
+ gdouble lat = g_value_get_double(value);
+ champlain_marker_set_position(marker, priv->lon, lat);
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void
+champlain_marker_finalize (GObject * object)
+{
+ ChamplainMarker *marker = CHAMPLAIN_MARKER (object);
+ ChamplainMarkerPrivate *priv = CHAMPLAIN_MARKER_GET_PRIVATE (marker);
+
+ G_OBJECT_CLASS (champlain_marker_parent_class)->finalize (object);
+}
+
+static void
+champlain_marker_class_init (ChamplainMarkerClass *champlainMarkerClass)
+{
+ g_type_class_add_private (champlainMarkerClass, sizeof (ChamplainMarkerPrivate));
+
+ GObjectClass *objectClass = G_OBJECT_CLASS (champlainMarkerClass);
+ objectClass->finalize = champlain_marker_finalize;
+ objectClass->get_property = champlain_marker_get_property;
+ objectClass->set_property = champlain_marker_set_property;
+
+ /**
+ * ChamplainMarker:longitude:
+ *
+ * The longitude coordonate of the map
+ *
+ * Since: 0.3
+ */
+ g_object_class_install_property(objectClass, PROP_LONGITUDE,
+ g_param_spec_double("longitude",
+ "Longitude",
+ "The longitude coordonate of the marker",
+ -180.0f,
+ 180.0f,
+ 0.0f,
+ CHAMPLAIN_PARAM_READWRITE));
+
+ /**
+ * ChamplainMarker:latitude:
+ *
+ * The latitude coordonate of the map
+ *
+ * Since: 0.3
+ */
+ g_object_class_install_property(objectClass, PROP_LATITUDE,
+ g_param_spec_double("latitude",
+ "Latitude",
+ "The latitude coordonate of the marker",
+ -90.0f,
+ 90.0f,
+ 0.0f,
+ CHAMPLAIN_PARAM_READWRITE));
+
+}
+
+static void
+champlain_marker_init (ChamplainMarker *champlainMarker)
+{
+ ChamplainMarkerPrivate *priv = CHAMPLAIN_MARKER_GET_PRIVATE (champlainMarker);
+ priv->anchor.x = 0;
+ priv->anchor.y = 0;
+}
+
+
+/**
+ * champlain_marker_new:
+ *
+ * Returns a new #ChamplainWidget ready to be used as a #ClutterActor.
+ *
+ * Since: 0.3
+ */
+ClutterActor *
+champlain_marker_new ()
+{
+ ChamplainMarker *marker;
+
+ marker = CHAMPLAIN_MARKER (g_object_new (CHAMPLAIN_TYPE_MARKER, NULL));
+ ChamplainMarkerPrivate *priv = CHAMPLAIN_MARKER_GET_PRIVATE (marker);
+
+ return CLUTTER_ACTOR (marker);
+}
+
+/**
+ * champlain_marker_set_position:
+ * @marker: a #ChamplainMarker
+ * @longitude: the longitude to center the map at
+ * @latitude: the longitude to center the map at
+ *
+ * Positions the marker on the map at the coordinates
+ *
+ * Since: 0.3
+ */
+void
+champlain_marker_set_position (ChamplainMarker *champlainMarker, gdouble longitude, gdouble latitude)
+{
+ ChamplainMarkerPrivate *priv = CHAMPLAIN_MARKER_GET_PRIVATE (champlainMarker);
+
+ priv->lon = longitude;
+ priv->lat = latitude;
+
+ g_object_notify(G_OBJECT(champlainMarker), "longitude");
+ g_object_notify(G_OBJECT(champlainMarker), "latitude");
+}
+
+
+/**
+ * champlain_marker_set_anchor:
+ * @marker: a #ChamplainMarker
+ * @x: the position in the actor that represents the longitude
+ * @y: the position in the actor that represents the latitude
+ *
+ * Marks the point (x, y) as the place where the #ChamplainMarker position is at (longitude, latitude).
+ *
+ * Since: 0.3
+ */
+void
+champlain_marker_set_anchor (ChamplainMarker *champlainMarker, gint x, gint y)
+{
+ ChamplainMarkerPrivate *priv = CHAMPLAIN_MARKER_GET_PRIVATE (champlainMarker);
+
+ priv->anchor.x = x;
+ priv->anchor.y = y;
+
+ clutter_actor_set_position(CLUTTER_ACTOR(champlainMarker), -x, -y);
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc@squidy.info>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef CHAMPLAIN_MARKER_H
+#define CHAMPLAIN_MARKER_H
+
+#include <champlain_defines.h>
+#include <glib-object.h>
+#include <clutter/clutter.h>
+
+#define CHAMPLAIN_TYPE_MARKER (champlain_marker_get_type())
+#define CHAMPLAIN_MARKER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CHAMPLAIN_TYPE_MARKER, ChamplainMarker))
+#define CHAMPLAIN_MARKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CHAMPLAIN_TYPE_MARKER, ChamplainMarkerClass))
+#define CHAMPLAIN_IS_MARKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CHAMPLAIN_TYPE_MARKER))
+#define CHAMPLAIN_IS_MARKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CHAMPLAIN_TYPE_MARKER))
+#define CHAMPLAIN_MARKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CHAMPLAIN_TYPE_MARKER, ChamplainMarkerClass))
+
+typedef struct _ChamplainMarkerPrivate ChamplainMarkerPrivate;
+
+struct _ChamplainMarker
+{
+ ClutterGroup group;
+
+ ChamplainMarkerPrivate *priv;
+};
+
+struct _ChamplainMarkerClass
+{
+ ClutterGroupClass parent_class;
+
+};
+
+CHAMPLAIN_API GType champlain_marker_get_type (void);
+
+CHAMPLAIN_API ClutterActor *champlain_marker_new ();
+
+CHAMPLAIN_API void champlain_marker_set_position (ChamplainMarker *marker, gdouble longitude, gdouble latitude);
+
+CHAMPLAIN_API void champlain_marker_set_anchor (ChamplainMarker *marker, gint x, gint y);
+
+#endif
priv->map->current_level->level);
}
+static void
+for_each_marker (ChamplainMarker *marker, ChamplainView* champlainView)
+{
+ ChamplainViewPrivate *priv = CHAMPLAIN_VIEW_GET_PRIVATE (champlainView);
+ ChamplainMarkerPrivate *marker_priv = CHAMPLAIN_MARKER_GET_PRIVATE (marker);
+
+ gint x, y;
+
+ 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);
+
+ clutter_actor_set_position(CLUTTER_ACTOR(marker), x - marker_priv->anchor.x, y - marker_priv->anchor.y);
+}
+
+static void
+for_each_layer (ClutterActor *layer, ChamplainView* champlainView)
+{
+ clutter_container_foreach(CLUTTER_CONTAINER(layer), CLUTTER_CALLBACK(for_each_marker), champlainView);
+}
+
+static void
+marker_reposition (ChamplainView* champlainView)
+{
+ ChamplainViewPrivate *priv = CHAMPLAIN_VIEW_GET_PRIVATE (champlainView);
+ clutter_container_foreach(CLUTTER_CONTAINER(priv->user_layers), CLUTTER_CALLBACK(for_each_layer), champlainView);
+}
+
static void
resize_viewport(ChamplainView *champlainView)
{
ChamplainViewPrivate *priv = CHAMPLAIN_VIEW_GET_PRIVATE (champlainView);
- if(priv->map == NULL)
+ if(!priv->map)
{
priv->map = map_new(priv->map_source);
map_load_level(priv->map, priv->zoomLevel);
clutter_container_add_actor (CLUTTER_CONTAINER (priv->map_layer), priv->map->current_level->group);
+ marker_reposition(champlainView);
+
g_object_notify(G_OBJECT(champlainView), "zoom-level");
g_object_notify(G_OBJECT(champlainView), "map-source");
}
clutter_container_remove_actor (CLUTTER_CONTAINER (priv->viewport), group);
clutter_container_add_actor (CLUTTER_CONTAINER (priv->viewport), priv->map->current_level->group);
champlain_view_center_on(view, lon, lat);
+ marker_reposition(view);
}
}
}
map_load_visible_tiles (priv->map, priv->viewport_size, priv->offline);
}
-static void
-for_each_marker (ChamplainMarker *marker, ChamplainView* champlainView)
-{
- ChamplainViewPrivate *priv = CHAMPLAIN_VIEW_GET_PRIVATE (champlainView);
- ChamplainMarkerPrivate *marker_priv = CHAMPLAIN_MARKER_GET_PRIVATE (marker);
-
- gint x, y;
-
- 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);
-
- clutter_actor_set_position(CLUTTER_ACTOR(marker), x - marker_priv->anchor.x, y - marker_priv->anchor.y);
-}
-
-static void
-for_each_layer (ClutterActor *layer, ChamplainView* champlainView)
-{
- clutter_container_foreach(CLUTTER_CONTAINER(layer), CLUTTER_CALLBACK(for_each_marker), champlainView);
-}
-
-static void
-marker_reposition (ChamplainView* champlainView)
-{
- ChamplainViewPrivate *priv = CHAMPLAIN_VIEW_GET_PRIVATE (champlainView);
- clutter_container_foreach(CLUTTER_CONTAINER(priv->user_layers), CLUTTER_CALLBACK(for_each_layer), champlainView);
-}
-
/**
* champlain_view_zoom_in:
* @view: a #ChamplainView
clutter_container_add(CLUTTER_CONTAINER(priv->user_layers), layer, NULL);
clutter_actor_raise_top(layer);
- marker_reposition(champlainView);
+ if(priv->map)
+ marker_reposition(champlainView);
}
gtk_main_quit ();
}
+
+static ClutterActor*
+create_marker (gchar* title, gdouble lon, gdouble lat)
+{
+ ClutterActor* marker, *actor;
+
+ marker = champlain_marker_new();
+ champlain_marker_set_position(CHAMPLAIN_MARKER(marker), lon, lat);
+ champlain_marker_set_anchor(CHAMPLAIN_MARKER(marker), 0, 32);
+
+ actor = clutter_texture_new_from_file("marker.svg", NULL);
+ clutter_container_add_actor(CLUTTER_CONTAINER(marker), actor);
+
+ actor = clutter_label_new_with_text("Arial 14", title);
+ clutter_actor_set_position(actor, 30, 0);
+ clutter_container_add_actor(CLUTTER_CONTAINER(marker), actor);
+
+ return marker;
+}
+
+static ClutterActor*
+create_marker_layer ()
+{
+ ClutterActor* layer, * marker;
+
+ layer = clutter_group_new();
+
+ marker = create_marker("Montréal", -73.563788, 45.528178);
+ clutter_container_add(CLUTTER_CONTAINER(layer), marker, NULL);
+ marker = create_marker("New York", -73.98, 40.77);
+ clutter_container_add(CLUTTER_CONTAINER(layer), marker, NULL);
+ marker = create_marker("Miami", -80.28, 25.82);
+ clutter_container_add(CLUTTER_CONTAINER(layer), marker, NULL);
+
+ clutter_actor_hide(layer);
+ return layer;
+}
+
static void
-go_to_montreal (GtkWidget * widget, ChamplainView* view)
+toggle_layer (GtkToggleButton * widget, ClutterActor* layer)
{
- champlain_view_center_on(view, -73.75, 45.466);
+ if(gtk_toggle_button_get_active(widget))
+ clutter_actor_show_all(layer);
+ else
+ clutter_actor_hide(layer);
}
static void
GtkWidget *window;
GtkWidget *widget, *vbox, *bbox, *button, *viewport;
GtkWidget *scrolled;
+ ClutterActor* layer;
g_thread_init (NULL);
gtk_clutter_init (&argc, &argv);
widget = champlain_view_new (CHAMPLAIN_VIEW_MODE_KINETIC);
g_object_set(G_OBJECT(widget), "zoom-level", 5, NULL);
-// g_object_set(G_OBJECT(widget), "decel-rate", 1.1, NULL);
-// g_object_set(G_OBJECT(widget), "offline", TRUE, NULL);
+ layer = create_marker_layer();
+ champlain_view_add_layer(widget, layer);
gtk_widget_set_size_request(widget, 640, 480);
G_CALLBACK (zoom_out),
widget);
gtk_container_add (GTK_CONTAINER (bbox), button);
- button = gtk_button_new_with_label ("Montréal");
+ button = gtk_toggle_button_new_with_label ("Markers");
g_signal_connect (button,
- "clicked",
- G_CALLBACK (go_to_montreal),
- widget);
+ "toggled",
+ G_CALLBACK (toggle_layer),
+ layer);
gtk_container_add (GTK_CONTAINER (bbox), button);
button = gtk_combo_box_new_text();