From 382fa013017aaa7d1b6e9d0a58c3d3d5770af26b Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 13 Jul 2020 15:22:24 +0100 Subject: [PATCH] Plumb all the GtkAccessibleProperty values into GtkAccessibleValue Similarly to how we deal with GtkAccessibleState. --- gtk/gtkaccessiblevalue.c | 575 ++++++++++++++++++++++++++++++-- gtk/gtkaccessiblevalueprivate.h | 66 +++- gtk/gtkaccessiblevaluestatic.c | 199 +++++++---- gtk/gtkenums.h | 1 + 4 files changed, 718 insertions(+), 123 deletions(-) diff --git a/gtk/gtkaccessiblevalue.c b/gtk/gtkaccessiblevalue.c index 617f512c92..2fd6f76742 100644 --- a/gtk/gtkaccessiblevalue.c +++ b/gtk/gtkaccessiblevalue.c @@ -184,42 +184,258 @@ gtk_accessible_value_equal (const GtkAccessibleValue *value_a, return value_a->value_class->equal (value_a, value_b); } +/* {{{ Basic types */ + +typedef struct { + GtkAccessibleValue parent; + + int value; +} GtkIntAccessibleValue; + +static gboolean +gtk_int_accessible_value_equal (const GtkAccessibleValue *value_a, + const GtkAccessibleValue *value_b) +{ + const GtkIntAccessibleValue *self_a = (GtkIntAccessibleValue *) value_a; + const GtkIntAccessibleValue *self_b = (GtkIntAccessibleValue *) value_b; + + return self_a->value == self_b->value; +} + +static void +gtk_int_accessible_value_print (const GtkAccessibleValue *value, + GString *buffer) +{ + const GtkIntAccessibleValue *self = (GtkIntAccessibleValue *) value; + + g_string_append_printf (buffer, "%d", self->value); +} + +static const GtkAccessibleValueClass GTK_INT_ACCESSIBLE_VALUE = { + .type_name = "GtkIntAccessibleValue", + .instance_size = sizeof (GtkIntAccessibleValue), + .equal = gtk_int_accessible_value_equal, + .print = gtk_int_accessible_value_print, +}; + +GtkAccessibleValue * +gtk_int_accessible_value_new (int value) +{ + GtkAccessibleValue *res = gtk_accessible_value_alloc (>K_INT_ACCESSIBLE_VALUE); + + /* XXX: Possible optimization: statically allocate the first N values + * and hand out references to them, instead of dynamically + * allocating a new GtkAccessibleValue instance. Needs some profiling + * to figure out the common integer values used by large applications + */ + GtkIntAccessibleValue *self = (GtkIntAccessibleValue *) res; + self->value = value; + + return res; +} + +int +gtk_int_accessible_value_get (const GtkAccessibleValue *value) +{ + GtkIntAccessibleValue *self = (GtkIntAccessibleValue *) value; + + g_return_val_if_fail (value != NULL, 0); + g_return_val_if_fail (value->value_class == >K_INT_ACCESSIBLE_VALUE, 0); + + return self->value; +} + +typedef struct { + GtkAccessibleValue parent; + + double value; +} GtkNumberAccessibleValue; + +static gboolean +gtk_number_accessible_value_equal (const GtkAccessibleValue *value_a, + const GtkAccessibleValue *value_b) +{ + const GtkNumberAccessibleValue *self_a = (GtkNumberAccessibleValue *) value_a; + const GtkNumberAccessibleValue *self_b = (GtkNumberAccessibleValue *) value_b; + + return G_APPROX_VALUE (self_a->value, self_b->value, 0.001); +} + +static void +gtk_number_accessible_value_print (const GtkAccessibleValue *value, + GString *buffer) +{ + const GtkNumberAccessibleValue *self = (GtkNumberAccessibleValue *) value; + + g_string_append_printf (buffer, "%g", self->value); +} + +static const GtkAccessibleValueClass GTK_NUMBER_ACCESSIBLE_VALUE = { + .type_name = "GtkNumberAccessibleValue", + .instance_size = sizeof (GtkNumberAccessibleValue), + .equal = gtk_number_accessible_value_equal, + .print = gtk_number_accessible_value_print, +}; + +GtkAccessibleValue * +gtk_number_accessible_value_new (double value) +{ + GtkAccessibleValue *res = gtk_accessible_value_alloc (>K_NUMBER_ACCESSIBLE_VALUE); + + GtkNumberAccessibleValue *self = (GtkNumberAccessibleValue *) res; + self->value = value; + + return res; +} + +double +gtk_number_accessible_value_get (const GtkAccessibleValue *value) +{ + GtkNumberAccessibleValue *self = (GtkNumberAccessibleValue *) value; + + g_return_val_if_fail (value != NULL, 0); + g_return_val_if_fail (value->value_class == >K_NUMBER_ACCESSIBLE_VALUE, 0); + + return self->value; +} + +typedef struct { + GtkAccessibleValue parent; + + char *value; + gsize length; +} GtkStringAccessibleValue; + +static void +gtk_string_accessible_value_finalize (GtkAccessibleValue *value) +{ + GtkStringAccessibleValue *self = (GtkStringAccessibleValue *) value; + + g_free (self->value); +} + +static gboolean +gtk_string_accessible_value_equal (const GtkAccessibleValue *value_a, + const GtkAccessibleValue *value_b) +{ + const GtkStringAccessibleValue *self_a = (GtkStringAccessibleValue *) value_a; + const GtkStringAccessibleValue *self_b = (GtkStringAccessibleValue *) value_b; + + if (self_a->length != self_b->length) + return FALSE; + + return g_strcmp0 (self_a->value, self_b->value) == 0; +} + +static void +gtk_string_accessible_value_print (const GtkAccessibleValue *value, + GString *buffer) +{ + const GtkStringAccessibleValue *self = (GtkStringAccessibleValue *) value; + + g_string_append (buffer, self->value); +} + +static const GtkAccessibleValueClass GTK_STRING_ACCESSIBLE_VALUE = { + .type_name = "GtkStringAccessibleValue", + .instance_size = sizeof (GtkStringAccessibleValue), + .finalize = gtk_string_accessible_value_finalize, + .equal = gtk_string_accessible_value_equal, + .print = gtk_string_accessible_value_print, +}; + +GtkAccessibleValue * +gtk_string_accessible_value_new (const char *str) +{ + GtkAccessibleValue *res = gtk_accessible_value_alloc (>K_STRING_ACCESSIBLE_VALUE); + + GtkStringAccessibleValue *self = (GtkStringAccessibleValue *) res; + + self->value = g_strdup (str); + self->length = strlen (str); + + return res; +} + +const char * +gtk_string_accessible_value_get (const GtkAccessibleValue *value) +{ + GtkStringAccessibleValue *self = (GtkStringAccessibleValue *) value; + + g_return_val_if_fail (value != NULL, 0); + g_return_val_if_fail (value->value_class == >K_STRING_ACCESSIBLE_VALUE, 0); + + return self->value; +} + +/* }}} */ + +/* {{{ Collection API */ + typedef enum { GTK_ACCESSIBLE_COLLECT_INVALID, GTK_ACCESSIBLE_COLLECT_BOOLEAN, - GTK_ACCESSIBLE_COLLECT_INTEGER, + GTK_ACCESSIBLE_COLLECT_INT, GTK_ACCESSIBLE_COLLECT_TRISTATE, - GTK_ACCESSIBLE_COLLECT_ENUM + GTK_ACCESSIBLE_COLLECT_ENUM, + GTK_ACCESSIBLE_COLLECT_NUMBER, + GTK_ACCESSIBLE_COLLECT_STRING } GtkAccessibleCollectType; -typedef GtkAccessibleValue *(* GtkAccessibleValueConstructor) (void); - typedef struct { - GtkAccessibleState state; + int value; GtkAccessibleCollectType ctype; - const char *state_name; + const char *name; GCallback ctor; -} GtkAccessibleCollectState; +} GtkAccessibleCollect; -static const GtkAccessibleCollectState collect_states[] = { +static const GtkAccessibleCollect 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_BUSY, GTK_ACCESSIBLE_COLLECT_BOOLEAN, "busy", (GCallback) gtk_boolean_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_DISABLED, GTK_ACCESSIBLE_COLLECT_BOOLEAN, "disabled", (GCallback) gtk_boolean_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_HIDDEN, GTK_ACCESSIBLE_COLLECT_BOOLEAN, "hidden", (GCallback) gtk_boolean_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); +static const GtkAccessibleCollect collect_props[] = { + { GTK_ACCESSIBLE_PROPERTY_ACTIVE_DESCENDANT, GTK_ACCESSIBLE_COLLECT_STRING, "activedescendant", (GCallback) gtk_string_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE, GTK_ACCESSIBLE_COLLECT_ENUM, "autocomplete", (GCallback) gtk_autocomplete_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_CONTROLS, GTK_ACCESSIBLE_COLLECT_STRING, "controls", (GCallback) gtk_string_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_DESCRIBED_BY, GTK_ACCESSIBLE_COLLECT_STRING, "describedby", (GCallback) gtk_string_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_FLOW_TO, GTK_ACCESSIBLE_COLLECT_STRING, "flowto", (GCallback) gtk_string_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_HAS_POPUP, GTK_ACCESSIBLE_COLLECT_BOOLEAN, "haspopup", (GCallback) gtk_boolean_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_LABEL, GTK_ACCESSIBLE_COLLECT_STRING, "label", (GCallback) gtk_string_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_LABELLED_BY, GTK_ACCESSIBLE_COLLECT_STRING, "labelledby", (GCallback) gtk_string_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_LEVEL, GTK_ACCESSIBLE_COLLECT_INT, "level", (GCallback) gtk_int_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_MULTI_LINE, GTK_ACCESSIBLE_COLLECT_BOOLEAN, "multiline", (GCallback) gtk_boolean_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE, GTK_ACCESSIBLE_COLLECT_BOOLEAN, "multiselectable", (GCallback) gtk_boolean_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_ORIENTATION, GTK_ACCESSIBLE_COLLECT_ENUM, "orientation", (GCallback) gtk_orientation_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_OWNS, GTK_ACCESSIBLE_COLLECT_STRING, "owns", (GCallback) gtk_string_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_POS_IN_SET, GTK_ACCESSIBLE_COLLECT_INT, "posinset", (GCallback) gtk_int_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_READ_ONLY, GTK_ACCESSIBLE_COLLECT_BOOLEAN, "readonly", (GCallback) gtk_boolean_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_RELEVANT, GTK_ACCESSIBLE_COLLECT_STRING, "relevant", (GCallback) gtk_string_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_REQUIRED, GTK_ACCESSIBLE_COLLECT_BOOLEAN, "required", (GCallback) gtk_boolean_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_SET_SIZE, GTK_ACCESSIBLE_COLLECT_INT, "setsize", (GCallback) gtk_int_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_SORT, GTK_ACCESSIBLE_COLLECT_ENUM, "sort", (GCallback) gtk_sort_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_VALUE_MAX, GTK_ACCESSIBLE_COLLECT_NUMBER, "valuemax", (GCallback) gtk_number_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_VALUE_MIN, GTK_ACCESSIBLE_COLLECT_NUMBER, "valuemin", (GCallback) gtk_number_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_VALUE_NOW, GTK_ACCESSIBLE_COLLECT_NUMBER, "valuenow", (GCallback) gtk_number_accessible_value_new }, + { GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT, GTK_ACCESSIBLE_COLLECT_STRING, "valuetext", (GCallback) gtk_string_accessible_value_new }, +}; + +typedef GtkAccessibleValue * (* GtkAccessibleValueBooleanCtor) (gboolean value); +typedef GtkAccessibleValue * (* GtkAccessibleValueIntCtor) (int value); +typedef GtkAccessibleValue * (* GtkAccessibleValueTristateCtor) (int value); +typedef GtkAccessibleValue * (* GtkAccessibleValueEnumCtor) (int value); +typedef GtkAccessibleValue * (* GtkAccessibleValueNumberCtor) (double value); +typedef GtkAccessibleValue * (* GtkAccessibleValueStringCtor) (const char *value); /*< private > * gtk_accessible_value_get_default_for_state: @@ -235,28 +451,24 @@ gtk_accessible_value_get_default_for_state (GtkAccessibleState state) { g_assert (state != GTK_ACCESSIBLE_STATE_NONE); - const GtkAccessibleCollectState *cstate = &collect_states[state]; + const GtkAccessibleCollect *cstate = &collect_states[state]; - switch (cstate->state) + switch (cstate->value) { case GTK_ACCESSIBLE_STATE_BUSY: - return gtk_busy_accessible_value_new (FALSE); + case GTK_ACCESSIBLE_STATE_DISABLED: + case GTK_ACCESSIBLE_STATE_HIDDEN: + return gtk_boolean_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); @@ -266,9 +478,8 @@ gtk_accessible_value_get_default_for_state (GtkAccessibleState state) 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); + g_critical ("Unknown value for accessible state “%s”", cstate->name); break; } @@ -291,7 +502,7 @@ gtk_accessible_value_collect_for_state (GtkAccessibleState state, { g_assert (state != GTK_ACCESSIBLE_STATE_NONE); - const GtkAccessibleCollectState *cstate = &collect_states[state]; + const GtkAccessibleCollect *cstate = &collect_states[state]; GtkAccessibleValue *res = NULL; @@ -308,7 +519,7 @@ gtk_accessible_value_collect_for_state (GtkAccessibleState state, } break; - case GTK_ACCESSIBLE_COLLECT_INTEGER: + case GTK_ACCESSIBLE_COLLECT_INT: { GtkAccessibleValueIntCtor ctor = (GtkAccessibleValueIntCtor) cstate->ctor; @@ -341,9 +552,31 @@ gtk_accessible_value_collect_for_state (GtkAccessibleState state, } break; + case GTK_ACCESSIBLE_COLLECT_NUMBER: + { + GtkAccessibleValueNumberCtor ctor = + (GtkAccessibleValueNumberCtor) cstate->ctor; + + double value = va_arg (*args, double); + + res = (* ctor) (value); + } + break; + + case GTK_ACCESSIBLE_COLLECT_STRING: + { + GtkAccessibleValueStringCtor ctor = + (GtkAccessibleValueStringCtor) cstate->ctor; + + const char *value = va_arg (*args, char*); + + res = (* ctor) (value); + } + break; + case GTK_ACCESSIBLE_COLLECT_INVALID: default: - g_critical ("Unknown type for accessible state “%s”", cstate->state_name); + g_critical ("Unknown type for accessible state “%s”", cstate->name); break; } @@ -366,7 +599,7 @@ gtk_accessible_value_collect_for_state_value (GtkAccessibleState state, { g_assert (state != GTK_ACCESSIBLE_STATE_NONE); - const GtkAccessibleCollectState *cstate = &collect_states[state]; + const GtkAccessibleCollect *cstate = &collect_states[state]; GtkAccessibleValue *res = NULL; @@ -383,7 +616,7 @@ gtk_accessible_value_collect_for_state_value (GtkAccessibleState state, } break; - case GTK_ACCESSIBLE_COLLECT_INTEGER: + case GTK_ACCESSIBLE_COLLECT_INT: { GtkAccessibleValueIntCtor ctor = (GtkAccessibleValueIntCtor) cstate->ctor; @@ -416,11 +649,289 @@ gtk_accessible_value_collect_for_state_value (GtkAccessibleState state, } break; + case GTK_ACCESSIBLE_COLLECT_NUMBER: + { + GtkAccessibleValueNumberCtor ctor = + (GtkAccessibleValueNumberCtor) cstate->ctor; + + double value_ = g_value_get_double (value); + + res = (* ctor) (value_); + } + break; + + case GTK_ACCESSIBLE_COLLECT_STRING: + { + GtkAccessibleValueStringCtor ctor = + (GtkAccessibleValueStringCtor) cstate->ctor; + + const char *value_ = g_value_get_string (value); + + res = (* ctor) (value_); + } + break; + case GTK_ACCESSIBLE_COLLECT_INVALID: default: - g_critical ("Unknown value type for accessible state “%s”", cstate->state_name); + g_critical ("Unknown value type for accessible state “%s”", cstate->name); break; } return res; } + +/*< private > + * gtk_accessible_value_get_default_for_property: + * @property: a #GtkAccessibleProperty + * + * Retrieves the #GtkAccessibleValue that contains the default for the + * given @property. + * + * Returns: (transfer full): the #GtkAccessibleValue + */ +GtkAccessibleValue * +gtk_accessible_value_get_default_for_property (GtkAccessibleProperty property) +{ + const GtkAccessibleCollect *cstate = &collect_props[property]; + + switch (cstate->value) + { + case GTK_ACCESSIBLE_PROPERTY_ACTIVE_DESCENDANT: + case GTK_ACCESSIBLE_PROPERTY_CONTROLS: + case GTK_ACCESSIBLE_PROPERTY_DESCRIBED_BY: + case GTK_ACCESSIBLE_PROPERTY_FLOW_TO: + case GTK_ACCESSIBLE_PROPERTY_LABELLED_BY: + case GTK_ACCESSIBLE_PROPERTY_OWNS: + case GTK_ACCESSIBLE_PROPERTY_RELEVANT: + g_critical ("Unsupported property “%s”", cstate->name); + return NULL; + + case GTK_ACCESSIBLE_PROPERTY_HAS_POPUP: + case GTK_ACCESSIBLE_PROPERTY_MULTI_LINE: + case GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE: + case GTK_ACCESSIBLE_PROPERTY_READ_ONLY: + case GTK_ACCESSIBLE_PROPERTY_REQUIRED: + return gtk_boolean_accessible_value_new (FALSE); + + case GTK_ACCESSIBLE_PROPERTY_LEVEL: + case GTK_ACCESSIBLE_PROPERTY_POS_IN_SET: + case GTK_ACCESSIBLE_PROPERTY_SET_SIZE: + return gtk_int_accessible_value_new (0); + + case GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE: + return gtk_autocomplete_accessible_value_new (GTK_ACCESSIBLE_AUTOCOMPLETE_NONE); + + case GTK_ACCESSIBLE_PROPERTY_ORIENTATION: + return gtk_orientation_accessible_value_new (GTK_ORIENTATION_HORIZONTAL); + + case GTK_ACCESSIBLE_PROPERTY_SORT: + return gtk_sort_accessible_value_new (GTK_ACCESSIBLE_SORT_NONE); + + case GTK_ACCESSIBLE_PROPERTY_VALUE_MAX: + case GTK_ACCESSIBLE_PROPERTY_VALUE_MIN: + case GTK_ACCESSIBLE_PROPERTY_VALUE_NOW: + return gtk_number_accessible_value_new (0); + + case GTK_ACCESSIBLE_PROPERTY_LABEL: + case GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT: + return gtk_string_accessible_value_new (""); + + default: + g_critical ("Unknown value for accessible state “%s”", cstate->name); + break; + } + + return NULL; +} + +/*< private > + * gtk_accessible_value_collect_for_property: + * @property: a #GtkAccessibleProperty + * @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_property (GtkAccessibleProperty property, + va_list *args) +{ + const GtkAccessibleCollect *cstate = &collect_props[property]; + + 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_INT: + { + 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_NUMBER: + { + GtkAccessibleValueNumberCtor ctor = + (GtkAccessibleValueNumberCtor) cstate->ctor; + + double value = va_arg (*args, double); + + res = (* ctor) (value); + } + break; + + case GTK_ACCESSIBLE_COLLECT_STRING: + { + GtkAccessibleValueStringCtor ctor = + (GtkAccessibleValueStringCtor) cstate->ctor; + + const char *value = va_arg (*args, char*); + + res = (* ctor) (value); + } + break; + + case GTK_ACCESSIBLE_COLLECT_INVALID: + default: + g_critical ("Unknown type for accessible state “%s”", cstate->name); + break; + } + + return res; +} + +/*< private > + * gtk_accessible_value_collect_for_property_value: + * @property: a #GtkAccessibleProperty + * @value: a #GValue + * + * Retrieves the value stored inside @value and returns a #GtkAccessibleValue + * for the given @property. + * + * Returns: (transfer full): a #GtkAccessibleValue + */ +GtkAccessibleValue * +gtk_accessible_value_collect_for_property_value (GtkAccessibleProperty property, + const GValue *value) +{ + const GtkAccessibleCollect *cstate = &collect_props[property]; + + 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_INT: + { + 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_NUMBER: + { + GtkAccessibleValueNumberCtor ctor = + (GtkAccessibleValueNumberCtor) cstate->ctor; + + double value_ = g_value_get_double (value); + + res = (* ctor) (value_); + } + break; + + case GTK_ACCESSIBLE_COLLECT_STRING: + { + GtkAccessibleValueStringCtor ctor = + (GtkAccessibleValueStringCtor) cstate->ctor; + + const char *value_ = g_value_get_string (value); + + res = (* ctor) (value_); + } + break; + + case GTK_ACCESSIBLE_COLLECT_INVALID: + default: + g_critical ("Unknown value type for accessible state “%s”", cstate->name); + break; + } + + return res; +} + +/* }}} */ diff --git a/gtk/gtkaccessiblevalueprivate.h b/gtk/gtkaccessiblevalueprivate.h index 30454c4ed2..d924fa0f9f 100644 --- a/gtk/gtkaccessiblevalueprivate.h +++ b/gtk/gtkaccessiblevalueprivate.h @@ -73,12 +73,20 @@ gboolean gtk_accessible_value_equal (const G 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); +GtkAccessibleValue * gtk_accessible_value_get_default_for_property (GtkAccessibleProperty property); +GtkAccessibleValue * gtk_accessible_value_collect_for_property (GtkAccessibleProperty property, + va_list *args); +GtkAccessibleValue * gtk_accessible_value_collect_for_property_value (GtkAccessibleProperty property, + const GValue *value); + + +#define GTK_ACCESSIBLE_STATE_UNDEFINED (-1) + typedef enum { /*< prefix=GTK_ACCESSIBLE_CHECKED >*/ GTK_ACCESSIBLE_CHECKED_FALSE = 0, GTK_ACCESSIBLE_CHECKED_TRUE = 1, @@ -100,36 +108,60 @@ typedef enum { /*< prefix=GTK_ACCESSIBLE_INVALID >*/ GTK_ACCESSIBLE_INVALID_SPELLING, } GtkAccessibleInvalidState; -#define GTK_ACCESSIBLE_STATE_UNDEFINED (-1) +typedef enum { /*< prefix=GTK_ACCESSIBLE_AUTOCOMPLETE >*/ + GTK_ACCESSIBLE_AUTOCOMPLETE_NONE, + GTK_ACCESSIBLE_AUTOCOMPLETE_INLINE, + GTK_ACCESSIBLE_AUTOCOMPLETE_LIST, + GTK_ACCESSIBLE_AUTOCOMPLETE_BOTH +} GtkAccessibleAutocomplete; -/* Boolean states */ -GtkAccessibleValue * gtk_busy_accessible_value_new (gboolean state); -gboolean gtk_busy_accessible_value_get (const GtkAccessibleValue *value); +typedef enum { /*< prefix=GTK_ACCESSIBLE_SORT >*/ + GTK_ACCESSIBLE_SORT_NONE, + GTK_ACCESSIBLE_SORT_ASCENDING, + GTK_ACCESSIBLE_SORT_DESCENDING, + GTK_ACCESSIBLE_SORT_OTHER +} GtkAccessibleSort; -GtkAccessibleValue * gtk_disabled_accessible_value_new (gboolean state); -gboolean gtk_disabled_accessible_value_get (const GtkAccessibleValue *value); +/* Basic values */ +GtkAccessibleValue * gtk_boolean_accessible_value_new (gboolean value); +gboolean gtk_boolean_accessible_value_get (const GtkAccessibleValue *value); -GtkAccessibleValue * gtk_hidden_accessible_value_new (gboolean state); -gboolean gtk_hidden_accessible_value_get (const GtkAccessibleValue *value); +GtkAccessibleValue * gtk_int_accessible_value_new (int value); +int gtk_int_accessible_value_get (const GtkAccessibleValue *value); -/* Tri-state states */ -GtkAccessibleValue * gtk_expanded_accessible_value_new (int state); +GtkAccessibleValue * gtk_number_accessible_value_new (double value); +double gtk_number_accessible_value_get (const GtkAccessibleValue *value); + +GtkAccessibleValue * gtk_string_accessible_value_new (const char *value); +const char * gtk_string_accessible_value_get (const GtkAccessibleValue *value); + +/* Tri-state values */ +GtkAccessibleValue * gtk_expanded_accessible_value_new (int value); int gtk_expanded_accessible_value_get (const GtkAccessibleValue *value); -GtkAccessibleValue * gtk_grabbed_accessible_value_new (int state); +GtkAccessibleValue * gtk_grabbed_accessible_value_new (int value); int gtk_grabbed_accessible_value_get (const GtkAccessibleValue *value); -GtkAccessibleValue * gtk_selected_accessible_value_new (int state); +GtkAccessibleValue * gtk_selected_accessible_value_new (int value); int gtk_selected_accessible_value_get (const GtkAccessibleValue *value); -/* Token states */ -GtkAccessibleValue * gtk_pressed_accessible_value_new (GtkAccessiblePressedState state); +/* Token values */ +GtkAccessibleValue * gtk_pressed_accessible_value_new (GtkAccessiblePressedState value); GtkAccessiblePressedState gtk_pressed_accessible_value_get (const GtkAccessibleValue *value); -GtkAccessibleValue * gtk_checked_accessible_value_new (GtkAccessibleCheckedState state); +GtkAccessibleValue * gtk_checked_accessible_value_new (GtkAccessibleCheckedState value); GtkAccessibleCheckedState gtk_checked_accessible_value_get (const GtkAccessibleValue *value); -GtkAccessibleValue * gtk_invalid_accessible_value_new (GtkAccessibleInvalidState state); +GtkAccessibleValue * gtk_invalid_accessible_value_new (GtkAccessibleInvalidState value); GtkAccessibleInvalidState gtk_invalid_accessible_value_get (const GtkAccessibleValue *value); +GtkAccessibleValue * gtk_autocomplete_accessible_value_new (GtkAccessibleAutocomplete value); +GtkAccessibleAutocomplete gtk_autocomplete_accessible_value_get (const GtkAccessibleValue *value); + +GtkAccessibleValue * gtk_orientation_accessible_value_new (GtkOrientation value); +GtkOrientation gtk_orientation_accessible_value_get (const GtkAccessibleValue *value); + +GtkAccessibleValue * gtk_sort_accessible_value_new (GtkAccessibleSort value); +GtkAccessibleSort gtk_sort_accessible_value_get (const GtkAccessibleValue *value); + G_END_DECLS diff --git a/gtk/gtkaccessiblevaluestatic.c b/gtk/gtkaccessiblevaluestatic.c index c41f92cac7..9fa9982248 100644 --- a/gtk/gtkaccessiblevaluestatic.c +++ b/gtk/gtkaccessiblevaluestatic.c @@ -50,98 +50,34 @@ gtk_boolean_accessible_value_print (const GtkAccessibleValue *value, g_string_append_printf (buffer, "%s", self->value ? "true" : "false"); } -static const GtkAccessibleValueClass GTK_BUSY_ACCESSIBLE_VALUE = { - .type_name = "GtkBusyAccessibleValue", +static const GtkAccessibleValueClass GTK_BOOLEAN_ACCESSIBLE_VALUE = { + .type_name = "GtkBooleanAccessibleValue", .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 }, +static GtkBooleanAccessibleValue boolean_values[] = { + { { >K_BOOLEAN_ACCESSIBLE_VALUE, 1 }, FALSE }, + { { >K_BOOLEAN_ACCESSIBLE_VALUE, 1 }, TRUE }, }; GtkAccessibleValue * -gtk_busy_accessible_value_new (gboolean state) +gtk_boolean_accessible_value_new (gboolean state) { if (state) - return gtk_accessible_value_ref ((GtkAccessibleValue *) &busy_values[1]); + return gtk_accessible_value_ref ((GtkAccessibleValue *) &boolean_values[1]); - return gtk_accessible_value_ref ((GtkAccessibleValue *) &busy_values[0]); + return gtk_accessible_value_ref ((GtkAccessibleValue *) &boolean_values[0]); } gboolean -gtk_busy_accessible_value_get (const GtkAccessibleValue *value) +gtk_boolean_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); + g_return_val_if_fail (value->value_class == >K_BOOLEAN_ACCESSIBLE_VALUE, FALSE); return self->value; } @@ -492,4 +428,119 @@ gtk_invalid_accessible_value_get (const GtkAccessibleValue *value) return self->value; } +static const GtkAccessibleValueClass GTK_AUTOCOMPLETE_ACCESSIBLE_VALUE = { + .type_name = "GtkAutocompleteAccessibleValue", + .instance_size = sizeof (GtkEnumAccessibleValue), + .equal = gtk_enum_accessible_value_equal, + .print = gtk_enum_accessible_value_print, +}; + +static GtkEnumAccessibleValue autocomplete_values[] = { + { { >K_AUTOCOMPLETE_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_AUTOCOMPLETE_NONE, "none" }, + { { >K_AUTOCOMPLETE_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_AUTOCOMPLETE_INLINE, "inline" }, + { { >K_AUTOCOMPLETE_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_AUTOCOMPLETE_LIST, "list" }, + { { >K_AUTOCOMPLETE_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_AUTOCOMPLETE_BOTH, "both" }, +}; + +GtkAccessibleValue * +gtk_autocomplete_accessible_value_new (GtkAccessibleAutocomplete value) +{ + g_return_val_if_fail (value >= GTK_ACCESSIBLE_AUTOCOMPLETE_NONE && + value <= GTK_ACCESSIBLE_AUTOCOMPLETE_BOTH, + NULL); + + return gtk_accessible_value_ref ((GtkAccessibleValue *) &autocomplete_values[value]); +} + +GtkAccessibleAutocomplete +gtk_autocomplete_accessible_value_get (const GtkAccessibleValue *value) +{ + GtkEnumAccessibleValue *self = (GtkEnumAccessibleValue *) value; + + g_return_val_if_fail (value != NULL, GTK_ACCESSIBLE_AUTOCOMPLETE_NONE); + g_return_val_if_fail (value->value_class == >K_AUTOCOMPLETE_ACCESSIBLE_VALUE, + GTK_ACCESSIBLE_AUTOCOMPLETE_NONE); + + return self->value; +} + +static const GtkAccessibleValueClass GTK_ORIENTATION_ACCESSIBLE_VALUE = { + .type_name = "GtkOrientationAccessibleValue", + .instance_size = sizeof (GtkEnumAccessibleValue), + .equal = gtk_enum_accessible_value_equal, + .print = gtk_enum_accessible_value_print, +}; + +static GtkEnumAccessibleValue orientation_values[] = { + { { >K_ORIENTATION_ACCESSIBLE_VALUE, 1 }, GTK_ORIENTATION_HORIZONTAL, "horizontal" }, + { { >K_ORIENTATION_ACCESSIBLE_VALUE, 1 }, GTK_ORIENTATION_VERTICAL, "vertical" }, +}; + +GtkAccessibleValue * +gtk_orientation_accessible_value_new (GtkOrientation value) +{ + switch (value) + { + case GTK_ORIENTATION_HORIZONTAL: + return gtk_accessible_value_ref ((GtkAccessibleValue *) &orientation_values[0]); + + case GTK_ORIENTATION_VERTICAL: + return gtk_accessible_value_ref ((GtkAccessibleValue *) &orientation_values[1]); + + default: + g_assert_not_reached (); + break; + } + + return NULL; +} + +GtkOrientation +gtk_orientation_accessible_value_get (const GtkAccessibleValue *value) +{ + GtkEnumAccessibleValue *self = (GtkEnumAccessibleValue *) value; + + g_return_val_if_fail (value != NULL, GTK_ORIENTATION_HORIZONTAL); + g_return_val_if_fail (value->value_class == >K_ORIENTATION_ACCESSIBLE_VALUE, + GTK_ORIENTATION_HORIZONTAL); + + return self->value; +} + +static const GtkAccessibleValueClass GTK_SORT_ACCESSIBLE_VALUE = { + .type_name = "GtkSortAccessibleValue", + .instance_size = sizeof (GtkEnumAccessibleValue), + .equal = gtk_enum_accessible_value_equal, + .print = gtk_enum_accessible_value_print, +}; + +static GtkEnumAccessibleValue sort_values[] = { + { { >K_SORT_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_SORT_NONE, "none" }, + { { >K_SORT_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_SORT_ASCENDING, "ascending" }, + { { >K_SORT_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_SORT_DESCENDING, "descending" }, + { { >K_SORT_ACCESSIBLE_VALUE, 1 }, GTK_ACCESSIBLE_SORT_OTHER, "other" }, +}; + +GtkAccessibleValue * +gtk_sort_accessible_value_new (GtkAccessibleSort value) +{ + g_return_val_if_fail (value >= GTK_ACCESSIBLE_SORT_NONE && + value <= GTK_ACCESSIBLE_SORT_OTHER, + NULL); + + return gtk_accessible_value_ref ((GtkAccessibleValue *) &sort_values[value]); +} + +GtkAccessibleSort +gtk_sort_accessible_value_get (const GtkAccessibleValue *value) +{ + GtkEnumAccessibleValue *self = (GtkEnumAccessibleValue *) value; + + g_return_val_if_fail (value != NULL, GTK_ACCESSIBLE_SORT_NONE); + g_return_val_if_fail (value->value_class == >K_SORT_ACCESSIBLE_VALUE, + GTK_ACCESSIBLE_SORT_NONE); + + return self->value; +} + /* }}} */ diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h index 2fc8b4cdea..d7080d47c7 100644 --- a/gtk/gtkenums.h +++ b/gtk/gtkenums.h @@ -1338,6 +1338,7 @@ typedef enum { typedef enum { GTK_ACCESSIBLE_PROPERTY_ACTIVE_DESCENDANT, + GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE, GTK_ACCESSIBLE_PROPERTY_CONTROLS, GTK_ACCESSIBLE_PROPERTY_DESCRIBED_BY, GTK_ACCESSIBLE_PROPERTY_FLOW_TO,