[libchamplain] Completely remove the anchor complexity from ChamplainView



commit 42ee0ab8fe3dc8107e7f594cbae2beb386461d98
Author: Jiří Techet <techet gmail com>
Date:   Wed May 1 01:05:32 2013 +0200

    Completely remove the anchor complexity from ChamplainView

 champlain/champlain-view.c     |  141 +++++++++++-----------------------------
 champlain/champlain-viewport.c |   98 ++++++++++++++++++----------
 2 files changed, 102 insertions(+), 137 deletions(-)
---
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index 83efa53..b75738a 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -165,10 +165,6 @@ struct _ChamplainViewPrivate
   /* Timer to track time between viewport updates */
   GTimer *update_viewport_timer;
 
-  guint anchor_zoom_level; /* the zoom_level for which the current anchor has
-                                been computed for */
-
-  
   gint bg_offset_x;
   gint bg_offset_y;
 
@@ -220,9 +216,6 @@ static gboolean kinetic_scroll_button_press_cb (ClutterActor *actor,
 static void view_load_visible_tiles (ChamplainView *view);
 static void view_position_tile (ChamplainView *view,
     ChamplainTile *tile);
-static gboolean view_update_anchor (ChamplainView *view,
-    gint x,
-    gint y);
 static gboolean view_set_zoom_level_at (ChamplainView *view,
     guint zoom_level,
     gboolean use_event_coord,
@@ -240,6 +233,7 @@ static void champlain_view_go_to_with_duration (ChamplainView *view,
     guint duration);
 static gboolean fill_tile_cb (FillTileCallbackData *data);
 static gboolean redraw_timeout_cb(gpointer view);
+static void remove_all_tiles (ChamplainView *view);
 
 
 /* Updates the internals after the viewport changed */
@@ -247,16 +241,22 @@ static void
 update_viewport (ChamplainView *view,
     gdouble x,
     gdouble y,
-    gboolean force_relocate)
+    gboolean relocate)
 {
   DEBUG_LOG ()
 
   ChamplainViewPrivate *priv = view->priv;
-  gboolean relocate;
-  gfloat bg_width = 1.0; 
-  gfloat bg_height = 1.0;
-  gboolean moved = ABS (x - priv->viewport_x) > 0.5 || ABS (y - priv->viewport_y) > 0.5;
 
+  /* remember the relative offset of the background tile */
+  gfloat bg_width = 1.0;
+  gfloat bg_height = 1.0;
+  if (priv->background_content)
+      clutter_content_get_preferred_size (priv->background_content, &bg_width, &bg_height);
+  gint old_bg_offset_x = (priv->viewport_x + priv->bg_offset_x) % (gint)bg_width;
+  gint old_bg_offset_y = (priv->viewport_y + priv->bg_offset_y) % (gint)bg_height;
+    
+  priv->viewport_x = x;
+  priv->viewport_y = y;
   priv->longitude = champlain_map_source_get_longitude (priv->map_source,
         priv->zoom_level,
         x + priv->viewport_width / 2.0);
@@ -265,18 +265,7 @@ update_viewport (ChamplainView *view,
         priv->zoom_level,
         y + priv->viewport_height / 2.0);
 
-  /* remember the relative offset of the background tile */
-  if (priv->background_content)
-    clutter_content_get_preferred_size (priv->background_content, &bg_width, &bg_height);
-  gint old_bg_offset_x = (priv->viewport_x + priv->bg_offset_x) % (gint)bg_width;
-  gint old_bg_offset_y = (priv->viewport_y + priv->bg_offset_y) % (gint)bg_height;
-  
-  relocate = view_update_anchor (view, x, y);
-
-  priv->viewport_x = x;
-  priv->viewport_y = y;
-
-  if (relocate || force_relocate)
+  if (relocate)
     {
       /* compute the new relative offset of the background tile */
       gint new_bg_offset_x = priv->viewport_x % (gint)bg_width;
@@ -288,22 +277,28 @@ update_viewport (ChamplainView *view,
       if (priv->bg_offset_y < 0)
         priv->bg_offset_y += bg_height;
 
-      g_signal_handlers_block_by_func (priv->viewport, G_CALLBACK (viewport_pos_changed_cb), view);
+      remove_all_tiles (view);  
       champlain_viewport_set_origin (CHAMPLAIN_VIEWPORT (priv->viewport),
           priv->viewport_x,
           priv->viewport_y);
-      g_signal_handlers_unblock_by_func (priv->viewport, G_CALLBACK (viewport_pos_changed_cb), view);
 
       g_signal_emit_by_name (view, "layer-relocated", NULL);
     }
 
   view_load_visible_tiles (view);
   
-  if (moved)
-    {
-      g_object_notify (G_OBJECT (view), "longitude");
-      g_object_notify (G_OBJECT (view), "latitude");
-    }
+  g_object_notify (G_OBJECT (view), "longitude");
+  g_object_notify (G_OBJECT (view), "latitude");
+}
+
+
+static void
+view_relocated_cb (G_GNUC_UNUSED ChamplainViewport *viewport,
+    ChamplainView *view)
+{
+  remove_all_tiles (view);  
+  view_load_visible_tiles (view);
+  g_signal_emit_by_name (view, "layer-relocated", NULL);
 }
 
 
@@ -318,7 +313,7 @@ panning_completed (G_GNUC_UNUSED ChamplainKineticScrollView *scroll,
 
   champlain_viewport_get_origin (CHAMPLAIN_VIEWPORT (priv->viewport), &x, &y);
 
-  update_viewport (view, x, y, FALSE);
+  update_viewport (view, ceil(x), ceil(y), FALSE);
 }
 
 
@@ -358,18 +353,15 @@ resize_viewport (ChamplainView *view)
   champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport), &hadjust,
       &vadjust);
 
