[gtk+/touchscreens: 3/4] gtk, scrolledwindow: Clamp early overshooting when snapping back



commit 814156181491c7511f9e03c19e37fa43cd0e8a10
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sat Nov 26 20:23:08 2011 +0100

    gtk,scrolledwindow: Clamp early overshooting when snapping back
    
    Fixes the situation where overshooting in scrolled windows with a
    small viewport could end up overshooting right to the opposite
    side, and then back again indefinitely.

 gtk/gtkscrolledwindow.c |   80 ++++++++++++++++++++---------------------------
 1 files changed, 34 insertions(+), 46 deletions(-)
---
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 64f2adf..1314f55 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -286,7 +286,8 @@ static void     gtk_scrolled_window_auto_hide_scrollbars_stop  (GtkScrolledWindo
 static gboolean _gtk_scrolled_window_set_adjustment_value      (GtkScrolledWindow *scrolled_window,
                                                                 GtkAdjustment     *adjustment,
                                                                 gdouble            value,
-                                                                gboolean           allow_overshooting);
+                                                                gboolean           allow_overshooting,
+                                                                gboolean           snap_to_border);
 
 static guint signals[LAST_SIGNAL] = {0};
 
@@ -2275,37 +2276,41 @@ static gboolean
 _gtk_scrolled_window_set_adjustment_value (GtkScrolledWindow *scrolled_window,
                                            GtkAdjustment     *adjustment,
                                            gdouble            value,
-                                           gboolean           allow_overshooting)
+                                           gboolean           allow_overshooting,
+                                           gboolean           snap_to_border)
 {
   GtkScrolledWindowPrivate *priv = scrolled_window->priv;
-  gdouble lower, upper;
+  gdouble lower, upper, *prev_value;
 
   lower = gtk_adjustment_get_lower (adjustment);
   upper = gtk_adjustment_get_upper (adjustment) -
     gtk_adjustment_get_page_size (adjustment);
 
-  if (allow_overshooting)
+  if (adjustment == gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar)))
+    prev_value = &priv->unclamped_hadj_value;
+  else if (adjustment == gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar)))
+    prev_value = &priv->unclamped_vadj_value;
+  else
+    return FALSE;
+
+  if (snap_to_border)
     {
-      lower -= MAX_OVERSHOOT_DISTANCE;
-      upper += MAX_OVERSHOOT_DISTANCE;
+      if (*prev_value < 0 && value > 0)
+        value = 0;
+      else if (*prev_value > upper && value < upper)
+        value = upper;
     }
 
-  if (adjustment == gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar)))
+  if (allow_overshooting)
     {
-      priv->unclamped_hadj_value = CLAMP (value, lower, upper);
-      gtk_adjustment_set_value (adjustment, value);
-
-      return (priv->unclamped_hadj_value != value);
+      lower -= MAX_OVERSHOOT_DISTANCE;
+      upper += MAX_OVERSHOOT_DISTANCE;
     }
-  else if (adjustment == gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar)))
-    {
-      priv->unclamped_vadj_value = CLAMP (value, lower, upper);
-      gtk_adjustment_set_value (adjustment, value);
 
-      return (priv->unclamped_vadj_value != value);
-    }
+  *prev_value = CLAMP (value, lower, upper);
+  gtk_adjustment_set_value (adjustment, value);
 
-  return FALSE;
+  return (*prev_value != value);
 }
 
 static gboolean
@@ -2316,7 +2321,7 @@ scrolled_window_deceleration_cb (gpointer user_data)
   GtkScrolledWindowPrivate *priv = scrolled_window->priv;
   GtkAdjustment *hadjustment, *vadjustment;
   gint old_overshoot_x, old_overshoot_y, overshoot_x, overshoot_y;
-  gdouble value, clamp_value;
+  gdouble value;
   gint64 current_time;
   guint elapsed;
 
