[gimp] app: support smooth scroll events in GimpTagPopup widget.



commit d10a4cb83d4ef9d60eef150bc0d59e86caf28876
Author: Jehan <jehan girinstud io>
Date:   Sun Sep 22 18:57:25 2019 +0200

    app: support smooth scroll events in GimpTagPopup widget.

 app/widgets/gimptagpopup.c | 85 ++++++++++++++++++++++++++++++++++------------
 app/widgets/gimptagpopup.h |  2 ++
 2 files changed, 66 insertions(+), 21 deletions(-)
---
diff --git a/app/widgets/gimptagpopup.c b/app/widgets/gimptagpopup.c
index 38a2eb9656..c2d9b457d9 100644
--- a/app/widgets/gimptagpopup.c
+++ b/app/widgets/gimptagpopup.c
@@ -112,7 +112,8 @@ static gboolean gimp_tag_popup_scroll_timeout_initial  (gpointer        data);
 static void     gimp_tag_popup_start_scrolling         (GimpTagPopup   *popup);
 static void     gimp_tag_popup_stop_scrolling          (GimpTagPopup   *popup);
 static void     gimp_tag_popup_scroll_by               (GimpTagPopup   *popup,
-                                                        gint            step);
+                                                        gint            step,
+                                                        const GdkEvent *event);
 static void     gimp_tag_popup_handle_scrolling        (GimpTagPopup   *popup,
                                                         gint            x,
                                                         gint            y,
@@ -751,20 +752,8 @@ gimp_tag_popup_border_event (GtkWidget *widget,
     }
   else if (event->type == GDK_SCROLL)
     {
-      GdkEventScroll *scroll_event = (GdkEventScroll *) event;
-
-      switch (scroll_event->direction)
-        {
-        case GDK_SCROLL_RIGHT:
-        case GDK_SCROLL_DOWN:
-          gimp_tag_popup_scroll_by (popup, MENU_SCROLL_STEP2);
-          return TRUE;
-
-        case GDK_SCROLL_LEFT:
-        case GDK_SCROLL_UP:
-          gimp_tag_popup_scroll_by (popup, - MENU_SCROLL_STEP2);
-          return TRUE;
-        }
+      gimp_tag_popup_scroll_by (popup, 0, event);
+      return TRUE;
     }
 
   return FALSE;
@@ -1119,7 +1108,7 @@ gimp_tag_popup_scroll_timeout (gpointer data)
                 "gtk-touchscreen-mode", &touchscreen_mode,
                 NULL);
 
-  gimp_tag_popup_scroll_by (popup, popup->scroll_step);
+  gimp_tag_popup_scroll_by (popup, popup->scroll_step, NULL);
 
   return TRUE;
 }
@@ -1146,7 +1135,7 @@ gimp_tag_popup_scroll_timeout_initial (gpointer data)
                 "gtk-touchscreen-mode", &touchscreen_mode,
                 NULL);
 
-  gimp_tag_popup_scroll_by (popup, popup->scroll_step);
+  gimp_tag_popup_scroll_by (popup, popup->scroll_step, NULL);
 
   gimp_tag_popup_remove_scroll_timeout (popup);
 
@@ -1169,7 +1158,7 @@ gimp_tag_popup_start_scrolling (GimpTagPopup *popup)
                 "gtk-touchscreen-mode", &touchscreen_mode,
                 NULL);
 
-  gimp_tag_popup_scroll_by (popup, popup->scroll_step);
+  gimp_tag_popup_scroll_by (popup, popup->scroll_step, NULL);
 
   popup->scroll_timeout_id =
     gdk_threads_add_timeout (timeout,
@@ -1196,12 +1185,66 @@ gimp_tag_popup_stop_scrolling (GimpTagPopup *popup)
 }
 
 static void
-gimp_tag_popup_scroll_by (GimpTagPopup *popup,
-                          gint          step)
+gimp_tag_popup_scroll_by (GimpTagPopup   *popup,
+                          gint            step,
+                          const GdkEvent *event)
 {
   GtkStateType arrow_state;
-  gint         new_scroll_y = popup->scroll_y + step;
+  gint         new_scroll_y = popup->scroll_y;
+
+  /* If event is set, we override the step value. */
+  if (event)
+    {
+      GdkEventScroll *scroll_event = (GdkEventScroll *) event;
+      gdouble         delta_x;
+      gdouble         delta_y;
+
+      switch (scroll_event->direction)
+        {
+        case GDK_SCROLL_RIGHT:
+        case GDK_SCROLL_DOWN:
+          if (popup->smooth_scrolling)
+            /* In some case, we get both a SMOOTH event and step events
+             * (right, left, up, down). If we process them all, we get
+             * some fluid scrolling with regular bumps, which feels
+             * buggy. So when smooth scrolling is in progress, we just
+             * skip step events until we receive the stop scroll event.
+             */
+            return;
+
+          step = MENU_SCROLL_STEP2;
+          break;
+
+        case GDK_SCROLL_LEFT:
+        case GDK_SCROLL_UP:
+          if (popup->smooth_scrolling)
+            return;
+
+          step = - MENU_SCROLL_STEP2;
+          break;
+
+        case GDK_SCROLL_SMOOTH:
+          if (gdk_event_get_scroll_deltas (event, &delta_x, &delta_y))
+            {
+              popup->smooth_scrolling = TRUE;
+              step = 0;
+
+              if (delta_x < 0.0 || delta_y < 0.0)
+                step = (gint) (MIN (delta_x, delta_y) * MENU_SCROLL_STEP2);
+              else if (delta_x > 0.0 || delta_y > 0.0)
+                step = (gint) (MAX (delta_x, delta_y) * MENU_SCROLL_STEP2);
+            }
+          break;
+        }
+
+      if (gdk_event_is_scroll_stop_event (event))
+        popup->smooth_scrolling = FALSE;
+    }
+
+  if (step == 0)
+    return;
 
+  new_scroll_y += step;
   arrow_state = popup->upper_arrow_state;
 
   if (new_scroll_y < 0)
diff --git a/app/widgets/gimptagpopup.h b/app/widgets/gimptagpopup.h
index 7b6c9b6a5e..693666301f 100644
--- a/app/widgets/gimptagpopup.h
+++ b/app/widgets/gimptagpopup.h
@@ -64,6 +64,8 @@ struct _GimpTagPopup
   gboolean           lower_arrow_prelight;
   GtkStateType       upper_arrow_state;
   GtkStateType       lower_arrow_state;
+
+  gboolean           smooth_scrolling;
 };
 
 struct _GimpTagPopupClass


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