[gtk+/drop-gail] Move GailScale to GtkScaleAccessible



commit 3bd4300f3e46195d0ea6a1fca4ae1035ef9662af
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat May 14 23:27:36 2011 -0400

    Move GailScale to GtkScaleAccessible

 gtk/Makefile.am           |    1 +
 gtk/gtkscale.c            |  406 +++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkscaleaccessible.h  |   57 +++++++
 modules/other/gail/gail.c |    6 +-
 4 files changed, 468 insertions(+), 2 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index ff63509..2857af3 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -434,6 +434,7 @@ gtk_private_h_sources =		\
 	gtkrecentchooserdefault.h \
 	gtkrecentchooserprivate.h \
 	gtkrecentchooserutils.h	\
+	gtkscaleaccessible.h	\
 	gtkscaleprivate.h	\
 	gtkscrolledwindowaccessible.h \
 	gtksearchengine.h	\
diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c
index 95ce6ba..7dadc5b 100644
--- a/gtk/gtkscale.c
+++ b/gtk/gtkscale.c
@@ -41,6 +41,7 @@
 #include "gtkintl.h"
 #include "gtkbuildable.h"
 #include "gtkbuilderprivate.h"
+#include "gtkpango.h"
 
 
 /**
@@ -1815,3 +1816,408 @@ gtk_scale_buildable_custom_finished (GtkBuildable *buildable,
       g_slice_free (MarksSubparserData, marks_data);
     }
 }
+
+/* --- Accessibility --- */
+
+#include "gtkaccessibility.h"
+#include "gtkscaleaccessible.h"
+
+static void atk_text_interface_init (AtkTextIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkScaleAccessible, gtk_scale_accessible, GTK_TYPE_RANGE_ACCESSIBLE,
+                         G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
+
+static void
+gtk_scale_accessible_notify (GObject    *obj,
+                             GParamSpec *pspec)
+{
+  /* FIXME move this up to where the layout is changed */
+  if (strcmp (pspec->name, "accessible-value") == 0)
+    {
+      GtkWidget *widget;
+
+      widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+      if (widget)
+        {
+          GtkScale *gtk_scale;
+          PangoLayout *layout;
+          const gchar *txt;
+
+          gtk_scale = GTK_SCALE (widget);
+          layout = gtk_scale_get_layout (gtk_scale);
+          if (layout)
+            {
+              txt = pango_layout_get_text (layout);
+              if (txt)
+                {
+                  g_signal_emit_by_name (obj, "text_changed::delete", 0, 0); /* FIXME */
+                  g_signal_emit_by_name (obj, "text_changed::insert", 0,
+                                         g_utf8_strlen (txt, -1));
+                }
+            }
+        }
+    }
+
+  G_OBJECT_CLASS (gtk_scale_accessible_parent_class)->notify (obj, pspec);
+}
+
+
+static void
+gtk_scale_accessible_class_init (GtkScaleAccessibleClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->notify = gtk_scale_accessible_notify;
+}
+
+static void
+gtk_scale_accessible_init (GtkScaleAccessible *scale)
+{
+}
+
+GTK_ACCESSIBLE_FACTORY(GTK_TYPE_SCALE_ACCESSIBLE, gtk_scale_accessible)
+
+static gchar*
+gtk_scale_accessible_get_text (AtkText *atk_text,
+                               gint    start_pos,
+                               gint    end_pos)
+{
+  GtkWidget *widget;
+  GtkScale *scale;
+  PangoLayout *layout;
+  const gchar *text;
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
+  if (widget == NULL)
+    return NULL;
+
+  scale = GTK_SCALE (widget);
+  layout = gtk_scale_get_layout (scale);
+  if (layout == NULL)
+    return NULL;
+
+  text = pango_layout_get_text (layout);
+
+  if (text)
+    return _g_utf8_substring (text, start_pos, end_pos);
+
+  return NULL;
+}
+
+static gunichar
+gtk_scale_accessible_get_character_at_offset (AtkText *atk_text,
+                                              gint     offset)
+{
+  GtkWidget *widget;
+  const gchar *text;
+  gchar *index;
+  GtkScale *scale;
+  PangoLayout *layout;
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
+  if (widget == NULL)
+    return '\0';
+
+  scale = GTK_SCALE (widget);
+  layout = gtk_scale_get_layout (scale);
+  if (layout == NULL)
+    return '\0';
+
+  text = pango_layout_get_text (layout);
+
+  if (offset >= g_utf8_strlen (text, -1))
+    return '\0';
+
+  index = g_utf8_offset_to_pointer (text, offset);
+
+  return g_utf8_get_char (index);
+}
+
+static gchar*
+gtk_scale_accessible_get_text_before_offset (AtkText         *atk_text,
+                                             gint             offset,
+                                             AtkTextBoundary  boundary_type,
+                                             gint            *start_offset,
+                                             gint            *end_offset)
+{
+  GtkWidget *widget;
+  PangoLayout *layout;
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
+  if (widget == NULL)
+    return NULL;
+
+  layout = gtk_scale_get_layout (GTK_SCALE (widget));
+  if (layout)
+    return _gtk_pango_get_text_before (layout,
+                                       boundary_type, offset,
+                                       start_offset, end_offset);
+  return NULL;
+}
+
+static gchar*
+gtk_scale_accessible_get_text_at_offset (AtkText         *atk_text,
+                                         gint             offset,
+                                         AtkTextBoundary  boundary_type,
+                                         gint            *start_offset,
+                                         gint            *end_offset)
+{
+  GtkWidget *widget;
+  PangoLayout *layout;
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
+  if (widget == NULL)
+    return NULL;
+
+  layout = gtk_scale_get_layout (GTK_SCALE (widget));
+  if (layout)
+    return _gtk_pango_get_text_at (layout,
+                                   boundary_type, offset,
+                                   start_offset, end_offset);
+  return NULL;
+}
+
+static gchar*
+gtk_scale_accessible_get_text_after_offset (AtkText         *atk_text,
+                                            gint             offset,
+                                            AtkTextBoundary  boundary_type,
+                                            gint            *start_offset,
+                                            gint            *end_offset)
+{
+  GtkWidget *widget;
+  PangoLayout *layout;
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
+  if (widget == NULL)
+    return NULL;
+
+  layout = gtk_scale_get_layout (GTK_SCALE (widget));
+  if (layout)
+    return _gtk_pango_get_text_after (layout,
+                                      boundary_type, offset,
+                                      start_offset, end_offset);
+  return NULL;
+}
+
+static gint
+gtk_scale_accessible_get_character_count (AtkText *atk_text)
+{
+  GtkWidget *widget;
+  PangoLayout *layout;
+  const gchar *text;
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
+  if (widget == NULL)
+    return 0;
+
+  layout = gtk_scale_get_layout (GTK_SCALE (widget));
+  if (layout == NULL)
+    return 0;
+
+  text = pango_layout_get_text (layout);
+  if (text)
+    return g_utf8_strlen (text, -1);
+
+  return 0;
+}
+
+static void
+gtk_scale_accessible_get_character_extents (AtkText      *atk_text,
+                                            gint          offset,
+                                            gint         *x,
+                                            gint         *y,
+                                            gint         *width,
+                                            gint         *height,
+                                            AtkCoordType  coords)
+{
+  GtkWidget *widget;
+  GtkScale *scale;
+  PangoRectangle char_rect;
+  const gchar *text;
+  gint index, x_layout, y_layout;
+  GdkWindow *window;
+  gint x_window, y_window;
+  PangoLayout *layout;
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
+  if (widget == NULL)
+    return;
+
+  scale = GTK_SCALE (widget);
+  layout = gtk_scale_get_layout (scale);
+  if (layout == NULL)
+    return;
+
+  gtk_scale_get_layout_offsets (scale, &x_layout, &y_layout);
+  text = pango_layout_get_text (layout);
+  index = g_utf8_offset_to_pointer (text, offset) - text;
+  pango_layout_index_to_pos (layout, index, &char_rect);
+  pango_extents_to_pixels (&char_rect, NULL);
+
+  window = gtk_widget_get_window (widget);
+  gdk_window_get_origin (window, &x_window, &y_window);
+
+  *x = x_window + x_layout + char_rect.x;
+  *y = x_window + y_layout + char_rect.y;
+  *width = char_rect.width;
+  *height = char_rect.height;
+
+  if (coords == ATK_XY_WINDOW)
+    {
+      window = gdk_window_get_toplevel (window);
+      gdk_window_get_origin (window, &x_window, &y_window);
+
+      *x -= x_window;
+      *y -= y_window;
+    }
+}
+
+static gint
+gtk_scale_accessible_get_offset_at_point (AtkText      *atk_text,
+                                          gint          x,
+                                          gint          y,
+                                          AtkCoordType  coords)
+{
+  GtkWidget *widget;
+  GtkScale *scale;
+  const gchar *text;
+  gint index, x_layout, y_layout;
+  gint x_window, y_window;
+  gint x_local, y_local;
+  GdkWindow *window;
+  PangoLayout *layout;
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
+  if (widget == NULL)
+    return -1;
+
+  scale = GTK_SCALE (widget);
+  layout = gtk_scale_get_layout (scale);
+  if (layout == NULL)
+    return -1;
+
+  gtk_scale_get_layout_offsets (scale, &x_layout, &y_layout);
+
+  window = gtk_widget_get_window (widget);
+  gdk_window_get_origin (window, &x_window, &y_window);
+
+  x_local = x - x_layout - x_window;
+  y_local = y - y_layout - y_window;
+
+  if (coords == ATK_XY_WINDOW)
+    {
+      window = gdk_window_get_toplevel (window);
+      gdk_window_get_origin (window, &x_window, &y_window);
+
+      x_local += x_window;
+      y_local += y_window;
+    }
+
+  if (!pango_layout_xy_to_index (layout,
+                                 x_local * PANGO_SCALE,
+                                 y_local * PANGO_SCALE,
+                                 &index, NULL))
+    {
+      if (x_local < 0 || y_local < 0)
+        index = 0;
+      else
+        index = -1;
+    }
+
+  if (index != -1)
+    {
+      text = pango_layout_get_text (layout);
+      return g_utf8_pointer_to_offset (text, text + index);
+    }
+
+  return -1;
+}
+
+static AtkAttributeSet *
+add_attribute (AtkAttributeSet  *attributes,
+               AtkTextAttribute  attr,
+               const gchar      *value)
+{
+  AtkAttribute *at;
+
+  at = g_new (AtkAttribute, 1);
+  at->name = g_strdup (atk_text_attribute_get_name (attr));
+  at->value = g_strdup (value);
+
+  return g_slist_prepend (attributes, at);
+}
+
+static AtkAttributeSet*
+gtk_scale_accessible_get_run_attributes (AtkText *text,
+                                         gint     offset,
+                                         gint    *start_offset,
+                                         gint    *end_offset)
+{
+  GtkWidget *widget;
+  AtkAttributeSet *attributes;
+  GtkScale *scale;
+  PangoLayout *layout;
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+  if (widget == NULL)
+    return NULL;
+
+  scale = GTK_SCALE (widget);
+  layout = gtk_scale_get_layout (scale);
+
+  attributes = NULL;
+  attributes = add_attribute (attributes, ATK_TEXT_ATTR_DIRECTION,
+                   atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION,
+                                                 gtk_widget_get_direction (widget)));
+  if (layout != NULL)
+    attributes = _gtk_pango_get_run_attributes (attributes,
+                                                layout,
+                                                offset,
+                                                start_offset,
+                                                end_offset);
+
+  return attributes;
+}
+
+static AtkAttributeSet*
+gtk_scale_accessible_get_default_attributes (AtkText *text)
+{
+  GtkWidget *widget;
+  AtkAttributeSet *attributes;
+  GtkScale *scale;
+  PangoLayout *layout;
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+  if (widget == NULL)
+    return NULL;
+
+  scale = GTK_SCALE (widget);
+  layout = gtk_scale_get_layout (scale);
+
+  attributes = NULL;
+  attributes = add_attribute (attributes, ATK_TEXT_ATTR_DIRECTION,
+                   atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION,
+                                                 gtk_widget_get_direction (widget)));
+  if (layout != NULL)
+    attributes = _gtk_pango_get_default_attributes (attributes, layout);
+  attributes = _gtk_style_context_get_attributes (attributes,
+                                                  gtk_widget_get_style_context (widget),
+                                                  gtk_widget_get_state_flags (widget));
+
+  return attributes;
+}
+
+static void
+atk_text_interface_init (AtkTextIface *iface)
+{
+  iface->get_text = gtk_scale_accessible_get_text;
+  iface->get_character_at_offset = gtk_scale_accessible_get_character_at_offset;
+  iface->get_text_before_offset = gtk_scale_accessible_get_text_before_offset;
+  iface->get_text_at_offset = gtk_scale_accessible_get_text_at_offset;
+  iface->get_text_after_offset = gtk_scale_accessible_get_text_after_offset;
+  iface->get_character_count = gtk_scale_accessible_get_character_count;
+  iface->get_character_extents = gtk_scale_accessible_get_character_extents;
+  iface->get_offset_at_point = gtk_scale_accessible_get_offset_at_point;
+  iface->get_run_attributes = gtk_scale_accessible_get_run_attributes;
+  iface->get_default_attributes = gtk_scale_accessible_get_default_attributes;
+}
diff --git a/gtk/gtkscaleaccessible.h b/gtk/gtkscaleaccessible.h
new file mode 100644
index 0000000..32bdc11
--- /dev/null
+++ b/gtk/gtkscaleaccessible.h
@@ -0,0 +1,57 @@
+/* GTK - The GIMP Toolkit
+ * Copyright 2011 Red Hat, Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_SCALE_ACCESSIBLE_H__
+#define __GTK_SCALE_ACCESSIBLE_H__
+
+#include <gtk/gtkrangeaccessible.h>
+#include <gtk/gtkscale.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_SCALE_ACCESSIBLE (gtk_scale_accessible_get_type ())
+#define GTK_SCALE_ACCESSIBLE(obj)(G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SCALE_ACCESSIBLE, GtkScaleAccessible))
+#define GTK_SCALE_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SCALE_ACCESSIBLE, GtkScaleAccessibleClass))
+#define GTK_SCALE_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SCALE_ACCESSIBLE, GtkScaleAccessibleClass))
+
+typedef struct _GtkScaleAccessible GtkScaleAccessible;
+typedef struct _GtkScaleAccessibleClass GtkScaleAccessibleClass;
+
+struct _GtkScaleAccessible
+{
+  GtkRangeAccessible parent;
+};
+
+struct _GtkScaleAccessibleClass
+{
+  GtkRangeAccessibleClass parent_class;
+};
+
+
+GType gtk_scale_accessible_get_type (void) G_GNUC_CONST;
+GType gtk_scale_accessible_factory_get_type (void) G_GNUC_CONST;
+
+
+G_END_DECLS
+
+#endif  /* __GTK_SCALE_ACCESSIBLE_H__ */
diff --git a/modules/other/gail/gail.c b/modules/other/gail/gail.c
index 78eda3b..fc4d67c 100644
--- a/modules/other/gail/gail.c
+++ b/modules/other/gail/gail.c
@@ -35,6 +35,7 @@
 #include <gtk/gtkpanedaccessible.h>
 #include <gtk/gtkprogressbaraccessible.h>
 #include <gtk/gtkrangeaccessible.h>
