[gtk+] scrolledwindow: Allow overshooting on scroll events



commit 103e11c9372c1fbdb6bd8311b7b7f2ee9981ccf8
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sun Oct 12 13:22:43 2014 +0200

    scrolledwindow: Allow overshooting on scroll events
    
    The overshoot visual notification is probably also nice to have in this
    context.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=738533

 gtk/gtkscrolledwindow.c |   62 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 48 insertions(+), 14 deletions(-)
---
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index ad5b917..7547ac6 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -153,6 +153,8 @@ struct _GtkScrolledWindowPrivate
   gint     min_content_width;
   gint     min_content_height;
 
+  guint scroll_events_overshoot_id;
+
   /* Kinetic scrolling */
   GtkGesture *long_press_gesture;
   GtkGesture *swipe_gesture;
@@ -1458,6 +1460,12 @@ gtk_scrolled_window_destroy (GtkWidget *widget)
       priv->deceleration_id = 0;
     }
 
+  if (priv->scroll_events_overshoot_id)
+    {
+      g_source_remove (priv->scroll_events_overshoot_id);
+      priv->scroll_events_overshoot_id = 0;
+    }
+
   g_clear_object (&priv->drag_gesture);
   g_clear_object (&priv->swipe_gesture);
   g_clear_object (&priv->long_press_gesture);
@@ -2376,6 +2384,18 @@ gtk_scrolled_window_size_allocate (GtkWidget     *widget,
 }
 
 static gboolean
+start_scroll_deceleration_cb (gpointer user_data)
+{
+  GtkScrolledWindow *scrolled_window = user_data;
+  GtkScrolledWindowPrivate *priv = scrolled_window->priv;
+
+  priv->scroll_events_overshoot_id = 0;
+  gtk_scrolled_window_start_deceleration (scrolled_window);
+  return FALSE;
+}
+
+
+static gboolean
 gtk_scrolled_window_scroll_event (GtkWidget      *widget,
                                  GdkEventScroll *event)
 {
@@ -2389,6 +2409,8 @@ gtk_scrolled_window_scroll_event (GtkWidget      *widget,
   scrolled_window = GTK_SCROLLED_WINDOW (widget);
   priv = scrolled_window->priv;
 
+  gtk_scrolled_window_invalidate_overshoot (scrolled_window);
+
   if (gdk_event_get_scroll_deltas ((GdkEvent *) event, &delta_x, &delta_y))
     {
       if (delta_x != 0.0 &&
@@ -2408,13 +2430,9 @@ gtk_scrolled_window_scroll_event (GtkWidget      *widget,
           scroll_unit = pow (page_size, 2.0 / 3.0);
 #endif
 
-          new_value = CLAMP (gtk_adjustment_get_value (adj) + delta_x * scroll_unit,
-                             gtk_adjustment_get_lower (adj),
-                             gtk_adjustment_get_upper (adj) -
-                             gtk_adjustment_get_page_size (adj));
-
-          gtk_adjustment_set_value (adj, new_value);
-
+          new_value = priv->unclamped_hadj_value + delta_x * scroll_unit;
+          _gtk_scrolled_window_set_adjustment_value (scrolled_window, adj,
+                                                     new_value);
           handled = TRUE;
         }
 
@@ -2435,13 +2453,9 @@ gtk_scrolled_window_scroll_event (GtkWidget      *widget,
           scroll_unit = pow (page_size, 2.0 / 3.0);
 #endif
 
-          new_value = CLAMP (gtk_adjustment_get_value (adj) + delta_y * scroll_unit,
-                             gtk_adjustment_get_lower (adj),
-                             gtk_adjustment_get_upper (adj) -
-                             gtk_adjustment_get_page_size (adj));
-
-          gtk_adjustment_set_value (adj, new_value);
-
+          new_value = priv->unclamped_vadj_value + delta_y * scroll_unit;
+          _gtk_scrolled_window_set_adjustment_value (scrolled_window, adj,
+                                                     new_value);
           handled = TRUE;
         }
     }
@@ -2479,6 +2493,26 @@ gtk_scrolled_window_scroll_event (GtkWidget      *widget,
         }
     }
 
+  if (handled)
+    {
+      gtk_scrolled_window_cancel_deceleration (scrolled_window);
+      gtk_scrolled_window_invalidate_overshoot (scrolled_window);
+
+      if (priv->scroll_events_overshoot_id)
+        {
+          g_source_remove (priv->scroll_events_overshoot_id);
+          priv->scroll_events_overshoot_id = 0;
+        }
+
+      if (_gtk_scrolled_window_get_overshoot (scrolled_window, NULL, NULL))
+        {
+          priv->scroll_events_overshoot_id =
+            gdk_threads_add_timeout (50, start_scroll_deceleration_cb, scrolled_window);
+          g_source_set_name_by_id (priv->scroll_events_overshoot_id,
+                                   "[gtk+] start_scroll_deceleration_cb");
+        }
+    }
+
   return handled;
 }
 


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