[libchamplain] Introduce the API for route drawing



commit f1d0cd196826a3eb23bfc91eff1a9f9c4db8b8a6
Author: Pierre-Luc Beaudoin <pierre-luc pierlux com>
Date:   Wed Jun 3 17:01:07 2009 -0400

    Introduce the API for route drawing

 champlain/Makefile.am         |   12 +++-
 champlain/champlain-defines.h |    6 ++
 champlain/champlain-line.c    |  156 +++++++++++++++++++++++++++++++++++++++++
 champlain/champlain-line.h    |   72 +++++++++++++++++++
 champlain/champlain-private.h |    2 +-
 champlain/champlain-view.c    |   48 ++++++++++++-
 champlain/champlain-view.h    |    6 ++-
 demos/Makefile.am             |    5 +-
 demos/lines.c                 |  126 +++++++++++++++++++++++++++++++++
 9 files changed, 423 insertions(+), 10 deletions(-)
---
diff --git a/champlain/Makefile.am b/champlain/Makefile.am
index 9898dde..67cdcee 100644
--- a/champlain/Makefile.am
+++ b/champlain/Makefile.am
@@ -28,6 +28,7 @@ libchamplain_headers = \
 	champlain-network-map-source.h	\
 	champlain-map-source-factory.h	\
 	champlain-map-source-desc.h	\
+	champlain-line.h		\
 	champlain-version.h
 
 
@@ -45,7 +46,8 @@ libchamplain_0_3_la_SOURCES = \
 	champlain-map-source.c		\
 	champlain-network-map-source.c	\
 	champlain-map-source-factory.c	\
-	champlain-cache.c
+	champlain-cache.c		\
+	champlain-line.c
 
 noinst_HEADERS = \
 	champlain-debug.h  		\
@@ -62,7 +64,9 @@ noinst_HEADERS = \
 	champlain-map-source-factory.h	\
 	champlain-map-source-desc.h	\
 	champlain-version.h		\
-	champlain-cache.h
+	champlain-cache.h		\
+	champlain-line.h		\
+	champlain-version.h
 
 libchamplain_include_HEADERS = \
 	champlain.h 			\
@@ -79,7 +83,9 @@ libchamplain_include_HEADERS = \
 	champlain-base-marker.h		\
 	champlain-marker.h		\
 	champlain-version.h		\
-	champlain-cache.h
+	champlain-cache.h		\
+	champlain-line.h		\
+	champlain-version.h
 
 libchamplain_0_3_la_LIBADD = $(DEPS_LIBS) $(SOUP_LIBS) ../tidy/libtidy-1.0.la
 
diff --git a/champlain/champlain-defines.h b/champlain/champlain-defines.h
index 54056b7..1f98d31 100644
--- a/champlain/champlain-defines.h
+++ b/champlain/champlain-defines.h
@@ -47,4 +47,10 @@ typedef enum
   CHAMPLAIN_STATE_DONE
 } ChamplainState;
 
+typedef struct
+{
+  double lat;
+  double lon;
+} ChamplainPoint;
+
 #endif
