[libchamplain] Resize polygon actors on ChamplainView resize



commit c975748539b47aa06bf7b7b124746cbd6f7f6524
Author: Pierre-Luc Beaudoin <pierre-luc pierlux com>
Date:   Tue Jun 9 23:30:30 2009 -0400

    Resize polygon actors on ChamplainView resize
    
    Also add visibility

 champlain/champlain-polygon.c |   77 +++++++++++++++++-
 champlain/champlain-polygon.h |    4 +
 champlain/champlain-private.h |    1 +
 champlain/champlain-view.c    |  175 +++++++++++++++++++++++++++--------------
 demos/launcher-gtk.c          |   27 ++++++-
 5 files changed, 221 insertions(+), 63 deletions(-)
---
diff --git a/champlain/champlain-polygon.c b/champlain/champlain-polygon.c
index 2a8d978..f2281ca 100644
--- a/champlain/champlain-polygon.c
+++ b/champlain/champlain-polygon.c
@@ -55,6 +55,7 @@ enum
   PROP_FILL,
   PROP_FILL_COLOR,
   PROP_STROKE,
+  PROP_VISIBLE,
 };
 
 static void
@@ -85,6 +86,9 @@ champlain_polygon_get_property (GObject *object,
       case PROP_STROKE_WIDTH:
         g_value_set_double (value, priv->stroke_width);
         break;
+      case PROP_VISIBLE:
+        g_value_set_boolean (value, priv->visible);
+        break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
     }
@@ -123,6 +127,12 @@ champlain_polygon_set_property (GObject *object,
         champlain_polygon_set_stroke_width (CHAMPLAIN_POLYGON (object),
             g_value_get_double (value));
         break;
+      case PROP_VISIBLE:
+        if (g_value_get_boolean (value) == TRUE)
+            champlain_polygon_show (CHAMPLAIN_POLYGON (object));
+        else
+            champlain_polygon_hide (CHAMPLAIN_POLYGON (object));
+        break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
     }
@@ -131,7 +141,13 @@ champlain_polygon_set_property (GObject *object,
 static void
 champlain_polygon_dispose (GObject *object)
 {
-  //ChamplainPolygonPrivate *priv = GET_PRIVATE (object);
+  ChamplainPolygonPrivate *priv = GET_PRIVATE (object);
+
+  if (priv->actor != NULL)
+    {
+      g_object_unref (priv->actor);
+      priv->actor = NULL;
+    }
 
   G_OBJECT_CLASS (champlain_polygon_parent_class)->dispose (object);
 }
@@ -241,6 +257,21 @@ champlain_polygon_class_init (ChamplainPolygonClass *klass)
           0, 100.0,
           2.0,
           CHAMPLAIN_PARAM_READWRITE));
+
+  /**
+  * ChamplainPolygon:visible:
+  *
+  * Wether the polygon is visible
+  *
+  * Since: 0.4
+  */
+  g_object_class_install_property (object_class,
+      PROP_VISIBLE,
+      g_param_spec_boolean ("visible",
+          "Visible",
+          "The polygon's visibility",
+          TRUE,
+          CHAMPLAIN_PARAM_READWRITE));
 }
 
 static void
