[atk] AtkValue: refactoring AtkValue



commit 98838b2af5c88326225041024bfc49e0f4e6fd1e
Author: Alejandro Piñeiro <apinheiro igalia com>
Date:   Wed Mar 5 18:32:42 2014 +0100

    AtkValue: refactoring AtkValue
    
    In summary:
      * Stop to use GValue to get/set the value and use doubles instead
      * Include the support for a string description and subranges
    
    https://bugzilla.gnome.org/show_bug.cgi?id=684576

 atk/Makefile.am       |    3 +
 atk/atk.h             |    1 +
 atk/atk.symbols       |    7 +
 atk/atkmarshal.list   |    1 +
 atk/atkobject.c       |   88 ++--------
 atk/atkprivate.c      |  110 ++++++++++++
 atk/atkprivate.h      |   36 ++++
 atk/atkrange.c        |  167 +++++++++++++++++++
 atk/atkrange.h        |   51 ++++++
 atk/atkutil.c         |    8 +-
 atk/atkvalue.c        |  440 ++++++++++++++++++++++++++++++++++++++++++++++++-
 atk/atkvalue.h        |   97 +++++++++--
 docs/Makefile.am      |    2 +-
 docs/atk-docs.sgml    |    2 +
 docs/atk-sections.txt |   18 ++
 15 files changed, 930 insertions(+), 101 deletions(-)
---
diff --git a/atk/Makefile.am b/atk/Makefile.am
index 3f5be61..7417fd3 100644
--- a/atk/Makefile.am
+++ b/atk/Makefile.am
@@ -45,6 +45,8 @@ atk_sources =         \
        atkobject.c             \
        atkobjectfactory.c      \
        atkplug.c               \
+       atkprivate.c            \
+       atkrange.c              \
        atkregistry.c           \
        atkrelation.c           \
        atkrelationset.c        \
@@ -83,6 +85,7 @@ atk_headers = \
        atkobjectfactory.h      \
         atkplug.h              \
         atkimage.h             \
+       atkrange.h              \
         atkregistry.h          \
         atkrelation.h          \
         atkrelationtype.h      \
diff --git a/atk/atk.h b/atk/atk.h
index 5af7b1e..dc121a5 100755
--- a/atk/atk.h
+++ b/atk/atk.h
@@ -37,6 +37,7 @@
 #include <atk/atknoopobjectfactory.h>
 #include <atk/atkobjectfactory.h>
 #include <atk/atkplug.h>
+#include <atk/atkrange.h>
 #include <atk/atkregistry.h>
 #include <atk/atkrelation.h>
 #include <atk/atkrelationset.h>
diff --git a/atk/atk.symbols b/atk/atk.symbols
index 48ea935..5f0ecde 100644
--- a/atk/atk.symbols
+++ b/atk/atk.symbols
@@ -122,6 +122,13 @@
        atk_object_set_role
        atk_plug_get_type
        atk_rectangle_get_type
+        atk_range_get_type
+        atk_range_copy
+        atk_range_free
+        atk_range_get_lower_limit
+        atk_range_get_upper_limit
+        atk_range_get_description
+        atk_range_new
        atk_registry_get_factory
        atk_registry_get_factory_type
        atk_registry_get_type
diff --git a/atk/atkmarshal.list b/atk/atkmarshal.list
index 0763ae8..2bb343d 100644
--- a/atk/atkmarshal.list
+++ b/atk/atkmarshal.list
@@ -26,3 +26,4 @@ VOID:INT,INT
 VOID:INT,INT,STRING
 VOID:INT,INT,INT,STRING
 VOID:STRING,BOOLEAN
+VOID:DOUBLE,STRING
diff --git a/atk/atkobject.c b/atk/atkobject.c
index 3d4060a..8ef8967 100755
--- a/atk/atkobject.c
+++ b/atk/atkobject.c
@@ -35,6 +35,7 @@
 
 #include "atk.h"
 #include "atkmarshal.h"
+#include "atkprivate.h"
 
 /**
  * SECTION:atkobject
@@ -298,80 +299,9 @@ DllMain (HINSTANCE hinstDLL,
   return TRUE;
 }
 
-static const char *
-get_atk_locale_dir (void)
-{
-  static gchar *atk_localedir = NULL;
-
-  if (!atk_localedir)
-    {
-      const gchar *p;
-      gchar *root, *temp;
-      
-      /* ATK_LOCALEDIR might end in either /lib/locale or
-       * /share/locale. Scan for that slash.
-       */
-      p = ATK_LOCALEDIR + strlen (ATK_LOCALEDIR);
-      while (*--p != '/')
-       ;
-      while (*--p != '/')
-       ;
-
-      root = g_win32_get_package_installation_directory_of_module (atk_dll);
-      temp = g_build_filename (root, p, NULL);
-      g_free (root);
-
-      /* atk_localedir is passed to bindtextdomain() which isn't
-       * UTF-8-aware.
-       */
-      atk_localedir = g_win32_locale_filename_from_utf8 (temp);
-      g_free (temp);
-    }
-  return atk_localedir;
-}
-
-#undef ATK_LOCALEDIR
-
-#define ATK_LOCALEDIR get_atk_locale_dir()
-
 #endif
 
 static void
