diff options
author | Alexander Mikhaylenko <alexm@gnome.org> | 2021-09-17 23:50:10 +0500 |
---|---|---|
committer | Alexander Mikhaylenko <alexm@gnome.org> | 2021-10-14 18:24:48 +0500 |
commit | fe93d6c0a346ae16b4659941667a8ea8c0ddf898 (patch) | |
tree | 37afc3f2fbdb9970f65381af990d1dea070d78d2 | |
parent | 9ddf5892f7e65d6d5d889f1dcd6bd98e772eae2e (diff) | |
download | gtk+-fe93d6c0a346ae16b4659941667a8ea8c0ddf898.tar.gz |
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.
-rw-r--r-- | gtk/gtk.h | 1 | ||||
-rw-r--r-- | gtk/gtkeventcontrollerwheel.c | 195 | ||||
-rw-r--r-- | gtk/gtkeventcontrollerwheel.h | 47 | ||||
-rw-r--r-- | gtk/meson.build | 2 |
4 files changed, 245 insertions, 0 deletions
@@ -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', |