[libchamplain] Fixes in kinetic scroll



commit 89be3c21f617c78e43326af8aae5b2d29de6a282
Author: Jiří Techet <techet gmail com>
Date:   Wed Apr 17 11:46:51 2013 +0200

    Fixes in kinetic scroll
    
    Remove drag threshold which is not necessary for libchamplain, add sanity
    check that mouse button is released during motion event.

 champlain/champlain-kinetic-scroll-view.c | 183 ++++++++++++++----------------
 champlain/champlain-kinetic-scroll-view.h |   3 +-
 champlain/champlain-view.c                |   2 +-
 3 files changed, 90 insertions(+), 98 deletions(-)
---
diff --git a/champlain/champlain-kinetic-scroll-view.c b/champlain/champlain-kinetic-scroll-view.c
index c249a9f..14d0551 100644
--- a/champlain/champlain-kinetic-scroll-view.c
+++ b/champlain/champlain-kinetic-scroll-view.c
@@ -55,8 +55,7 @@ struct _ChamplainKineticScrollViewPrivate
   gdouble dy;
   gdouble decel_rate;
 
-  ClutterActor *child;
-  gboolean in_drag;
+  ClutterActor *viewport;
 };
 
 enum
@@ -75,6 +74,11 @@ enum
 
 static guint signals[LAST_SIGNAL] = { 0, };
 
+static gboolean
+button_release_event_cb (ClutterActor *stage,
+    ClutterButtonEvent *event,
+    ChamplainKineticScrollView *scroll);
+
 static void
 champlain_kinetic_scroll_view_get_property (GObject *object, guint property_id,
     GValue *value, GParamSpec *pspec)