-gettext_initialization (void)
-{
-#ifdef ENABLE_NLS
-  static gboolean gettext_initialized = FALSE;
-
-  if (!gettext_initialized)
-    {
-      const char *dir = g_getenv ("ATK_ALT_LOCALEDIR");
-
-      gettext_initialized = TRUE;
-      if (dir == NULL)
-        dir = ATK_LOCALEDIR;
-
-      bindtextdomain (GETTEXT_PACKAGE, dir);
-#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
-      bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-#endif
-    }
-#endif
-}
-
-static void
-compact_role_name (gchar *role_name)
-{
-  gchar *p = role_name;
-
-  while (*p)
-    {
-      if (*p == '-')
-        *p = ' ';
-      p++;
-    }
-}
-
-static void
 initialize_role_names ()
 {
   GTypeClass *enum_class;
@@ -392,7 +322,7 @@ initialize_role_names ()
       enum_value = g_enum_get_value (G_ENUM_CLASS (enum_class), i);
       role_name = g_strdup (enum_value->value_nick);
       // We want the role names to be in the format "check button" and not "check-button"
-      compact_role_name (role_name);
+      _compact_name (role_name);
       g_ptr_array_add (role_names, role_name);
     }
 
@@ -463,7 +393,7 @@ atk_object_class_init (AtkObjectClass *klass)
   klass->visible_data_changed = NULL;
   klass->active_descendant_changed = NULL;
 
-  gettext_initialization ();
+  _gettext_initialization ();
 
   g_object_class_install_property (gobject_class,
                                    PROP_NAME,
@@ -486,6 +416,16 @@ atk_object_class_init (AtkObjectClass *klass)
                                                         _("Parent of the current accessible as returned by 
atk_object_get_parent()"),
                                                         ATK_TYPE_OBJECT,
                                                         G_PARAM_READWRITE));