@@ -2336,7 +2341,7 @@ scrolled_window_deceleration_cb (gpointer user_data)
 
       if (_gtk_scrolled_window_set_adjustment_value (scrolled_window,
                                                      hadjustment,
-                                                     value, TRUE))
+                                                     value, TRUE, TRUE))
         data->x_velocity = 0;
     }
   else
@@ -2348,7 +2353,7 @@ scrolled_window_deceleration_cb (gpointer user_data)
 
       if (_gtk_scrolled_window_set_adjustment_value (scrolled_window,
                                                      vadjustment,
-                                                     value, TRUE))
+                                                     value, TRUE, TRUE))
         data->y_velocity = 0;
     }
   else
@@ -2361,17 +2366,7 @@ scrolled_window_deceleration_cb (gpointer user_data)
     {
       if (old_overshoot_x != 0)
         {
-          /* Overshooting finished, clamp to border */
-          clamp_value = (old_overshoot_x < 0) ?
-            gtk_adjustment_get_lower (hadjustment) :
-            gtk_adjustment_get_upper (hadjustment) -
-            gtk_adjustment_get_page_size (hadjustment);
-
-          _gtk_scrolled_window_set_adjustment_value (scrolled_window,
-                                                     hadjustment,
-                                                     clamp_value,
-                                                     FALSE);
-
+          /* Overshooting finished snapping back */
           data->x_velocity = 0;
         }
       else if (data->x_velocity > 0)
@@ -2394,16 +2389,7 @@ scrolled_window_deceleration_cb (gpointer user_data)
     {
       if (old_overshoot_y != 0)
         {
-          /* Overshooting finished, clamp to border */
-          clamp_value = (old_overshoot_y < 0) ?
-            gtk_adjustment_get_lower (vadjustment) :
-            gtk_adjustment_get_upper (vadjustment) -
-            gtk_adjustment_get_page_size (vadjustment);
-
-          _gtk_scrolled_window_set_adjustment_value (scrolled_window,
-                                                     vadjustment,
-                                                     clamp_value,
-                                                     FALSE);
+          /* Overshooting finished snapping back */
           data->y_velocity = 0;
         }
       else if (data->y_velocity > 0)
@@ -2469,11 +2455,11 @@ gtk_scrolled_window_cancel_deceleration (GtkScrolledWindow *scrolled_window)
       _gtk_scrolled_window_set_adjustment_value (scrolled_window,
                                                  vadjustment,
                                                  gtk_adjustment_get_value (vadjustment),
-                                                 FALSE);
+                                                 FALSE, TRUE);
       _gtk_scrolled_window_set_adjustment_value (scrolled_window,
                                                  hadjustment,
                                                  gtk_adjustment_get_value (hadjustment),
-                                                 FALSE);
+                                                 FALSE, TRUE);
     }
 }
 
@@ -2674,14 +2660,16 @@ gtk_scrolled_window_motion_notify_event (GtkWidget *widget,
   if (hadjustment && priv->hscrollbar_visible)
     {
       dx = (priv->last_motion_event_x_root - event->x_root) + priv->unclamped_hadj_value;
-      _gtk_scrolled_window_set_adjustment_value (scrolled_window, hadjustment, dx, TRUE);
+      _gtk_scrolled_window_set_adjustment_value (scrolled_window, hadjustment,
+                                                 dx, TRUE, FALSE);
     }
 
   vadjustment = gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar));
   if (vadjustment && priv->vscrollbar_visible)
     {
       dy = (priv->last_motion_event_y_root - event->y_root) + priv->unclamped_vadj_value;
-      _gtk_scrolled_window_set_adjustment_value (scrolled_window, vadjustment, dy, TRUE);
+      _gtk_scrolled_window_set_adjustment_value (scrolled_window, vadjustment,
+                                                 dy, TRUE, FALSE);
     }
 
   _gtk_scrolled_window_get_overshoot (scrolled_window,



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