]> err.no Git - libchamplain/commitdiff
Fix Bug 559522 – Lack of user feedback during loading of tiles
authorPierre-Luc Beaudoin <pierre-luc@pierlux.com>
Tue, 10 Mar 2009 20:46:35 +0000 (22:46 +0200)
committerPierre-Luc Beaudoin <pierre-luc@pierlux.com>
Tue, 10 Mar 2009 20:46:35 +0000 (22:46 +0200)
by adding ChamplainView:state which changes state depending if there is any tile loading.

champlain/champlain-view.c
demos/launcher-gtk.c

index 5ef29117fe1d48fcf90abbcbcfcc74c2c7b3cf32..6fd97a29756f313d8650da5bfe5dc88deb147e2f 100644 (file)
@@ -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");
+    }
 }
 
 /**
index e528f7de4fa6841dbcf33cfd0fe8c6d9dc7ec13f..a3a3779fc2d631e55c5f200440a26909e2cb3f30 100644 (file)
@@ -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);