+#include <gtk/gtkscaleaccessible.h>
 #include <gtk/gtkscrollbaraccessible.h>
 #include <gtk/gtkscrolledwindowaccessible.h>
 #include <gtk/gtkseparatoraccessible.h>
@@ -97,7 +98,6 @@ GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_ENTRY, GailEntry, gail_entry, GTK_TYPE_ENTRY)
 GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_MENU_SHELL, GailMenuShell, gail_menu_shell, GTK_TYPE_MENU_SHELL)
 GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_MENU, GailMenu, gail_menu, GTK_TYPE_MENU)
 GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_WINDOW, GailWindow, gail_window, GTK_TYPE_BIN)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SCALE, GailScale, gail_scale, GTK_TYPE_SCALE)
 GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SCALE_BUTTON, GailScaleButton, gail_scale_button, GTK_TYPE_SCALE_BUTTON)
 GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_STATUSBAR, GailStatusbar, gail_statusbar, GTK_TYPE_STATUSBAR)
 GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_NOTEBOOK, GailNotebook, gail_notebook, GTK_TYPE_NOTEBOOK)
@@ -929,6 +929,9 @@ gail_accessibility_module_init (void)
   atk_registry_set_factory_type (atk_get_default_registry (),
                                  GTK_TYPE_LABEL,
                                  gtk_label_accessible_factory_get_type ());
+  atk_registry_set_factory_type (atk_get_default_registry (),
+                                 GTK_TYPE_SCALE,
+                                 gtk_scale_accessible_factory_get_type ());
   GAIL_WIDGET_SET_FACTORY (GTK_TYPE_BUTTON, gail_button);
   GAIL_WIDGET_SET_FACTORY (GTK_TYPE_LINK_BUTTON, gail_link_button);
   GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU_ITEM, gail_menu_item);
@@ -938,7 +941,6 @@ gail_accessibility_module_init (void)
   GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU_BAR, gail_menu_shell);
   GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU, gail_menu);
   GAIL_WIDGET_SET_FACTORY (GTK_TYPE_WINDOW, gail_window);
-  GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SCALE, gail_scale);
   GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SCALE_BUTTON, gail_scale_button);
   GAIL_WIDGET_SET_FACTORY (GTK_TYPE_STATUSBAR, gail_statusbar);
   GAIL_WIDGET_SET_FACTORY (GTK_TYPE_NOTEBOOK, gail_notebook);



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