viewport: Add gtk_viewport_scroll_to()
authorBenjamin Otte <otte@redhat.com>
Tue, 7 Mar 2023 04:33:47 +0000 (05:33 +0100)
committerBenjamin Otte <otte@redhat.com>
Sat, 5 Aug 2023 01:51:50 +0000 (03:51 +0200)
First implementation of GtkScrollInfo

gtk/gtkviewport.c
gtk/gtkviewport.h

index 5f9cc86fe49b9e0277daba6571db8cb7484bc4a1..8fc93718da1057dd6c40e390ca599f9b8c78ae44 100644 (file)
 #include "gtkmarshalers.h"
 #include "gtkprivate.h"
 #include "gtkscrollable.h"
+#include "gtkscrollinfoprivate.h"
 #include "gtktypebuiltins.h"
 #include "gtkwidgetprivate.h"
 #include "gtkbuildable.h"
 #include "gtktext.h"
 
+#include <math.h>
 
 /**
  * GtkViewport:
@@ -720,3 +722,54 @@ gtk_viewport_get_child (GtkViewport *viewport)
   return viewport->child;
 }
 
+/**
+ * gtk_viewport_scroll_to:
+ * @viewport: a `GtkViewport`
+ * @descendant: a descendant widget of the viewport
+ * @scroll: (nullable) (transfer full): details of how to perform
+ *   the scroll operation or NULL to scroll into view
+ *
+ * Scrolls a descendant of the viewport into view.
+ *
+ * The viewport and the descendant must be visible and mapped for
+ * this function to work, otherwise no scrolling will be performed.
+ *
+ * Since: 4.12
+ **/
+void
+gtk_viewport_scroll_to (GtkViewport   *viewport,
+                        GtkWidget     *descendant,
+                        GtkScrollInfo *scroll)
+{
+  graphene_rect_t bounds;
+  int x, y;
+  double adj_x, adj_y;
+
+  g_return_if_fail (GTK_IS_VIEWPORT (viewport));
+  g_return_if_fail (GTK_IS_WIDGET (descendant));
+
+  if (!gtk_widget_compute_bounds (descendant, GTK_WIDGET (viewport), &bounds))
+    return;
+
+  adj_x = gtk_adjustment_get_value (viewport->adjustment[GTK_ORIENTATION_HORIZONTAL]);
+  adj_y = gtk_adjustment_get_value (viewport->adjustment[GTK_ORIENTATION_VERTICAL]);
+
+  gtk_scroll_info_compute_scroll (scroll,
+                                  &(GdkRectangle) {
+                                    floor (bounds.origin.x + adj_x),
+                                    floor (bounds.origin.y + adj_y),
+                                    ceil (bounds.origin.x + bounds.size.width) - floor (bounds.origin.x),
+                                    ceil (bounds.origin.y + bounds.size.height) - floor (bounds.origin.y)
+                                  },
+                                  &(GdkRectangle) {
+                                    adj_x,
+                                    adj_y,
+                                    gtk_widget_get_width (GTK_WIDGET (viewport)),
+                                    gtk_widget_get_height (GTK_WIDGET (viewport))
+                                  },
+                                  &x, &y);
+
+  gtk_adjustment_animate_to_value (viewport->adjustment[GTK_ORIENTATION_HORIZONTAL], x);
+  gtk_adjustment_animate_to_value (viewport->adjustment[GTK_ORIENTATION_VERTICAL], y);
+}
+
index 5663ebd04b3a046bc456ab145ea53e95f3bf1815..700dffb86d5236de3f1920c52a4ed0679aefe6d7 100644 (file)
@@ -61,6 +61,11 @@ void           gtk_viewport_set_child           (GtkViewport *viewport,
 GDK_AVAILABLE_IN_ALL
 GtkWidget *    gtk_viewport_get_child           (GtkViewport *viewport);
 
+GDK_AVAILABLE_IN_4_12
+void           gtk_viewport_scroll_to           (GtkViewport   *viewport,
+                                                 GtkWidget     *descendant,
+                                                 GtkScrollInfo *scroll);
+
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkViewport, g_object_unref)
 
 G_END_DECLS