From: Pierre-Luc Beaudoin Date: Tue, 10 Mar 2009 20:46:35 +0000 (+0200) Subject: Fix Bug 559522 – Lack of user feedback during loading of tiles X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=df6a2d229af79da6052d13a85023d92a09e5fdda;p=libchamplain Fix Bug 559522 – Lack of user feedback during loading of tiles by adding ChamplainView:state which changes state depending if there is any tile loading. --- diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c index 5ef2911..6fd97a2 100644 --- a/champlain/champlain-view.c +++ b/champlain/champlain-view.c @@ -88,7 +88,8 @@ enum PROP_SCROLL_MODE, PROP_KEEP_CENTER_ON_RESIZE, PROP_SHOW_LICENSE, - PROP_ZOOM_ON_DOUBLE_CLICK + PROP_ZOOM_ON_DOUBLE_CLICK, + PROP_STATE }; #define PADDING 10 @@ -126,6 +127,8 @@ struct _ChamplainViewPrivate gboolean show_license; ClutterActor *license_actor; /* Contains the licence info */ + + ChamplainState state; /* View's global state */ }; G_DEFINE_TYPE (ChamplainView, champlain_view, CLUTTER_TYPE_GROUP); @@ -163,6 +166,7 @@ static void license_set_position (ChamplainView *view); static void view_load_visible_tiles (ChamplainView *view); static void view_position_tile (ChamplainView* view, ChamplainTile* tile); static void view_tiles_reposition (ChamplainView* view); +static void view_update_state (ChamplainView *view); static gdouble viewport_get_longitude_at (ChamplainViewPrivate *priv, gint x) @@ -465,6 +469,9 @@ champlain_view_get_property (GObject *object, case PROP_ZOOM_ON_DOUBLE_CLICK: g_value_set_boolean (value, priv->zoom_on_double_click); break; + case PROP_STATE: + g_value_set_enum (value, priv->state); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -668,6 +675,23 @@ champlain_view_class_init (ChamplainViewClass *champlainViewClass) "Zoom in on double click", "Zoom in and recenter on double click on the map", TRUE, CHAMPLAIN_PARAM_READWRITE)); + + /** + * ChamplainView:state + * + * The view's global state. Useful to inform using if the view is busy loading + * tiles or not. + * + * Since: 0.4 + */ + g_object_class_install_property (object_class, + PROP_STATE, + g_param_spec_enum ("state", + "View's state", + "View's global state", + CHAMPLAIN_TYPE_STATE, + CHAMPLAIN_STATE_INIT, + G_PARAM_READABLE)); } static void @@ -691,6 +715,7 @@ champlain_view_init (ChamplainView *view) priv->viewport_size.height = 0; priv->anchor.x = 0; priv->anchor.y = 0; + priv->state = CHAMPLAIN_STATE_INIT; /* Setup viewport */ priv->viewport = tidy_viewport_new (); @@ -726,6 +751,9 @@ champlain_view_init (ChamplainView *view) clutter_container_add_actor (CLUTTER_CONTAINER (priv->viewport), priv->user_layers); clutter_actor_raise (priv->user_layers, priv->map_layer); + + priv->state = CHAMPLAIN_STATE_DONE; + g_object_notify (G_OBJECT (view), "state"); } static void @@ -1154,6 +1182,7 @@ view_load_visible_tiles (ChamplainView *view) viewport.y += priv->anchor.y; map_load_visible_tiles (priv->map, view, priv->map_source, viewport); + view_update_state (view); } static void @@ -1209,6 +1238,28 @@ champlain_view_tile_ready (ChamplainView *view, clutter_container_add (CLUTTER_CONTAINER (champlain_zoom_level_get_actor (level)), actor, NULL); view_position_tile (view, tile); + view_update_state (view); +} + +static void +view_update_state (ChamplainView *view) +{ + ChamplainViewPrivate *priv = GET_PRIVATE (view); + ChamplainState new_state = CHAMPLAIN_STATE_DONE; + gint i; + + for (i = 0; i < champlain_zoom_level_tile_count (priv->map->current_level); i++) + { + ChamplainTile *tile = champlain_zoom_level_get_nth_tile (priv->map->current_level, i); + if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_LOADING) + new_state = CHAMPLAIN_STATE_LOADING; + } + + if (priv->state != new_state) + { + priv->state = new_state; + g_object_notify (G_OBJECT (view), "state"); + } } /** diff --git a/demos/launcher-gtk.c b/demos/launcher-gtk.c index e528f7d..a3a3779 100644 --- a/demos/launcher-gtk.c +++ b/demos/launcher-gtk.c @@ -110,6 +110,26 @@ map_zoom_changed (ChamplainView *view, gtk_spin_button_set_value(spinbutton, zoom); } +static void +view_state_changed (ChamplainView *view, + GParamSpec *gobject, + GtkImage *image) +{ + ChamplainState state; + + g_object_get (G_OBJECT (view), "state", &state, NULL); + if (state == CHAMPLAIN_STATE_LOADING) + { + gtk_image_set_from_stock (image, GTK_STOCK_NETWORK, GTK_ICON_SIZE_BUTTON); + g_print("STATE: loading\n"); + } + else + { + gtk_image_clear (image); + g_print("STATE: done\n"); + } +} + static void zoom_in (GtkWidget *widget, ChamplainView *view) @@ -190,6 +210,11 @@ main (int argc, button); gtk_container_add (GTK_CONTAINER (bbox), button); + button = gtk_image_new (); + g_signal_connect (view, "notify::state", G_CALLBACK (view_state_changed), + button); + gtk_box_pack_end (GTK_HBOX (bbox), button, FALSE, FALSE, 0); + viewport = gtk_viewport_new (NULL, NULL); gtk_viewport_set_shadow_type (GTK_VIEWPORT(viewport), GTK_SHADOW_ETCHED_IN); gtk_container_add (GTK_CONTAINER (viewport), widget);