@@ -248,6 +279,7 @@ champlain_polygon_init (ChamplainPolygon *self)
 {
   self->priv = GET_PRIVATE (self);
 
+  self->priv->visible = TRUE;
   self->priv->points = NULL;
   self->priv->fill = FALSE;
   self->priv->stroke = TRUE;
@@ -255,8 +287,6 @@ champlain_polygon_init (ChamplainPolygon *self)
 
   self->priv->fill_color = clutter_color_copy (&DEFAULT_FILL_COLOR);
   self->priv->stroke_color = clutter_color_copy (&DEFAULT_STROKE_COLOR);
-  self->priv->actor = g_object_ref (clutter_cairo_new (800, 600));
-  clutter_actor_set_position (self->priv->actor, 0, 0);
 }
 
 /**
@@ -470,6 +500,7 @@ champlain_polygon_set_stroke (ChamplainPolygon *polygon,
   g_return_if_fail (CHAMPLAIN_IS_POLYGON (polygon));
 
   polygon->priv->stroke = value;
+  g_object_notify (G_OBJECT (polygon), "stroke");
 }
 
 /**
@@ -504,6 +535,7 @@ champlain_polygon_set_fill (ChamplainPolygon *polygon,
   g_return_if_fail (CHAMPLAIN_IS_POLYGON (polygon));
 
   polygon->priv->fill = value;
+  g_object_notify (G_OBJECT (polygon), "fill");
 }
 
 /**
@@ -538,6 +570,7 @@ champlain_polygon_set_stroke_width (ChamplainPolygon *polygon,
   g_return_if_fail (CHAMPLAIN_IS_POLYGON (polygon));
 
   polygon->priv->stroke_width = value;
+  g_object_notify (G_OBJECT (polygon), "stroke-width");
 }
 
 /**
@@ -555,3 +588,41 @@ champlain_polygon_get_stroke_width (ChamplainPolygon *polygon)
 
   return polygon->priv->stroke_width;
 }
+
+/**
+ * champlain_polygon_show:
+ * @polygon: The polygon
+ *
+ * Makes the polygon visible
+ *
+ * Since: 0.4
+ */
+void
+champlain_polygon_show (ChamplainPolygon *polygon)
+{
+  g_return_if_fail (CHAMPLAIN_IS_POLYGON (polygon));
+
+  polygon->priv->visible = TRUE;
+  if (polygon->priv->actor != NULL)
+    clutter_actor_show (polygon->priv->actor);
+  g_object_notify (G_OBJECT (polygon), "visible");
+}
+
+/**
+ * champlain_polygon_hide:
+ * @polygon: The polygon
+ *
+ * Hides the polygon
+ *
+ * Since: 0.4
+ */
+void
+champlain_polygon_hide (ChamplainPolygon *polygon)
+{
+  g_return_if_fail (CHAMPLAIN_IS_POLYGON (polygon));
+
+  polygon->priv->visible = FALSE;
+  if (polygon->priv->actor != NULL)
+    clutter_actor_hide (polygon->priv->actor);
+  g_object_notify (G_OBJECT (polygon), "visible");
+}
diff --git a/champlain/champlain-polygon.h b/champlain/champlain-polygon.h
index d5ab205..4bdaa74 100644
--- a/champlain/champlain-polygon.h
+++ b/champlain/champlain-polygon.h
@@ -88,6 +88,10 @@ void champlain_polygon_set_stroke (ChamplainPolygon *polygon,
 void champlain_polygon_set_stroke_width (ChamplainPolygon *polygon,
     gdouble value);
 gdouble champlain_polygon_get_stroke_width (ChamplainPolygon *polygon);
+
+void champlain_polygon_show (ChamplainPolygon *polygon);
+void champlain_polygon_hide (ChamplainPolygon *polygon);
+
 G_END_DECLS
 
 #endif
diff --git a/champlain/champlain-private.h b/champlain/champlain-private.h
index 65e94e9..adc4c7a 100644
--- a/champlain/champlain-private.h
+++ b/champlain/champlain-private.h
@@ -46,6 +46,7 @@ struct _ChamplainPolygonPrivate {
   gboolean stroke;
   gdouble stroke_width;
   ClutterActor *actor;
+  gboolean visible;
 };
 
 typedef struct
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index d204f62..cd8c283 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -365,10 +365,82 @@ license_set_position (ChamplainView *view)
 }
 
 static void
