[gtk/gtk-3-24: 1/2] Implement ATK's scrollSubstringTo()




commit df670047ea2fafb558dac1b148998735396ef857
Author: Martin Pieuchot <mpi grenadille net>
Date:   Wed Sep 25 14:35:07 2019 -0300

    Implement ATK's scrollSubstringTo()
    
    This implementation is based on gtk_text_view_scroll_to_iter() and
    thus shares its limitations for the sake of simplicity.
    
    A single offset is opportunistically picked to build the iterator
    needed for gtk_text_view_scroll_to_iter().  That means that substrings
    spanning over multiple lines or larger than the current window might
    not be displayed optimally after scrolling.
    
    Partially closes #1625, the toPoint() variant has been discarded.

 configure.ac                     |  2 +-
 gtk/a11y/gtktextviewaccessible.c | 94 ++++++++++++++++++++++++++++++++++++++++
 meson.build                      |  5 ++-
 3 files changed, 98 insertions(+), 3 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index a26b03d3c3..38fd9a4804 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,7 +56,7 @@ GLIB_VERSION_CFLAGS="-DGLIB_MIN_REQUIRED_VERSION=glib_min_required_version -DGLI
 
 m4_define([pango_required_version], [1.41.0])
 m4_define([fribidi_required_version], [0.19.7])
-m4_define([atk_required_version], [2.15.1])
+m4_define([atk_required_version], [2.32.0])
 m4_define([cairo_required_version], [1.14.0])
 m4_define([gdk_pixbuf_required_version], [2.30.0])
 m4_define([introspection_required_version], [1.39.0])
diff --git a/gtk/a11y/gtktextviewaccessible.c b/gtk/a11y/gtktextviewaccessible.c
index c1092026bf..f490d3043d 100644
--- a/gtk/a11y/gtktextviewaccessible.c
+++ b/gtk/a11y/gtktextviewaccessible.c
@@ -1309,6 +1309,99 @@ gtk_text_view_accessible_set_selection (AtkText *text,
     return FALSE;
 }
 
+static gboolean
+gtk_text_view_accessible_scroll_substring_to(AtkText *text,
+                                             gint start_offset,
+                                             gint end_offset,
+                                             AtkScrollType type)
+{
+  GtkTextView *view;
+  GtkWidget *widget;
+  GtkTextBuffer *buffer;
+  GtkTextIter iter;
+  gdouble xalign = -1.0, yalign = -1.0;
+  gboolean use_align = TRUE;
+  gint offset, rtl = 0;
+
+  if (end_offset < start_offset)
+    return FALSE;
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+  if (widget == NULL)
+    return FALSE;
+
+  view = GTK_TEXT_VIEW (widget);
+  buffer = gtk_text_view_get_buffer (view);
+
+  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+    rtl = 1;
+
+  /*
+   * Opportunistically pick which offset should be used to calculate
+   * the scrolling factor.
+   *
+   * Considering only an extremity of the substring is good enough when
+   * the selected string doesn't include line break and isn't larger than
+   * the visible rectangle.
+   */
+  switch (type)
+    {
+    case ATK_SCROLL_TOP_LEFT:
+      offset = (rtl) ? end_offset : start_offset;
+      xalign = 0.0;
+      yalign = 0.0;
+      break;
+    case ATK_SCROLL_BOTTOM_RIGHT:
+      offset = (rtl) ? start_offset : end_offset;
+      xalign = 1.0;
+      yalign = 1.0;
+      break;
+    case ATK_SCROLL_TOP_EDGE:
+      offset = start_offset;
+      yalign = 0.0;
+      break;
+    case ATK_SCROLL_BOTTOM_EDGE:
+      offset = end_offset;
+      yalign = 1.0;
+      break;
+    case ATK_SCROLL_LEFT_EDGE:
+      offset = (rtl) ? end_offset : start_offset;
+      xalign = 0.0;
+      break;
+    case ATK_SCROLL_RIGHT_EDGE:
+      offset = (rtl) ? start_offset : end_offset;
+      xalign = 1.0;
+      break;
+    case ATK_SCROLL_ANYWHERE:
+      offset = start_offset;
+      use_align = FALSE;
+      xalign = yalign = 0.0;
+      break;
+    default:
+      return FALSE;
+    }
+
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
+
+  /* Get current iter location to be able to scroll in a single direction. */
+  if (use_align && (xalign == -1.0 || yalign == -1.0))
+    {
+      GdkRectangle rect, irect;
+
+      gtk_text_view_get_visible_rect (view, &rect);
+      gtk_text_view_get_iter_location (view, &iter, &irect);
+
+      if (xalign == -1.0)
+        xalign = ((gdouble) (irect.x - rect.x)) / (rect.width - 1);
+      if (yalign == -1.0)
+        yalign = ((gdouble) (irect.y - rect.y)) / (rect.height - 1);
+    }
+
+  gtk_text_view_scroll_to_iter (view, &iter, 0, use_align, xalign, yalign);
+
+  return TRUE;
+}
+
 static void
 atk_text_interface_init (AtkTextIface *iface)
 {
@@ -1329,6 +1422,7 @@ atk_text_interface_init (AtkTextIface *iface)
   iface->set_selection = gtk_text_view_accessible_set_selection;
   iface->get_run_attributes = gtk_text_view_accessible_get_run_attributes;
   iface->get_default_attributes = gtk_text_view_accessible_get_default_attributes;
+  iface->scroll_substring_to = gtk_text_view_accessible_scroll_substring_to;
 }
 
 /* atkeditabletext.h */
diff --git a/meson.build b/meson.build
index 9c80fafc03..94ccb81432 100644
--- a/meson.build
+++ b/meson.build
@@ -26,7 +26,8 @@ endif
 glib_req           = '>= @0@.@1@.@2@'.format(glib_major_req, glib_minor_req, glib_micro_req)
 pango_req          = '>= 1.41.0'
 fribidi_req        = '>= 0.19.7'
-atk_req            = '>= 2.15.1'
+atk_req            = '>= 2.32.0'
+at_spi2_atk_req    = '>= 2.15.1'
 cairo_req          = '>= 1.14.0'
 gdk_pixbuf_req     = '>= 2.30.0'
 introspection_req  = '>= 1.39.0'
@@ -575,7 +576,7 @@ if x11_enabled
   xfixes_dep     = dependency('xfixes', required: false)
   xcomposite_dep = dependency('xcomposite', required: false)
   fontconfig_dep = dependency('fontconfig', fallback: ['fontconfig', 'fontconfig_dep'])
-  atkbridge_dep  = dependency('atk-bridge-2.0', version: atk_req)
+  atkbridge_dep  = dependency('atk-bridge-2.0', version: at_spi2_atk_req)
 
   x11_pkgs = ['fontconfig', 'x11', 'xext', 'xi', 'xrandr']
 


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