gtk: Add GtkScrollInfo
authorBenjamin Otte <otte@redhat.com>
Tue, 7 Mar 2023 04:29:31 +0000 (05:29 +0100)
committerBenjamin Otte <otte@redhat.com>
Sat, 5 Aug 2023 01:51:50 +0000 (03:51 +0200)
This struct carries information about scrolling a scrollable, so that
individual scrollables can share this struct for their scrolling APIs.

For now, there's not much information here, we're still trying to cook
up an API that works well.

gtk/gtk.h
gtk/gtkscrollinfo.c [new file with mode: 0644]
gtk/gtkscrollinfo.h [new file with mode: 0644]
gtk/gtkscrollinfoprivate.h [new file with mode: 0644]
gtk/gtktypes.h
gtk/meson.build

index c5f9b4b583449fc5f3226307d1ccc4a3ce0ae1c7..6a849ecf6cccf0a78bfece7f6875e284031a2742 100644 (file)
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
 #include <gtk/gtkscalebutton.h>
 #include <gtk/gtkscrollable.h>
 #include <gtk/gtkscrollbar.h>
+#include <gtk/gtkscrollinfo.h>
 #include <gtk/gtkscrolledwindow.h>
 #include <gtk/gtksearchbar.h>
 #include <gtk/gtksearchentry.h>