-  if (priv->zoom_level < 8)
-    {
-      gdouble map_width = champlain_map_source_get_column_count (priv->map_source, priv->zoom_level) *
-        champlain_map_source_get_tile_size (priv->map_source);
-      gdouble map_height = champlain_map_source_get_row_count (priv->map_source, priv->zoom_level) *
-        champlain_map_source_get_tile_size (priv->map_source);
-      
-      lower_x = MIN (-priv->viewport_width / 2.0, -priv->viewport_width + map_width / 2.0);
-      lower_y = MIN (-priv->viewport_height / 2.0, -priv->viewport_height + map_height / 2.0);
-      upper_x = MAX (map_width - priv->viewport_width / 2.0, map_width / 2.0);
-      upper_y = MAX (map_height - priv->viewport_height / 2.0, map_height / 2.0);
-    }
+  gdouble map_width = champlain_map_source_get_column_count (priv->map_source, priv->zoom_level) *
+    champlain_map_source_get_tile_size (priv->map_source);
+  gdouble map_height = champlain_map_source_get_row_count (priv->map_source, priv->zoom_level) *
+    champlain_map_source_get_tile_size (priv->map_source);
+  
+  lower_x = MIN (-priv->viewport_width / 2.0, -priv->viewport_width + map_width / 2.0);
+  lower_y = MIN (-priv->viewport_height / 2.0, -priv->viewport_height + map_height / 2.0);
+  upper_x = MAX (map_width - priv->viewport_width / 2.0, map_width / 2.0);
+  upper_y = MAX (map_height - priv->viewport_height / 2.0, map_height / 2.0);
 
   /*
    * block emmision of signal by priv->viewport with viewport_pos_changed_cb()
@@ -1008,7 +1000,6 @@ champlain_view_init (ChamplainView *view)
   priv->viewport_y = 0;
   priv->viewport_width = 0;
   priv->viewport_height = 0;
-  priv->anchor_zoom_level = 0;
   priv->state = CHAMPLAIN_STATE_NONE;
   priv->latitude = 0.0;
   priv->longitude = 0.0;
@@ -1047,6 +1038,7 @@ champlain_view_init (ChamplainView *view)
   /* Setup viewport */
   priv->viewport = champlain_viewport_new ();
   champlain_viewport_set_child (CHAMPLAIN_VIEWPORT (priv->viewport), viewport_container);
+  g_signal_connect (priv->viewport, "relocated", G_CALLBACK (view_relocated_cb), view);
 
   g_signal_connect (priv->viewport, "notify::x-origin",
       G_CALLBACK (viewport_pos_changed_cb), view);
@@ -1301,62 +1293,6 @@ champlain_view_new (void)
 }
 
 