+draw_polygon (ChamplainView *view, ChamplainPolygon *polygon)
+{
+  cairo_t *cr;
+  ChamplainViewPrivate *priv = view->priv;
+
+  if (polygon->priv->visible == FALSE)
+    return;
+
+  cr = clutter_cairo_create (CLUTTER_CAIRO (polygon->priv->actor));
+
+  /* Clear the drawing area */
+  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+  cairo_rectangle (cr, 0, 0,
+      view->priv->viewport_size.width,
+      view->priv->viewport_size.height);
+  cairo_fill (cr);
+
+  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+  GList *list = g_list_first (polygon->priv->points);
+  while (list != NULL)
+    {
+      ChamplainPoint *point = (ChamplainPoint*) list->data;
+      gint x, y;
+
+      x = champlain_map_source_get_x (priv->map_source, priv->zoom_level,
+          point->lon);
+      y = champlain_map_source_get_y (priv->map_source, priv->zoom_level,
+          point->lat);
+
+      x -= priv->viewport_size.x + priv->anchor.x;
+      y -= priv->viewport_size.y + priv->anchor.y;
+
+      cairo_line_to (cr, x, y);
+      list = list->next;
+    }
+
+  if (polygon->priv->closed_path)
+    cairo_close_path (cr);
+
+  cairo_set_source_rgba (cr,
+      polygon->priv->fill_color->red / 255.0,
+      polygon->priv->fill_color->green / 255.0,
+      polygon->priv->fill_color->blue / 255.0,
+      polygon->priv->fill_color->alpha / 255.0);
+
+  if (polygon->priv->fill)
+    cairo_fill_preserve (cr);
+
+  cairo_set_source_rgba (cr,
+      polygon->priv->stroke_color->red / 255.0,
+      polygon->priv->stroke_color->green / 255.0,
+      polygon->priv->stroke_color->blue / 255.0,
+      polygon->priv->stroke_color->alpha / 255.0);
+
+  cairo_set_line_width (cr, polygon->priv->stroke_width);
+
+  if (polygon->priv->stroke)
+    cairo_stroke (cr);
+
+  cairo_destroy (cr);
+}
+
+static void
+notify_polygon_visible_cb (ChamplainPolygon *polygon,
+    GParamSpec *arg1,
+    ChamplainView *view)
+{
+  draw_polygon (view, polygon);
+}
+
+static void
 resize_viewport (ChamplainView *view)
 {
   gdouble lower, upper;
   TidyAdjustment *hadjust, *vadjust;
+  GList *polygons;
 
   ChamplainViewPrivate *priv = view->priv;
 
@@ -410,6 +482,37 @@ resize_viewport (ChamplainView *view)
     }
   g_object_set (vadjust, "lower", lower, "upper", upper,
       "page-size", 1.0, "step-increment", 1.0, "elastic", TRUE, NULL);
+
+  /* Resize polygon actors */
+  if (priv->viewport_size.width == 0 ||
+      priv->viewport_size.height == 0)
+    return;
+
+  polygons = priv->polygons;
+  while (polygons != NULL)
+    {
+      ChamplainPolygon *polygon;
+
+      polygon = CHAMPLAIN_POLYGON (polygons->data);
+
+      if (polygon->priv->actor != NULL)
+        {
+          g_object_unref (polygon->priv->actor);
+          clutter_container_remove_actor (CLUTTER_CONTAINER (view->priv->polygon_layer),
+              polygon->priv->actor);
+        }
+
+      polygon->priv->actor = g_object_ref (clutter_cairo_new (
+          view->priv->viewport_size.width,
+          view->priv->viewport_size.height));
+      g_object_set (G_OBJECT (polygon->priv->actor), "visible",
+          polygon->priv->visible, NULL);
+      clutter_container_add_actor (CLUTTER_CONTAINER (view->priv->polygon_layer),
+          polygon->priv->actor);
+      clutter_actor_set_position (polygon->priv->actor, 0, 0);
+      draw_polygon (view, polygon);
+      polygons = polygons->next;
+    }
 }
 
 static void
@@ -2190,64 +2293,6 @@ champlain_view_get_zoom_on_double_click (ChamplainView *view)
 }
 
 static void