+
+  /**
+   * AtkObject:accessible-value:
+   *
+   * Numeric value of this object, in case being and AtkValue.
+   *
+   * Deprecated: Since 2.12. Use atk_value_get_value_and_text() to get
+   * the value, and value-changed signal to be notified on their value
+   * changes.
+   */
   g_object_class_install_property (gobject_class,
                                    PROP_VALUE,
                                    g_param_spec_double (atk_object_name_property_value,
@@ -1655,7 +1595,7 @@ atk_role_get_name (AtkRole role)
 const gchar*
 atk_role_get_localized_name (AtkRole role)
 {
-  gettext_initialization ();
+  _gettext_initialization ();
 
   return dgettext (GETTEXT_PACKAGE, atk_role_get_name (role));
 }
diff --git a/atk/atkprivate.c b/atk/atkprivate.c
new file mode 100644
index 0000000..de60c2f
--- /dev/null
+++ b/atk/atkprivate.c
@@ -0,0 +1,110 @@
+/* ATK -  Accessibility Toolkit
+ *
+ * Copyright (C) 2014 Igalia, S.L.
+ *
+ * Author: Alejandro Piñeiro Iglesias <apinheiro igalia com>
+ *
+ * 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.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <locale.h>
+
+#include <glib-object.h>
+#include <glib/gi18n-lib.h>
+
+#include "atkprivate.h"
+
+#ifdef G_OS_WIN32
+
+static const char *
+get_atk_locale_dir (void)
+{
+  static gchar *atk_localedir = NULL;
+
+  if (!atk_localedir)
+    {
+      const gchar *p;
+      gchar *root, *temp;
+      
+      /* ATK_LOCALEDIR might end in either /lib/locale or
+       * /share/locale. Scan for that slash.
+       */
+      p = ATK_LOCALEDIR + strlen (ATK_LOCALEDIR);
+      while (*--p != '/')
+       ;
+      while (*--p != '/')
+       ;
+
+      root = g_win32_get_package_installation_directory_of_module (atk_dll);
+      temp = g_build_filename (root, p, NULL);
+      g_free (root);
+
+      /* atk_localedir is passed to bindtextdomain() which isn't
+       * UTF-8-aware.
+       */
+      atk_localedir = g_win32_locale_filename_from_utf8 (temp);
+      g_free (temp);
+    }
+  return atk_localedir;
+}
+
+#undef ATK_LOCALEDIR
+
+#define ATK_LOCALEDIR get_atk_locale_dir()
+
+#endif
+
+void
+_gettext_initialization (void)
+{
+#ifdef ENABLE_NLS
+  static gboolean gettext_initialized = FALSE;
+
+  if (!gettext_initialized)
+    {
+      const char *dir = g_getenv ("ATK_ALT_LOCALEDIR");
+
+      gettext_initialized = TRUE;
+      if (dir == NULL)
+        dir = ATK_LOCALEDIR;
+
+      bindtextdomain (GETTEXT_PACKAGE, dir);
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+      bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+#endif
+    }
+#endif
+}
+
+/*
+ * Compacts a name. For example: to get "accelerator label" instead of
+ * "accelerator-label"
+ */
+void
+_compact_name (gchar *name)
+{
+  gchar *p = name;
+
+  while (*p)
+    {
+      if (*p == '-')
+        *p = ' ';
+      p++;
+    }
+}
diff --git a/atk/atkprivate.h b/atk/atkprivate.h
new file mode 100644
index 0000000..3d33c90
--- /dev/null
+++ b/atk/atkprivate.h
@@ -0,0 +1,36 @@
+/* ATK -  Accessibility Toolkit
+ * Copyright (C) 2014 Igalia, S.L.
+ *
+ * Author: Alejandro Piñeiro Iglesias <apinheiro igalia com>
+ *
+ * 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(ATK_DISABLE_SINGLE_INCLUDES) && !defined (__ATK_H_INSIDE__) && !defined (ATK_COMPILATION)
+#error "Only <atk/atk.h> can be included directly."
+#endif
+
+#ifndef __ATK_PRIVATE_H__
+#define __ATK_PRIVATE_H__
+
+G_BEGIN_DECLS
+
+void      _gettext_initialization (void);
+void      _compact_name (gchar *name);
+
+G_END_DECLS
+
+#endif /* __ATK_PRIVATE_H__ */
diff --git a/atk/atkrange.c b/atk/atkrange.c
new file mode 100644
index 0000000..db48c14
--- /dev/null
+++ b/atk/atkrange.c
@@ -0,0 +1,167 @@
+/* ATK -  Accessibility Toolkit
+ * Copyright 2014 Igalia S.L.
+ *
+ * Author: Alejandro Piñeiro Iglesias <apinheiro igalia com>
+ *
+ * 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "atkvalue.h"
+
+/**
+ * SECTION:atkrange
+ * @Short_description: A given range or subrange, to be used with #AtkValue
+ * @Title:AtkRange
+ *
+ * #AtkRange are used on #AtkValue, in order to represent the full
+ * range of a given component (for example an slider or a range
+ * control), or to define each individual subrange this full range is
+ * splitted if available. See #AtkValue documentation for further
+ * details.
+ */
+
+struct _AtkRange {
+  gdouble lower;
+  gdouble upper;
+  gchar *description;
+};
+
+/**
+ * atk_range_copy:
+ * @src: #AtkRange to copy
+ *
+ * Returns a new #AtkRange that is a exact copy of @src
+ *
+ * Since: 2.12
+ *
+ * Returns: (transfer full): a new #AtkRange copy of @src
+ */
+AtkRange *
+atk_range_copy (AtkRange *src)
+{
+  g_return_val_if_fail (src != NULL, NULL);
+
+  return atk_range_new (src->lower,
+                        src->upper,
+                        src->description);
+}
+
+/**
+ * atk_range_free:
+ * @range: #AtkRange to free
+ *
+ * Free @range
+ *
+ * Since: 2.12
+ */
+void
+atk_range_free (AtkRange *range)
+{
+  g_return_if_fail (range != NULL);
+
+  if (range->description)
+    g_free (range->description);
+
+  g_slice_free (AtkRange, range);
+}
+
+G_DEFINE_BOXED_TYPE (AtkRange, atk_range, atk_range_copy,
+                     atk_range_free)
+
+
+/**
+ * atk_range_new:
+ * @lower_limit: inferior limit for this range
+ * @upper_limit: superior limit for this range
+ * @description: human readable description of this range.
+ *
+ * Creates a new #AtkRange.
+ *
+ * Since: 2.12
+ *
+ * Returns: (transfer full): a new #AtkRange
+ *
+ */
+AtkRange*
+atk_range_new  (gdouble   lower_limit,
+                gdouble   upper_limit,
+                const gchar *description)
+{
+  AtkRange *range;
+
+  range = g_slice_new0 (AtkRange);
+
+  range->lower = lower_limit;
+  range->upper = upper_limit;
+  if (description != NULL)
+    range->description = g_strdup (description);
+
+  return range;
+}
+
+/**
+ * atk_range_get_lower_limit:
+ * @range: an #AtkRange
+ *
+ * Returns the lower limit of @range
+ *
+ * Since: 2.12
+ *
+ * Returns: the lower limit of @range
+ */
+gdouble
+atk_range_get_lower_limit  (AtkRange *range)
+{
+  g_return_val_if_fail (range != NULL, 0);
+
+  return range->lower;
+}
+
+/**
+ * atk_range_get_upper_limit:
+ * @range: an #AtkRange
+ *
+ * Returns the upper limit of @range
+ *
+ * Since: 2.12
+ *
+ * Returns: the upper limit of @range
+ */
+gdouble
+atk_range_get_upper_limit (AtkRange *range)
+{
+  g_return_val_if_fail (range != NULL, 0);
+
+  return range->upper;
+}
+
+/**
+ * atk_range_get_description:
+ * @range: an #AtkRange
+ *
+ * Returns the human readable description of @range
+ *
+ * Since: 2.12
+ *
+ * Returns: the human-readable description of @range
+ */
+const gchar*
+atk_range_get_description  (AtkRange *range)
+{
+  g_return_val_if_fail (range != NULL, NULL);
+
+  return range->description;
+}
diff --git a/atk/atkrange.h b/atk/atkrange.h
new file mode 100644
index 0000000..12e22d9
--- /dev/null
+++ b/atk/atkrange.h
@@ -0,0 +1,51 @@
+/* ATK -  Accessibility Toolkit
+ * Copyright 2014 Igalia S.L.
+ *
+ * Author: Alejandro Piñeiro Iglesias <apinheiro igalia com>
+ *
+ * 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(ATK_DISABLE_SINGLE_INCLUDES) && !defined (__ATK_H_INSIDE__) && !defined (ATK_COMPILATION)
+#error "Only <atk/atk.h> can be included directly."
+#endif
+
+#ifndef __ATK_RANGE_H__
+#define __ATK_RANGE_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define ATK_TYPE_RANGE         (atk_range_get_type ())
+
+typedef struct _AtkRange AtkRange;
+
+/* AtkRange methods */
+GType atk_range_get_type (void);
+
+AtkRange*    atk_range_copy (AtkRange *src);
+void         atk_range_free (AtkRange *range);
+
+gdouble      atk_range_get_lower_limit  (AtkRange    *range);
+gdouble      atk_range_get_upper_limit  (AtkRange    *range);
+const gchar* atk_range_get_description  (AtkRange    *range);
+AtkRange*    atk_range_new              (gdouble      lower_limit,
+                                         gdouble      upper_limit,
+                                         const gchar *description);
+
+G_END_DECLS
+
+#endif /* __ATK_RANGE_H__ */
diff --git a/atk/atkutil.c b/atk/atkutil.c
index 058fc6d..f19e334 100755
--- a/atk/atkutil.c
+++ b/atk/atkutil.c
@@ -353,11 +353,11 @@ atk_util_real_remove_global_event_listener (guint remove_listener)
  * when an ATK event of type event_type occurs.
  *
  * The format of event_type is the following:
- *  "ATK:<atk_type>:<atk_event>:<atk_event_detail>
+ *  "ATK:&lt;atk_type&gt;:&lt;atk_event&gt;:&lt;atk_event_detail&gt;
  *
- * Where "ATK" works as the namespace, <atk_interface> is the name of
- * the ATK type (interface or object), <atk_event> is the name of the
- * signal defined on that interface and <atk_event_detail> is the
+ * Where "ATK" works as the namespace, &lt;atk_interface&gt; is the name of
+ * the ATK type (interface or object), &lt;atk_event&gt; is the name of the
+ * signal defined on that interface and &lt;atk_event_detail&gt; is the
  * gsignal detail of that signal. You can find more info about gsignal
  * details here:
  * http://developer.gnome.org/gobject/stable/gobject-Signals.html
diff --git a/atk/atkvalue.c b/atk/atkvalue.c
index 2a6b083..ec3156b 100755
--- a/atk/atkvalue.c
+++ b/atk/atkvalue.c
@@ -17,8 +17,15 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include "config.h"
+
 #include <string.h>
+#include <glib/gi18n-lib.h>
+
 #include "atkvalue.h"
+#include "atkmarshal.h"
+#include "atk-enum-types.h"
+#include "atkprivate.h"
 
 /**
  * SECTION:atkvalue
@@ -29,13 +36,157 @@
  *
  * #AtkValue should be implemented for components which either display
  * a value from a bounded range, or which allow the user to specify a
- * value from a bounded range, or both.  For instance, most sliders
- * and range controls, as well as dials, should have #AtkObject
+ * value from a bounded range, or both. For instance, most sliders and
+ * range controls, as well as dials, should have #AtkObject
  * representations which implement #AtkValue on the component's
- * behalf.  #AtKValues may be read-only, in which case attempts to
- * alter the value return FALSE to indicate failure.
+ * behalf. #AtKValues may be read-only, in which case attempts to
+ * alter the value return would fail.
+ *
+ * <refsect1 id="current-value-text">
+ * <title>On the subject of current value text</title>
+ * <para>
+ * In addition to providing the current value, implementors can
+ * optionally provide an end-user-consumable textual description
+ * associated with this value. This description should be included
+ * when the numeric value fails to convey the full, on-screen
+ * representation seen by users.
+ * </para>
+ *
+ * <example>
+ * <title>Password strength</title>
+ * A password strength meter whose value changes as the user types
+ * their new password. Red is used for values less than 4.0, yellow
+ * for values between 4.0 and 7.0, and green for values greater than
+ * 7.0. In this instance, value text should be provided by the
+ * implementor. Appropriate value text would be "weak", "acceptable,"
+ * and "strong" respectively.
+ * </example>
+ *
+ * A level bar whose value changes to reflect the battery charge. The
+ * color remains the same regardless of the charge and there is no
+ * on-screen text reflecting the fullness of the battery. In this
+ * case, because the position within the bar is the only indication
+ * the user has of the current charge, value text should not be
+ * provided by the implementor.
+ *
+ * <refsect2 id="implementor-notes">
+ * <title>Implementor Notes</title>
+ * <para>
+ * Implementors should bear in mind that assistive technologies will
+ * likely prefer the value text provided over the numeric value when
+ * presenting a widget's value. As a result, strings not intended for
+ * end users should not be exposed in the value text, and strings
+ * which are exposed should be localized. In the case of widgets which
+ * display value text on screen, for instance through a separate label
+ * in close proximity to the value-displaying widget, it is still
+ * expected that implementors will expose the value text using the
+ * above API.
+ * </para>
+ *
+ * <para>
+ * #AtkValue should NOT be implemented for widgets whose displayed
+ * value is not reflective of a meaningful amount. For instance, a
+ * progress pulse indicator whose value alternates between 0.0 and 1.0
+ * to indicate that some process is still taking place should not
+ * implement #AtkValue because the current value does not reflect
+ * progress towards completion.
+ * </para>
+ * </refsect2>
+ * </refsect1>
+ *
+ * <refsect1 id="ranges">
+ * <title>On the subject of ranges</title>
+ * <para>
+ * In addition to providing the minimum and maximum values,
+ * implementors can optionally provide details about subranges
+ * associated with the widget. These details should be provided by the
+ * implementor when both of the following are communicated visually to
+ * the end user:
+ * </para>
+ * <itemizedlist>
+ *   <listitem>The existence of distinct ranges such as "weak",
+ *   "acceptable", and "strong" indicated by color, bar tick marks,
+ *   and/or on-screen text.</listitem>
+ *   <listitem>Where the current value stands within a given subrange,
+ *   for instance illustrating progression from very "weak" towards
+ *   nearly "acceptable" through changes in shade and/or position on
+ *   the bar within the "weak" subrange.</listitem>
+ * </itemizedlist>
+ * <para>
+ * If both of the above do not apply to the widget, it should be
+ * sufficient to expose the numeric value, along with the value text
+ * if appropriate, to make the widget accessible.
+ * </para>
+ *
+ * <refsect2 id="ranges-implementor-notes">
+ * <title>Implementor Notes</title>
+ * <para>
+ * If providing subrange details is deemed necessary, all possible
+ * values of the widget are expected to fall within one of the
+ * subranges defined by the implementor.
+ * </para>
+ * </refsect2>
+ * </refsect1>
+ *
+ * <refsect1 id="localization">
+ * <title>On the subject of localization of end-user-consumable text
+ * values</title>
+ * <para>
+ * Because value text and subrange descriptors are human-consumable,
+ * implementors are expected to provide localized strings which can be
+ * directly presented to end users via their assistive technology. In
+ * order to simplify this for implementors, implementors can use
+ * atk_value_type_get_localized_name() with the following
+ * already-localized constants for commonly-needed values can be used:
+ * </para>
+ *
+ * <itemizedlist>
+ *   <listitem>ATK_VALUE_VERY_WEAK</listitem>
+ *   <listitem>ATK_VALUE_WEAK</listitem>
+ *   <listitem>ATK_VALUE_ACCEPTABLE</listitem>
+ *   <listitem>ATK_VALUE_STRONG</listitem>
+ *   <listitem>ATK_VALUE_VERY_STRONG</listitem>
+ *   <listitem>ATK_VALUE_VERY_LOW</listitem>
+ *   <listitem>ATK_VALUE_LOW</listitem>
+ *   <listitem>ATK_VALUE_MEDIUM</listitem>
+ *   <listitem>ATK_VALUE_HIGH</listitem>
+ *   <listitem>ATK_VALUE_VERY_HIGH</listitem>
+ *   <listitem>ATK_VALUE_VERY_BAD</listitem>
+ *   <listitem>ATK_VALUE_BAD</listitem>
+ *   <listitem>ATK_VALUE_GOOD</listitem>
+ *   <listitem>ATK_VALUE_VERY_GOOD</listitem>
+ *   <listitem>ATK_VALUE_BEST</listitem>
+ *   <listitem>ATK_VALUE_SUBSUBOPTIMAL</listitem>
+ *   <listitem>ATK_VALUE_SUBOPTIMAL</listitem>
+ *   <listitem>ATK_VALUE_OPTIMAL</listitem>
+ * </itemizedlist>
+ * <para>
+ * Proposals for additional constants, along with their use cases,
+ * should be submitted to the GNOME Accessibility Team.
+ * </para>
+ * </refsect1>
+ *
+ * <refsect1 id="changes">
+ * <title>On the subject of changes</title>
+ * <para>
+ * Note that if there is a textual description associated with the new
+ * numeric value, that description should be included regardless of
+ * whether or not it has also changed.
+ * </para>
+ * </refsect1>
  */
 
