1 /* GTK+ - accessibility implementations
2 * Copyright (C) 2002, 2004 Anders Carlsson <andersca@gnu.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library 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 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
20 #include "gtkiconviewaccessibleprivate.h"
24 #include "gtk/gtkadjustment.h"
25 #include "gtk/gtkiconviewprivate.h"
26 #include "gtk/gtkcellrendererpixbuf.h"
27 #include "gtk/gtkcellrenderertext.h"
28 #include "gtk/gtkpango.h"
29 #include "gtk/gtkwidgetprivate.h"
31 #define GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE (_gtk_icon_view_item_accessible_get_type ())
32 #define GTK_ICON_VIEW_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE, GtkIconViewItemAccessible))
33 #define GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE))
35 struct _GtkIconViewAccessiblePrivate
45 GtkIconViewItem *item;
47 AtkStateSet *state_set;
49 gchar *action_description;
50 gchar *image_description;
51 guint action_idle_handler;
52 } GtkIconViewItemAccessible;
56 AtkObjectClass parent_class;
58 } GtkIconViewItemAccessibleClass;
60 GType _gtk_icon_view_item_accessible_get_type (void);
62 static gboolean gtk_icon_view_item_accessible_is_showing (GtkIconViewItemAccessible *item);
64 static void atk_component_item_interface_init (AtkComponentIface *iface);
65 static void atk_action_item_interface_init (AtkActionIface *iface);
66 static void atk_text_item_interface_init (AtkTextIface *iface);
67 static void atk_image_item_interface_init (AtkImageIface *iface);
69 G_DEFINE_TYPE_WITH_CODE (GtkIconViewItemAccessible, _gtk_icon_view_item_accessible, ATK_TYPE_OBJECT,
70 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_item_interface_init)
71 G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_item_interface_init)
72 G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_item_interface_init)
73 G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_item_interface_init))
77 idle_do_action (gpointer data)
79 GtkIconViewItemAccessible *item;
80 GtkIconView *icon_view;
83 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (data);
84 item->action_idle_handler = 0;
86 if (item->widget != NULL)
88 icon_view = GTK_ICON_VIEW (item->widget);
89 path = gtk_tree_path_new_from_indices (item->item->index, -1);
90 gtk_icon_view_item_activated (icon_view, path);
91 gtk_tree_path_free (path);
98 gtk_icon_view_item_accessible_do_action (AtkAction *action,
101 GtkIconViewItemAccessible *item;
106 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
108 if (!GTK_IS_ICON_VIEW (item->widget))
111 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
114 if (!item->action_idle_handler)
115 item->action_idle_handler = gdk_threads_add_idle (idle_do_action, item);
121 gtk_icon_view_item_accessible_get_n_actions (AtkAction *action)
127 gtk_icon_view_item_accessible_get_description (AtkAction *action,
130 GtkIconViewItemAccessible *item;
135 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
137 if (item->action_description)
138 return item->action_description;
140 return "Activate item";
144 gtk_icon_view_item_accessible_get_name (AtkAction *action,
154 gtk_icon_view_item_accessible_set_description (AtkAction *action,
156 const gchar *description)
158 GtkIconViewItemAccessible *item;
163 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
165 g_free (item->action_description);
166 item->action_description = g_strdup (description);
172 atk_action_item_interface_init (AtkActionIface *iface)
174 iface->do_action = gtk_icon_view_item_accessible_do_action;
175 iface->set_description = gtk_icon_view_item_accessible_set_description;
176 iface->get_name = gtk_icon_view_item_accessible_get_name;
177 iface->get_n_actions = gtk_icon_view_item_accessible_get_n_actions;
178 iface->get_description = gtk_icon_view_item_accessible_get_description;
182 gtk_icon_view_item_accessible_get_image_description (AtkImage *image)
184 GtkIconViewItemAccessible *item;
186 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
188 return item->image_description;
192 gtk_icon_view_item_accessible_set_image_description (AtkImage *image,
193 const gchar *description)
195 GtkIconViewItemAccessible *item;
197 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
199 g_free (item->image_description);
200 item->image_description = g_strdup (description);
207 gboolean pixbuf_found;
211 get_pixbuf_foreach (GtkCellRenderer *renderer,
212 const GdkRectangle *cell_area,
213 const GdkRectangle *cell_background,
214 GetPixbufBoxData *data)
216 if (GTK_IS_CELL_RENDERER_PIXBUF (renderer))
218 data->box = *cell_area;
219 data->pixbuf_found = TRUE;
221 return (data->pixbuf_found != FALSE);
225 get_pixbuf_box (GtkIconView *icon_view,
226 GtkIconViewItem *item,
229 GetPixbufBoxData data = { { 0, }, FALSE };
230 GtkCellAreaContext *context;
232 context = g_ptr_array_index (icon_view->priv->row_contexts, item->row);
234 _gtk_icon_view_set_cell_data (icon_view, item);
235 gtk_cell_area_foreach_alloc (icon_view->priv->cell_area, context,
236 GTK_WIDGET (icon_view),
237 &item->cell_area, &item->cell_area,
238 (GtkCellAllocCallback)get_pixbuf_foreach, &data);
240 return data.pixbuf_found;
244 get_text_foreach (GtkCellRenderer *renderer,
247 if (GTK_IS_CELL_RENDERER_TEXT (renderer))
249 g_object_get (renderer, "text", text, NULL);
256 get_text (GtkIconView *icon_view,
257 GtkIconViewItem *item)
261 _gtk_icon_view_set_cell_data (icon_view, item);
262 gtk_cell_area_foreach (icon_view->priv->cell_area,
263 (GtkCellCallback)get_text_foreach, &text);
269 gtk_icon_view_item_accessible_get_image_size (AtkImage *image,
273 GtkIconViewItemAccessible *item;
276 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
278 if (!GTK_IS_ICON_VIEW (item->widget))
281 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
287 if (get_pixbuf_box (GTK_ICON_VIEW (item->widget), item->item, &box))
290 *height = box.height;
295 gtk_icon_view_item_accessible_get_image_position (AtkImage *image,
298 AtkCoordType coord_type)
300 GtkIconViewItemAccessible *item;
303 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
305 if (!GTK_IS_ICON_VIEW (item->widget))
308 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
311 atk_component_get_position (ATK_COMPONENT (image), x, y, coord_type);
313 if (get_pixbuf_box (GTK_ICON_VIEW (item->widget), item->item, &box))
315 *x+= box.x - item->item->cell_area.x;
316 *y+= box.y - item->item->cell_area.y;
322 atk_image_item_interface_init (AtkImageIface *iface)
324 iface->get_image_description = gtk_icon_view_item_accessible_get_image_description;
325 iface->set_image_description = gtk_icon_view_item_accessible_set_image_description;
326 iface->get_image_size = gtk_icon_view_item_accessible_get_image_size;
327 iface->get_image_position = gtk_icon_view_item_accessible_get_image_position;
331 gtk_icon_view_item_accessible_get_text (AtkText *text,
335 GtkIconViewItemAccessible *item;
337 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
338 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
342 return g_utf8_substring (item->text, start_pos, end_pos > -1 ? end_pos : g_utf8_strlen (item->text, -1));
344 return g_strdup ("");
348 gtk_icon_view_item_accessible_get_character_at_offset (AtkText *text,
351 GtkIconViewItemAccessible *item;
355 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
356 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
364 if (offset >= g_utf8_strlen (string, -1))
367 index = g_utf8_offset_to_pointer (string, offset);
369 return g_utf8_get_char (index);
373 create_pango_layout (GtkIconViewItemAccessible *item)
377 layout = gtk_widget_create_pango_layout (item->widget, item->text);
383 gtk_icon_view_item_accessible_get_text_before_offset (AtkText *atk_text,
385 AtkTextBoundary boundary_type,
389 GtkIconViewItemAccessible *item;
393 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (atk_text);
394 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
397 layout = create_pango_layout (item);
398 text = _gtk_pango_get_text_before (layout, boundary_type, offset, start_offset, end_offset);
399 g_object_unref (layout);
405 gtk_icon_view_item_accessible_get_text_at_offset (AtkText *atk_text,
407 AtkTextBoundary boundary_type,
411 GtkIconViewItemAccessible *item;
415 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (atk_text);
416 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
419 layout = create_pango_layout (item);
420 text = _gtk_pango_get_text_at (layout, boundary_type, offset, start_offset, end_offset);
421 g_object_unref (layout);
427 gtk_icon_view_item_accessible_get_text_after_offset (AtkText *atk_text,
429 AtkTextBoundary boundary_type,
433 GtkIconViewItemAccessible *item;
437 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (atk_text);
438 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
441 layout = create_pango_layout (item);
442 text = _gtk_pango_get_text_after (layout, boundary_type, offset, start_offset, end_offset);
443 g_object_unref (layout);
449 gtk_icon_view_item_accessible_get_character_count (AtkText *text)
451 GtkIconViewItemAccessible *item;
453 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
454 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
458 return g_utf8_strlen (item->text, -1);
464 gtk_icon_view_item_accessible_get_character_extents (AtkText *text,
470 AtkCoordType coord_type)
472 GtkIconViewItemAccessible *item;
474 GtkIconView *icon_view;
475 PangoRectangle char_rect;
476 const gchar *item_text;
480 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
482 if (!GTK_IS_ICON_VIEW (item->widget))
485 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
489 icon_view = GTK_ICON_VIEW (item->widget);
490 /* FIXME we probably have to use GailTextCell to salvage this */
491 gtk_icon_view_update_item_text (icon_view, item->item);
492 item_text = pango_layout_get_text (icon_view->priv->layout);
493 index = g_utf8_offset_to_pointer (item_text, offset) - item_text;
494 pango_layout_index_to_pos (icon_view->priv->layout, index, &char_rect);
496 atk_component_get_position (ATK_COMPONENT (text), x, y, coord_type);
497 *x += item->item->layout_x - item->item->x + char_rect.x / PANGO_SCALE;
498 /* Look at gtk_icon_view_paint_item() to see where the text is. */
499 *x -= ((item->item->width - item->item->layout_width) / 2) + (MAX (item->item->pixbuf_width, icon_view->priv->item_width) - item->item->width) / 2,
500 *y += item->item->layout_y - item->item->y + char_rect.y / PANGO_SCALE;
501 *width = char_rect.width / PANGO_SCALE;
502 *height = char_rect.height / PANGO_SCALE;
507 gtk_icon_view_item_accessible_get_offset_at_point (AtkText *text,
510 AtkCoordType coord_type)
512 GtkIconViewItemAccessible *item;
515 GtkIconView *icon_view;
516 const gchar *item_text;
521 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
523 if (!GTK_IS_ICON_VIEW (item->widget))
526 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
530 icon_view = GTK_ICON_VIEW (item->widget);
531 /* FIXME we probably have to use GailTextCell to salvage this */
532 gtk_icon_view_update_item_text (icon_view, item->item);
533 atk_component_get_position (ATK_COMPONENT (text), &l_x, &l_y, coord_type);
534 x -= l_x + item->item->layout_x - item->item->x;
535 x += ((item->item->width - item->item->layout_width) / 2) + (MAX (item->item->pixbuf_width, icon_view->priv->item_width) - item->item->width) / 2,
536 y -= l_y + item->item->layout_y - item->item->y;
537 item_text = pango_layout_get_text (icon_view->priv->layout);
538 if (!pango_layout_xy_to_index (icon_view->priv->layout,
549 offset = g_utf8_strlen (item_text, -1);
551 offset = g_utf8_pointer_to_offset (item_text, item_text + index);
557 atk_text_item_interface_init (AtkTextIface *iface)
559 iface->get_text = gtk_icon_view_item_accessible_get_text;
560 iface->get_character_at_offset = gtk_icon_view_item_accessible_get_character_at_offset;
561 iface->get_text_before_offset = gtk_icon_view_item_accessible_get_text_before_offset;
562 iface->get_text_at_offset = gtk_icon_view_item_accessible_get_text_at_offset;
563 iface->get_text_after_offset = gtk_icon_view_item_accessible_get_text_after_offset;
564 iface->get_character_count = gtk_icon_view_item_accessible_get_character_count;
565 iface->get_character_extents = gtk_icon_view_item_accessible_get_character_extents;
566 iface->get_offset_at_point = gtk_icon_view_item_accessible_get_offset_at_point;
570 gtk_icon_view_item_accessible_get_extents (AtkComponent *component,
575 AtkCoordType coord_type)
577 GtkIconViewItemAccessible *item;
578 AtkObject *parent_obj;
581 g_return_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component));
583 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (component);
584 if (!GTK_IS_WIDGET (item->widget))
587 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
590 *width = item->item->cell_area.width;
591 *height = item->item->cell_area.height;
592 if (gtk_icon_view_item_accessible_is_showing (item))
594 parent_obj = gtk_widget_get_accessible (item->widget);
595 atk_component_get_position (ATK_COMPONENT (parent_obj), &l_x, &l_y, coord_type);
596 *x = l_x + item->item->cell_area.x;
597 *y = l_y + item->item->cell_area.y;
607 gtk_icon_view_item_accessible_grab_focus (AtkComponent *component)
609 GtkIconViewItemAccessible *item;
612 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component), FALSE);
614 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (component);
615 if (!GTK_IS_WIDGET (item->widget))
618 gtk_widget_grab_focus (item->widget);
619 _gtk_icon_view_set_cursor_item (GTK_ICON_VIEW (item->widget), item->item, NULL);
620 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item->widget));
621 if (gtk_widget_is_toplevel (toplevel))
622 gtk_window_present (GTK_WINDOW (toplevel));
628 atk_component_item_interface_init (AtkComponentIface *iface)
630 iface->get_extents = gtk_icon_view_item_accessible_get_extents;
631 iface->grab_focus = gtk_icon_view_item_accessible_grab_focus;
635 gtk_icon_view_item_accessible_add_state (GtkIconViewItemAccessible *item,
636 AtkStateType state_type,
637 gboolean emit_signal)
641 rc = atk_state_set_add_state (item->state_set, state_type);
643 /* The signal should only be generated if the value changed,
644 * not when the item is set up. So states that are set
645 * initially should pass FALSE as the emit_signal argument.
649 atk_object_notify_state_change (ATK_OBJECT (item), state_type, TRUE);
650 /* If state_type is ATK_STATE_VISIBLE, additional notification */
651 if (state_type == ATK_STATE_VISIBLE)
652 g_signal_emit_by_name (item, "visible-data-changed");
659 gtk_icon_view_item_accessible_remove_state (GtkIconViewItemAccessible *item,
660 AtkStateType state_type,
661 gboolean emit_signal)
663 if (atk_state_set_contains_state (item->state_set, state_type))
667 rc = atk_state_set_remove_state (item->state_set, state_type);
669 /* The signal should only be generated if the value changed,
670 * not when the item is set up. So states that are set
671 * initially should pass FALSE as the emit_signal argument.
675 atk_object_notify_state_change (ATK_OBJECT (item), state_type, FALSE);
676 /* If state_type is ATK_STATE_VISIBLE, additional notification */
677 if (state_type == ATK_STATE_VISIBLE)
678 g_signal_emit_by_name (item, "visible-data-changed");
688 gtk_icon_view_item_accessible_is_showing (GtkIconViewItemAccessible *item)
690 GtkAllocation allocation;
691 GtkIconView *icon_view;
692 GdkRectangle visible_rect;
695 /* An item is considered "SHOWING" if any part of the item
696 * is in the visible rectangle.
698 if (!GTK_IS_ICON_VIEW (item->widget))
701 if (item->item == NULL)
704 gtk_widget_get_allocation (item->widget, &allocation);
706 icon_view = GTK_ICON_VIEW (item->widget);
708 if (icon_view->priv->hadjustment)
709 visible_rect.x += gtk_adjustment_get_value (icon_view->priv->hadjustment);
711 if (icon_view->priv->vadjustment)
712 visible_rect.y += gtk_adjustment_get_value (icon_view->priv->vadjustment);
713 visible_rect.width = allocation.width;
714 visible_rect.height = allocation.height;
716 if (((item->item->cell_area.x + item->item->cell_area.width) < visible_rect.x) ||
717 ((item->item->cell_area.y + item->item->cell_area.height) < (visible_rect.y)) ||
718 (item->item->cell_area.x > (visible_rect.x + visible_rect.width)) ||
719 (item->item->cell_area.y > (visible_rect.y + visible_rect.height)))
728 gtk_icon_view_item_accessible_set_visibility (GtkIconViewItemAccessible *item,
729 gboolean emit_signal)
731 if (gtk_icon_view_item_accessible_is_showing (item))
732 return gtk_icon_view_item_accessible_add_state (item, ATK_STATE_SHOWING,
735 return gtk_icon_view_item_accessible_remove_state (item, ATK_STATE_SHOWING,
740 _gtk_icon_view_item_accessible_init (GtkIconViewItemAccessible *item)
742 item->state_set = atk_state_set_new ();
744 atk_state_set_add_state (item->state_set, ATK_STATE_ENABLED);
745 atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSABLE);
746 atk_state_set_add_state (item->state_set, ATK_STATE_SENSITIVE);
747 atk_state_set_add_state (item->state_set, ATK_STATE_SELECTABLE);
748 atk_state_set_add_state (item->state_set, ATK_STATE_VISIBLE);
750 item->action_description = NULL;
751 item->image_description = NULL;
753 item->action_idle_handler = 0;
757 _gtk_icon_view_item_accessible_finalize (GObject *object)
759 GtkIconViewItemAccessible *item;
761 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (object);
764 g_object_remove_weak_pointer (G_OBJECT (item->widget), (gpointer) &item->widget);
767 g_object_unref (item->state_set);
771 g_free (item->action_description);
772 g_free (item->image_description);
774 if (item->action_idle_handler)
776 g_source_remove (item->action_idle_handler);
777 item->action_idle_handler = 0;
780 G_OBJECT_CLASS (_gtk_icon_view_item_accessible_parent_class)->finalize (object);
784 _gtk_icon_view_item_accessible_get_parent (AtkObject *obj)
786 GtkIconViewItemAccessible *item;
788 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (obj), NULL);
789 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
792 return gtk_widget_get_accessible (item->widget);
798 _gtk_icon_view_item_accessible_get_index_in_parent (AtkObject *obj)
800 GtkIconViewItemAccessible *item;
802 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (obj), 0);
803 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
805 return item->item->index;
809 _gtk_icon_view_item_accessible_ref_state_set (AtkObject *obj)
811 GtkIconViewItemAccessible *item;
812 GtkIconView *icon_view;
814 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
815 g_return_val_if_fail (item->state_set, NULL);
820 icon_view = GTK_ICON_VIEW (item->widget);
821 if (icon_view->priv->cursor_item == item->item)
822 atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSED);
824 atk_state_set_remove_state (item->state_set, ATK_STATE_FOCUSED);
825 if (item->item->selected)
826 atk_state_set_add_state (item->state_set, ATK_STATE_SELECTED);
828 atk_state_set_remove_state (item->state_set, ATK_STATE_SELECTED);
830 return g_object_ref (item->state_set);
834 _gtk_icon_view_item_accessible_class_init (GtkIconViewItemAccessibleClass *klass)
836 GObjectClass *gobject_class;
837 AtkObjectClass *atk_class;
839 gobject_class = (GObjectClass *)klass;
840 atk_class = (AtkObjectClass *)klass;
842 gobject_class->finalize = _gtk_icon_view_item_accessible_finalize;
844 atk_class->get_index_in_parent = _gtk_icon_view_item_accessible_get_index_in_parent;
845 atk_class->get_parent = _gtk_icon_view_item_accessible_get_parent;
846 atk_class->ref_state_set = _gtk_icon_view_item_accessible_ref_state_set;
849 static void atk_component_interface_init (AtkComponentIface *iface);
850 static void atk_selection_interface_init (AtkSelectionIface *iface);
852 G_DEFINE_TYPE_WITH_CODE (GtkIconViewAccessible, gtk_icon_view_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
853 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)
854 G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
860 } GtkIconViewItemAccessibleInfo;
864 gtk_icon_view_item_accessible_info_new (AtkObject *accessible,
868 GtkIconViewAccessible *view = (GtkIconViewAccessible *)accessible;
869 GtkIconViewItemAccessibleInfo *info;
870 GtkIconViewItemAccessibleInfo *tmp_info;
873 info = g_new (GtkIconViewItemAccessibleInfo, 1);
877 items = view->priv->items;
880 tmp_info = items->data;
881 if (tmp_info->index > index)
885 view->priv->items = g_list_insert_before (view->priv->items, items, info);
889 gtk_icon_view_accessible_get_n_children (AtkObject *accessible)
891 GtkIconView *icon_view;
894 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
898 icon_view = GTK_ICON_VIEW (widget);
900 return g_list_length (icon_view->priv->items);
904 gtk_icon_view_accessible_find_child (AtkObject *accessible,
907 GtkIconViewAccessible *view = (GtkIconViewAccessible*)accessible;
908 GtkIconViewItemAccessibleInfo *info;
911 items = view->priv->items;
916 if (info->index == index)
925 gtk_icon_view_accessible_ref_child (AtkObject *accessible,
928 GtkIconView *icon_view;
932 GtkIconViewItemAccessible *a11y_item;
934 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
938 icon_view = GTK_ICON_VIEW (widget);
939 icons = g_list_nth (icon_view->priv->items, index);
943 GtkIconViewItem *item = icons->data;
945 g_return_val_if_fail (item->index == index, NULL);
946 obj = gtk_icon_view_accessible_find_child (accessible, index);
949 obj = g_object_new (GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE, NULL);
950 gtk_icon_view_item_accessible_info_new (accessible, obj, index);
951 obj->role = ATK_ROLE_ICON;
952 a11y_item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
953 a11y_item->item = item;
954 a11y_item->widget = widget;
956 g_free (a11y_item->text);
957 a11y_item->text = get_text (icon_view, item);
959 gtk_icon_view_item_accessible_set_visibility (a11y_item, FALSE);
960 g_object_add_weak_pointer (G_OBJECT (widget), (gpointer) &(a11y_item->widget));
968 gtk_icon_view_accessible_traverse_items (GtkIconViewAccessible *view,
971 GtkIconViewItemAccessibleInfo *info;
972 GtkIconViewItemAccessible *item;
975 if (view->priv->items)
978 gboolean act_on_item;
980 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (view));
984 items = view->priv->items;
986 act_on_item = (list == NULL);
991 info = (GtkIconViewItemAccessibleInfo *)items->data;
992 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
994 if (act_on_item == FALSE && list == items)
998 gtk_icon_view_item_accessible_set_visibility (item, TRUE);
1000 items = items->next;
1006 _gtk_icon_view_accessible_adjustment_changed (GtkIconView *icon_view)
1008 GtkIconViewAccessible *view;
1010 view = GTK_ICON_VIEW_ACCESSIBLE (_gtk_widget_peek_accessible (GTK_WIDGET (icon_view)));
1014 gtk_icon_view_accessible_traverse_items (view, NULL);
1018 gtk_icon_view_accessible_model_row_changed (GtkTreeModel *tree_model,
1026 GtkIconView *icon_view;
1027 GtkIconViewItem *item;
1028 GtkIconViewItemAccessible *a11y_item;
1031 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
1032 index = gtk_tree_path_get_indices(path)[0];
1033 a11y_item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (
1034 gtk_icon_view_accessible_find_child (atk_obj, index));
1038 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_obj));
1039 icon_view = GTK_ICON_VIEW (widget);
1040 item = a11y_item->item;
1042 name = atk_object_get_name (ATK_OBJECT (a11y_item));
1043 if (!name || strcmp (name, "") == 0)
1045 g_free (a11y_item->text);
1046 a11y_item->text = get_text (icon_view, item);
1050 g_signal_emit_by_name (atk_obj, "visible-data-changed");
1056 gtk_icon_view_accessible_model_row_inserted (GtkTreeModel *tree_model,
1061 GtkIconViewItemAccessibleInfo *info;
1062 GtkIconViewAccessible *view;
1063 GtkIconViewItemAccessible *item;
1069 index = gtk_tree_path_get_indices(path)[0];
1070 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
1071 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
1073 items = view->priv->items;
1078 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
1079 if (info->index != item->item->index)
1081 if (info->index < index)
1082 g_warning ("Unexpected index value on insertion %d %d", index, info->index);
1084 if (tmp_list == NULL)
1087 info->index = item->item->index;
1090 items = items->next;
1092 gtk_icon_view_accessible_traverse_items (view, tmp_list);
1093 g_signal_emit_by_name (atk_obj, "children-changed::add",
1099 gtk_icon_view_accessible_model_row_deleted (GtkTreeModel *tree_model,
1103 GtkIconViewItemAccessibleInfo *info;
1104 GtkIconViewAccessible *view;
1105 GtkIconViewItemAccessible *item;
1108 GList *deleted_item;
1112 index = gtk_tree_path_get_indices(path)[0];
1113 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
1114 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
1116 items = view->priv->items;
1118 deleted_item = NULL;
1123 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
1124 if (info->index == index)
1126 deleted_item = items;
1128 if (info->index != item->item->index)
1130 if (tmp_list == NULL)
1133 info->index = item->item->index;
1136 items = items->next;
1138 gtk_icon_view_accessible_traverse_items (view, tmp_list);
1141 info = deleted_item->data;
1142 gtk_icon_view_item_accessible_add_state (GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item), ATK_STATE_DEFUNCT, TRUE);
1143 g_signal_emit_by_name (atk_obj, "children-changed::remove",
1145 view->priv->items = g_list_delete_link (view->priv->items, deleted_item);
1146 g_object_unref (info->item);
1154 gtk_icon_view_accessible_item_compare (GtkIconViewItemAccessibleInfo *i1,
1155 GtkIconViewItemAccessibleInfo *i2)
1157 return i1->index - i2->index;
1161 gtk_icon_view_accessible_model_rows_reordered (GtkTreeModel *tree_model,
1167 GtkIconViewAccessible *view;
1168 GtkIconViewItemAccessibleInfo *info;
1169 GtkIconView *icon_view;
1170 GtkIconViewItemAccessible *item;
1176 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
1177 icon_view = GTK_ICON_VIEW (user_data);
1178 view = (GtkIconViewAccessible*)atk_obj;
1180 length = gtk_tree_model_iter_n_children (tree_model, NULL);
1182 order = g_new (gint, length);
1183 for (i = 0; i < length; i++)
1184 order [new_order[i]] = i;
1186 items = view->priv->items;
1190 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
1191 info->index = order[info->index];
1192 item->item = g_list_nth_data (icon_view->priv->items, info->index);
1193 items = items->next;
1196 view->priv->items = g_list_sort (view->priv->items,
1197 (GCompareFunc)gtk_icon_view_accessible_item_compare);
1203 gtk_icon_view_accessible_disconnect_model_signals (GtkTreeModel *model,
1208 obj = G_OBJECT (model);
1209 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_changed, widget);
1210 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_inserted, widget);
1211 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_deleted, widget);
1212 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_rows_reordered, widget);
1216 gtk_icon_view_accessible_connect_model_signals (GtkIconView *icon_view)
1220 obj = G_OBJECT (icon_view->priv->model);
1221 g_signal_connect_data (obj, "row-changed",
1222 (GCallback) gtk_icon_view_accessible_model_row_changed,
1223 icon_view, NULL, 0);
1224 g_signal_connect_data (obj, "row-inserted",
1225 (GCallback) gtk_icon_view_accessible_model_row_inserted,
1226 icon_view, NULL, G_CONNECT_AFTER);
1227 g_signal_connect_data (obj, "row-deleted",
1228 (GCallback) gtk_icon_view_accessible_model_row_deleted,
1229 icon_view, NULL, G_CONNECT_AFTER);
1230 g_signal_connect_data (obj, "rows-reordered",
1231 (GCallback) gtk_icon_view_accessible_model_rows_reordered,
1232 icon_view, NULL, G_CONNECT_AFTER);
1236 gtk_icon_view_accessible_clear_cache (GtkIconViewAccessible *view)
1238 GtkIconViewItemAccessibleInfo *info;
1241 items = view->priv->items;
1244 info = (GtkIconViewItemAccessibleInfo *) items->data;
1245 gtk_icon_view_item_accessible_add_state (GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item), ATK_STATE_DEFUNCT, TRUE);
1246 g_object_unref (info->item);
1247 g_free (items->data);
1248 items = items->next;
1250 g_list_free (view->priv->items);
1251 view->priv->items = NULL;
1255 gtk_icon_view_accessible_notify_gtk (GObject *obj,
1258 GtkIconView *icon_view;
1261 GtkIconViewAccessible *view;
1263 if (strcmp (pspec->name, "model") == 0)
1265 widget = GTK_WIDGET (obj);
1266 atk_obj = gtk_widget_get_accessible (widget);
1267 view = (GtkIconViewAccessible*)atk_obj;
1268 if (view->priv->model)
1270 g_object_remove_weak_pointer (G_OBJECT (view->priv->model),
1271 (gpointer *)&view->priv->model);
1272 gtk_icon_view_accessible_disconnect_model_signals (view->priv->model, widget);
1274 gtk_icon_view_accessible_clear_cache (view);
1276 icon_view = GTK_ICON_VIEW (obj);
1277 view->priv->model = icon_view->priv->model;
1278 /* If there is no model the GtkIconView is probably being destroyed */
1279 if (view->priv->model)
1281 g_object_add_weak_pointer (G_OBJECT (view->priv->model), (gpointer *)&view->priv->model);
1282 gtk_icon_view_accessible_connect_model_signals (icon_view);
1290 gtk_icon_view_accessible_initialize (AtkObject *accessible,
1293 GtkIconViewAccessible *view;
1294 GtkIconView *icon_view;
1296 if (ATK_OBJECT_CLASS (gtk_icon_view_accessible_parent_class)->initialize)
1297 ATK_OBJECT_CLASS (gtk_icon_view_accessible_parent_class)->initialize (accessible, data);
1299 icon_view = (GtkIconView*)data;
1300 view = (GtkIconViewAccessible*)accessible;
1302 g_signal_connect (data, "notify",
1303 G_CALLBACK (gtk_icon_view_accessible_notify_gtk), NULL);
1305 view->priv->model = icon_view->priv->model;
1306 if (view->priv->model)
1308 g_object_add_weak_pointer (G_OBJECT (view->priv->model), (gpointer *)&view->priv->model);
1309 gtk_icon_view_accessible_connect_model_signals (icon_view);
1312 accessible->role = ATK_ROLE_LAYERED_PANE;
1316 gtk_icon_view_accessible_finalize (GObject *object)
1318 GtkIconViewAccessible *view = (GtkIconViewAccessible*)object;
1320 gtk_icon_view_accessible_clear_cache (view);
1322 G_OBJECT_CLASS (gtk_icon_view_accessible_parent_class)->finalize (object);
1326 gtk_icon_view_accessible_class_init (GtkIconViewAccessibleClass *klass)
1328 GObjectClass *gobject_class;
1329 AtkObjectClass *atk_class;
1331 gobject_class = (GObjectClass *)klass;
1332 atk_class = (AtkObjectClass *)klass;
1334 gobject_class->finalize = gtk_icon_view_accessible_finalize;
1336 atk_class->get_n_children = gtk_icon_view_accessible_get_n_children;
1337 atk_class->ref_child = gtk_icon_view_accessible_ref_child;
1338 atk_class->initialize = gtk_icon_view_accessible_initialize;
1340 g_type_class_add_private (klass, sizeof (GtkIconViewAccessiblePrivate));
1344 gtk_icon_view_accessible_init (GtkIconViewAccessible *accessible)
1346 accessible->priv = G_TYPE_INSTANCE_GET_PRIVATE (accessible,
1347 GTK_TYPE_ICON_VIEW_ACCESSIBLE,
1348 GtkIconViewAccessiblePrivate);
1352 gtk_icon_view_accessible_ref_accessible_at_point (AtkComponent *component,
1355 AtkCoordType coord_type)
1358 GtkIconView *icon_view;
1359 GtkIconViewItem *item;
1362 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
1366 icon_view = GTK_ICON_VIEW (widget);
1367 atk_component_get_extents (component, &x_pos, &y_pos, NULL, NULL, coord_type);
1368 item = _gtk_icon_view_get_item_at_coords (icon_view, x - x_pos, y - y_pos, TRUE, NULL);
1370 return gtk_icon_view_accessible_ref_child (ATK_OBJECT (component), item->index);
1376 atk_component_interface_init (AtkComponentIface *iface)
1378 iface->ref_accessible_at_point = gtk_icon_view_accessible_ref_accessible_at_point;
1382 gtk_icon_view_accessible_add_selection (AtkSelection *selection,
1386 GtkIconView *icon_view;
1387 GtkIconViewItem *item;
1389 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1393 icon_view = GTK_ICON_VIEW (widget);
1395 item = g_list_nth_data (icon_view->priv->items, i);
1399 _gtk_icon_view_select_item (icon_view, item);
1405 gtk_icon_view_accessible_clear_selection (AtkSelection *selection)
1408 GtkIconView *icon_view;
1410 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1414 icon_view = GTK_ICON_VIEW (widget);
1415 gtk_icon_view_unselect_all (icon_view);
1421 gtk_icon_view_accessible_ref_selection (AtkSelection *selection,
1426 GtkIconView *icon_view;
1427 GtkIconViewItem *item;
1429 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1433 icon_view = GTK_ICON_VIEW (widget);
1435 l = icon_view->priv->items;
1442 return atk_object_ref_accessible_child (gtk_widget_get_accessible (widget), item->index);
1453 gtk_icon_view_accessible_get_selection_count (AtkSelection *selection)
1456 GtkIconView *icon_view;
1457 GtkIconViewItem *item;
1461 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1465 icon_view = GTK_ICON_VIEW (widget);
1467 l = icon_view->priv->items;
1483 gtk_icon_view_accessible_is_child_selected (AtkSelection *selection,
1487 GtkIconView *icon_view;
1488 GtkIconViewItem *item;
1490 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1494 icon_view = GTK_ICON_VIEW (widget);
1496 item = g_list_nth_data (icon_view->priv->items, i);
1500 return item->selected;
1504 gtk_icon_view_accessible_remove_selection (AtkSelection *selection,
1508 GtkIconView *icon_view;
1509 GtkIconViewItem *item;
1513 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1517 icon_view = GTK_ICON_VIEW (widget);
1518 l = icon_view->priv->items;
1527 _gtk_icon_view_unselect_item (icon_view, item);
1539 gtk_icon_view_accessible_select_all_selection (AtkSelection *selection)
1542 GtkIconView *icon_view;
1544 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1548 icon_view = GTK_ICON_VIEW (widget);
1549 gtk_icon_view_select_all (icon_view);
1554 atk_selection_interface_init (AtkSelectionIface *iface)
1556 iface->add_selection = gtk_icon_view_accessible_add_selection;
1557 iface->clear_selection = gtk_icon_view_accessible_clear_selection;
1558 iface->ref_selection = gtk_icon_view_accessible_ref_selection;
1559 iface->get_selection_count = gtk_icon_view_accessible_get_selection_count;
1560 iface->is_child_selected = gtk_icon_view_accessible_is_child_selected;
1561 iface->remove_selection = gtk_icon_view_accessible_remove_selection;
1562 iface->select_all_selection = gtk_icon_view_accessible_select_all_selection;