diff --git a/champlain/champlain-line.c b/champlain/champlain-line.c
new file mode 100644
index 0000000..2eeb5cb
--- /dev/null
+++ b/champlain/champlain-line.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2009 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/**
+ * SECTION:champlain-line
+ * @short_description: A container for #ChamplainMarker
+ *
+ * A ChamplainLine is little more than a #ClutterContainer. It keeps the
+ * markers ordered so that they display correctly.
+ *
+ * Use #clutter_container_add to add markers to the line and
+ * #clutter_container_remove to remove them.
+ */
+
+#include "config.h"
+
+#include "champlain-line.h"
+
+#include "champlain-defines.h"
+
+#include <clutter/clutter.h>
+#include <glib.h>
+
+G_DEFINE_TYPE (ChamplainLine, champlain_line, G_TYPE_OBJECT)
+
+#define GET_PRIVATE(o) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), CHAMPLAIN_TYPE_LINE, ChamplainLinePrivate))
+
+enum
+{
+  PROP_0
+};
+
+struct _ChamplainLinePrivate {
+  GList *points;
+};
+
+static void
+champlain_line_get_property (GObject *object,
+    guint property_id,
+    GValue *value,
+    GParamSpec *pspec)
+{
+  //ChamplainLine *self = CHAMPLAIN_LINE (object);
+  switch (property_id)
+    {
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+static void
+champlain_line_set_property (GObject *object,
+    guint property_id,
+    const GValue *value,
+    GParamSpec *pspec)
+{
+  //ChamplainLine *self = CHAMPLAIN_LINE (object);
+  switch (property_id)
+    {
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+static void
+champlain_line_dispose (GObject *object)
+{
+  //ChamplainLinePrivate *priv = GET_PRIVATE (object);
+
+  G_OBJECT_CLASS (champlain_line_parent_class)->dispose (object);
+}
+
+static void
+champlain_line_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (champlain_line_parent_class)->finalize (object);
+}
+
+static void
+champlain_line_class_init (ChamplainLineClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (ChamplainLinePrivate));
+
+  object_class->get_property = champlain_line_get_property;
+  object_class->set_property = champlain_line_set_property;
+  object_class->dispose = champlain_line_dispose;
+  object_class->finalize = champlain_line_finalize;
+}
+
+static void
+champlain_line_init (ChamplainLine *self)
+{
+  self->priv = GET_PRIVATE (self);
+
+  self->priv->points = NULL;
+}
+
+/**
+ * champlain_line_new:
+ *
+ * Returns a new #ChamplainLine ready to be to draw lines on the map
+ *
+ * Since: 0.4
+ */
+ChamplainLine *
+champlain_line_new ()
+{
+  return g_object_new (CHAMPLAIN_TYPE_LINE, NULL);
+}
+
+void
+champlain_line_add_point (ChamplainLine *self,
+    gdouble lat,
+    gdouble lon)
+{
+  g_return_if_fail (CHAMPLAIN_IS_LINE (self));
+
+  ChamplainPoint *point = g_new0 (ChamplainPoint, 1);
+  point->lat = lat;
+  point->lon = lon;
+
+  self->priv->points = g_list_append (self->priv->points, point);
+}
+
+void
+champlain_line_clear_points (ChamplainLine *self)
+{
+  g_return_if_fail (CHAMPLAIN_IS_LINE (self));
+
+  GList *next = self->priv->points;
+  while (next != NULL)
+  {
+    g_free (next->data);
+    next = g_list_next (next);
+  }
+  g_list_free (self->priv->points);
+}
+
diff --git a/champlain/champlain-line.h b/champlain/champlain-line.h
new file mode 100644
index 0000000..a2879ea
--- /dev/null
+++ b/champlain/champlain-line.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2009 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#if !defined (__CHAMPLAIN_CHAMPLAIN_H_INSIDE__) && !defined (CHAMPLAIN_COMPILATION)
+#error "Only <champlain/champlain.h> can be included directly."
+#endif
+
+#ifndef CHAMPLAIN_LINE_H
+#define CHAMPLAIN_LINE_H
+
+#include <champlain/champlain-defines.h>
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define CHAMPLAIN_TYPE_LINE champlain_line_get_type()
+
+#define CHAMPLAIN_LINE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), CHAMPLAIN_TYPE_LINE, ChamplainLine))
+
+#define CHAMPLAIN_LINE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), CHAMPLAIN_TYPE_LINE, ChamplainLineClass))
+
+#define CHAMPLAIN_IS_LINE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CHAMPLAIN_TYPE_LINE))
+
+#define CHAMPLAIN_IS_LINE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), CHAMPLAIN_TYPE_LINE))
+
+#define CHAMPLAIN_LINE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), CHAMPLAIN_TYPE_LINE, ChamplainLineClass))
+
+typedef struct _ChamplainLinePrivate ChamplainLinePrivate;
+
+typedef struct {
+  GObject parent;
+  ChamplainLinePrivate *priv;
+} ChamplainLine;
+
+typedef struct {
+  GObjectClass parent_class;
+} ChamplainLineClass;
+
+GType champlain_line_get_type (void);
+
+ChamplainLine* champlain_line_new (void);
+
+void champlain_line_add_point (ChamplainLine *line,
+    gdouble lat,
+    gdouble lon);
+
+void champlain_line_clear_points (ChamplainLine *line);
+
+G_END_DECLS
+
+#endif
diff --git a/champlain/champlain-private.h b/champlain/champlain-private.h
index 9af67e0..d27e705 100644
--- a/champlain/champlain-private.h
+++ b/champlain/champlain-private.h
@@ -29,7 +29,7 @@ typedef struct
   gint x;
   gint y;
   gint z;
-} ChamplainPoint;
+} ChamplainIntPoint;
 
 struct _ChamplainBaseMarkerPrivate
 {
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index c601333..1406a1d 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -64,6 +64,7 @@
 #include "champlain-zoom-level.h"
 
 #include <clutter/clutter.h>
+#include <clutter-cairo/clutter-cairo.h>
 #include <glib.h>
 #include <glib-object.h>
 #include <math.h>
@@ -129,7 +130,7 @@ struct _ChamplainViewPrivate
   gdouble latitude;
 
   /* Hack to get smaller x,y coordinates as the clutter limit is G_MAXINT16 */
-  ChamplainPoint anchor;
+  ChamplainIntPoint anchor;
   gdouble anchor_zoom_level; /* the zoom_level for which the current anchor has
                                 been computed for */
 
@@ -141,6 +142,7 @@ struct _ChamplainViewPrivate
   ChamplainRectangle viewport_size;
 
   ClutterActor *user_layers; /* Contains the markers */
+  ClutterActor *line_layer;  /* Contains the lines */
 
   gboolean keep_center_on_resize;
 
@@ -153,6 +155,8 @@ struct _ChamplainViewPrivate
 
   /* champlain_view_go_to's context, kept for stop_go_to */
   GoToContext *goto_context;
+
+  ChamplainLine *line;
 };
 
 G_DEFINE_TYPE (ChamplainView, champlain_view, CLUTTER_TYPE_GROUP);
