[gtk/wip/exalm/scroll-gesture: 366/369] Add GtkEventControllerWheel




commit fe93d6c0a346ae16b4659941667a8ea8c0ddf898
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Fri Sep 17 23:50:10 2021 +0500

    Add GtkEventControllerWheel
    
    Gestures handle touchpad and trackpoint scrolling now, but we still need
    something for mice. Add a new controller that does just that, without
    scroll-begin/end or deceleration handling.

 gtk/gtk.h                     |   1 +
 gtk/gtkeventcontrollerwheel.c | 195 ++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkeventcontrollerwheel.h |  47 ++++++++++
 gtk/meson.build               |   2 +
 4 files changed, 245 insertions(+)
---
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 0d4521e4ac..ff1ed5f1d9 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -114,6 +114,7 @@
 #include <gtk/gtkeventcontrollerlegacy.h>
 #include <gtk/gtkeventcontrollermotion.h>
 #include <gtk/gtkeventcontrollerscroll.h>
+#include <gtk/gtkeventcontrollerwheel.h>
 #include <gtk/gtkexpander.h>
 #include <gtk/gtkexpression.h>
 #include <gtk/gtkfixed.h>
diff --git a/gtk/gtkeventcontrollerwheel.c b/gtk/gtkeventcontrollerwheel.c
new file mode 100644
index 0000000000..0aa2aece14
--- /dev/null
+++ b/gtk/gtkeventcontrollerwheel.c
@@ -0,0 +1,195 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2017, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Carlos Garnacho <carlosg gnome org>
+ */
+
+/**
+ * GtkEventControllerWheel:
+ *
+ * `GtkEventControllerWheel` is an event controller that handles mouse scroll
+ * events.
+ *
+ * It is capable of handling both discrete and continuous scroll
+ * events from mice or touchpads, abstracting them both with the
+ * [signal@Gtk.EventControllerScroll::scroll] signal. Deltas in
+ * the discrete case are multiples of 1.
+ *
+ * In the case of continuous scroll events, `GtkEventControllerScroll`
+ * encloses all [signal@Gtk.EventControllerScroll::scroll] emissions
+ * between two [signal@Gtk.EventControllerScroll::scroll-begin] and
+ * [signal@Gtk.EventControllerScroll::scroll-end] signals.
+ *
+ * The behavior of the event controller can be modified by the flags
+ * given at creation time, or modified at a later point through
+ * [method@Gtk.EventControllerScroll.set_flags] (e.g. because the scrolling
+ * conditions of the widget changed).
+ *
+ * The controller can be set up to emit motion for either/both vertical
+ * and horizontal scroll events through %GTK_EVENT_CONTROLLER_SCROLL_VERTICAL,
+ * %GTK_EVENT_CONTROLLER_SCROLL_HORIZONTAL and %GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES.
+ * If any axis is disabled, the respective [signal@Gtk.EventControllerScroll::scroll]
+ * delta will be 0. Vertical scroll events will be translated to horizontal
+ * motion for the devices incapable of horizontal scrolling.
+ *
+ * The event controller can also be forced to emit discrete events on all
+ * devices through %GTK_EVENT_CONTROLLER_SCROLL_DISCRETE. This can be used
+ * to implement discrete actions triggered through scroll events (e.g.
+ * switching across combobox options).
+ *
+ * The %GTK_EVENT_CONTROLLER_SCROLL_KINETIC flag toggles the emission of the
+ * [signal@Gtk.EventControllerScroll::decelerate] signal, emitted at the end
+ * of scrolling with two X/Y velocity arguments that are consistent with the
+ * motion that was received.
+ */
+#include "config.h"
+
+#include "gtkintl.h"
+#include "gtkeventcontrollerprivate.h"
+#include "gtkeventcontrollerwheel.h"
+#include "gtkmarshalers.h"
+#include "gtkprivate.h"
+
+struct _GtkEventControllerWheel
+{
+  GtkEventController parent_instance;
+};
+
+struct _GtkEventControllerWheelClass
+{
+  GtkEventControllerClass parent_class;
+};
+
+enum {
+  SCROLL,
+  N_SIGNALS
+};
+
+static guint signals[N_SIGNALS] = { 0 };
+
+G_DEFINE_TYPE (GtkEventControllerWheel, gtk_event_controller_wheel,
+               GTK_TYPE_EVENT_CONTROLLER)
+
+static GtkFilterEventStatus
+gtk_event_controller_wheel_filter_event (GtkEventController *controller,
+                                         GdkEvent           *event)
+{
+  GdkEventType event_type = gdk_event_get_event_type (event);
+
+  if (event_type == GDK_SCROLL) {
+    GdkDevice *source_device = gdk_event_get_device (event);
+    GdkInputSource source = gdk_device_get_source (source_device);
+
+    if (source == GDK_SOURCE_MOUSE)
+      return GTK_EVENT_HANDLE;
+  }
+
+  return GTK_EVENT_SKIP;
+}
+
+static gboolean
+gtk_event_controller_wheel_handle_event (GtkEventController *controller,
+                                         GdkEvent           *event,
+                                         double              x,
+                                         double              y)
+{
+  GdkScrollDirection direction = GDK_SCROLL_SMOOTH;
+  double dx = 0, dy = 0;
+  gboolean handled = GDK_EVENT_PROPAGATE;
+
+  /* FIXME: Handle device changes */
+  direction = gdk_scroll_event_get_direction (event);
+  if (direction == GDK_SCROLL_SMOOTH)
+    gdk_scroll_event_get_deltas (event, &dx, &dy);
+  else
+    {
+      switch (direction)
+        {
+        case GDK_SCROLL_UP:
+          dy -= 1;
+          break;
+        case GDK_SCROLL_DOWN:
+          dy += 1;
+          break;
+        case GDK_SCROLL_LEFT:
+          dx -= 1;
+          break;
+        case GDK_SCROLL_RIGHT:
+          dx += 1;
+          break;
+        case GDK_SCROLL_SMOOTH:
+        default:
+          g_assert_not_reached ();
+          break;
+        }
+    }
+
+  if (dx != 0 || dy != 0)
+    g_signal_emit (controller, signals[SCROLL], 0, dx, dy, &handled);
+
+  return handled;
+}
+
+static void
+gtk_event_controller_wheel_class_init (GtkEventControllerWheelClass *klass)
+{
+  GtkEventControllerClass *controller_class = GTK_EVENT_CONTROLLER_CLASS (klass);
+
+  controller_class->filter_event = gtk_event_controller_wheel_filter_event;
+  controller_class->handle_event = gtk_event_controller_wheel_handle_event;
+
+  /**
+   * GtkEventControllerWheel:scroll:
+   * @controller: The object that received the signal
+   * @dx: X delta
+   * @dy: Y delta
+   *
+   * Signals that the widget should scroll by the
+   * amount specified by @dx and @dy.
+   *
+   * Returns: %TRUE if the scroll event was handled,
+   *   %FALSE otherwise.
+   */
+  signals[SCROLL] =
+    g_signal_new (I_("scroll"),
+                  GTK_TYPE_EVENT_CONTROLLER_WHEEL,
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  _gtk_marshal_BOOLEAN__DOUBLE_DOUBLE,
+                  G_TYPE_BOOLEAN, 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
+  g_signal_set_va_marshaller (signals[SCROLL],
+                              G_TYPE_FROM_CLASS (klass),
+                              _gtk_marshal_BOOLEAN__DOUBLE_DOUBLEv);
+}
+
+static void
+gtk_event_controller_wheel_init (GtkEventControllerWheel *self)
+{
+}
+
+/**
+ * gtk_event_controller_wheel_new:
+ *
+ * Creates a new event controller that will handle scroll events.
+ *
+ * Returns: a new `GtkEventControllerWheel`
+ */
+GtkEventController *
+gtk_event_controller_wheel_new (void)
+{
+  return g_object_new (GTK_TYPE_EVENT_CONTROLLER_WHEEL,
+                       NULL);
+}
diff --git a/gtk/gtkeventcontrollerwheel.h b/gtk/gtkeventcontrollerwheel.h
new file mode 100644
index 0000000000..c93a8de6e7
--- /dev/null
+++ b/gtk/gtkeventcontrollerwheel.h
@@ -0,0 +1,47 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2017, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Carlos Garnacho <carlosg gnome org>
+ */
+
+#pragma once
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gdk/gdk.h>
+#include <gtk/gtkeventcontroller.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_EVENT_CONTROLLER_WHEEL         (gtk_event_controller_wheel_get_type ())
+#define GTK_EVENT_CONTROLLER_WHEEL(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), 
GTK_TYPE_EVENT_CONTROLLER_WHEEL, GtkEventControllerWheel))
+#define GTK_EVENT_CONTROLLER_WHEEL_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), 
GTK_TYPE_EVENT_CONTROLLER_WHEEL, GtkEventControllerWheelClass))
+#define GTK_IS_EVENT_CONTROLLER_WHEEL(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), 
GTK_TYPE_EVENT_CONTROLLER_WHEEL))
+#define GTK_IS_EVENT_CONTROLLER_WHEEL_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), 
GTK_TYPE_EVENT_CONTROLLER_WHEEL))
+#define GTK_EVENT_CONTROLLER_WHEEL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), 
GTK_TYPE_EVENT_CONTROLLER_WHEEL, GtkEventControllerWheelClass))
+
+typedef struct _GtkEventControllerWheel GtkEventControllerWheel;
+typedef struct _GtkEventControllerWheelClass GtkEventControllerWheelClass;
+
+GDK_AVAILABLE_IN_ALL
+GType               gtk_event_controller_wheel_get_type  (void) G_GNUC_CONST;
+
+GDK_AVAILABLE_IN_ALL
+GtkEventController *gtk_event_controller_wheel_new       (void);
+
+G_END_DECLS
diff --git a/gtk/meson.build b/gtk/meson.build
index e31b9e67ff..8f29c03271 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -240,6 +240,7 @@ gtk_public_sources = files([
   'gtkeventcontrollerlegacy.c',
   'gtkeventcontrollermotion.c',
   'gtkeventcontrollerscroll.c',
+  'gtkeventcontrollerwheel.c',
   'gtkexpander.c',
   'gtkexpression.c',
   'gtkfilechooser.c',
@@ -529,6 +530,7 @@ gtk_public_headers = files([
   'gtkeventcontrollerscroll.h',
   'gtkeventcontrollermotion.h',
   'gtkeventcontrollerlegacy.h',
+  'gtkeventcontrollerwheel.h',
   'gtkexpander.h',
   'gtkexpression.h',
   'gtkfilechooser.h',


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