-draw_polygon (ChamplainView *view, ChamplainPolygon *polygon)
-{
-  cairo_t *cr;
-  ChamplainViewPrivate *priv = view->priv;
-
-  cr = clutter_cairo_create (CLUTTER_CAIRO (polygon->priv->actor));
-
-  /* Clear the drawing area */
-  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
-  cairo_rectangle (cr, 0, 0, 800, 600); //XXX
-  cairo_fill (cr);
-
-  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
-  GList *list = g_list_first (polygon->priv->points);
-  while (list != NULL)
-    {
-      ChamplainPoint *point = (ChamplainPoint*) list->data;
-      gint x, y;
-
-      x = champlain_map_source_get_x (priv->map_source, priv->zoom_level,
-          point->lon);
-      y = champlain_map_source_get_y (priv->map_source, priv->zoom_level,
-          point->lat);
-
-      x -= priv->viewport_size.x + priv->anchor.x;
-      y -= priv->viewport_size.y + priv->anchor.y;
-
-      cairo_line_to (cr, x, y);
-      list = list->next;
-    }
-
-  if (polygon->priv->closed_path)
-    cairo_close_path (cr);
-
-  cairo_set_source_rgba (cr,
-      polygon->priv->fill_color->red / 255.0,
-      polygon->priv->fill_color->green / 255.0,
-      polygon->priv->fill_color->blue / 255.0,
-      polygon->priv->fill_color->alpha / 255.0);
-
-  if (polygon->priv->fill)
-    cairo_fill_preserve (cr);
-
-  cairo_set_source_rgba (cr,
-      polygon->priv->stroke_color->red / 255.0,
-      polygon->priv->stroke_color->green / 255.0,
-      polygon->priv->stroke_color->blue / 255.0,
-      polygon->priv->stroke_color->alpha / 255.0);
-
-  cairo_set_line_width (cr, polygon->priv->stroke_width);
-
-  if (polygon->priv->stroke)
-    cairo_stroke (cr);
-
-  cairo_destroy (cr);
-}
-
-static void
 view_update_polygons (ChamplainView *view)
 {
   ChamplainViewPrivate *priv = view->priv;
@@ -2291,6 +2336,20 @@ champlain_view_add_polygon (ChamplainView *view,
   g_return_if_fail (CHAMPLAIN_IS_POLYGON (polygon));
 
   view->priv->polygons = g_list_append (view->priv->polygons, g_object_ref (polygon));
+
+  g_signal_connect (polygon, "notify::visible",
+      G_CALLBACK (notify_polygon_visible_cb), view);
+
+  if (view->priv->viewport_size.width == 0 ||
+      view->priv->viewport_size.height == 0)
+    return;
+
+  polygon->priv->actor = g_object_ref (clutter_cairo_new (
+      view->priv->viewport_size.width,
+      view->priv->viewport_size.height));
+  g_object_set (G_OBJECT (polygon->priv->actor), "visible",
+      polygon->priv->visible, NULL);
+  clutter_actor_set_position (polygon->priv->actor, 0, 0);
   clutter_container_add_actor (CLUTTER_CONTAINER (view->priv->polygon_layer),
       polygon->priv->actor);
 }
diff --git a/demos/launcher-gtk.c b/demos/launcher-gtk.c
index 194d9fd..420b9b1 100644
--- a/demos/launcher-gtk.c
+++ b/demos/launcher-gtk.c
@@ -28,6 +28,8 @@
 #define COL_ID 0
 #define COL_NAME 1
 
+static ChamplainPolygon *polygon;
+
 /*
  * Terminate the main loop.
  */
@@ -42,9 +44,15 @@ toggle_layer (GtkToggleButton *widget,
               ClutterActor *layer)
 {
   if(gtk_toggle_button_get_active(widget))
-    clutter_actor_show_all(layer);
+    {
+      champlain_polygon_show (polygon);
+      clutter_actor_show_all (layer);
+    }
   else
-    clutter_actor_hide(layer);
+    {
+      champlain_polygon_hide (polygon);
+      clutter_actor_hide (layer);
+    }
 }
 
 static void
@@ -207,6 +215,21 @@ main (int argc,
   champlain_view_add_layer(CHAMPLAIN_VIEW (view), layer);
   clutter_actor_hide (CLUTTER_ACTOR (layer));
 
+  polygon = champlain_polygon_new ();
+  /* Cheap approx of Highway 10 */
+  champlain_polygon_append_point (polygon, 45.4095, -73.3197);
+  champlain_polygon_append_point (polygon, 45.4104, -73.2846);
+  champlain_polygon_append_point (polygon, 45.4178, -73.2239);
+  champlain_polygon_append_point (polygon, 45.4176, -73.2181);
+  champlain_polygon_append_point (polygon, 45.4151, -73.2126);
+  champlain_polygon_append_point (polygon, 45.4016, -73.1926);
+  champlain_polygon_append_point (polygon, 45.3994, -73.1877);
+  champlain_polygon_append_point (polygon, 45.4000, -73.1815);
+  champlain_polygon_append_point (polygon, 45.4151, -73.1218);
+  champlain_polygon_set_stroke_width (polygon, 5.0);
+  champlain_view_add_polygon (CHAMPLAIN_VIEW (view), polygon);
+  champlain_polygon_hide (polygon);
+
   gtk_widget_set_size_request(widget, 640, 480);
 
   bbox =  gtk_hbox_new (FALSE, 10);



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