From c975748539b47aa06bf7b7b124746cbd6f7f6524 Mon Sep 17 00:00:00 2001 From: Pierre-Luc Beaudoin Date: Tue, 9 Jun 2009 23:30:30 -0400 Subject: [PATCH] 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 @@ -364,11 +364,83 @@ license_set_position (ChamplainView *view) PADDING - width, priv->viewport_size.height - PADDING - height); } +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 @@ -2189,64 +2292,6 @@ champlain_view_get_zoom_on_double_click (ChamplainView *view) return priv->zoom_on_double_click; } -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) { @@ -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); -- 2.39.5