/* gtkaccessibleattributeset.c: Accessible attribute containt * * 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 . */ #include "config.h" #include "gtkaccessibleattributesetprivate.h" #include "gtkbitmaskprivate.h" #include "gtkenums.h" struct _GtkAccessibleAttributeSet { gsize n_attributes; GtkAccessibleAttributeDefaultFunc default_func; GtkBitmask *attributes_set; char **attribute_names; GtkAccessibleValue **attribute_values; }; static GtkAccessibleAttributeSet * gtk_accessible_attribute_set_init (GtkAccessibleAttributeSet *self, gsize n_attributes, const char **attribute_names, GtkAccessibleAttributeDefaultFunc default_func) { self->n_attributes = n_attributes; self->default_func = default_func; self->attribute_names = g_new (char *, n_attributes); self->attribute_values = g_new (GtkAccessibleValue *, n_attributes); self->attributes_set = _gtk_bitmask_new (); /* Initialize all attribute values, so we can always get the full attribute */ for (int i = 0; i < self->n_attributes; i++) { self->attribute_names[i] = g_strdup (attribute_names[i]); self->attribute_values[i] = (* self->default_func) (i); } return self; } GtkAccessibleAttributeSet * gtk_accessible_attribute_set_new (gsize n_attributes, const char **attribute_names, GtkAccessibleAttributeDefaultFunc default_func) { GtkAccessibleAttributeSet *set = g_rc_box_new0 (GtkAccessibleAttributeSet); return gtk_accessible_attribute_set_init (set, n_attributes, attribute_names, default_func); } GtkAccessibleAttributeSet * gtk_accessible_attribute_set_ref (GtkAccessibleAttributeSet *self) { g_return_val_if_fail (self != NULL, NULL); return g_rc_box_acquire (self); } static void gtk_accessible_attribute_set_free (gpointer data) { GtkAccessibleAttributeSet *self = data; for (int i = 0; i < self->n_attributes; i++) { g_free (self->attribute_names[i]); if (self->attribute_values[i] != NULL) gtk_accessible_value_unref (self->attribute_values[i]); } g_free (self->attribute_names); g_free (self->attribute_values); _gtk_bitmask_free (self->attributes_set); } void gtk_accessible_attribute_set_unref (GtkAccessibleAttributeSet *self) { g_rc_box_release_full (self, gtk_accessible_attribute_set_free); } /*< private > * gtk_accessible_attribute_set_add: * @self: a #GtkAccessibleAttributeSet * @attribute: the attribute to set * @value: (nullable): a #GtkAccessibleValue * * Adds @attribute to the attributes set, and sets its value. * * If @value is %NULL, the @attribute is reset to its default value. * * If you want to remove @attribute from the set, use gtk_accessible_attribute_set_remove() * instead. */ void gtk_accessible_attribute_set_add (GtkAccessibleAttributeSet *self, int attribute, GtkAccessibleValue *value) { g_return_if_fail (attribute >= 0 && attribute < self->n_attributes); g_clear_pointer (&(self->attribute_values[attribute]), gtk_accessible_value_unref); if (value != NULL) self->attribute_values[attribute] = gtk_accessible_value_ref (value); else self->attribute_values[attribute] = (* self->default_func) (attribute); self->attributes_set = _gtk_bitmask_set (self->attributes_set, attribute, TRUE); } void gtk_accessible_attribute_set_remove (GtkAccessibleAttributeSet *self, int attribute) { g_return_if_fail (attribute >= 0 && attribute < self->n_attributes); g_clear_pointer (&(self->attribute_values[attribute]), gtk_accessible_value_unref); self->attribute_values[attribute] = (* self->default_func) (attribute); self->attributes_set = _gtk_bitmask_set (self->attributes_set, attribute, FALSE); } gboolean gtk_accessible_attribute_set_contains (GtkAccessibleAttributeSet *self, int attribute) { g_return_val_if_fail (attribute >= 0 && attribute < self->n_attributes, FALSE); return _gtk_bitmask_get (self->attributes_set, attribute); } /*< private > * gtk_accessible_attribute_set_get_value: * @self: a #GtkAccessibleAttributeSet * @attribute: the attribute to retrieve * * Retrieves the value of the given @attribute in the set. * * Returns: (transfer none): the value for the attribute */ GtkAccessibleValue * gtk_accessible_attribute_set_get_value (GtkAccessibleAttributeSet *self, int attribute) { g_return_val_if_fail (attribute >= 0 && attribute < self->n_attributes, NULL); return self->attribute_values[attribute]; } gsize gtk_accessible_attribute_set_get_length (GtkAccessibleAttributeSet *self) { return self->n_attributes; } guint gtk_accessible_attribute_set_get_changed (GtkAccessibleAttributeSet *self) { guint changed = 0; for (gsize i = 0; i < self->n_attributes; i++) { if (gtk_accessible_attribute_set_contains (self, i)) changed |= (1 << i); } return changed; } /*< private > * gtk_accessible_attribute_set_print: * @self: a #GtkAccessibleAttributeSet * @only_set: %TRUE if only the set attributes should be printed * @buffer: a #GString * * Prints the contents of the #GtkAccessibleAttributeSet into @buffer. */ void gtk_accessible_attribute_set_print (GtkAccessibleAttributeSet *self, gboolean only_set, GString *buffer) { if (only_set && _gtk_bitmask_is_empty (self->attributes_set)) { g_string_append (buffer, "{}"); return; } g_string_append (buffer, "{\n"); for (gsize i = 0; i < self->n_attributes; i++) { if (only_set && !_gtk_bitmask_get (self->attributes_set, i)) continue; g_string_append (buffer, " "); g_string_append (buffer, self->attribute_names[i]); g_string_append (buffer, ": "); gtk_accessible_value_print (self->attribute_values[i], buffer); g_string_append (buffer, ",\n"); } g_string_append (buffer, "}"); } /*< private > * gtk_accessible_attribute_set_to_string: * @self: a #GtkAccessibleAttributeSet * * Prints the contents of a #GtkAccessibleAttributeSet into a string. * * Returns: (transfer full): a newly allocated string with the contents * of the #GtkAccessibleAttributeSet */ char * gtk_accessible_attribute_set_to_string (GtkAccessibleAttributeSet *self) { GString *buf = g_string_new (NULL); gtk_accessible_attribute_set_print (self, TRUE, buf); return g_string_free (buf, FALSE); }