diff --git a/gtk/gtkscrollinfo.c b/gtk/gtkscrollinfo.c
new file mode 100644 (file)
index 0000000..513ecca
--- /dev/null
@@ -0,0 +1,249 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2023 Benjamin Otte
+ *
+ * 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/>.
+ */
+
+/**
+ * GtkScrollInfo:
+ *
+ * The `GtkScrollInfo` can be used to provide more accurate data on how a scroll
+ * operation should be performed.
+ *
+ * Scrolling functions usually allow passing a %NULL scroll info which will cause
+ * the default values to be used and just scroll the element into view.
+ *
+ * Since: 4.12
+ */
+
+#include "config.h"
+
+#include "gtkscrollinfoprivate.h"
+
+#include <math.h>
+
+struct _GtkScrollInfo
+{
+  guint ref_count;
+
+  gboolean enabled[2]; /* directions */
+};
+
+static GtkScrollInfo default_scroll_info = {
+  1,
+  { TRUE, TRUE }
+};
+
+G_DEFINE_BOXED_TYPE (GtkScrollInfo, gtk_scroll_info,
+                     gtk_scroll_info_ref,
+                     gtk_scroll_info_unref)
+
+
+/**
+ * gtk_scroll_info_new:
+ *
+ * Creates a new scroll info for scrolling an element into view.
+ *
+ * Returns: A new scroll info
+ *
+ * Since: 4.12
+ **/
+GtkScrollInfo *
+gtk_scroll_info_new (void)
+{
+  GtkScrollInfo *self;
+
+  self = g_new0 (GtkScrollInfo, 1);
+  self->ref_count = 1;
+  self->enabled[GTK_ORIENTATION_HORIZONTAL] = TRUE;
+  self->enabled[GTK_ORIENTATION_VERTICAL] = TRUE;
+
+  return self;
+}
+
+/**
+ * gtk_scroll_info_ref:
+ * @self:  a `GtkScrollInfo`
+ *
+ * Increases the reference count of a `GtkScrollInfo` by one.
+ *
+ * Returns: the passed in `GtkScrollInfo`.
+ *
+ * Since: 4.12
+ */
+GtkScrollInfo *
+gtk_scroll_info_ref (GtkScrollInfo *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  self->ref_count++;
+
+  return self;
+}
+
+/**
+ * gtk_scroll_info_unref:
+ * @self: a `GtkScrollInfo`
+ *
+ * Decreases the reference count of a `GtkScrollInfo` by one.
+ *
+ * If the resulting reference count is zero, frees the self.
+ *
+ * Since: 4.12
+ */
+void
+gtk_scroll_info_unref (GtkScrollInfo *self)
+{
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (self->ref_count > 0);
+
+  self->ref_count--;
+  if (self->ref_count > 0)
+    return;
+
+  g_free (self);
+}
+
+/**
+ * gtk_scroll_info_set_enable_horizontal:
+ * @self: a `GtkScrollInfo`
+ * @horizontal: if scrolling in the horizontal direction
+ *     should happen
+ *
+ * Turns horizontal scrolling on or off.
+ *
+ * Since: 4.12
+ **/
+void
+gtk_scroll_info_set_enable_horizontal (GtkScrollInfo *self,
+                                       gboolean       horizontal)
+{
+  g_return_if_fail (self != NULL);
+
+  self->enabled[GTK_ORIENTATION_HORIZONTAL] = horizontal;
+}
+
+/**
+ * gtk_scroll_info_get_enable_horizontal:
+ * @self: a `GtkScrollInfo`
+ *
+ * Checks if horizontal scrolling is enabled.
+ *
+ * Returns: %TRUE if horizontal scrolling is enabled.
+ *
+ * Since: 4.12
+ **/
+gboolean
+gtk_scroll_info_get_enable_horizontal (GtkScrollInfo *self)
+{
+  g_return_val_if_fail (self != NULL, FALSE);
+
+  return self->enabled[GTK_ORIENTATION_HORIZONTAL];
+}
+
+/**
+ * gtk_scroll_info_set_enable_vertical:
+ * @self: a `GtkScrollInfo`
+ * @vertical: if scrolling in the vertical direction
+ *     should happen
+ *
+ * Turns vertical scrolling on or off.
+ *
+ * Since: 4.12
+ **/
+void
+gtk_scroll_info_set_enable_vertical (GtkScrollInfo *self,
+                                     gboolean       vertical)
+{
+  g_return_if_fail (self != NULL);
+
+  self->enabled[GTK_ORIENTATION_VERTICAL] = vertical;
+}
+
+/**
+ * gtk_scroll_info_get_enable_vertical:
+ * @self: a `GtkScrollInfo`
+ *
+ * Checks if vertical scrolling is enabled.
+ *
+ * Returns: %TRUE if vertical scrolling is enabled.
+ *
+ * Since: 4.12
+ **/
+gboolean
+gtk_scroll_info_get_enable_vertical (GtkScrollInfo *self)
+{
+  g_return_val_if_fail (self != NULL, FALSE);
+
+  return self->enabled[GTK_ORIENTATION_VERTICAL];
+}
+
+int
+gtk_scroll_info_compute_for_orientation (GtkScrollInfo  *self,
+                                         GtkOrientation  orientation,
+                                         int             area_origin,
+                                         int             area_size,
+                                         int             viewport_origin,
+                                         int             viewport_size)
+{
+  float origin, size;
+  int delta;
+
+  if (self == NULL)
+    self = &default_scroll_info;
+
+  if (!self->enabled[orientation])
+    return viewport_origin;
+
+  origin = viewport_origin;
+  size = viewport_size;
+
+  if (area_origin <= origin)
+    delta = area_origin - ceil (origin);
+  else if (area_origin + area_size > origin + size)
+    delta = area_origin + area_size - floor (origin + size);
+  else
+    delta = 0;
+                                      
+  return viewport_origin + delta;
+}
+
+/*<private>
+ * gtk_scroll_info_compute_scroll:
+ * @self: a `GtkScrollInfo`
+ * @area: area to scroll
+ * @viewport: viewport area to scroll into
+ * @out_x: (out): x coordinate to scroll viewport to
+ * @out_y: (out): y coordinate to scroll viewport to
+ *
+ * Computes The new x/y coordinate to move the viewport to
+ * according to this scroll info.
+ **/
+void
+gtk_scroll_info_compute_scroll (GtkScrollInfo               *self,
+                                const cairo_rectangle_int_t *area,
+                                const cairo_rectangle_int_t *viewport,
+                                int                         *out_x,
+                                int                         *out_y)
+{
+  *out_x = gtk_scroll_info_compute_for_orientation (self,
+                                                    GTK_ORIENTATION_HORIZONTAL,
+                                                    area->x, area->width,
+                                                    viewport->x, viewport->width);
+  *out_y = gtk_scroll_info_compute_for_orientation (self,
+                                                    GTK_ORIENTATION_VERTICAL,
+                                                    area->y, area->height,
+                                                    viewport->y, viewport->height);
+}
+
diff --git a/gtk/gtkscrollinfo.h b/gtk/gtkscrollinfo.h
new file mode 100644 (file)
index 0000000..56cbf63
--- /dev/null
@@ -0,0 +1,61 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2023 Benjamin Otte
+ *
+ * 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/>.
+ */
+
+#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/gtkenums.h>
+#include <gtk/gtktypes.h>
+
+#include <graphene.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_SCROLL_INFO    (gtk_scroll_info_get_type ())
+
+GDK_AVAILABLE_IN_4_12
+GType                   gtk_scroll_info_get_type                (void) G_GNUC_CONST;
+GDK_AVAILABLE_IN_4_12
+GtkScrollInfo *         gtk_scroll_info_new                     (void);
+
+GDK_AVAILABLE_IN_4_12
+GtkScrollInfo *         gtk_scroll_info_ref                     (GtkScrollInfo           *self);
+GDK_AVAILABLE_IN_4_12
+void                    gtk_scroll_info_unref                   (GtkScrollInfo           *self);
+
+GDK_AVAILABLE_IN_4_12
+void                    gtk_scroll_info_set_enable_horizontal   (GtkScrollInfo           *self,
+                                                                 gboolean                 horizontal);
+GDK_AVAILABLE_IN_4_12
+gboolean                gtk_scroll_info_get_enable_horizontal   (GtkScrollInfo           *self);
+
+GDK_AVAILABLE_IN_4_12
+void                    gtk_scroll_info_set_enable_vertical     (GtkScrollInfo           *self,
+                                                                 gboolean                 vertical);
+GDK_AVAILABLE_IN_4_12
+gboolean                gtk_scroll_info_get_enable_vertical     (GtkScrollInfo           *self);
+
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkScrollInfo, gtk_scroll_info_unref)
+
+G_END_DECLS
+
diff --git a/gtk/gtkscrollinfoprivate.h b/gtk/gtkscrollinfoprivate.h
new file mode 100644 (file)
index 0000000..f1ac1a6
--- /dev/null
@@ -0,0 +1,42 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2023 Benjamin Otte
+ *
+ * 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/>.
+ */
+
+#pragma once
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+
+#include <gtk/gtkscrollinfo.h>
+
+G_BEGIN_DECLS
+
+void                    gtk_scroll_info_compute_scroll          (GtkScrollInfo                  *self,
+                                                                 const cairo_rectangle_int_t    *area,
+                                                                 const cairo_rectangle_int_t    *viewport,
+                                                                 int                            *out_x,
+                                                                 int                            *out_y);
+int                     gtk_scroll_info_compute_for_orientation (GtkScrollInfo                  *self,
+                                                                 GtkOrientation                  orientation,
+                                                                 int                             area_origin,
+                                                                 int                             area_size,
+                                                                 int                             viewport_origin,
+                                                                 int                             viewport_size);
+
+G_END_DECLS
+
index 6efa78f837d63cdf4f7b1d2b20b0cf419bc59e68..e30194a1e5b2a2e1c893cc9afff84f1c9ce9a33b 100644 (file)
@@ -46,6 +46,7 @@ typedef struct _GtkListItemFactory     GtkListItemFactory;
 typedef struct _GtkNative              GtkNative;
 typedef struct _GtkRequisition        GtkRequisition;
 typedef struct _GtkRoot               GtkRoot;
+typedef struct _GtkScrollInfo                 GtkScrollInfo;
 typedef struct _GtkSettings            GtkSettings;
 typedef struct _GtkShortcut            GtkShortcut;
 typedef struct _GtkShortcutAction      GtkShortcutAction;
index 19bc2212772dbf18dccfbf7a62f853d8a0b4d4ca..765925dc263edbdf559e45293439f83a6654421f 100644 (file)
@@ -327,6 +327,7 @@ gtk_public_sources = files([
   'gtkscalebutton.c',
   'gtkscrollable.c',
   'gtkscrollbar.c',
+  'gtkscrollinfo.c',
   'gtkscrolledwindow.c',
   'gtksearchbar.c',
   'gtksearchentry.c',
@@ -557,6 +558,7 @@ gtk_public_headers = files([
   'gtkscalebutton.h',
   'gtkscrollable.h',
   'gtkscrollbar.h',
+  'gtkscrollinfo.h',
   'gtkscrolledwindow.h',
   'gtksearchbar.h',
   'gtksearchentry.h',