@@ -199,6 +203,7 @@ static gboolean view_set_zoom_level_at (ChamplainView *view,
 static void tile_state_notify (GObject *gobject,
     GParamSpec *pspec,
     gpointer data);
+static void view_update_lines (ChamplainView *view);
 
 static gdouble
 viewport_get_longitude_at (ChamplainViewPrivate *priv, gint x)
@@ -850,6 +855,14 @@ champlain_view_init (ChamplainView *view)
       priv->user_layers);
   clutter_actor_raise (priv->user_layers, priv->map_layer);
 
+  /* Setup user_layers */
+  priv->line_layer = g_object_ref (clutter_cairo_new (800, 600));
+  clutter_actor_show (priv->line_layer);
+  clutter_container_add_actor (CLUTTER_CONTAINER (priv->viewport),
+      priv->line_layer);
+  clutter_actor_raise (priv->line_layer, priv->map_layer);
+  clutter_actor_set_position (priv->line_layer, 0, 0);
+
   champlain_view_set_size (view, priv->viewport_size.width,
       priv->viewport_size.height);
 
@@ -866,8 +879,8 @@ viewport_x_changed_cb (GObject *gobject,
 {
   ChamplainViewPrivate *priv = view->priv;
 
-  ChamplainPoint rect;
-  ChamplainPoint old_anchor;
+  ChamplainIntPoint rect;
+  ChamplainIntPoint old_anchor;
 
   tidy_viewport_get_origin (TIDY_VIEWPORT (priv->viewport), &rect.x, &rect.y,
       NULL);
@@ -885,7 +898,7 @@ viewport_x_changed_cb (GObject *gobject,
 
   if (priv->anchor.x - old_anchor.x != 0)
     {
-      ChamplainPoint diff;
+      ChamplainIntPoint diff;
 
       diff.x = priv->anchor.x - old_anchor.x;
       diff.y = priv->anchor.y - old_anchor.y;
@@ -902,6 +915,7 @@ viewport_x_changed_cb (GObject *gobject,
   view_load_visible_tiles (view);
   view_tiles_reposition (view);
   marker_reposition (view);
+  view_update_lines (view);
 
   priv->longitude = viewport_get_current_longitude (priv);
   priv->latitude = viewport_get_current_latitude (priv);
@@ -2158,3 +2172,29 @@ champlain_view_get_zoom_on_double_click (ChamplainView *view)
   return priv->zoom_on_double_click;
 }
 
+void
+champlain_view_add_line (ChamplainView *view,
+    ChamplainLine *line)
+{
+  g_return_if_fail (CHAMPLAIN_IS_VIEW (view));
+  g_return_if_fail (CHAMPLAIN_IS_LINE (line));
+
+  view->priv->line = g_object_ref (line);
+}
+
+static void
+view_update_lines (ChamplainView *view)
+{
+  cairo_t *cr;
+  cr = clutter_cairo_create (CLUTTER_CAIRO (view->priv->line_layer));
+
+  cairo_move_to (cr, 0, 0);
+  cairo_line_to (cr, 100, 0);
+  cairo_line_to (cr, 100, 200);
+  cairo_line_to (cr, 100, 100);
+  cairo_line_to (cr, 0, 100);
+
+  cairo_stroke (cr);
+  cairo_destroy (cr);
+
+}
diff --git a/champlain/champlain-view.h b/champlain/champlain-view.h
index c998b60..1645cdc 100644
--- a/champlain/champlain-view.h
+++ b/champlain/champlain-view.h
@@ -24,8 +24,9 @@
 #define CHAMPLAIN_VIEW_H
 
 #include <champlain/champlain-defines.h>
-#include <champlain/champlain-layer.h>
 #include <champlain/champlain-base-marker.h>
+#include <champlain/champlain-layer.h>
+#include <champlain/champlain-line.h>
 #include <champlain/champlain-map-source.h>
 #include <champlain/champlain-zoom-level.h>
 
@@ -139,6 +140,9 @@ gboolean champlain_view_get_keep_center_on_resize (ChamplainView *view);
 gboolean champlain_view_get_show_license (ChamplainView *view);
 gboolean champlain_view_get_zoom_on_double_click (ChamplainView *view);
 
+void champlain_view_add_line (ChamplainView *view,
+    ChamplainLine *line);
+
 G_END_DECLS
 
 #endif
diff --git a/demos/Makefile.am b/demos/Makefile.am
index 51263c1..5d9e6b4 100644
--- a/demos/Makefile.am
+++ b/demos/Makefile.am
@@ -1,4 +1,4 @@
-noinst_PROGRAMS = launcher animated-marker
+noinst_PROGRAMS = launcher animated-marker lines
 
 INCLUDES = -I$(top_srcdir)
 
@@ -11,6 +11,9 @@ launcher_LDADD = $(DEPS_LIBS) ../champlain/libchamplain-0.3.la
 animated_marker_SOURCES = animated-marker.c
 animated_marker_LDADD = $(DEPS_LIBS) ../champlain/libchamplain-0.3.la
 
+lines_SOURCES = lines.c
+lines_LDADD = $(DEPS_LIBS) ../champlain/libchamplain-0.3.la
+
 if ENABLE_GTK
 noinst_PROGRAMS += launcher-gtk
 launcher_gtk_SOURCES = launcher-gtk.c markers.c
diff --git a/demos/lines.c b/demos/lines.c
new file mode 100644
index 0000000..f47b66b
--- /dev/null
+++ b/demos/lines.c
@@ -0,0 +1,126 @@
+/*
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <champlain/champlain.h>
+
+#define PADDING 10
+
+static gboolean
+zoom_in (ClutterActor *actor,
+    ClutterButtonEvent *event,
+    ChamplainView * view)
+{
+  champlain_view_zoom_in (view);
+  return TRUE;
+}
+
+static gboolean
+zoom_out (ClutterActor *actor,
+    ClutterButtonEvent *event,
+    ChamplainView * view)
+{
+  champlain_view_zoom_out (view);
+  return TRUE;
+}
+
+static ClutterActor *
+make_button (char *text)
+{
+  ClutterActor *button, *button_bg, *button_text;
+  ClutterColor white = { 0xff, 0xff, 0xff, 0xff };
+  ClutterColor black = { 0x00, 0x00, 0x00, 0xff };
+  guint width, height;
+
+  button = clutter_group_new ();
+
+  button_bg = clutter_rectangle_new_with_color (&white);
+  clutter_container_add_actor (CLUTTER_CONTAINER (button), button_bg);
+  clutter_actor_set_opacity (button_bg, 0xcc);
+
+  button_text = clutter_label_new_full ("Sans 10", text, &black);
+  clutter_container_add_actor (CLUTTER_CONTAINER (button), button_text);
+  clutter_actor_get_size (button_text, &width, &height);
+
+  clutter_actor_set_size (button_bg, width + PADDING * 2, height + PADDING * 2);
+  clutter_actor_set_position (button_bg, 0, 0);
+  clutter_actor_set_position (button_text, PADDING, PADDING);
+
+  return button;
+}
+
+int
+main (int argc,
+    char *argv[])
+{
+  ClutterActor* actor, *stage, *buttons, *button;
+  ChamplainLine *line;
+  guint width, total_width = 0;;
+
+  g_thread_init (NULL);
+  clutter_init (&argc, &argv);
+
+  stage = clutter_stage_get_default ();
+  clutter_actor_set_size (stage, 800, 600);
+
+  /* Create the map view */
+  actor = champlain_view_new ();
+  champlain_view_set_size (CHAMPLAIN_VIEW (actor), 800, 600);
+  clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
+
+  /* Create the buttons */
+  buttons = clutter_group_new ();
+  clutter_actor_set_position (buttons, PADDING, PADDING);
+
+  button = make_button ("Zoom in");
+  clutter_container_add_actor (CLUTTER_CONTAINER (buttons), button);
+  clutter_actor_set_reactive (button, TRUE);
+  clutter_actor_get_size (button, &width, NULL);
+  total_width += width + PADDING;
+  g_signal_connect (button, "button-release-event",
+      G_CALLBACK (zoom_in),
+      actor);
+
+  button = make_button ("Zoom out");
+  clutter_container_add_actor (CLUTTER_CONTAINER (buttons), button);
+  clutter_actor_set_reactive (button, TRUE);
+  clutter_actor_set_position (button, total_width, 0);
+  clutter_actor_get_size (button, &width, NULL);
+  total_width += width + PADDING;
+  g_signal_connect (button, "button-release-event",
+      G_CALLBACK (zoom_out),
+      actor);
+
+  clutter_container_add_actor (CLUTTER_CONTAINER (stage), buttons);
+
+  /* draw a line */
+  line = champlain_line_new ();
+  champlain_line_add_point (line, -40, -70);
+  champlain_line_add_point (line, -45, -75);
+  champlain_view_add_line (CHAMPLAIN_VIEW (actor), line);
+
+
+  /* Finish initialising the map view */
+  g_object_set (G_OBJECT (actor), "zoom-level", 12,
+      "scroll-mode", CHAMPLAIN_SCROLL_MODE_KINETIC, NULL);
+  champlain_view_center_on(CHAMPLAIN_VIEW(actor), 45.466, -73.75);
+
+  clutter_actor_show (stage);
+  clutter_main ();
+
+  return 0;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]