@@ -135,10 +139,10 @@ champlain_kinetic_scroll_view_dispose (GObject *object)
 {
   ChamplainKineticScrollViewPrivate *priv = CHAMPLAIN_KINETIC_SCROLL_VIEW (object)->priv;
 
-  if (priv->child)
+  if (priv->viewport)
     {
       clutter_actor_remove_all_children (CLUTTER_ACTOR (object));
-      priv->child = NULL;
+      priv->viewport = NULL;
     }
 
   if (priv->deceleration_timeline)
@@ -213,6 +217,59 @@ champlain_kinetic_scroll_view_class_init (ChamplainKineticScrollViewClass *klass
 }
 
 
+static void
+clamp_adjustments (ChamplainKineticScrollView *scroll)
+{
+  ChamplainKineticScrollViewPrivate *priv = scroll->priv;
+
+  if (priv->viewport)
+    {
+      guint fps, n_frames;
+      ChamplainAdjustment *hadj, *vadj;
+      gboolean snap;
+
+      champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport),
+          &hadj, &vadj);
+
+      /* FIXME: Hard-coded value here */
+      fps = clutter_get_default_frame_rate ();
+      n_frames = fps / 6;
+
+      snap = TRUE;
+      if (champlain_adjustment_get_elastic (hadj))
+        snap = !champlain_adjustment_clamp (hadj, TRUE, n_frames, fps);
+
+      /* Snap to the nearest step increment on hadjustment */
+      if (snap)
+        {
+          gdouble d, value, lower, step_increment;
+
+          champlain_adjustment_get_values (hadj, &value, &lower, NULL,
+              &step_increment);
+          d = (rint ((value - lower) / step_increment) *
+               step_increment) + lower;
+          champlain_adjustment_set_value (hadj, d);
+        }
+
+      snap = TRUE;
+      if (champlain_adjustment_get_elastic (vadj))
+        snap = !champlain_adjustment_clamp (vadj, TRUE, n_frames, fps);
+
+      /* Snap to the nearest step increment on vadjustment */
+      if (snap)
+        {
+          gdouble d, value, lower, step_increment;
+
+          champlain_adjustment_get_values (vadj, &value, &lower, NULL,
+              &step_increment);
+          d = (rint ((value - lower) / step_increment) *
+               step_increment) + lower;
+          champlain_adjustment_set_value (vadj, d);
+        }
+    }
+}
+
+
 static gboolean
 motion_event_cb (ClutterActor *stage,
     ClutterMotionEvent *event,
@@ -224,7 +281,22 @@ motion_event_cb (ClutterActor *stage,
 
   if (event->type != CLUTTER_MOTION)
     return FALSE;
-
+    
+  if (!(event->modifier_state & CLUTTER_BUTTON1_MASK))
+  {
+    /* It sometimes -very rarely - happens that we miss the release event for some
+     * reason. This is a sanity check to disconnect the event handlers when the 
+     * button is not pressed. */
+    g_signal_handlers_disconnect_by_func (stage,
+        motion_event_cb,
+        scroll);
+    g_signal_handlers_disconnect_by_func (stage,
+        button_release_event_cb,
+        scroll);
+    clamp_adjustments (scroll);
+    g_signal_emit_by_name (scroll, "panning-completed", NULL);
+  }
+  
   if (clutter_actor_transform_stage_point (actor,
           event->x,
           event->y,
@@ -232,29 +304,12 @@ motion_event_cb (ClutterActor *stage,
     {
       ChamplainKineticScrollViewMotion *motion;
 
-      if (!priv->in_drag)
-        {
-          guint threshold = 4;
-
-          motion = &g_array_index (priv->motion_buffer,
-                ChamplainKineticScrollViewMotion, 0);
-
-          if ((ABS (motion->x - x) >= threshold) ||
-              (ABS (motion->y - y) >= threshold))
-            {
-              clutter_stage_set_motion_events_enabled (CLUTTER_STAGE (stage), TRUE);
-              priv->in_drag = TRUE;
-            }
-          else
-            return FALSE;
-        }
-
-      if (priv->child)
+      if (priv->viewport)
         {
           gdouble dx, dy;
           ChamplainAdjustment *hadjust, *vadjust;
 
-          champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->child),
+          champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport),
               &hadjust,
               &vadjust);
 
@@ -295,59 +350,6 @@ motion_event_cb (ClutterActor *stage,
 
 
 static void
-clamp_adjustments (ChamplainKineticScrollView *scroll)
-{
-  ChamplainKineticScrollViewPrivate *priv = scroll->priv;
-
-  if (priv->child)
-    {
-      guint fps, n_frames;
-      ChamplainAdjustment *hadj, *vadj;
-      gboolean snap;
-
-      champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->child),
-          &hadj, &vadj);
-
-      /* FIXME: Hard-coded value here */
-      fps = clutter_get_default_frame_rate ();
-      n_frames = fps / 6;
-
-      snap = TRUE;
-      if (champlain_adjustment_get_elastic (hadj))
-        snap = !champlain_adjustment_clamp (hadj, TRUE, n_frames, fps);
-
-      /* Snap to the nearest step increment on hadjustment */
-      if (snap)
-        {
-          gdouble d, value, lower, step_increment;
-
-          champlain_adjustment_get_values (hadj, &value, &lower, NULL,
-              &step_increment);
-          d = (rint ((value - lower) / step_increment) *
-               step_increment) + lower;
-          champlain_adjustment_set_value (hadj, d);
-        }
-
-      snap = TRUE;
-      if (champlain_adjustment_get_elastic (vadj))
-        snap = !champlain_adjustment_clamp (vadj, TRUE, n_frames, fps);
-
-      /* Snap to the nearest step increment on vadjustment */
-      if (snap)
-        {
-          gdouble d, value, lower, step_increment;
-
-          champlain_adjustment_get_values (vadj, &value, &lower, NULL,
-              &step_increment);
-          d = (rint ((value - lower) / step_increment) *
-               step_increment) + lower;
-          champlain_adjustment_set_value (vadj, d);
-        }
-    }
-}
-
-
-static void
 deceleration_completed_cb (ClutterTimeline *timeline,
     ChamplainKineticScrollView *scroll)
 {
@@ -366,14 +368,14 @@ deceleration_new_frame_cb (ClutterTimeline *timeline,
 {
   ChamplainKineticScrollViewPrivate *priv = scroll->priv;
 
-  if (priv->child)
+  if (priv->viewport)
     {
       gdouble value, lower, upper;
       ChamplainAdjustment *hadjust, *vadjust;
       gint i;
       gboolean stop = TRUE;
 
-      champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->child),
+      champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport),
           &hadjust,
           &vadjust);
 
@@ -434,12 +436,7 @@ button_release_event_cb (ClutterActor *stage,
       button_release_event_cb,
       scroll);
 
-  if (!priv->in_drag)
-    return FALSE;
-
-  clutter_stage_set_motion_events_enabled (CLUTTER_STAGE (stage), TRUE);
-
-  if (priv->kinetic && priv->child)
+  if (priv->kinetic && priv->viewport)
     {
       gfloat x, y;
 
@@ -454,8 +451,6 @@ button_release_event_cb (ClutterActor *stage,
           glong time_diff;
           gint i;
 
-          priv->in_drag = TRUE;
-
           /* Get time delta */
           g_get_current_time (&release_time);
 
@@ -503,7 +498,7 @@ button_release_event_cb (ClutterActor *stage,
               priv->dy = (y_origin - y) / frac;
 
               /* Get adjustments to do step-increment snapping */
-              champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->child),
+              champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport),
                   &hadjust,
                   &vadjust);
 
@@ -607,7 +602,6 @@ button_release_event_cb (ClutterActor *stage,
 
   /* Reset motion event buffer */
   priv->last_motion = 0;
-  priv->in_drag = FALSE;
 
   if (!decelerating)
     {
@@ -658,8 +652,6 @@ button_press_event_cb (ClutterActor *actor,
               "captured-event",
               G_CALLBACK (button_release_event_cb),
               scroll);
-
-          priv->in_drag = FALSE;
         }
     }
 
@@ -676,8 +668,7 @@ champlain_kinetic_scroll_view_init (ChamplainKineticScrollView *self)
         sizeof (ChamplainKineticScrollViewMotion), 3);
   g_array_set_size (priv->motion_buffer, 3);
   priv->decel_rate = 1.1f;
-  priv->child = NULL;
-  priv->in_drag = FALSE;
+  priv->viewport = NULL;
 
   clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
   g_signal_connect (self, "button-press-event",
@@ -687,14 +678,14 @@ champlain_kinetic_scroll_view_init (ChamplainKineticScrollView *self)
 
 ClutterActor *
 champlain_kinetic_scroll_view_new (gboolean kinetic,
-    ClutterActor *viewport)
+    ChamplainViewport *viewport)
 {
   ClutterActor *scroll_view;
   
   scroll_view = CLUTTER_ACTOR (g_object_new (CHAMPLAIN_TYPE_KINETIC_SCROLL_VIEW,
           "mode", kinetic, NULL));
-  CHAMPLAIN_KINETIC_SCROLL_VIEW (scroll_view)->priv->child = viewport;
-  clutter_actor_add_child (CLUTTER_ACTOR (scroll_view), viewport);
+  CHAMPLAIN_KINETIC_SCROLL_VIEW (scroll_view)->priv->viewport = CLUTTER_ACTOR (viewport);
+  clutter_actor_add_child (scroll_view, CLUTTER_ACTOR (viewport));
 
   return scroll_view;
 }
diff --git a/champlain/champlain-kinetic-scroll-view.h b/champlain/champlain-kinetic-scroll-view.h
index 2045888..0557f70 100644
--- a/champlain/champlain-kinetic-scroll-view.h
+++ b/champlain/champlain-kinetic-scroll-view.h
@@ -25,6 +25,7 @@
 
 #include <glib-object.h>
 #include <clutter/clutter.h>
+#include <champlain-viewport.h>
 
 G_BEGIN_DECLS
 
@@ -65,7 +66,7 @@ struct _ChamplainKineticScrollViewClass
 GType champlain_kinetic_scroll_view_get_type (void) G_GNUC_CONST;
 
 ClutterActor *champlain_kinetic_scroll_view_new (gboolean kinetic,
-    ClutterActor *viewport);
+    ChamplainViewport *viewport);
 
 void champlain_kinetic_scroll_view_stop (ChamplainKineticScrollView *self);
 
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index 8c1340d..48add5b 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -1037,7 +1037,7 @@ champlain_view_init (ChamplainView *view)
       G_CALLBACK (viewport_pos_changed_cb), view);
 
   /* Setup kinetic scroll */
-  priv->kinetic_scroll = champlain_kinetic_scroll_view_new (FALSE, priv->viewport);
+  priv->kinetic_scroll = champlain_kinetic_scroll_view_new (FALSE, CHAMPLAIN_VIEWPORT (priv->viewport));
 
   g_signal_connect (priv->kinetic_scroll, "scroll-event",
       G_CALLBACK (scroll_event), view);


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