-static gboolean
-view_update_anchor (ChamplainView *view,
-    gint x,  /* Absolute x of the viewport center */
-    gint y)  /* Absolute y of the viewport center */
-{
-  DEBUG_LOG ()
-
-  ChamplainViewPrivate *priv = view->priv;
-  gboolean need_anchor = FALSE;
-  gboolean need_update = FALSE;
-  gint anchor_x, anchor_y;
-  
-  champlain_viewport_get_anchor (CHAMPLAIN_VIEWPORT (priv->viewport), &anchor_x, &anchor_y);
-  
-  if (priv->zoom_level >= 8)
-    need_anchor = TRUE;
-  else if (anchor_x == 0 && anchor_y == 0)
-    return FALSE;
-
-  /* update anchor one viewport size before reaching the margin to be sure */
-  if (priv->anchor_zoom_level != priv->zoom_level ||
-      x - anchor_x >= G_MAXINT16 - 2 * priv->viewport_width ||
-      y - anchor_y >= G_MAXINT16 - 2 * priv->viewport_height ||
-      x - anchor_x <= 0 + priv->viewport_width ||
-      y - anchor_y <= 0 + priv->viewport_height)
-    need_update = TRUE;
-
-  if (need_update)
-    {
-      if (need_anchor)
-        {
-          anchor_x = x - G_MAXINT16 / 2;
-          anchor_y = y - G_MAXINT16 / 2;
-
-          if (anchor_x < 0)
-            anchor_x = 0;
-          if (anchor_y < 0)
-            anchor_y = 0;
-
-          DEBUG ("New Anchor (%d, %d) at (%d, %d)", anchor_x, anchor_y, x, y);
-        }
-      else
-        {
-          anchor_x = 0;
-          anchor_y = 0;
-          DEBUG ("Clear Anchor at (%d, %d)", x, y);
-        }
-
-      priv->anchor_zoom_level = priv->zoom_level;
-      champlain_viewport_set_anchor (CHAMPLAIN_VIEWPORT (priv->viewport), anchor_x, anchor_y);
-    }
-
-  return need_update;
-}
-
-
 /**
  * champlain_view_center_on:
  * @view: a #ChamplainView
@@ -2107,6 +2043,8 @@ remove_all_tiles (ChamplainView *view)
   ClutterActorIter iter;
   ClutterActor *child;
 
+  clutter_actor_destroy_all_children (priv->zoom_layer);
+
   clutter_actor_iter_init (&iter, priv->map_layer);
   while (clutter_actor_iter_next (&iter, &child))
     {
@@ -2654,7 +2592,6 @@ view_set_zoom_level_at (ChamplainView *view,
   gdouble lon = 0.0, lat = 0.0;
   gint x_diff = 0, y_diff = 0;
 
-
   if (zoom_level == priv->zoom_level || ZOOM_LEVEL_OUT_OF_RANGE (priv, zoom_level))
     return FALSE;
 
diff --git a/champlain/champlain-viewport.c b/champlain/champlain-viewport.c
index ce79331..c85f280 100644
--- a/champlain/champlain-viewport.c
+++ b/champlain/champlain-viewport.c
@@ -34,8 +34,8 @@ G_DEFINE_TYPE (ChamplainViewport, champlain_viewport, CLUTTER_TYPE_ACTOR)
 
 struct _ChamplainViewportPrivate
 {
-  gfloat x;
-  gfloat y;
+  gdouble x;
+  gdouble y;
 
   gint anchor_x;
   gint anchor_y;
@@ -54,11 +54,20 @@ enum
   PROP_VADJUST,
 };
 
+enum
+{
+  /* normal signals */
+  RELOCATED,
+  LAST_SIGNAL
+};
 
-static void set_origin (ChamplainViewport *viewport,
-    gdouble x,
-    gdouble y);
+static guint signals[LAST_SIGNAL] = { 0, };
 
+static void
+set_origin (ChamplainViewport *viewport,
+    gdouble x,
+    gdouble y,
+    gboolean emit);
 
 static void
 champlain_viewport_get_property (GObject *object,
@@ -216,6 +225,15 @@ champlain_viewport_class_init (ChamplainViewportClass *klass)
           "Vertical adjustment",
           CHAMPLAIN_TYPE_ADJUSTMENT,
           G_PARAM_READWRITE));
+          
+  signals[RELOCATED] =
+    g_signal_new ("relocated", 
+        G_OBJECT_CLASS_TYPE (gobject_class),
+        G_SIGNAL_RUN_LAST, 
+        0, NULL, NULL,
+        g_cclosure_marshal_VOID__VOID, 
+        G_TYPE_NONE, 
+        0);
 }
 
 
