[gtk/ebassi/new-a11y: 15/29] Add GtkAccessiblePropertySet



commit 5e2718a5ec00e496e45fac22d5fbb0901464be57
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Sun Jul 12 20:07:57 2020 +0100

    Add GtkAccessiblePropertySet
    
    Like GtkAccessibleStateSet, the PropertySet is a set for accessible
    properties.

 gtk/gtkaccessiblepropertyset.c        | 221 ++++++++++++++++++++++++++++++++++
 gtk/gtkaccessiblepropertysetprivate.h |  49 ++++++++
 gtk/meson.build                       |   1 +
 3 files changed, 271 insertions(+)
---
diff --git a/gtk/gtkaccessiblepropertyset.c b/gtk/gtkaccessiblepropertyset.c
new file mode 100644
index 0000000000..9a703fe6a9
--- /dev/null
+++ b/gtk/gtkaccessiblepropertyset.c
@@ -0,0 +1,221 @@
+/* gtkaccessiblepropertyset.c: Accessible properties
+ *
+ * Copyright 2020  GNOME Foundation
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * 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.1 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/>.
+ */
+
+#include "config.h"
+
+#include "gtkaccessiblepropertysetprivate.h"
+
+#include "gtkbitmaskprivate.h"
+#include "gtkenums.h"
+
+/* Keep in sync with GtkAccessibleProperty in gtkenums.h */
+#define LAST_PROPERTY GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT
+
+struct _GtkAccessiblePropertySet
+{
+  GtkBitmask *property_set;
+
+  GtkAccessibleValue **property_values;
+};
+
+static GtkAccessiblePropertySet *
+gtk_accessible_property_set_init (GtkAccessiblePropertySet *self)
+{
+  self->property_set = _gtk_bitmask_new ();
+  self->property_values = g_new (GtkAccessibleValue *, LAST_PROPERTY);
+
+  /* Initialize all property values, so we can always get the full set */
+  for (int i = 0; i < LAST_PROPERTY; i++)
+    self->property_values[i] = gtk_accessible_value_get_default_for_property (i);
+
+  return self;
+}
+
+GtkAccessiblePropertySet *
+gtk_accessible_property_set_new (void)
+{
+  GtkAccessiblePropertySet *set = g_rc_box_new0 (GtkAccessiblePropertySet);
+
+  return gtk_accessible_property_set_init (set);
+}
+
+GtkAccessiblePropertySet *
+gtk_accessible_property_set_ref (GtkAccessiblePropertySet *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return g_rc_box_acquire (self);
+}
+
+static void
+gtk_accessible_property_set_free (gpointer data)
+{
+  GtkAccessiblePropertySet *self = data;
+
+  for (int i = 0; i < LAST_PROPERTY; i++)
+    {
+      if (self->property_values[i] != NULL)
+        gtk_accessible_value_unref (self->property_values[i]);
+    }
+
+  g_free (self->property_values);
+
+  _gtk_bitmask_free (self->property_set);
+}
+
+void
+gtk_accessible_property_set_unref (GtkAccessiblePropertySet *self)
+{
+  g_rc_box_release_full (self, gtk_accessible_property_set_free);
+}
+
+void
+gtk_accessible_property_set_add (GtkAccessiblePropertySet *self,
+                                 GtkAccessibleProperty     property,
+                                 GtkAccessibleValue       *value)
+{
+  g_return_if_fail (property >= GTK_ACCESSIBLE_PROPERTY_ACTIVE_DESCENDANT &&
+                    property <= GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT);
+
+  if (gtk_accessible_property_set_contains (self, property))
+    gtk_accessible_value_unref (self->property_values[property]);
+  else
+    self->property_set = _gtk_bitmask_set (self->property_set, property, TRUE);
+
+  self->property_values[property] = gtk_accessible_value_ref (value);
+}
+
+void
+gtk_accessible_property_set_remove (GtkAccessiblePropertySet *self,
+                                    GtkAccessibleProperty     property)
+{
+  g_return_if_fail (property >= GTK_ACCESSIBLE_PROPERTY_ACTIVE_DESCENDANT &&
+                    property <= GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT);
+
+  if (gtk_accessible_property_set_contains (self, property))
+    {
+      g_clear_pointer (&(self->property_values[property]), gtk_accessible_value_unref);
+      self->property_set = _gtk_bitmask_set (self->property_set, property, FALSE);
+    }
+}
+
+gboolean
+gtk_accessible_property_set_contains (GtkAccessiblePropertySet *self,
+                                      GtkAccessibleProperty     property)
+{
+  g_return_val_if_fail (property >= GTK_ACCESSIBLE_PROPERTY_ACTIVE_DESCENDANT &&
+                        property <= GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT,
+                        FALSE);
+
+  return _gtk_bitmask_get (self->property_set, property);
+}
+
+GtkAccessibleValue *
+gtk_accessible_property_set_get_value (GtkAccessiblePropertySet *self,
+                                       GtkAccessibleProperty     property)
+{
+  g_return_val_if_fail (property >= GTK_ACCESSIBLE_PROPERTY_ACTIVE_DESCENDANT &&
+                        property <= GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT,
+                        NULL);
+
+  return self->property_values[property];
+}
+
+static const char *property_names[] = {
+  [GTK_ACCESSIBLE_PROPERTY_ACTIVE_DESCENDANT] = "active-descendant",
+  [GTK_ACCESSIBLE_PROPERTY_CONTROLS]          = "controls",
+  [GTK_ACCESSIBLE_PROPERTY_DESCRIBED_BY]      = "described-by",
+  [GTK_ACCESSIBLE_PROPERTY_FLOW_TO]           = "flow-to",
+  [GTK_ACCESSIBLE_PROPERTY_HAS_POPUP]         = "has-popup",
+  [GTK_ACCESSIBLE_PROPERTY_LABEL]             = "label",
+  [GTK_ACCESSIBLE_PROPERTY_LABELLED_BY]       = "labelled-by",
+  [GTK_ACCESSIBLE_PROPERTY_LEVEL]             = "level",
+  [GTK_ACCESSIBLE_PROPERTY_MULTI_LINE]        = "multiline",
+  [GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE]  = "multi-selectable",
+  [GTK_ACCESSIBLE_PROPERTY_ORIENTATION]       = "orientation",
+  [GTK_ACCESSIBLE_PROPERTY_OWNS]              = "owns",
+  [GTK_ACCESSIBLE_PROPERTY_POS_IN_SET]        = "pos-in-set",
+  [GTK_ACCESSIBLE_PROPERTY_READ_ONLY]         = "read-only",
+  [GTK_ACCESSIBLE_PROPERTY_RELEVANT]          = "relevant",
+  [GTK_ACCESSIBLE_PROPERTY_REQUIRED]          = "required",
+  [GTK_ACCESSIBLE_PROPERTY_SET_SIZE]          = "set-size",
+  [GTK_ACCESSIBLE_PROPERTY_SORT]              = "sort",
+  [GTK_ACCESSIBLE_PROPERTY_VALUE_MAX]         = "value-max",
+  [GTK_ACCESSIBLE_PROPERTY_VALUE_MIN]         = "value-min",
+  [GTK_ACCESSIBLE_PROPERTY_VALUE_NOW]         = "value-now",
+  [GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT]        = "value-text",
+};
+
+/*< private >
+ * gtk_accessible_property_set_print:
+ * @self: a #GtkAccessiblePropertySet
+ * @only_set: %TRUE if only the set properties should be printed
+ * @buffer: a #GString
+ *
+ * Prints the contents of the #GtkAccessiblePropertySet into @buffer.
+ */
+void
+gtk_accessible_property_set_print (GtkAccessiblePropertySet *self,
+                                   gboolean               only_set,
+                                   GString               *buffer)
+{
+  if (only_set && _gtk_bitmask_is_empty (self->property_set))
+    {
+      g_string_append (buffer, "{}");
+      return;
+    }
+
+  g_string_append (buffer, "{\n");
+
+  for (int i = 0; i < G_N_ELEMENTS (property_names); i++)
+    {
+      if (only_set && !_gtk_bitmask_get (self->property_set, i))
+        continue;
+
+      g_string_append (buffer, "    ");
+      g_string_append (buffer, property_names[i]);
+      g_string_append (buffer, ": ");
+
+      gtk_accessible_value_print (self->property_values[i], buffer);
+
+      g_string_append (buffer, ",\n");
+    }
+
+  g_string_append (buffer, "}");
+}
+
+/*< private >
+ * gtk_accessible_property_set_to_string:
+ * @self: a #GtkAccessiblePropertySet
+ *
+ * Prints the contents of a #GtkAccessiblePropertySet into a string.
+ *
+ * Returns: (transfer full): a newly allocated string with the contents
+ *   of the #GtkAccessiblePropertySet
+ */
+char *
+gtk_accessible_property_set_to_string (GtkAccessiblePropertySet *self)
+{
+  GString *buf = g_string_new (NULL);
+
+  gtk_accessible_property_set_print (self, TRUE, buf);
+
+  return g_string_free (buf, FALSE);
+}
diff --git a/gtk/gtkaccessiblepropertysetprivate.h b/gtk/gtkaccessiblepropertysetprivate.h
new file mode 100644
index 0000000000..a6874379c4
--- /dev/null
+++ b/gtk/gtkaccessiblepropertysetprivate.h
@@ -0,0 +1,49 @@
+/* gtkaccessiblepropertysetprivate.h: Accessible property set
+ *
+ * Copyright 2020  GNOME Foundation
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * 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.1 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
+
+#include "gtkaccessibleprivate.h"
+#include "gtkaccessiblevalueprivate.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GtkAccessiblePropertySet   GtkAccessiblePropertySet;
+
+GtkAccessiblePropertySet *      gtk_accessible_property_set_new         (void);
+GtkAccessiblePropertySet *      gtk_accessible_property_set_ref         (GtkAccessiblePropertySet *self);
+void                            gtk_accessible_property_set_unref       (GtkAccessiblePropertySet *self);
+
+void                            gtk_accessible_property_set_add         (GtkAccessiblePropertySet *self,
+                                                                         GtkAccessibleProperty     property,
+                                                                         GtkAccessibleValue       *value);
+void                            gtk_accessible_property_set_remove      (GtkAccessiblePropertySet *self,
+                                                                         GtkAccessibleProperty     property);
+gboolean                        gtk_accessible_property_set_contains    (GtkAccessiblePropertySet *self,
+                                                                         GtkAccessibleProperty     property);
+GtkAccessibleValue *            gtk_accessible_property_set_get_value   (GtkAccessiblePropertySet *self,
+                                                                         GtkAccessibleProperty     property);
+
+void                            gtk_accessible_property_set_print       (GtkAccessiblePropertySet *self,
+                                                                         gboolean                  only_set,
+                                                                         GString                  *string);
+char *                          gtk_accessible_property_set_to_string   (GtkAccessiblePropertySet *self);
+
+G_END_DECLS
diff --git a/gtk/meson.build b/gtk/meson.build
index eea44c2753..432029a1ed 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -16,6 +16,7 @@ gtk_private_sources = files([
   'fnmatch.c',
   'tools/gdkpixbufutils.c',
   'gsettings-mapping.c',
+  'gtkaccessiblepropertyset.c',
   'gtkaccessiblestateset.c',
   'gtkaccessiblevalue.c',
   'gtkaccessiblevaluestatic.c',


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