1 /* GAIL - The GNOME Accessibility Implementation Library
2 * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
24 #include "gtkbuttonaccessible.h"
27 static void atk_action_interface_init (AtkActionIface *iface);
28 static void atk_image_interface_init (AtkImageIface *iface);
30 G_DEFINE_TYPE_WITH_CODE (GtkButtonAccessible, _gtk_button_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
31 G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
32 G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_interface_init))
35 state_changed_cb (GtkWidget *widget, GtkStateFlags previous_flags)
37 AtkObject *accessible;
42 flags = gtk_widget_get_state_flags (widget);
44 was_active = (previous_flags & GTK_STATE_FLAG_ACTIVE) != 0;
45 active = (flags & GTK_STATE_FLAG_ACTIVE) != 0;
47 accessible = gtk_widget_get_accessible (widget);
48 if (active && !was_active)
49 atk_object_notify_state_change (accessible, ATK_STATE_ARMED, TRUE);
50 else if (!active && was_active)
51 atk_object_notify_state_change (accessible, ATK_STATE_ARMED, FALSE);
55 gtk_button_accessible_initialize (AtkObject *obj,
60 ATK_OBJECT_CLASS (_gtk_button_accessible_parent_class)->initialize (obj, data);
62 g_signal_connect (data, "state-flags-changed", G_CALLBACK (state_changed_cb), NULL);
64 parent = gtk_widget_get_parent (gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)));
65 if (GTK_IS_TREE_VIEW (parent))
67 /* Even though the accessible parent of the column header will
68 * be reported as the table because the parent widget of the
69 * GtkTreeViewColumn's button is the GtkTreeView we set
70 * the accessible parent for column header to be the table
71 * to ensure that atk_object_get_index_in_parent() returns
72 * the correct value; see gail_widget_get_index_in_parent().
74 atk_object_set_parent (obj, gtk_widget_get_accessible (parent));
75 obj->role = ATK_ROLE_TABLE_COLUMN_HEADER;
78 obj->role = ATK_ROLE_PUSH_BUTTON;
82 get_image_from_button (GtkWidget *button)
86 image = gtk_button_get_image (GTK_BUTTON (button));
87 if (GTK_IS_IMAGE (image))
94 find_label_child (GtkContainer *container)
96 GList *children, *tmp_list;
99 children = gtk_container_get_children (container);
102 for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
104 if (GTK_IS_LABEL (tmp_list->data))
106 child = GTK_WIDGET (tmp_list->data);
109 else if (GTK_IS_CONTAINER (tmp_list->data))
111 child = find_label_child (GTK_CONTAINER (tmp_list->data));
116 g_list_free (children);
121 get_label_from_button (GtkWidget *button)
125 child = gtk_bin_get_child (GTK_BIN (button));
126 if (GTK_IS_ALIGNMENT (child))
127 child = gtk_bin_get_child (GTK_BIN (child));
129 if (GTK_IS_CONTAINER (child))
130 child = find_label_child (GTK_CONTAINER (child));
131 else if (!GTK_IS_LABEL (child))
138 gtk_button_accessible_get_name (AtkObject *obj)
140 const gchar *name = NULL;
144 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
148 name = ATK_OBJECT_CLASS (_gtk_button_accessible_parent_class)->get_name (obj);
152 child = get_label_from_button (widget);
153 if (GTK_IS_LABEL (child))
154 name = gtk_label_get_text (GTK_LABEL (child));
159 image = get_image_from_button (widget);
160 if (GTK_IS_IMAGE (image))
164 atk_obj = gtk_widget_get_accessible (image);
165 name = atk_object_get_name (atk_obj);
173 gtk_button_accessible_get_n_children (AtkObject* obj)
179 gtk_button_accessible_ref_child (AtkObject *obj,
186 gtk_button_accessible_ref_state_set (AtkObject *obj)
188 AtkStateSet *state_set;
191 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
195 state_set = ATK_OBJECT_CLASS (_gtk_button_accessible_parent_class)->ref_state_set (obj);
197 if ((gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_ACTIVE) != 0)
198 atk_state_set_add_state (state_set, ATK_STATE_ARMED);
200 if (!gtk_widget_get_can_focus (widget))
201 atk_state_set_remove_state (state_set, ATK_STATE_SELECTABLE);
207 gtk_button_accessible_notify_gtk (GObject *obj,
210 GtkWidget *widget = GTK_WIDGET (obj);
211 AtkObject *atk_obj = gtk_widget_get_accessible (widget);
213 if (strcmp (pspec->name, "label") == 0)
215 if (atk_obj->name == NULL)
216 g_object_notify (G_OBJECT (atk_obj), "accessible-name");
218 g_signal_emit_by_name (atk_obj, "visible-data-changed");
221 GTK_WIDGET_ACCESSIBLE_CLASS (_gtk_button_accessible_parent_class)->notify_gtk (obj, pspec);
225 _gtk_button_accessible_class_init (GtkButtonAccessibleClass *klass)
227 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
228 GtkContainerAccessibleClass *container_class = (GtkContainerAccessibleClass*)klass;
229 GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
231 class->get_name = gtk_button_accessible_get_name;
232 class->get_n_children = gtk_button_accessible_get_n_children;
233 class->ref_child = gtk_button_accessible_ref_child;
234 class->ref_state_set = gtk_button_accessible_ref_state_set;
235 class->initialize = gtk_button_accessible_initialize;
237 widget_class->notify_gtk = gtk_button_accessible_notify_gtk;
239 container_class->add_gtk = NULL;
240 container_class->remove_gtk = NULL;
244 _gtk_button_accessible_init (GtkButtonAccessible *button)
249 gtk_button_accessible_do_action (AtkAction *action,
254 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
261 if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
264 gtk_button_clicked (GTK_BUTTON (widget));
269 gtk_button_accessible_get_n_actions (AtkAction *action)
275 gtk_button_accessible_get_keybinding (AtkAction *action,
278 gchar *return_value = NULL;
283 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
290 label = get_label_from_button (widget);
291 if (GTK_IS_LABEL (label))
293 key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
294 if (key_val != GDK_KEY_VoidSymbol)
295 return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
297 if (return_value == NULL)
299 /* Find labelled-by relation */
301 AtkRelation *relation;
303 gpointer target_object;
305 set = atk_object_ref_relation_set (ATK_OBJECT (action));
308 relation = atk_relation_set_get_relation_by_type (set, ATK_RELATION_LABELLED_BY);
311 target = atk_relation_get_target (relation);
312 target_object = g_ptr_array_index (target, 0);
313 label = gtk_accessible_get_widget (GTK_ACCESSIBLE (target_object));
315 g_object_unref (set);
318 if (GTK_IS_LABEL (label))
320 key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
321 if (key_val != GDK_KEY_VoidSymbol)
322 return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
329 gtk_button_accessible_action_get_name (AtkAction *action,
339 atk_action_interface_init (AtkActionIface *iface)
341 iface->do_action = gtk_button_accessible_do_action;
342 iface->get_n_actions = gtk_button_accessible_get_n_actions;
343 iface->get_keybinding = gtk_button_accessible_get_keybinding;
344 iface->get_name = gtk_button_accessible_action_get_name;
348 gtk_button_accessible_get_image_description (AtkImage *image)
351 GtkWidget *button_image;
354 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
358 button_image = get_image_from_button (widget);
359 if (GTK_IS_IMAGE (button_image))
361 obj = gtk_widget_get_accessible (button_image);
362 return atk_image_get_image_description (ATK_IMAGE (obj));
369 gtk_button_accessible_get_image_position (AtkImage *image,
372 AtkCoordType coord_type)
375 GtkWidget *button_image;
378 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
386 button_image = get_image_from_button (widget);
387 if (button_image != NULL)
389 obj = gtk_widget_get_accessible (button_image);
390 atk_component_get_position (ATK_COMPONENT (obj), x, y, coord_type);
400 gtk_button_accessible_get_image_size (AtkImage *image,
405 GtkWidget *button_image;
408 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
416 button_image = get_image_from_button (widget);
417 if (GTK_IS_IMAGE (button_image))
419 obj = gtk_widget_get_accessible (GTK_WIDGET (button_image));
420 atk_image_get_image_size (ATK_IMAGE (obj), width, height);
430 gtk_button_accessible_set_image_description (AtkImage *image,
431 const gchar *description)
434 GtkWidget *button_image;
437 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
442 button_image = get_image_from_button (widget);
443 if (GTK_IMAGE (button_image))
445 obj = gtk_widget_get_accessible (GTK_WIDGET (button_image));
446 return atk_image_set_image_description (ATK_IMAGE (obj), description);
453 atk_image_interface_init (AtkImageIface *iface)
455 iface->get_image_description = gtk_button_accessible_get_image_description;
456 iface->get_image_position = gtk_button_accessible_get_image_position;
457 iface->get_image_size = gtk_button_accessible_get_image_size;
458 iface->set_image_description = gtk_button_accessible_set_image_description;