[gtk/ebassi/new-a11y: 64/87] Add GtkAccessibleValue
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/ebassi/new-a11y: 64/87] Add GtkAccessibleValue
- Date: Fri, 17 Jul 2020 13:11:49 +0000 (UTC)
commit 008905cca86f4877ad88e6029b4972bde89d5509
Author: Emmanuele Bassi <ebassi gnome org>
Date: Wed Jul 8 16:34:32 2020 +0100
Add GtkAccessibleValue
All accessible properties and states may have one of the following
types:
- true/false
- true/false/undefined
- true/false/mixed/undefined
- reference (to another UI element)
- reference list
- integer
- number (real numerical value)
- string
- token (one of a limited set of allowed values)
- token list
See: https://www.w3.org/WAI/PF/aria/states_and_properties#propcharacteristic_value
The GtkAccessibleValue is a simple reference counted type that can be
"subclassed" to implement each value type.
This initial commit adds GtkAccessibleValue and the basic subclasses for
plain boolean, tristate (true/false/undefined), and token types,
including statically allocated values that can be shared instead of
allocated.
gtk/gtkaccessiblevalue.c | 426 ++++++++++++++++++++++++++++++++++
gtk/gtkaccessiblevalueprivate.h | 135 +++++++++++
gtk/gtkaccessiblevaluestatic.c | 495 ++++++++++++++++++++++++++++++++++++++++
gtk/gtkenums.h | 61 +++++
gtk/meson.build | 2 +
5 files changed, 1119 insertions(+)
---
diff --git a/gtk/gtkaccessiblevalue.c b/gtk/gtkaccessiblevalue.c
new file mode 100644
index 0000000000..617f512c92
--- /dev/null
+++ b/gtk/gtkaccessiblevalue.c
@@ -0,0 +1,426 @@
+/* gtkaccessiblevalue.c: Accessible value
+ *
+ * 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/>.
+ */
+
+/*< private >
+ * SECTION: gtkaccessiblevalue
+ * @Title: GtkAccessibleValue
+ * @Short_description: Container for accessible state and property values
+ *
+ * GtkAccessibleValue is a reference counted, generic container for values used
+ * to represent the state and properties of a #GtkAccessible implementation.
+ *
+ * There are two kinds of accessible value types:
+ *
+ * - hard coded, static values; GTK owns them, and their contents, and are
+ * guaranteed to exist for the duration of the application's life time
+ * - dynamic values; the accessible state owns the value and their contents,
+ * and they can be allocated and freed
+ *
+ * Typically, the former type of values is used for boolean, tristate, and
+ * token value; the latter is used for numbers, strings, and token lists.
+ *
+ * For more information on the types of values, see the
[WAI-ARIA](https://www.w3.org/WAI/PF/aria/states_and_properties#propcharacteristic_value)
+ * reference.
+ */
+
+#include "config.h"
+
+#include "gtkaccessiblevalueprivate.h"
+
+#include "gtkenums.h"
+
+G_DEFINE_QUARK (gtk-accessible-value-error-quark, gtk_accessible_value_error)
+
+G_DEFINE_BOXED_TYPE (GtkAccessibleValue, gtk_accessible_value,
+ gtk_accessible_value_ref,
+ gtk_accessible_value_unref)
+
+/*< private >
+ * gtk_accessible_value_alloc:
+ * @value_class: a #GtkAccessibleValueClass structure
+ *
+ * Allocates a new #GtkAccessibleValue subclass using @value_class as the
+ * type definition.
+ *
+ * Returns: (transfer full): the newly allocated #GtkAccessibleValue
+ */
+GtkAccessibleValue *
+gtk_accessible_value_alloc (const GtkAccessibleValueClass *value_class)
+{
+ g_return_val_if_fail (value_class != NULL, NULL);
+ g_return_val_if_fail (value_class->instance_size >= sizeof (GtkAccessibleValue), NULL);
+
+ GtkAccessibleValue *res = g_malloc0 (value_class->instance_size);
+
+ /* We do not use grefcount, here, because we want to have statically
+ * allocated GtkAccessibleValue subclasses, and those cannot be initialized
+ * with g_ref_count_init()
+ */
+ res->ref_count = 1;
+ res->value_class = value_class;
+
+ if (res->value_class->init != NULL)
+ res->value_class->init (res);
+
+ return res;
+}
+
+/*< private >
+ * gtk_accessible_value_ref:
+ * @self: a #GtkAccessibleValue
+ *
+ * Acquires a reference on the given #GtkAccessibleValue.
+ *
+ * Returns: (transfer full): the value, with an additional reference
+ */
+GtkAccessibleValue *
+gtk_accessible_value_ref (GtkAccessibleValue *self)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+
+ self->ref_count += 1;
+
+ return self;
+}
+
+/*< private >
+ * gtk_accessible_value_unref:
+ * @self: (transfer full): a #GtkAccessibleValue
+ *
+ * Releases a reference on the given #GtkAccessibleValue.
+ */
+void
+gtk_accessible_value_unref (GtkAccessibleValue *self)
+{
+ g_return_if_fail (self != NULL);
+
+ self->ref_count -= 1;
+ if (self->ref_count == 0)
+ {
+ if (self->value_class->finalize != NULL)
+ self->value_class->finalize (self);
+
+ g_free (self);
+ }
+}
+
+/*< private >
+ * gtk_accessible_value_print:
+ * @self: a #GtkAccessibleValue
+ * @buffer: a #GString
+ *
+ * Prints the contents of a #GtkAccessibleValue into the given @buffer.
+ */
+void
+gtk_accessible_value_print (const GtkAccessibleValue *self,
+ GString *buffer)
+{
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (buffer != NULL);
+
+ if (self->value_class->print != NULL)
+ self->value_class->print (self, buffer);
+}
+
+/*< private >
+ * gtk_accessible_value_to_string:
+ * @self: a #GtkAccessibleValue
+ *
+ * Fills a string with the contents of the given #GtkAccessibleValue.
+ *
+ * Returns: (transfer full): a string with the contents of the value
+ */
+char *
+gtk_accessible_value_to_string (const GtkAccessibleValue *self)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+
+ GString *buffer = g_string_new (NULL);
+
+ gtk_accessible_value_print (self, buffer);
+
+ return g_string_free (buffer, FALSE);
+}
+
+/*< private >
+ * gtk_accessible_value_equal:
+ * @value_a: (nullable): the first #GtkAccessibleValue
+ * @value_b: (nullable): the second #GtkAccessibleValue
+ *
+ * Checks whether @value_a and @value_b are equal.
+ *
+ * This function is %NULL-safe.
+ *
+ * Returns: %TRUE if the given #GtkAccessibleValue instances are equal,
+ * and %FALSE otherwise
+ */
+gboolean
+gtk_accessible_value_equal (const GtkAccessibleValue *value_a,
+ const GtkAccessibleValue *value_b)
+{
+ if (value_a == value_b)
+ return TRUE;
+
+ if (value_a == NULL || value_b == NULL)
+ return FALSE;
+
+ return value_a->value_class->equal (value_a, value_b);
+}
+
+typedef enum {
+ GTK_ACCESSIBLE_COLLECT_INVALID,
+ GTK_ACCESSIBLE_COLLECT_BOOLEAN,
+ GTK_ACCESSIBLE_COLLECT_INTEGER,
+ GTK_ACCESSIBLE_COLLECT_TRISTATE,
+ GTK_ACCESSIBLE_COLLECT_ENUM
+} GtkAccessibleCollectType;
+
+typedef GtkAccessibleValue *(* GtkAccessibleValueConstructor) (void);
+
+typedef struct {
+ GtkAccessibleState state;
+ GtkAccessibleCollectType ctype;
+ const char *state_name;
+ GCallback ctor;
+} GtkAccessibleCollectState;
+
+static const GtkAccessibleCollectState collect_states[] = {
+/* | State | Collected type | Name | Constructor
|
+ *
|-------------------------------|--------------------------------|-----------|----------------------------------|
+ */
+ { GTK_ACCESSIBLE_STATE_BUSY, GTK_ACCESSIBLE_COLLECT_BOOLEAN, "busy", (GCallback)
gtk_busy_accessible_value_new },
+ { GTK_ACCESSIBLE_STATE_CHECKED, GTK_ACCESSIBLE_COLLECT_ENUM, "checked", (GCallback)
gtk_checked_accessible_value_new },
+ { GTK_ACCESSIBLE_STATE_DISABLED, GTK_ACCESSIBLE_COLLECT_BOOLEAN, "disabled", (GCallback)
gtk_disabled_accessible_value_new },
+ { GTK_ACCESSIBLE_STATE_EXPANDED, GTK_ACCESSIBLE_COLLECT_TRISTATE, "expanded", (GCallback)
gtk_expanded_accessible_value_new },
+ { GTK_ACCESSIBLE_STATE_GRABBED, GTK_ACCESSIBLE_COLLECT_TRISTATE, "grabbed", (GCallback)
gtk_grabbed_accessible_value_new },
+ { GTK_ACCESSIBLE_STATE_HIDDEN, GTK_ACCESSIBLE_COLLECT_BOOLEAN, "hidden", (GCallback)
gtk_hidden_accessible_value_new },
+ { GTK_ACCESSIBLE_STATE_INVALID, GTK_ACCESSIBLE_COLLECT_ENUM, "invalid", (GCallback)
gtk_invalid_accessible_value_new },
+ { GTK_ACCESSIBLE_STATE_PRESSED, GTK_ACCESSIBLE_COLLECT_ENUM, "pressed", (GCallback)
gtk_pressed_accessible_value_new },
+ { GTK_ACCESSIBLE_STATE_SELECTED, GTK_ACCESSIBLE_COLLECT_TRISTATE, "selected", (GCallback)
gtk_selected_accessible_value_new },
+};
+
+typedef GtkAccessibleValue * (* GtkAccessibleValueBooleanCtor) (gboolean state);
+typedef GtkAccessibleValue * (* GtkAccessibleValueIntCtor) (int state);
+typedef GtkAccessibleValue * (* GtkAccessibleValueTristateCtor) (int state);
+typedef GtkAccessibleValue * (* GtkAccessibleValueEnumCtor) (int state);
+
+/*< private >
+ * gtk_accessible_value_get_default_for_state:
+ * @state: a #GtkAccessibleState
+ *
+ * Retrieves the #GtkAccessibleValue that contains the default for the
+ * given @state.
+ *
+ * Returns: (transfer full): the #GtkAccessibleValue
+ */
+GtkAccessibleValue *
+gtk_accessible_value_get_default_for_state (GtkAccessibleState state)
+{
+ g_assert (state != GTK_ACCESSIBLE_STATE_NONE);
+
+ const GtkAccessibleCollectState *cstate = &collect_states[state];
+
+ switch (cstate->state)
+ {
+ case GTK_ACCESSIBLE_STATE_BUSY:
+ return gtk_busy_accessible_value_new (FALSE);
+
+ case GTK_ACCESSIBLE_STATE_CHECKED:
+ return gtk_checked_accessible_value_new (GTK_ACCESSIBLE_CHECKED_UNDEFINED);
+
+ case GTK_ACCESSIBLE_STATE_DISABLED:
+ return gtk_disabled_accessible_value_new (FALSE);
+
+ case GTK_ACCESSIBLE_STATE_EXPANDED:
+ return gtk_expanded_accessible_value_new (GTK_ACCESSIBLE_STATE_UNDEFINED);
+
+ case GTK_ACCESSIBLE_STATE_GRABBED:
+ return gtk_grabbed_accessible_value_new (GTK_ACCESSIBLE_STATE_UNDEFINED);
+
+ case GTK_ACCESSIBLE_STATE_HIDDEN:
+ return gtk_hidden_accessible_value_new (FALSE);
+
+ case GTK_ACCESSIBLE_STATE_INVALID:
+ return gtk_invalid_accessible_value_new (GTK_ACCESSIBLE_INVALID_FALSE);
+
+ case GTK_ACCESSIBLE_STATE_PRESSED:
+ return gtk_pressed_accessible_value_new (GTK_ACCESSIBLE_PRESSED_UNDEFINED);
+
+ case GTK_ACCESSIBLE_STATE_SELECTED:
+ return gtk_selected_accessible_value_new (GTK_ACCESSIBLE_STATE_UNDEFINED);
+
+ case GTK_ACCESSIBLE_STATE_NONE:
+ default:
+ g_critical ("Unknown value for accessible state “%s”", cstate->state_name);
+ break;
+ }
+
+ return NULL;
+}
+
+/*< private >
+ * gtk_accessible_value_collect_for_state:
+ * @state: a #GtkAccessibleState
+ * @args: a `va_list` reference
+ *
+ * Collects and consumes the next item in the @args variadic arguments list,
+ * and returns a #GtkAccessibleValue for it.
+ *
+ * Returns: (transfer full): a #GtkAccessibleValue
+ */
+GtkAccessibleValue *
+gtk_accessible_value_collect_for_state (GtkAccessibleState state,
+ va_list *args)
+{
+ g_assert (state != GTK_ACCESSIBLE_STATE_NONE);
+
+ const GtkAccessibleCollectState *cstate = &collect_states[state];
+
+ GtkAccessibleValue *res = NULL;
+
+ switch (cstate->ctype)
+ {
+ case GTK_ACCESSIBLE_COLLECT_BOOLEAN:
+ {
+ GtkAccessibleValueBooleanCtor ctor =
+ (GtkAccessibleValueBooleanCtor) cstate->ctor;
+
+ gboolean value = va_arg (*args, gboolean);
+
+ res = (* ctor) (value);
+ }
+ break;
+
+ case GTK_ACCESSIBLE_COLLECT_INTEGER:
+ {
+ GtkAccessibleValueIntCtor ctor =
+ (GtkAccessibleValueIntCtor) cstate->ctor;
+
+ int value = va_arg (*args, int);
+
+ res = (* ctor) (value);
+ }
+ break;
+
+ case GTK_ACCESSIBLE_COLLECT_TRISTATE:
+ {
+ GtkAccessibleValueTristateCtor ctor =
+ (GtkAccessibleValueIntCtor) cstate->ctor;
+
+ int value = va_arg (*args, int);
+
+ res = (* ctor) (value);
+ }
+ break;
+
+ case GTK_ACCESSIBLE_COLLECT_ENUM:
+ {
+ GtkAccessibleValueEnumCtor ctor =
+ (GtkAccessibleValueEnumCtor) cstate->ctor;
+
+ int value = va_arg (*args, int);
+
+ res = (* ctor) (value);
+ }
+ break;
+
+ case GTK_ACCESSIBLE_COLLECT_INVALID:
+ default:
+ g_critical ("Unknown type for accessible state “%s”", cstate->state_name);
+ break;
+ }
+
+ return res;
+}
+
+/*< private >
+ * gtk_accessible_value_collect_for_state_value:
+ * @state: a #GtkAccessibleState
+ * @value: a #GValue
+ *
+ * Retrieves the value stored inside @value and returns a #GtkAccessibleValue
+ * for the given @state.
+ *
+ * Returns: (transfer full): a #GtkAccessibleValue
+ */
+GtkAccessibleValue *
+gtk_accessible_value_collect_for_state_value (GtkAccessibleState state,
+ const GValue *value)
+{
+ g_assert (state != GTK_ACCESSIBLE_STATE_NONE);
+
+ const GtkAccessibleCollectState *cstate = &collect_states[state];
+
+ GtkAccessibleValue *res = NULL;
+
+ switch (cstate->ctype)
+ {
+ case GTK_ACCESSIBLE_COLLECT_BOOLEAN:
+ {
+ GtkAccessibleValueBooleanCtor ctor =
+ (GtkAccessibleValueBooleanCtor) cstate->ctor;
+
+ gboolean value_ = g_value_get_boolean (value);
+
+ res = (* ctor) (value_);
+ }
+ break;
+
+ case GTK_ACCESSIBLE_COLLECT_INTEGER:
+ {
+ GtkAccessibleValueIntCtor ctor =
+ (GtkAccessibleValueIntCtor) cstate->ctor;
+
+ int value_ = g_value_get_int (value);
+
+ res = (* ctor) (value_);
+ }
+ break;
+
+ case GTK_ACCESSIBLE_COLLECT_TRISTATE:
+ {
+ GtkAccessibleValueTristateCtor ctor =
+ (GtkAccessibleValueIntCtor) cstate->ctor;
+
+ int value_ = g_value_get_int (value);
+
+ res = (* ctor) (value_);
+ }
+ break;
+
+ case GTK_ACCESSIBLE_COLLECT_ENUM:
+ {
+ GtkAccessibleValueEnumCtor ctor =
+ (GtkAccessibleValueEnumCtor) cstate->ctor;
+
+ int value_ = g_value_get_enum (value);
+
+ res = (* ctor) (value_);
+ }
+ break;
+
+ case GTK_ACCESSIBLE_COLLECT_INVALID:
+ default:
+ g_critical ("Unknown value type for accessible state “%s”", cstate->state_name);
+ break;
+ }
+
+ return res;
+}
diff --git a/gtk/gtkaccessiblevalueprivate.h b/gtk/gtkaccessiblevalueprivate.h
new file mode 100644
index 0000000000..30454c4ed2
--- /dev/null
+++ b/gtk/gtkaccessiblevalueprivate.h
@@ -0,0 +1,135 @@
+/* gtkaccessiblevalueprivate.h: Accessible value
+ *
+ * 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 <glib-object.h>
+
+#include "gtkenums.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_ACCESSIBLE_VALUE (gtk_accessible_value_get_type())
+
+#define GTK_ACCESSIBLE_VALUE_ERROR (gtk_accessible_value_error_quark())
+
+typedef struct _GtkAccessibleValue GtkAccessibleValue;
+typedef struct _GtkAccessibleValueClass GtkAccessibleValueClass;
+
+struct _GtkAccessibleValue
+{
+ const GtkAccessibleValueClass *value_class;
+
+ int ref_count;
+};
+
+struct _GtkAccessibleValueClass
+{
+ const char *type_name;
+ gsize instance_size;
+
+ void (* init) (GtkAccessibleValue *self);
+ void (* finalize) (GtkAccessibleValue *self);
+ void (* print) (const GtkAccessibleValue *self,
+ GString *string);
+ gboolean (* equal) (const GtkAccessibleValue *value_a,
+ const GtkAccessibleValue *value_b);
+};
+
+typedef enum {
+ GTK_ACCESSIBLE_VALUE_ERROR_READ_ONLY,
+ GTK_ACCESSIBLE_VALUE_ERROR_INVALID_VALUE,
+ GTK_ACCESSIBLE_VALUE_ERROR_INVALID_RANGE,
+ GTK_ACCESSIBLE_VALUE_ERROR_INVALID_TOKEN
+} GtkAccessibleValueError;
+
+GType gtk_accessible_value_get_type (void) G_GNUC_CONST;
+GQuark gtk_accessible_value_error_quark (void);
+
+GtkAccessibleValue * gtk_accessible_value_alloc (const GtkAccessibleValueClass
*klass);
+GtkAccessibleValue * gtk_accessible_value_ref (GtkAccessibleValue
*self);
+void gtk_accessible_value_unref (GtkAccessibleValue
*self);
+void gtk_accessible_value_print (const GtkAccessibleValue *self,
+ GString
*buffer);
+char * gtk_accessible_value_to_string (const GtkAccessibleValue
*self);
+gboolean gtk_accessible_value_equal (const GtkAccessibleValue
*value_a,
+ const GtkAccessibleValue
*value_b);
+
+GtkAccessibleValue * gtk_accessible_value_get_default_for_state (GtkAccessibleState
state);
+
+GtkAccessibleValue * gtk_accessible_value_collect_for_state (GtkAccessibleState
state,
+ va_list
*args);
+GtkAccessibleValue * gtk_accessible_value_collect_for_state_value (GtkAccessibleState
state,
+ const GValue
*value);
+
+typedef enum { /*< prefix=GTK_ACCESSIBLE_CHECKED >*/
+ GTK_ACCESSIBLE_CHECKED_FALSE = 0,
+ GTK_ACCESSIBLE_CHECKED_TRUE = 1,
+ GTK_ACCESSIBLE_CHECKED_UNDEFINED = -1,
+ GTK_ACCESSIBLE_CHECKED_MIXED = -2
+} GtkAccessibleCheckedState;
+
+typedef enum { /*< prefix=GTK_ACCESSIBLE_PRESSED >*/
+ GTK_ACCESSIBLE_PRESSED_FALSE = 0,
+ GTK_ACCESSIBLE_PRESSED_TRUE = 1,
+ GTK_ACCESSIBLE_PRESSED_UNDEFINED = -1,
+ GTK_ACCESSIBLE_PRESSED_MIXED = -2
+} GtkAccessiblePressedState;
+
+typedef enum { /*< prefix=GTK_ACCESSIBLE_INVALID >*/
+ GTK_ACCESSIBLE_INVALID_FALSE,
+ GTK_ACCESSIBLE_INVALID_TRUE,
+ GTK_ACCESSIBLE_INVALID_GRAMMAR,
+ GTK_ACCESSIBLE_INVALID_SPELLING,
+} GtkAccessibleInvalidState;
+
+#define GTK_ACCESSIBLE_STATE_UNDEFINED (-1)
+
+/* Boolean states */
+GtkAccessibleValue * gtk_busy_accessible_value_new (gboolean state);
+gboolean gtk_busy_accessible_value_get (const GtkAccessibleValue *value);
+
+GtkAccessibleValue * gtk_disabled_accessible_value_new (gboolean state);
+gboolean gtk_disabled_accessible_value_get (const GtkAccessibleValue *value);
+
+GtkAccessibleValue * gtk_hidden_accessible_value_new (gboolean state);
+gboolean gtk_hidden_accessible_value_get (const GtkAccessibleValue *value);
+
+/* Tri-state states */
+GtkAccessibleValue * gtk_expanded_accessible_value_new (int state);
+int gtk_expanded_accessible_value_get (const GtkAccessibleValue *value);
+
+GtkAccessibleValue * gtk_grabbed_accessible_value_new (int state);
+int gtk_grabbed_accessible_value_get (const GtkAccessibleValue *value);
+
+GtkAccessibleValue * gtk_selected_accessible_value_new (int state);
+int gtk_selected_accessible_value_get (const GtkAccessibleValue *value);
+
+/* Token states */
+GtkAccessibleValue * gtk_pressed_accessible_value_new (GtkAccessiblePressedState state);
+GtkAccessiblePressedState gtk_pressed_accessible_value_get (const GtkAccessibleValue *value);
+
+GtkAccessibleValue * gtk_checked_accessible_value_new (GtkAccessibleCheckedState state);
+GtkAccessibleCheckedState gtk_checked_accessible_value_get (const GtkAccessibleValue *value);
+
+GtkAccessibleValue * gtk_invalid_accessible_value_new (GtkAccessibleInvalidState state);
+GtkAccessibleInvalidState gtk_invalid_accessible_value_get (const GtkAccessibleValue *value);
+
+G_END_DECLS
diff --git a/gtk/gtkaccessiblevaluestatic.c b/gtk/gtkaccessiblevaluestatic.c
new file mode 100644
index 0000000000..c41f92cac7
--- /dev/null
+++ b/gtk/gtkaccessiblevaluestatic.c
@@ -0,0 +1,495 @@
+/* gtkaccessiblevaluestatic.c: GtkAccessibleValue static implementations
+ *
+ * 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 "gtkaccessiblevalueprivate.h"
+
+/* {{{ Boolean values */
+
+typedef struct
+{
+ GtkAccessibleValue parent;
+
+ gboolean value;
+} GtkBooleanAccessibleValue;
+
+static gboolean
+gtk_boolean_accessible_value_equal (const GtkAccessibleValue *value_a,
+ const GtkAccessibleValue *value_b)
+{
+ const GtkBooleanAccessibleValue *bool_a = (GtkBooleanAccessibleValue *) value_a;
+ const GtkBooleanAccessibleValue *bool_b = (GtkBooleanAccessibleValue *) value_b;
+
+ return bool_a->value == bool_b->value;
+}
+
+static void
+gtk_boolean_accessible_value_print (const GtkAccessibleValue *value,
+ GString *buffer)
+{
+ const GtkBooleanAccessibleValue *self = (GtkBooleanAccessibleValue *) value;
+
+ g_string_append_printf (buffer, "%s", self->value ? "true" : "false");
+}
+
+static const GtkAccessibleValueClass GTK_BUSY_ACCESSIBLE_VALUE = {
+ .type_name = "GtkBusyAccessibleValue",
+ .instance_size = sizeof (GtkBooleanAccessibleValue),
+ .equal = gtk_boolean_accessible_value_equal,
+ .print = gtk_boolean_accessible_value_print,
+};
+
+static GtkBooleanAccessibleValue busy_values[] = {
+ { { >K_BUSY_ACCESSIBLE_VALUE, 1 }, FALSE },
+ { { >K_BUSY_ACCESSIBLE_VALUE, 1 }, TRUE },
+};
+
+GtkAccessibleValue *
+gtk_busy_accessible_value_new (gboolean state)
+{
+ if (state)
+ return gtk_accessible_value_ref ((GtkAccessibleValue *) &busy_values[1]);
+
+ return gtk_accessible_value_ref ((GtkAccessibleValue *) &busy_values[0]);
+}
+
+gboolean
+gtk_busy_accessible_value_get (const GtkAccessibleValue *value)
+{
+ GtkBooleanAccessibleValue *self = (GtkBooleanAccessibleValue *) value;
+
+ g_return_val_if_fail (value != NULL, FALSE);
+ g_return_val_if_fail (value->value_class == >K_BUSY_ACCESSIBLE_VALUE, FALSE);
+
+ return self->value;
+}
+
+static const GtkAccessibleValueClass GTK_DISABLED_ACCESSIBLE_VALUE = {
+ .type_name = "GtkDisabledAccessibleValue",
+ .instance_size = sizeof (GtkBooleanAccessibleValue),
+ .equal = gtk_boolean_accessible_value_equal,
+ .print = gtk_boolean_accessible_value_print,
+};
+
+static GtkBooleanAccessibleValue disabled_values[] = {
+ { { >K_DISABLED_ACCESSIBLE_VALUE, 1 }, FALSE },
+ { { >K_DISABLED_ACCESSIBLE_VALUE, 1 }, TRUE },
+};
+
+GtkAccessibleValue *
+gtk_disabled_accessible_value_new (gboolean state)
+{
+ if (state)
+ return gtk_accessible_value_ref ((GtkAccessibleValue *) &disabled_values[1]);
+
+ return gtk_accessible_value_ref ((GtkAccessibleValue *) &disabled_values[0]);
+}
+
+gboolean
+gtk_disabled_accessible_value_get (const GtkAccessibleValue *value)
+{
+ GtkBooleanAccessibleValue *self = (GtkBooleanAccessibleValue *) value;
+
+ g_return_val_if_fail (value != NULL, FALSE);
+ g_return_val_if_fail (value->value_class == >K_DISABLED_ACCESSIBLE_VALUE, FALSE);
+
+ return self->value;
+}
+
+static const GtkAccessibleValueClass GTK_HIDDEN_ACCESSIBLE_VALUE = {
+ .type_name = "GtkHiddenAccessibleValue",
+ .instance_size = sizeof (GtkBooleanAccessibleValue),
+ .equal = gtk_boolean_accessible_value_equal,
+ .print = gtk_boolean_accessible_value_print,
+};
+
+static GtkBooleanAccessibleValue hidden_values[] = {
+ { { >K_HIDDEN_ACCESSIBLE_VALUE, 1 }, FALSE },
+ { { >K_HIDDEN_ACCESSIBLE_VALUE, 1 }, TRUE },
+};
+
+GtkAccessibleValue *
+gtk_hidden_accessible_value_new (gboolean state)
+{
+ if (state)
+ return gtk_accessible_value_ref ((GtkAccessibleValue *) &hidden_values[1]);
+
+ return gtk_accessible_value_ref ((GtkAccessibleValue *) &hidden_values[0]);
+}
+
+gboolean
+gtk_hidden_accessible_value_get (const GtkAccessibleValue *value)
+{
+ GtkBooleanAccessibleValue *self = (GtkBooleanAccessibleValue *) value;
+
+ g_return_val_if_fail (value != NULL, FALSE);
+ g_return_val_if_fail (value->value_class == >K_HIDDEN_ACCESSIBLE_VALUE, FALSE);
+
+ return self->value;
+}
+
+/* }}} */
+
+/* {{{ Tri-state values */
+
+typedef struct {
+ GtkAccessibleValue parent;
+
+ int value;
+} GtkTristateAccessibleValue;
+
+static gboolean
+gtk_tristate_accessible_value_equal (const GtkAccessibleValue *value_a,
+ const GtkAccessibleValue *value_b)
+{
+ const GtkTristateAccessibleValue *tri_a = (GtkTristateAccessibleValue *) value_a;
+ const GtkTristateAccessibleValue *tri_b = (GtkTristateAccessibleValue *) value_b;
+
+ return tri_a->value == tri_b->value;
+}
+
+static void
+gtk_tristate_accessible_value_print (const GtkAccessibleValue *value,
+ GString *buffer)
+{
+ const GtkTristateAccessibleValue *self = (GtkTristateAccessibleValue *) value;
+
+ switch (self->value)
+ {
+ case 0:
+ g_string_append (buffer, "false");
+ break;
+
+ case 1:
+ g_string_append (buffer, "true");
+ break;
+
+ case -1:
+ g_string_append (buffer, "undefined");
+ break;
+
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+static const GtkAccessibleValueClass GTK_EXPANDED_ACCESSIBLE_VALUE = {
+ .type_name = "GtkExpandedAccessibleValue",
+ .instance_size = sizeof (GtkTristateAccessibleValue),
+ .equal = gtk_tristate_accessible_value_equal,
+ .print = gtk_tristate_accessible_value_print,
+};
+
+static GtkTristateAccessibleValue expanded_values[] = {
+ { { >K_EXPANDED_ACCESSIBLE_VALUE, 1 }, -1 },
+ { { >K_EXPANDED_ACCESSIBLE_VALUE, 1 }, 0 },
+ { { >K_EXPANDED_ACCESSIBLE_VALUE, 1 }, 1 },
+};
+
+GtkAccessibleValue *
+gtk_expanded_accessible_value_new (int state)
+{
+ int index_;
+
+ if (state < 0)
+ index_ = 0;
+ else if (state == 0)
+ index_ = 1;
+ else
+ index_ = 2;
+
+ return gtk_accessible_value_ref ((GtkAccessibleValue *) &expanded_values[index_]);
+}
+
+int
+gtk_expanded_accessible_value_get (const GtkAccessibleValue *value)
+{
+ GtkTristateAccessibleValue *self = (GtkTristateAccessibleValue *) value;
+
+ g_return_val_if_fail (value != NULL, GTK_ACCESSIBLE_STATE_UNDEFINED);
+ g_return_val_if_fail (value->value_class == >K_EXPANDED_ACCESSIBLE_VALUE,
+ GTK_ACCESSIBLE_STATE_UNDEFINED);
+
+ return self->value;
+}
+
+static const GtkAccessibleValueClass GTK_GRABBED_ACCESSIBLE_VALUE = {
+ .type_name = "GtkGrabbedAccessibleValue",
+ .instance_size = sizeof (GtkTristateAccessibleValue),
+ .equal = gtk_tristate_accessible_value_equal,
+ .print = gtk_tristate_accessible_value_print,
+};
+
+static GtkTristateAccessibleValue grabbed_values[] = {
+ { { >K_GRABBED_ACCESSIBLE_VALUE, 1 }, -1 },
+ { { >K_GRABBED_ACCESSIBLE_VALUE, 1 }, 0 },
+ { { >K_GRABBED_ACCESSIBLE_VALUE, 1 }, 1 },
+};
+
+GtkAccessibleValue *
+gtk_grabbed_accessible_value_new (int state)
+{
+ int index_;
+
+ if (state < 0)
+ index_ = 0;
+ else if (state == 0)
+ index_ = 1;
+ else
+ index_ = 2;
+
+ return gtk_accessible_value_ref ((GtkAccessibleValue *) &grabbed_values[index_]);
+}
+
+int
+gtk_grabbed_accessible_value_get (const GtkAccessibleValue *value)
+{
+ GtkTristateAccessibleValue *self = (GtkTristateAccessibleValue *) value;
+
+ g_return_val_if_fail (value != NULL, GTK_ACCESSIBLE_STATE_UNDEFINED);
+ g_return_val_if_fail (value->value_class == >K_GRABBED_ACCESSIBLE_VALUE,
+ GTK_ACCESSIBLE_STATE_UNDEFINED);
+
+ return self->value;
+}
+
+static const GtkAccessibleValueClass GTK_SELECTED_ACCESSIBLE_VALUE = {
+ .type_name = "GtkSelectedAccessibleValue",
+ .instance_size = sizeof (GtkTristateAccessibleValue),
+ .equal = gtk_tristate_accessible_value_equal,
+ .print = gtk_tristate_accessible_value_print,
+};
+
+static GtkTristateAccessibleValue selected_values[] = {
+ { { >K_SELECTED_ACCESSIBLE_VALUE, 1 }, -1 },
+ { { >K_SELECTED_ACCESSIBLE_VALUE, 1 }, 0 },
+ { { >K_SELECTED_ACCESSIBLE_VALUE, 1 }, 1 },
+};
+
+GtkAccessibleValue *
+gtk_selected_accessible_value_new (int state)
+{
+ int index_;
+
+ if (state < 0)
+ index_ = 0;
+ else if (state == 0)
+ index_ = 1;
+ else
+ index_ = 2;
+
+ return gtk_accessible_value_ref ((GtkAccessibleValue *) &selected_values[index_]);
+}
+
+int
+gtk_selected_accessible_value_get (const GtkAccessibleValue *value)
+{
+ GtkTristateAccessibleValue *self = (GtkTristateAccessibleValue *) value;
+
+ g_return_val_if_fail (value != NULL, GTK_ACCESSIBLE_STATE_UNDEFINED);
+ g_return_val_if_fail (value->value_class == >K_SELECTED_ACCESSIBLE_VALUE,
+ GTK_ACCESSIBLE_STATE_UNDEFINED);
+
+ return self->value;
+}
+
+/* }}} */
+
+/* {{{ Enumeration values */
+
+typedef struct {
+ GtkAccessibleValue parent;
+
+ int value;
+ const char *token;
+} GtkEnumAccessibleValue;
+
+static gboolean
+gtk_enum_accessible_value_equal (const GtkAccessibleValue *value_a,
+ const GtkAccessibleValue *value_b)
+{
+ const GtkEnumAccessibleValue *enum_a = (GtkEnumAccessibleValue *) value_a;
+ const GtkEnumAccessibleValue *enum_b = (GtkEnumAccessibleValue *) value_b;
+
+ return enum_a->value == enum_b->value;
+}
+
+static void
+gtk_enum_accessible_value_print (const GtkAccessibleValue *value,
+ GString *buffer)
+{
+ const GtkEnumAccessibleValue *self = (GtkEnumAccessibleValue *) value;
+
+ g_string_append (buffer, self->token);
+}
+
+static const GtkAccessibleValueClass GTK_CHECKED_ACCESSIBLE_VALUE = {
+ .type_name = "GtkCheckedAccessibleValue",
+ .instance_size = sizeof (GtkEnumAccessibleValue),
+ .equal = gtk_enum_accessible_value_equal,
+ .print = gtk_enum_accessible_value_print,
+};
+
+static GtkEnumAccessibleValue checked_values[] = {
+ { { >K_CHECKED_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_CHECKED_FALSE, "false" },
+ { { >K_CHECKED_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_CHECKED_TRUE, "true" },
+ { { >K_CHECKED_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_PRESSED_UNDEFINED, "undefined" },
+ { { >K_CHECKED_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_CHECKED_MIXED, "mixed" },
+};
+
+GtkAccessibleValue *
+gtk_checked_accessible_value_new (GtkAccessibleCheckedState state)
+{
+ int index_;
+
+ switch (state)
+ {
+ case GTK_ACCESSIBLE_CHECKED_FALSE:
+ index_ = 0;
+ break;
+
+ case GTK_ACCESSIBLE_CHECKED_TRUE:
+ index_ = 1;
+ break;
+
+ case GTK_ACCESSIBLE_CHECKED_UNDEFINED:
+ index_ = 2;
+ break;
+
+ case GTK_ACCESSIBLE_CHECKED_MIXED:
+ index_ = 3;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+
+ return gtk_accessible_value_ref ((GtkAccessibleValue *) &checked_values[index_]);
+}
+
+GtkAccessibleCheckedState
+gtk_checked_accessible_value_get (const GtkAccessibleValue *value)
+{
+ GtkEnumAccessibleValue *self = (GtkEnumAccessibleValue *) value;
+
+ g_return_val_if_fail (value != NULL, GTK_ACCESSIBLE_CHECKED_UNDEFINED);
+ g_return_val_if_fail (value->value_class == >K_CHECKED_ACCESSIBLE_VALUE,
+ GTK_ACCESSIBLE_CHECKED_UNDEFINED);
+
+ return self->value;
+}
+
+static const GtkAccessibleValueClass GTK_PRESSED_ACCESSIBLE_VALUE = {
+ .type_name = "GtkPressedAccessibleValue",
+ .instance_size = sizeof (GtkEnumAccessibleValue),
+ .equal = gtk_enum_accessible_value_equal,
+ .print = gtk_enum_accessible_value_print,
+};
+
+static GtkEnumAccessibleValue pressed_values[] = {
+ { { >K_PRESSED_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_PRESSED_FALSE, "false" },
+ { { >K_PRESSED_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_PRESSED_TRUE, "true" },
+ { { >K_PRESSED_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_PRESSED_UNDEFINED, "undefined" },
+ { { >K_PRESSED_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_PRESSED_MIXED, "mixed" },
+};
+
+GtkAccessibleValue *
+gtk_pressed_accessible_value_new (GtkAccessiblePressedState state)
+{
+ int index_;
+
+ switch (state)
+ {
+ case GTK_ACCESSIBLE_PRESSED_FALSE:
+ index_ = 0;
+ break;
+
+ case GTK_ACCESSIBLE_PRESSED_TRUE:
+ index_ = 1;
+ break;
+
+ case GTK_ACCESSIBLE_PRESSED_UNDEFINED:
+ index_ = 2;
+ break;
+
+ case GTK_ACCESSIBLE_PRESSED_MIXED:
+ index_ = 3;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+
+ return gtk_accessible_value_ref ((GtkAccessibleValue *) &pressed_values[index_]);
+}
+
+GtkAccessiblePressedState
+gtk_pressed_accessible_value_get (const GtkAccessibleValue *value)
+{
+ GtkEnumAccessibleValue *self = (GtkEnumAccessibleValue *) value;
+
+ g_return_val_if_fail (value != NULL, GTK_ACCESSIBLE_PRESSED_UNDEFINED);
+ g_return_val_if_fail (value->value_class == >K_PRESSED_ACCESSIBLE_VALUE,
+ GTK_ACCESSIBLE_PRESSED_UNDEFINED);
+
+ return self->value;
+}
+
+static const GtkAccessibleValueClass GTK_INVALID_ACCESSIBLE_VALUE = {
+ .type_name = "GtkInvalidAccessibleValue",
+ .instance_size = sizeof (GtkEnumAccessibleValue),
+ .equal = gtk_enum_accessible_value_equal,
+ .print = gtk_enum_accessible_value_print,
+};
+
+static GtkEnumAccessibleValue invalid_values[] = {
+ { { >K_INVALID_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_INVALID_FALSE, "false" },
+ { { >K_INVALID_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_INVALID_TRUE, "true" },
+ { { >K_INVALID_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_INVALID_GRAMMAR, "grammar" },
+ { { >K_INVALID_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_INVALID_SPELLING, "spelling" },
+};
+
+GtkAccessibleValue *
+gtk_invalid_accessible_value_new (GtkAccessibleInvalidState state)
+{
+ g_return_val_if_fail (state >= GTK_ACCESSIBLE_INVALID_FALSE &&
+ state <= GTK_ACCESSIBLE_INVALID_SPELLING,
+ NULL);
+
+ return gtk_accessible_value_ref ((GtkAccessibleValue *) &invalid_values[state]);
+}
+
+GtkAccessibleInvalidState
+gtk_invalid_accessible_value_get (const GtkAccessibleValue *value)
+{
+ GtkEnumAccessibleValue *self = (GtkEnumAccessibleValue *) value;
+
+ g_return_val_if_fail (value != NULL, GTK_ACCESSIBLE_INVALID_FALSE);
+ g_return_val_if_fail (value->value_class == >K_INVALID_ACCESSIBLE_VALUE,
+ GTK_ACCESSIBLE_INVALID_FALSE);
+
+ return self->value;
+}
+
+/* }}} */
diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h
index c406fa0e48..2fc8b4cdea 100644
--- a/gtk/gtkenums.h
+++ b/gtk/gtkenums.h
@@ -1300,4 +1300,65 @@ typedef enum {
GTK_ACCESSIBLE_ROLE_WINDOW
} GtkAccessibleRole;
+/**
+ * GtkAccessibleState:
+ * @GTK_ACCESSIBLE_STATE_NONE: An invalid state, used as a sentinel value
+ * @GTK_ACCESSIBLE_STATE_BUSY: A “busy” state
+ * @GTK_ACCESSIBLE_STATE_CHECKED: A “checked” state; corresponds to the
+ * #GtkToggleButton:active property on #GtkToggleButton
+ * @GTK_ACCESSIBLE_STATE_DISABLED: A “disabled” state; corresponds to the
+ * #GtkWidget:sensitive property on #GtkWidget
+ * @GTK_ACCESSIBLE_STATE_EXPANDED: An “expanded” state; corresponds to the
+ * #GtkExpander:expanded property on #GtkExpander
+ * @GTK_ACCESSIBLE_STATE_GRABBED: A “grabbed” state; set when a widget is
+ * being grabbed in a drag and drop operation
+ * @GTK_ACCESSIBLE_STATE_HIDDEN: A “hidden” state; corresponds to the
+ * #GtkWidget:visible property on #GtkWidget
+ * @GTK_ACCESSIBLE_STATE_INVALID: An “invalid” state; set when a widget
+ * is showing an error
+ * @GTK_ACCESSIBLE_STATE_PRESSED: A “pressed” state; set when a widget
+ * is being activated by a pointer
+ * @GTK_ACCESSIBLE_STATE_SELECTED: A “selected” state; set when a widget
+ * is selected
+ *
+ * The possible accessible state of a #GtkAccessible.
+ */
+typedef enum {
+ GTK_ACCESSIBLE_STATE_NONE = -1,
+ GTK_ACCESSIBLE_STATE_BUSY = 0,
+ GTK_ACCESSIBLE_STATE_CHECKED,
+ GTK_ACCESSIBLE_STATE_DISABLED,
+ GTK_ACCESSIBLE_STATE_EXPANDED,
+ GTK_ACCESSIBLE_STATE_GRABBED,
+ GTK_ACCESSIBLE_STATE_HIDDEN,
+ GTK_ACCESSIBLE_STATE_INVALID,
+ GTK_ACCESSIBLE_STATE_PRESSED,
+ GTK_ACCESSIBLE_STATE_SELECTED
+} GtkAccessibleState;
+
+typedef enum {
+ GTK_ACCESSIBLE_PROPERTY_ACTIVE_DESCENDANT,
+ GTK_ACCESSIBLE_PROPERTY_CONTROLS,
+ GTK_ACCESSIBLE_PROPERTY_DESCRIBED_BY,
+ GTK_ACCESSIBLE_PROPERTY_FLOW_TO,
+ GTK_ACCESSIBLE_PROPERTY_HAS_POPUP,
+ GTK_ACCESSIBLE_PROPERTY_LABEL,
+ GTK_ACCESSIBLE_PROPERTY_LABELLED_BY,
+ GTK_ACCESSIBLE_PROPERTY_LEVEL,
+ GTK_ACCESSIBLE_PROPERTY_MULTI_LINE,
+ GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE,
+ GTK_ACCESSIBLE_PROPERTY_ORIENTATION,
+ GTK_ACCESSIBLE_PROPERTY_OWNS,
+ GTK_ACCESSIBLE_PROPERTY_POS_IN_SET,
+ GTK_ACCESSIBLE_PROPERTY_READ_ONLY,
+ GTK_ACCESSIBLE_PROPERTY_RELEVANT,
+ GTK_ACCESSIBLE_PROPERTY_REQUIRED,
+ GTK_ACCESSIBLE_PROPERTY_SET_SIZE,
+ GTK_ACCESSIBLE_PROPERTY_SORT,
+ GTK_ACCESSIBLE_PROPERTY_VALUE_MAX,
+ GTK_ACCESSIBLE_PROPERTY_VALUE_MIN,
+ GTK_ACCESSIBLE_PROPERTY_VALUE_NOW,
+ GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT
+} GtkAccessibleProperty;
+
#endif /* __GTK_ENUMS_H__ */
diff --git a/gtk/meson.build b/gtk/meson.build
index 9fadea55e0..5ac04668cb 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -16,6 +16,8 @@ gtk_private_sources = files([
'fnmatch.c',
'tools/gdkpixbufutils.c',
'gsettings-mapping.c',
+ 'gtkaccessiblevalue.c',
+ 'gtkaccessiblevaluestatic.c',
'gtkactionhelper.c',
'gtkactionmuxer.c',
'gtkactionobservable.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]