@@ -229,9 +247,7 @@ hadjustment_value_notify_cb (ChamplainAdjustment *adjustment,
 
   value = champlain_adjustment_get_value (adjustment);
 
-  set_origin (viewport,
-      value,
-      priv->y);
+  set_origin (viewport, value, priv->y, TRUE);
 }
 
 
@@ -244,9 +260,7 @@ vadjustment_value_notify_cb (ChamplainAdjustment *adjustment, GParamSpec *arg1,
 
   value = champlain_adjustment_get_value (adjustment);
 
-  set_origin (viewport,
-      priv->x,
-      value);
+  set_origin (viewport, priv->x, value, TRUE);
 }
 
 
@@ -375,43 +389,42 @@ champlain_viewport_new (void)
 }
 
 
-void
-champlain_viewport_set_origin (ChamplainViewport *viewport,
-    gdouble x,
-    gdouble y)
-{
-  g_return_if_fail (CHAMPLAIN_IS_VIEWPORT (viewport));
-
-  ChamplainViewportPrivate *priv = viewport->priv;
-
-  set_origin (viewport, x - priv->anchor_x, y - priv->anchor_y);
-}
-
+#define ANCHOR_LIMIT G_MAXINT16
 
 static void
 set_origin (ChamplainViewport *viewport,
     gdouble x,
-    gdouble y)
+    gdouble y,
+    gboolean emit)
 {
   g_return_if_fail (CHAMPLAIN_IS_VIEWPORT (viewport));
 
   ChamplainViewportPrivate *priv = viewport->priv;
   ClutterActor *child;
+  gboolean relocated;
 
-  priv = viewport->priv;
-
-  g_object_freeze_notify (G_OBJECT (viewport));
+  relocated = (ABS (priv->anchor_x - x) > ANCHOR_LIMIT || ABS (priv->anchor_y - y) > ANCHOR_LIMIT);
+  if (relocated)
+    {
+      priv->anchor_x = x - ANCHOR_LIMIT / 2;
+      priv->anchor_y = y - ANCHOR_LIMIT / 2;
+    }
   
   child = clutter_actor_get_first_child (CLUTTER_ACTOR (viewport));
   if (child && (x != priv->x || y != priv->y))
-    clutter_actor_set_position (child, -x, -y);
+    clutter_actor_set_position (child, -x + priv->anchor_x, -y + priv->anchor_y);
+
+  g_object_freeze_notify (G_OBJECT (viewport));
+  g_object_freeze_notify (G_OBJECT (priv->hadjustment));
+  g_object_freeze_notify (G_OBJECT (priv->vadjustment));
 
   if (x != priv->x)
     {
       priv->x = x;
-      g_object_notify (G_OBJECT (viewport), "x-origin");
+      if (emit)
+        g_object_notify (G_OBJECT (viewport), "x-origin");
 
-      if (priv->hadjustment)
+      if (priv->hadjustment && !emit)
         champlain_adjustment_set_value (priv->hadjustment,
             x);
     }
@@ -419,14 +432,29 @@ set_origin (ChamplainViewport *viewport,
   if (y != priv->y)
     {
       priv->y = y;
-      g_object_notify (G_OBJECT (viewport), "y-origin");
+      if (emit)
+        g_object_notify (G_OBJECT (viewport), "y-origin");
 
-      if (priv->vadjustment)
+      if (priv->vadjustment && !emit)
         champlain_adjustment_set_value (priv->vadjustment,
             y);
     }
-
+    
   g_object_thaw_notify (G_OBJECT (viewport));
+  g_object_thaw_notify (G_OBJECT (priv->hadjustment));
+  g_object_thaw_notify (G_OBJECT (priv->vadjustment));
+  
+  if (relocated && emit)
+    g_signal_emit_by_name (viewport, "relocated", NULL);
+}
+
+
+void
+champlain_viewport_set_origin (ChamplainViewport *viewport,
+    gdouble x,
+    gdouble y)
+{
+  set_origin (viewport, x, y, FALSE);
 }
 
 
@@ -440,10 +468,10 @@ champlain_viewport_get_origin (ChamplainViewport *viewport,
   ChamplainViewportPrivate *priv = viewport->priv;
 
   if (x)
-    *x = priv->x + priv->anchor_x;
+    *x = priv->x;
 
   if (y)
-    *y = priv->y + priv->anchor_y;
+    *y = priv->y;
 }
 
 


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