+static GPtrArray *value_type_names = NULL;
+
+enum {
+  VALUE_CHANGED,
+  LAST_SIGNAL
+};
+
+static void atk_value_base_init (AtkValueIface *class);
+
+static guint atk_value_signals[LAST_SIGNAL] = {0};
+
 GType
 atk_value_get_type (void)
 {
@@ -45,7 +196,7 @@ atk_value_get_type (void)
     GTypeInfo tinfo =
     {
       sizeof (AtkValueIface),
-      (GBaseInitFunc) NULL,
+      (GBaseInitFunc) atk_value_base_init,
       (GBaseFinalizeFunc) NULL,
 
     };
@@ -56,12 +207,57 @@ atk_value_get_type (void)
   return type;
 }
 
+static void
+atk_value_base_init (AtkValueIface *class)
+{
+  static gboolean initialized = FALSE;
+  if (!initialized)
+    {
+      /**
+       * AtkValue::value-changed:
+       * @atkvalue: the object on which the signal was emitted.
+       * @value: the new value in a numerical form.
+       * @text: human readable text alternative (also called
+       * description) of this object. NULL if not available.
+       *
+       * The 'value-changed' signal is emitted when the current value
+       * that represent the object changes. @value is the numerical
+       * representation of this new value.  @text is the human
+       * readable text alternative of @value, and can be NULL if it is
+       * not available. Note that if there is a textual description
+       * associated with the new numeric value, that description
+       * should be included regardless of whether or not it has also
+       * changed.
+       *
+       * Example: a password meter whose value changes as the user
+       * types their new password. Appropiate value text would be
+       * "weak", "acceptable" and "strong".
+       *
+       * Since: 2.12
+       */
+      atk_value_signals[VALUE_CHANGED] =
+        g_signal_new ("value_changed",
+                      ATK_TYPE_VALUE,
+                      G_SIGNAL_RUN_LAST,
+                      0,
+                      (GSignalAccumulator) NULL, NULL,
+                      atk_marshal_VOID__DOUBLE_STRING,
+                      G_TYPE_NONE,
+                      2, G_TYPE_DOUBLE, G_TYPE_STRING);
+
+      initialized = TRUE;
+    }
+}
+
 /**
  * atk_value_get_current_value:
  * @obj: a GObject instance that implements AtkValueIface
  * @value: a #GValue representing the current accessible value
  *
  * Gets the value of this object.
+ *
+ * Deprecated: Since 2.12. Use atk_value_get_value_and_text()
+ * instead.
  **/
 void
 atk_value_get_current_value (AtkValue *obj,
@@ -91,6 +287,8 @@ atk_value_get_current_value (AtkValue *obj,
  * @value: a #GValue representing the maximum accessible value
  *
  * Gets the maximum value of this object.
+ *
+ * Deprecated: Since 2.12. Use atk_value_get_range() instead.
  **/
 void
 atk_value_get_maximum_value  (AtkValue *obj,
@@ -120,6 +318,8 @@ atk_value_get_maximum_value  (AtkValue *obj,
  * @value: a #GValue representing the minimum accessible value
  *
  * Gets the minimum value of this object.
+ *
+ * Deprecated: Since 2.12. Use atk_value_get_range() instead.
  **/
 void
 atk_value_get_minimum_value (AtkValue *obj,
@@ -153,6 +353,8 @@ atk_value_get_minimum_value (AtkValue *obj,
  * floating point precision of the platform.
  *
  * Since: 1.12
+ *
+ * Deprecated: Since 2.12. Use atk_value_get_increment() instead.
  **/
 void
 atk_value_get_minimum_increment (AtkValue *obj,
@@ -184,6 +386,8 @@ atk_value_get_minimum_increment (AtkValue *obj,
  * Sets the value of this object.
  *
  * Returns: %TRUE if new value is successfully set, %FALSE otherwise.
+ *
+ * Deprecated: Since 2.12. Use atk_value_set_value() instead.
  **/
 gboolean
 atk_value_set_current_value (AtkValue       *obj, 
@@ -201,3 +405,229 @@ atk_value_set_current_value (AtkValue       *obj,
   else
     return FALSE;
 }
+
+
+/**
+ * atk_value_get_value_and_text:
+ * @obj: a GObject instance that implements AtkValueIface
+ * @value: (out): address of #gdouble to put the current value of @obj
+ * @text: (out) (allow-none): address of #gchar to put the human
+ * readable text alternative for @value
+ *
+ * Gets the current value and the human readable text alternative of
+ * @obj. @text is a newly created string, that must be freed by the
+ * caller. Can be NULL if not descriptor is available.
+ *
+ * Since: 2.12
+ **/
+
+void
+atk_value_get_value_and_text (AtkValue *obj,
+                              gdouble *value,
+                              gchar  **text)
+{
+  AtkValueIface *iface;
+
+  g_return_if_fail (ATK_IS_VALUE (obj));
+
+  iface = ATK_VALUE_GET_IFACE (obj);
+
+  if (iface->get_value_and_text)
+    {
+      (iface->get_value_and_text) (obj, value, text);
+    }
+}
+
+/**
+ * atk_value_get_range:
+ * @obj: a GObject instance that implements AtkValueIface
+ *
+ * Gets the range of this object.
+ *
+ * Returns: (transfer full): a newly allocated #AtkRange that
+ * represents the minimum, maximum and descriptor (if available) of
+ * @obj. NULL if that range is not defined.
+ *
+ * Since: 2.12
+ **/
+AtkRange*
+atk_value_get_range (AtkValue *obj)
+{
+  AtkValueIface *iface;
+
+  g_return_val_if_fail (ATK_IS_VALUE (obj), NULL);
+
+  iface = ATK_VALUE_GET_IFACE (obj);
+
+  if (iface->get_range)
+    {
+      return (iface->get_range) (obj);
+    }
+  else
+    return NULL;
+}
+
+/**
+ * atk_value_get_increment:
+ * @obj: a GObject instance that implements AtkValueIface
+ *
+ * Gets the minimum increment by which the value of this object may be
+ * changed.  If zero, the minimum increment is undefined, which may
+ * mean that it is limited only by the floating point precision of the
+ * platform.
+ *
+ * Return value: the minimum increment by which the value of this
+ * object may be changed. zero if undefined.
+ *
+ * Since: 2.12
+ **/
+gdouble
+atk_value_get_increment (AtkValue *obj)
+{
+  AtkValueIface *iface;
+
+  g_return_val_if_fail (ATK_IS_VALUE (obj), 0);
+
+  iface = ATK_VALUE_GET_IFACE (obj);
+
+  if (iface->get_increment)
+    {
+      return (iface->get_increment) (obj);
+    }
+  else
+    return 0;
+}
+
+
+/**
+ * atk_value_get_sub_ranges:
+ * @obj: a GObject instance that implements AtkValueIface
+ *
+ * Gets the list of subranges defined for this object. See #AtkValue
+ * introduction for examples of subranges and when to expose them.
+ *
+ * Returns: (element-type AtkRange) (transfer full): an #GSList of
+ * #AtkRange which each of the subranges defined for this object. Free
+ * the returns list with g_slist_free().
+ *
+ * Since: 2.12
+ **/
+GSList*
+atk_value_get_sub_ranges (AtkValue *obj)
+{
+  AtkValueIface *iface;
+
+  g_return_val_if_fail (ATK_IS_VALUE (obj), NULL);
+
+  iface = ATK_VALUE_GET_IFACE (obj);
+
+  if (iface->get_sub_ranges)
+    {
+      return (iface->get_sub_ranges) (obj);
+    }
+  else
+    return NULL;
+}
+
+/**
+ * atk_value_set_value:
+ * @obj: a GObject instance that implements AtkValueIface
+ * @new_value: a double which is the desired new accessible value.
+ *
+ * Sets the value of this object.
+ *
+ * This method is intended to provide a way to change the value of the
+ * object. In any case, it is possible that the value can't be
+ * modified (ie: a read-only component). If the value changes due this
+ * call, it is possible that the text could change, and will trigger
+ * an #AtkValue::value-changed signal emission.
+ *
+ * Note for implementors: the deprecated atk_value_set_current_value()
+ * method returned TRUE or FALSE depending if the value was assigned
+ * or not. In the practice several implementors were not able to
+ * decide it, and returned TRUE in any case. For that reason it is not
+ * required anymore to return if the value was properly assigned or
+ * not.
+ *
+ * Since: 2.12
+ **/
+void
+atk_value_set_value (AtkValue     *obj,
+                     const gdouble new_value)
+{
+  AtkValueIface *iface;
+
+  g_return_if_fail (ATK_IS_VALUE (obj));
+
+  iface = ATK_VALUE_GET_IFACE (obj);
+
+  if (iface->set_value)
+    {
+      (iface->set_value) (obj, new_value);
+    }
+}
+
+static void
+initialize_value_type_names ()
+{
+  GTypeClass *enum_class;
+  GEnumValue *enum_value;
+  int i;
+  gchar *value_type_name = NULL;
+
+  if (value_type_names)
+    return;
+
+  value_type_names = g_ptr_array_new ();
+  enum_class = g_type_class_ref (ATK_TYPE_VALUE_TYPE);
+  if (!G_IS_ENUM_CLASS(enum_class))
+    return;
+
+  for (i = 0; i < ATK_VALUE_LAST_DEFINED; i++)
+    {
+      enum_value = g_enum_get_value (G_ENUM_CLASS (enum_class), i);
+      value_type_name = g_strdup (enum_value->value_nick);
+      _compact_name (value_type_name);
+      g_ptr_array_add (value_type_names, value_type_name);
+    }
+
+  g_type_class_unref (enum_class);
+}
+
+/**
+ * atk_value_type_get_name:
+ * @role: The #AtkValueType whose name is required
+ *
+ * Gets the description string describing the #AtkValueType @value_type.
+ *
+ * Returns: the string describing the #AtkValueType
+ */
+const gchar*
+atk_value_type_get_name (AtkValueType value_type)
+{
+  g_return_val_if_fail (value_type >= 0, NULL);
+
+  if (!value_type_names)
+    initialize_value_type_names ();
+
+  if (value_type < value_type_names->len)
+    return g_ptr_array_index (value_type_names, value_type);
+
+  return NULL;
+}
+
+/**
+ * atk_value_type_get_localized_name:
+ * @value_type: The #AtkValueType whose localized name is required
+ *
+ * Gets the localized description string describing the #AtkValueType @value_type.
+ *
+ * Returns: the localized string describing the #AtkValueType
+ **/
+const gchar*
+atk_value_type_get_localized_name (AtkValueType value_type)
+{
+  _gettext_initialization ();
+
+  return dgettext (GETTEXT_PACKAGE, atk_value_type_get_name (value_type));
+}
diff --git a/atk/atkvalue.h b/atk/atkvalue.h
index 56554d3..54919d9 100755
--- a/atk/atkvalue.h
+++ b/atk/atkvalue.h
@@ -25,17 +25,10 @@
 #define __ATK_VALUE_H__
 
 #include <atk/atkobject.h>
+#include <atk/atkrange.h>
 
 G_BEGIN_DECLS
 
-/*
- * The AtkValue interface should be supported by any object that 
- * supports a numerical value (e.g., a scroll bar). This interface 
- * provides the standard mechanism for an assistive technology to 
- * determine and set the numerical value as well as get the minimum 
- * and maximum values.
- */
-
 #define ATK_TYPE_VALUE                    (atk_value_get_type ())
 #define ATK_IS_VALUE(obj)                 G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_VALUE)
 #define ATK_VALUE(obj)                    G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_VALUE, AtkValue)
@@ -47,10 +40,63 @@ typedef struct _AtkValue AtkValue;
 #endif
 typedef struct _AtkValueIface AtkValueIface;
 
+/**
+ * AtkValueType:
+ *
+ * Default types for a given value. Those are defined in order to
+ * easily get localized strings to describe a given value or a given
+ * subrange, using atk_value_type_get_localized_name().
+ *
+ */
+typedef enum
+{
+  ATK_VALUE_VERY_WEAK,
+  ATK_VALUE_WEAK,
+  ATK_VALUE_ACCEPTABLE,
+  ATK_VALUE_STRONG,
+  ATK_VALUE_VERY_STRONG,
+  ATK_VALUE_VERY_LOW,
+  ATK_VALUE_LOW,
+  ATK_VALUE_MEDIUM,
+  ATK_VALUE_HIGH,
+  ATK_VALUE_VERY_HIGH,
+  ATK_VALUE_VERY_BAD,
+  ATK_VALUE_BAD,
+  ATK_VALUE_GOOD,
+  ATK_VALUE_VERY_GOOD,
+  ATK_VALUE_BEST,
+  ATK_VALUE_LAST_DEFINED
+}AtkValueType;
+
+/**
+ * AtkValueIface:
+ * @get_current_value: This virtual function is deprecated since 2.12
+ *  and it should not be overriden.
+ * @get_maximum_value: This virtual function is deprecated since 2.12
+ *  and it should not be overriden.
+ * @get_minimum_value: This virtual function is deprecated since 2.12
+ *  and it should not be overriden.
+ * @set_current_value: This virtual function is deprecated since 2.12
+ *  and it should not be overriden.
+ * @get_minimum_increment: This virtual function is deprecated since
+ *  2.12 and it should not be overriden.
+ * @get_value_and_text: gets the current value and the human readable
+ * text alternative (if available) of this object. Since 2.12.
+ * @get_range: gets the range that defines the minimum and maximum
+ *  value of this object. Returns NULL if there is no range
+ *  defined. Since 2.12.
+ * @get_increment: gets the minimum increment by which the value of
+ *  this object may be changed. If zero it is undefined. Since 2.12.
+ * @get_sub_ranges: returns a list of different subranges, and their
+ *  description (if available) of this object. Returns NULL if there
+ *  is not subranges defined. Since 2.12.
+ * @set_value: sets the value of this object. Since 2.12.
+ */
 struct _AtkValueIface
 {
   GTypeInterface parent;
 
+  /*<deprecated>*/
   void     (* get_current_value) (AtkValue     *obj,
                                   GValue       *value);
   void     (* get_maximum_value) (AtkValue     *obj,
@@ -61,31 +107,48 @@ struct _AtkValueIface
                                   const GValue *value);
   void     (* get_minimum_increment) (AtkValue   *obj,
                                      GValue     *value);
+  /*</deprecated>*/
+  void     (* get_value_and_text) (AtkValue *obj,
+                                   gdouble *value,
+                                   gchar  **text);
+  AtkRange*(* get_range)          (AtkValue *obj);
+  gdouble  (* get_increment)      (AtkValue *obj);
+  GSList*  (* get_sub_ranges)     (AtkValue *obj);
+  void     (* set_value)          (AtkValue     *obj,
+                                   const gdouble new_value);
+
 };
 
 GType            atk_value_get_type (void);
 
+G_DEPRECATED_FOR(atk_value_get_value_and_text)
 void      atk_value_get_current_value (AtkValue     *obj,
                                        GValue       *value);
 
-
+G_DEPRECATED_FOR(atk_value_get_range)
 void     atk_value_get_maximum_value  (AtkValue     *obj,
                                        GValue       *value);
-
+G_DEPRECATED_FOR(atk_value_get_range)
 void     atk_value_get_minimum_value  (AtkValue     *obj,
                                        GValue       *value);
-
+G_DEPRECATED_FOR(atk_value_set_value)
 gboolean atk_value_set_current_value  (AtkValue     *obj,
                                        const GValue *value);
-
+G_DEPRECATED_FOR(atk_value_get_increment)
 void     atk_value_get_minimum_increment  (AtkValue     *obj,
                                           GValue       *value);
 
-/*
- * Additional GObject properties exported by GaccessibleValue:
- *    "accessible_value"
- *       (the accessible value has changed)
- */
+void      atk_value_get_value_and_text (AtkValue *obj,
+                                        gdouble *value,
+                                        gchar  **text);
+AtkRange* atk_value_get_range          (AtkValue *obj);
+gdouble   atk_value_get_increment      (AtkValue *obj);
+GSList*   atk_value_get_sub_ranges     (AtkValue *obj);
+void      atk_value_set_value          (AtkValue     *obj,
+                                        const gdouble new_value);
+/* AtkValueType methods */
+const gchar* atk_value_type_get_name           (AtkValueType value_type);
+const gchar* atk_value_type_get_localized_name (AtkValueType value_type);
 
 G_END_DECLS
 
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 99bff8f..5fd3fc1 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -31,7 +31,7 @@ GTKDOC_LIBS = $(top_builddir)/atk/libatk-$(ATK_API_VERSION).la \
               $(DEP_LIBS)
 
 # gtkdoc-mkdb related varaibles
-MKDB_OPTIONS =
+MKDB_OPTIONS =--sgml-mode
 content_files =                \
        version.xml
 HTML_IMAGES =
diff --git a/docs/atk-docs.sgml b/docs/atk-docs.sgml
index 393cc75..92236a4 100644
--- a/docs/atk-docs.sgml
+++ b/docs/atk-docs.sgml
@@ -16,6 +16,7 @@
   <!ENTITY atk-AtkPlug SYSTEM "xml/atkplug.xml">
   <!ENTITY atk-AtkObject SYSTEM "xml/atkobject.xml">
   <!ENTITY atk-AtkObjectFactory SYSTEM "xml/atkobjectfactory.xml">
+  <!ENTITY atk-AtkRange SYSTEM "xml/atkrange.xml">
   <!ENTITY atk-AtkRegistry SYSTEM "xml/atkregistry.xml">
   <!ENTITY atk-AtkRelation SYSTEM "xml/atkrelation.xml">
   <!ENTITY atk-AtkRelationSet SYSTEM "xml/atkrelationset.xml">
@@ -93,6 +94,7 @@
 
   <chapter id="data">
     <title>Basic accessible data types</title>
+    &atk-AtkRange;
     &atk-AtkRelation;
     &atk-AtkRelationSet;
     &atk-AtkState;
diff --git a/docs/atk-sections.txt b/docs/atk-sections.txt
index 8233e3d..f83bd50 100644
--- a/docs/atk-sections.txt
+++ b/docs/atk-sections.txt
@@ -478,6 +478,11 @@ atk_value_get_maximum_value
 atk_value_get_minimum_value
 atk_value_set_current_value
 atk_value_get_minimum_increment
+atk_value_get_value_and_text
+atk_value_get_range
+atk_value_get_increment
+atk_value_get_sub_ranges
+atk_value_set_value
 <SUBSECTION Standard>
 AtkValueIface
 ATK_VALUE
@@ -702,3 +707,16 @@ ATK_MINOR_VERSION
 ATK_MICRO_VERSION
 ATK_CHECK_VERSION
 </SECTION>
+
+<SECTION>
+<FILE>atkrange</FILE>
+<TITLE>AtkRange</TITLE>
+ATK_TYPE_RANGE
+atk_range_copy
+atk_range_free
+atk_range_get_lower_limit
+atk_range_get_upper_limit
+atk_range_get_description
+atk_range_new
+atk_range_get_type
+</SECTION>



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