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 "gtkiconviewaccessible.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))
39 GtkIconViewItem *item;
41 AtkStateSet *state_set;
43 gchar *action_description;
44 gchar *image_description;
45 guint action_idle_handler;
46 } GtkIconViewItemAccessible;
50 AtkObjectClass parent_class;
52 } GtkIconViewItemAccessibleClass;
54 static gboolean gtk_icon_view_item_accessible_is_showing (GtkIconViewItemAccessible *item);
56 static void atk_component_item_interface_init (AtkComponentIface *iface);
57 static void atk_action_item_interface_init (AtkActionIface *iface);
58 static void atk_text_item_interface_init (AtkTextIface *iface);
59 static void atk_image_item_interface_init (AtkImageIface *iface);
61 G_DEFINE_TYPE_WITH_CODE (GtkIconViewItemAccessible, _gtk_icon_view_item_accessible, ATK_TYPE_OBJECT,
62 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_item_interface_init)
63 G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_item_interface_init)
64 G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_item_interface_init)
65 G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_item_interface_init))
69 idle_do_action (gpointer data)
71 GtkIconViewItemAccessible *item;
72 GtkIconView *icon_view;
75 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (data);
76 item->action_idle_handler = 0;
78 if (item->widget != NULL)
80 icon_view = GTK_ICON_VIEW (item->widget);
81 path = gtk_tree_path_new_from_indices (item->item->index, -1);
82 gtk_icon_view_item_activated (icon_view, path);
83 gtk_tree_path_free (path);
90 gtk_icon_view_item_accessible_do_action (AtkAction *action,
93 GtkIconViewItemAccessible *item;
98 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
100 if (!GTK_IS_ICON_VIEW (item->widget))
103 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
106 if (!item->action_idle_handler)
107 item->action_idle_handler = gdk_threads_add_idle (idle_do_action, item);
113 gtk_icon_view_item_accessible_get_n_actions (AtkAction *action)
119 gtk_icon_view_item_accessible_get_description (AtkAction *action,
122 GtkIconViewItemAccessible *item;
127 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
129 if (item->action_description)
130 return item->action_description;
132 return "Activate item";
136 gtk_icon_view_item_accessible_get_name (AtkAction *action,
146 gtk_icon_view_item_accessible_set_description (AtkAction *action,
148 const gchar *description)
150 GtkIconViewItemAccessible *item;
155 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
157 g_free (item->action_description);
158 item->action_description = g_strdup (description);
164 atk_action_item_interface_init (AtkActionIface *iface)
166 iface->do_action = gtk_icon_view_item_accessible_do_action;
167 iface->set_description = gtk_icon_view_item_accessible_set_description;
168 iface->get_name = gtk_icon_view_item_accessible_get_name;
169 iface->get_n_actions = gtk_icon_view_item_accessible_get_n_actions;
170 iface->get_description = gtk_icon_view_item_accessible_get_description;
174 gtk_icon_view_item_accessible_get_image_description (AtkImage *image)
176 GtkIconViewItemAccessible *item;
178 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
180 return item->image_description;
184 gtk_icon_view_item_accessible_set_image_description (AtkImage *image,
185 const gchar *description)
187 GtkIconViewItemAccessible *item;
189 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
191 g_free (item->image_description);
192 item->image_description = g_strdup (description);
199 gboolean pixbuf_found;
203 get_pixbuf_foreach (GtkCellRenderer *renderer,
204 const GdkRectangle *cell_area,
205 const GdkRectangle *cell_background,
206 GetPixbufBoxData *data)
208 if (GTK_IS_CELL_RENDERER_PIXBUF (renderer))
210 data->box = *cell_area;
211 data->pixbuf_found = TRUE;
213 return (data->pixbuf_found != FALSE);
217 get_pixbuf_box (GtkIconView *icon_view,
218 GtkIconViewItem *item,
221 GetPixbufBoxData data = { { 0, }, FALSE };
222 GtkCellAreaContext *context;
224 context = g_ptr_array_index (icon_view->priv->row_contexts, item->row);
226 _gtk_icon_view_set_cell_data (icon_view, item);
227 gtk_cell_area_foreach_alloc (icon_view->priv->cell_area, context,
228 GTK_WIDGET (icon_view),
229 (GdkRectangle *)item, (GdkRectangle *)item,
230 (GtkCellAllocCallback)get_pixbuf_foreach, &data);
232 return data.pixbuf_found;
236 get_text_foreach (GtkCellRenderer *renderer,
239 if (GTK_IS_CELL_RENDERER_TEXT (renderer))
241 g_object_get (renderer, "text", text, NULL);
248 get_text (GtkIconView *icon_view,
249 GtkIconViewItem *item)
253 _gtk_icon_view_set_cell_data (icon_view, item);
254 gtk_cell_area_foreach (icon_view->priv->cell_area,
255 (GtkCellCallback)get_text_foreach, &text);
261 gtk_icon_view_item_accessible_get_image_size (AtkImage *image,
265 GtkIconViewItemAccessible *item;
268 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
270 if (!GTK_IS_ICON_VIEW (item->widget))
273 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
279 if (get_pixbuf_box (GTK_ICON_VIEW (item->widget), item->item, &box))
282 *height = box.height;
287 gtk_icon_view_item_accessible_get_image_position (AtkImage *image,
290 AtkCoordType coord_type)
292 GtkIconViewItemAccessible *item;
295 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
297 if (!GTK_IS_ICON_VIEW (item->widget))
300 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
303 atk_component_get_position (ATK_COMPONENT (image), x, y, coord_type);
305 if (get_pixbuf_box (GTK_ICON_VIEW (item->widget), item->item, &box))
307 *x+= box.x - item->item->cell_area.x;
308 *y+= box.y - item->item->cell_area.y;
314 atk_image_item_interface_init (AtkImageIface *iface)
316 iface->get_image_description = gtk_icon_view_item_accessible_get_image_description;
317 iface->set_image_description = gtk_icon_view_item_accessible_set_image_description;
318 iface->get_image_size = gtk_icon_view_item_accessible_get_image_size;
319 iface->get_image_position = gtk_icon_view_item_accessible_get_image_position;
323 gtk_icon_view_item_accessible_get_text (AtkText *text,
327 GtkIconViewItemAccessible *item;
329 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
330 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
334 return g_utf8_substring (item->text, start_pos, end_pos > -1 ? end_pos : g_utf8_strlen (item->text, -1));
336 return g_strdup ("");
340 gtk_icon_view_item_accessible_get_character_at_offset (AtkText *text,
343 GtkIconViewItemAccessible *item;
347 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
348 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
356 if (offset >= g_utf8_strlen (string, -1))
359 index = g_utf8_offset_to_pointer (string, offset);
361 return g_utf8_get_char (index);
365 create_pango_layout (GtkIconViewItemAccessible *item)
369 layout = gtk_widget_create_pango_layout (item->widget, item->text);
375 gtk_icon_view_item_accessible_get_text_before_offset (AtkText *atk_text,
377 AtkTextBoundary boundary_type,
381 GtkIconViewItemAccessible *item;
385 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (atk_text);
386 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
389 layout = create_pango_layout (item);
390 text = _gtk_pango_get_text_before (layout, boundary_type, offset, start_offset, end_offset);
391 g_object_unref (layout);
397 gtk_icon_view_item_accessible_get_text_at_offset (AtkText *atk_text,
399 AtkTextBoundary boundary_type,
403 GtkIconViewItemAccessible *item;
407 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (atk_text);
408 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
411 layout = create_pango_layout (item);
412 text = _gtk_pango_get_text_at (layout, boundary_type, offset, start_offset, end_offset);
413 g_object_unref (layout);
419 gtk_icon_view_item_accessible_get_text_after_offset (AtkText *atk_text,
421 AtkTextBoundary boundary_type,
425 GtkIconViewItemAccessible *item;
429 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (atk_text);
430 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
433 layout = create_pango_layout (item);
434 text = _gtk_pango_get_text_after (layout, boundary_type, offset, start_offset, end_offset);
435 g_object_unref (layout);
441 gtk_icon_view_item_accessible_get_character_count (AtkText *text)
443 GtkIconViewItemAccessible *item;
445 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
446 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
450 return g_utf8_strlen (item->text, -1);
456 gtk_icon_view_item_accessible_get_character_extents (AtkText *text,
462 AtkCoordType coord_type)
464 GtkIconViewItemAccessible *item;
466 GtkIconView *icon_view;
467 PangoRectangle char_rect;
468 const gchar *item_text;
472 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
474 if (!GTK_IS_ICON_VIEW (item->widget))
477 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
481 icon_view = GTK_ICON_VIEW (item->widget);
482 /* FIXME we probably have to use GailTextCell to salvage this */
483 gtk_icon_view_update_item_text (icon_view, item->item);
484 item_text = pango_layout_get_text (icon_view->priv->layout);
485 index = g_utf8_offset_to_pointer (item_text, offset) - item_text;
486 pango_layout_index_to_pos (icon_view->priv->layout, index, &char_rect);
488 atk_component_get_position (ATK_COMPONENT (text), x, y, coord_type);
489 *x += item->item->layout_x - item->item->x + char_rect.x / PANGO_SCALE;
490 /* Look at gtk_icon_view_paint_item() to see where the text is. */
491 *x -= ((item->item->width - item->item->layout_width) / 2) + (MAX (item->item->pixbuf_width, icon_view->priv->item_width) - item->item->width) / 2,
492 *y += item->item->layout_y - item->item->y + char_rect.y / PANGO_SCALE;
493 *width = char_rect.width / PANGO_SCALE;
494 *height = char_rect.height / PANGO_SCALE;
499 gtk_icon_view_item_accessible_get_offset_at_point (AtkText *text,
502 AtkCoordType coord_type)
504 GtkIconViewItemAccessible *item;
507 GtkIconView *icon_view;
508 const gchar *item_text;
513 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
515 if (!GTK_IS_ICON_VIEW (item->widget))
518 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
522 icon_view = GTK_ICON_VIEW (item->widget);
523 /* FIXME we probably have to use GailTextCell to salvage this */
524 gtk_icon_view_update_item_text (icon_view, item->item);
525 atk_component_get_position (ATK_COMPONENT (text), &l_x, &l_y, coord_type);
526 x -= l_x + item->item->layout_x - item->item->x;
527 x += ((item->item->width - item->item->layout_width) / 2) + (MAX (item->item->pixbuf_width, icon_view->priv->item_width) - item->item->width) / 2,
528 y -= l_y + item->item->layout_y - item->item->y;
529 item_text = pango_layout_get_text (icon_view->priv->layout);
530 if (!pango_layout_xy_to_index (icon_view->priv->layout,
541 offset = g_utf8_strlen (item_text, -1);
543 offset = g_utf8_pointer_to_offset (item_text, item_text + index);
549 atk_text_item_interface_init (AtkTextIface *iface)
551 iface->get_text = gtk_icon_view_item_accessible_get_text;
552 iface->get_character_at_offset = gtk_icon_view_item_accessible_get_character_at_offset;
553 iface->get_text_before_offset = gtk_icon_view_item_accessible_get_text_before_offset;
554 iface->get_text_at_offset = gtk_icon_view_item_accessible_get_text_at_offset;
555 iface->get_text_after_offset = gtk_icon_view_item_accessible_get_text_after_offset;
556 iface->get_character_count = gtk_icon_view_item_accessible_get_character_count;
557 iface->get_character_extents = gtk_icon_view_item_accessible_get_character_extents;
558 iface->get_offset_at_point = gtk_icon_view_item_accessible_get_offset_at_point;
562 gtk_icon_view_item_accessible_get_extents (AtkComponent *component,
567 AtkCoordType coord_type)
569 GtkIconViewItemAccessible *item;
570 AtkObject *parent_obj;
573 g_return_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component));
575 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (component);
576 if (!GTK_IS_WIDGET (item->widget))
579 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
582 *width = item->item->cell_area.width;
583 *height = item->item->cell_area.height;
584 if (gtk_icon_view_item_accessible_is_showing (item))
586 parent_obj = gtk_widget_get_accessible (item->widget);
587 atk_component_get_position (ATK_COMPONENT (parent_obj), &l_x, &l_y, coord_type);
588 *x = l_x + item->item->cell_area.x;
589 *y = l_y + item->item->cell_area.y;
599 gtk_icon_view_item_accessible_grab_focus (AtkComponent *component)
601 GtkIconViewItemAccessible *item;
604 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component), FALSE);
606 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (component);
607 if (!GTK_IS_WIDGET (item->widget))
610 gtk_widget_grab_focus (item->widget);
611 _gtk_icon_view_set_cursor_item (GTK_ICON_VIEW (item->widget), item->item, NULL);
612 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item->widget));
613 if (gtk_widget_is_toplevel (toplevel))
614 gtk_window_present (GTK_WINDOW (toplevel));
620 atk_component_item_interface_init (AtkComponentIface *iface)
622 iface->get_extents = gtk_icon_view_item_accessible_get_extents;
623 iface->grab_focus = gtk_icon_view_item_accessible_grab_focus;
627 gtk_icon_view_item_accessible_add_state (GtkIconViewItemAccessible *item,
628 AtkStateType state_type,
629 gboolean emit_signal)
633 rc = atk_state_set_add_state (item->state_set, state_type);
635 /* The signal should only be generated if the value changed,
636 * not when the item is set up. So states that are set
637 * initially should pass FALSE as the emit_signal argument.
641 atk_object_notify_state_change (ATK_OBJECT (item), state_type, TRUE);
642 /* If state_type is ATK_STATE_VISIBLE, additional notification */
643 if (state_type == ATK_STATE_VISIBLE)
644 g_signal_emit_by_name (item, "visible-data-changed");
651 gtk_icon_view_item_accessible_remove_state (GtkIconViewItemAccessible *item,
652 AtkStateType state_type,
653 gboolean emit_signal)
655 if (atk_state_set_contains_state (item->state_set, state_type))
659 rc = atk_state_set_remove_state (item->state_set, state_type);
661 /* The signal should only be generated if the value changed,
662 * not when the item is set up. So states that are set
663 * initially should pass FALSE as the emit_signal argument.
667 atk_object_notify_state_change (ATK_OBJECT (item), state_type, FALSE);
668 /* If state_type is ATK_STATE_VISIBLE, additional notification */
669 if (state_type == ATK_STATE_VISIBLE)
670 g_signal_emit_by_name (item, "visible-data-changed");
680 gtk_icon_view_item_accessible_is_showing (GtkIconViewItemAccessible *item)
682 GtkAllocation allocation;
683 GtkIconView *icon_view;
684 GdkRectangle visible_rect;
687 /* An item is considered "SHOWING" if any part of the item
688 * is in the visible rectangle.
690 if (!GTK_IS_ICON_VIEW (item->widget))
693 if (item->item == NULL)
696 gtk_widget_get_allocation (item->widget, &allocation);
698 icon_view = GTK_ICON_VIEW (item->widget);
700 if (icon_view->priv->hadjustment)
701 visible_rect.x += gtk_adjustment_get_value (icon_view->priv->hadjustment);
703 if (icon_view->priv->hadjustment)
704 visible_rect.y += gtk_adjustment_get_value (icon_view->priv->vadjustment);
705 visible_rect.width = allocation.width;
706 visible_rect.height = allocation.height;
708 if (((item->item->cell_area.x + item->item->cell_area.width) < visible_rect.x) ||
709 ((item->item->cell_area.y + item->item->cell_area.height) < (visible_rect.y)) ||
710 (item->item->cell_area.x > (visible_rect.x + visible_rect.width)) ||
711 (item->item->cell_area.y > (visible_rect.y + visible_rect.height)))
720 gtk_icon_view_item_accessible_set_visibility (GtkIconViewItemAccessible *item,
721 gboolean emit_signal)
723 if (gtk_icon_view_item_accessible_is_showing (item))
724 return gtk_icon_view_item_accessible_add_state (item, ATK_STATE_SHOWING,
727 return gtk_icon_view_item_accessible_remove_state (item, ATK_STATE_SHOWING,
732 _gtk_icon_view_item_accessible_init (GtkIconViewItemAccessible *item)
734 item->state_set = atk_state_set_new ();
736 atk_state_set_add_state (item->state_set, ATK_STATE_ENABLED);
737 atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSABLE);
738 atk_state_set_add_state (item->state_set, ATK_STATE_SENSITIVE);
739 atk_state_set_add_state (item->state_set, ATK_STATE_SELECTABLE);
740 atk_state_set_add_state (item->state_set, ATK_STATE_VISIBLE);
742 item->action_description = NULL;
743 item->image_description = NULL;
745 item->action_idle_handler = 0;
749 gtk_icon_view_item_accessible_finalize (GObject *object)
751 GtkIconViewItemAccessible *item;
753 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (object);
756 g_object_remove_weak_pointer (G_OBJECT (item->widget), (gpointer) &item->widget);
759 g_object_unref (item->state_set);
763 g_free (item->action_description);
764 g_free (item->image_description);
766 if (item->action_idle_handler)
768 g_source_remove (item->action_idle_handler);
769 item->action_idle_handler = 0;
772 G_OBJECT_CLASS (_gtk_icon_view_item_accessible_parent_class)->finalize (object);
776 gtk_icon_view_item_accessible_get_parent (AtkObject *obj)
778 GtkIconViewItemAccessible *item;
780 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (obj), NULL);
781 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
784 return gtk_widget_get_accessible (item->widget);
790 gtk_icon_view_item_accessible_get_index_in_parent (AtkObject *obj)
792 GtkIconViewItemAccessible *item;
794 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (obj), 0);
795 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
797 return item->item->index;
801 gtk_icon_view_item_accessible_ref_state_set (AtkObject *obj)
803 GtkIconViewItemAccessible *item;
804 GtkIconView *icon_view;
806 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
807 g_return_val_if_fail (item->state_set, NULL);
812 icon_view = GTK_ICON_VIEW (item->widget);
813 if (icon_view->priv->cursor_item == item->item)
814 atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSED);
816 atk_state_set_remove_state (item->state_set, ATK_STATE_FOCUSED);
817 if (item->item->selected)
818 atk_state_set_add_state (item->state_set, ATK_STATE_SELECTED);
820 atk_state_set_remove_state (item->state_set, ATK_STATE_SELECTED);
822 return g_object_ref (item->state_set);
826 _gtk_icon_view_item_accessible_class_init (GtkIconViewItemAccessibleClass *klass)
828 GObjectClass *gobject_class;
829 AtkObjectClass *atk_class;
831 gobject_class = (GObjectClass *)klass;
832 atk_class = (AtkObjectClass *)klass;
834 gobject_class->finalize = gtk_icon_view_item_accessible_finalize;
836 atk_class->get_index_in_parent = gtk_icon_view_item_accessible_get_index_in_parent;
837 atk_class->get_parent = gtk_icon_view_item_accessible_get_parent;
838 atk_class->ref_state_set = gtk_icon_view_item_accessible_ref_state_set;
841 static void atk_component_interface_init (AtkComponentIface *iface);
842 static void atk_selection_interface_init (AtkSelectionIface *iface);
844 G_DEFINE_TYPE_WITH_CODE (GtkIconViewAccessible, _gtk_icon_view_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
845 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)
846 G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
852 } GtkIconViewItemAccessibleInfo;
856 gtk_icon_view_item_accessible_info_new (AtkObject *accessible,
860 GtkIconViewAccessible *view = (GtkIconViewAccessible *)accessible;
861 GtkIconViewItemAccessibleInfo *info;
862 GtkIconViewItemAccessibleInfo *tmp_info;
865 info = g_new (GtkIconViewItemAccessibleInfo, 1);
872 tmp_info = items->data;
873 if (tmp_info->index > index)
877 view->items = g_list_insert_before (view->items, items, info);
881 gtk_icon_view_accessible_get_n_children (AtkObject *accessible)
883 GtkIconView *icon_view;
886 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
890 icon_view = GTK_ICON_VIEW (widget);
892 return g_list_length (icon_view->priv->items);
896 gtk_icon_view_accessible_find_child (AtkObject *accessible,
899 GtkIconViewAccessible *view = (GtkIconViewAccessible*)accessible;
900 GtkIconViewItemAccessibleInfo *info;
908 if (info->index == index)
917 gtk_icon_view_accessible_ref_child (AtkObject *accessible,
920 GtkIconView *icon_view;
924 GtkIconViewItemAccessible *a11y_item;
926 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
930 icon_view = GTK_ICON_VIEW (widget);
931 icons = g_list_nth (icon_view->priv->items, index);
935 GtkIconViewItem *item = icons->data;
937 g_return_val_if_fail (item->index == index, NULL);
938 obj = gtk_icon_view_accessible_find_child (accessible, index);
941 obj = g_object_new (GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE, NULL);
942 gtk_icon_view_item_accessible_info_new (accessible, obj, index);
943 obj->role = ATK_ROLE_ICON;
944 a11y_item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
945 a11y_item->item = item;
946 a11y_item->widget = widget;
948 g_free (a11y_item->text);
949 a11y_item->text = get_text (icon_view, item);
951 gtk_icon_view_item_accessible_set_visibility (a11y_item, FALSE);
952 g_object_add_weak_pointer (G_OBJECT (widget), (gpointer) &(a11y_item->widget));
960 gtk_icon_view_accessible_traverse_items (GtkIconViewAccessible *view,
963 GtkIconViewItemAccessibleInfo *info;
964 GtkIconViewItemAccessible *item;
970 gboolean act_on_item;
972 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (view));
978 act_on_item = (list == NULL);
983 info = (GtkIconViewItemAccessibleInfo *)items->data;
984 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
986 if (act_on_item == FALSE && list == items)
990 gtk_icon_view_item_accessible_set_visibility (item, TRUE);
998 _gtk_icon_view_accessible_adjustment_changed (GtkIconView *icon_view)
1000 GtkIconViewAccessible *view;
1002 view = GTK_ICON_VIEW_ACCESSIBLE (_gtk_widget_peek_accessible (GTK_WIDGET (icon_view)));
1006 gtk_icon_view_accessible_traverse_items (view, NULL);
1010 gtk_icon_view_accessible_model_row_changed (GtkTreeModel *tree_model,
1018 GtkIconView *icon_view;
1019 GtkIconViewItem *item;
1020 GtkIconViewItemAccessible *a11y_item;
1023 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
1024 index = gtk_tree_path_get_indices(path)[0];
1025 a11y_item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (
1026 gtk_icon_view_accessible_find_child (atk_obj, index));
1030 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_obj));
1031 icon_view = GTK_ICON_VIEW (widget);
1032 item = a11y_item->item;
1034 name = atk_object_get_name (ATK_OBJECT (a11y_item));
1035 if (!name || strcmp (name, "") == 0)
1037 g_free (a11y_item->text);
1038 a11y_item->text = get_text (icon_view, item);
1042 g_signal_emit_by_name (atk_obj, "visible-data-changed");
1048 gtk_icon_view_accessible_model_row_inserted (GtkTreeModel *tree_model,
1053 GtkIconViewItemAccessibleInfo *info;
1054 GtkIconViewAccessible *view;
1055 GtkIconViewItemAccessible *item;
1061 index = gtk_tree_path_get_indices(path)[0];
1062 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
1063 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
1065 items = view->items;
1070 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
1071 if (info->index != item->item->index)
1073 if (info->index < index)
1074 g_warning ("Unexpected index value on insertion %d %d", index, info->index);
1076 if (tmp_list == NULL)
1079 info->index = item->item->index;
1082 items = items->next;
1084 gtk_icon_view_accessible_traverse_items (view, tmp_list);
1085 g_signal_emit_by_name (atk_obj, "children-changed::add",
1091 gtk_icon_view_accessible_model_row_deleted (GtkTreeModel *tree_model,
1095 GtkIconViewItemAccessibleInfo *info;
1096 GtkIconViewAccessible *view;
1097 GtkIconViewItemAccessible *item;
1100 GList *deleted_item;
1104 index = gtk_tree_path_get_indices(path)[0];
1105 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
1106 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
1108 items = view->items;
1110 deleted_item = NULL;
1115 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
1116 if (info->index == index)
1118 deleted_item = items;
1120 if (info->index != item->item->index)
1122 if (tmp_list == NULL)
1125 info->index = item->item->index;
1128 items = items->next;
1130 gtk_icon_view_accessible_traverse_items (view, tmp_list);
1133 info = deleted_item->data;
1134 gtk_icon_view_item_accessible_add_state (GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item), ATK_STATE_DEFUNCT, TRUE);
1135 g_signal_emit_by_name (atk_obj, "children-changed::remove",
1137 view->items = g_list_remove_link (view->items, deleted_item);
1145 gtk_icon_view_accessible_item_compare (GtkIconViewItemAccessibleInfo *i1,
1146 GtkIconViewItemAccessibleInfo *i2)
1148 return i1->index - i2->index;
1152 gtk_icon_view_accessible_model_rows_reordered (GtkTreeModel *tree_model,
1158 GtkIconViewAccessible *view;
1159 GtkIconViewItemAccessibleInfo *info;
1160 GtkIconView *icon_view;
1161 GtkIconViewItemAccessible *item;
1167 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
1168 icon_view = GTK_ICON_VIEW (user_data);
1169 view = (GtkIconViewAccessible*)atk_obj;
1171 length = gtk_tree_model_iter_n_children (tree_model, NULL);
1173 order = g_new (gint, length);
1174 for (i = 0; i < length; i++)
1175 order [new_order[i]] = i;
1177 items = view->items;
1181 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
1182 info->index = order[info->index];
1183 item->item = g_list_nth_data (icon_view->priv->items, info->index);
1184 items = items->next;
1187 view->items = g_list_sort (view->items,
1188 (GCompareFunc)gtk_icon_view_accessible_item_compare);
1194 gtk_icon_view_accessible_disconnect_model_signals (GtkTreeModel *model,
1199 obj = G_OBJECT (model);
1200 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_changed, widget);
1201 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_inserted, widget);
1202 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_deleted, widget);
1203 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_rows_reordered, widget);
1207 gtk_icon_view_accessible_connect_model_signals (GtkIconView *icon_view)
1211 obj = G_OBJECT (icon_view->priv->model);
1212 g_signal_connect_data (obj, "row-changed",
1213 (GCallback) gtk_icon_view_accessible_model_row_changed,
1214 icon_view, NULL, 0);
1215 g_signal_connect_data (obj, "row-inserted",
1216 (GCallback) gtk_icon_view_accessible_model_row_inserted,
1217 icon_view, NULL, G_CONNECT_AFTER);
1218 g_signal_connect_data (obj, "row-deleted",
1219 (GCallback) gtk_icon_view_accessible_model_row_deleted,
1220 icon_view, NULL, G_CONNECT_AFTER);
1221 g_signal_connect_data (obj, "rows-reordered",
1222 (GCallback) gtk_icon_view_accessible_model_rows_reordered,
1223 icon_view, NULL, G_CONNECT_AFTER);
1227 gtk_icon_view_accessible_clear_cache (GtkIconViewAccessible *view)
1229 GtkIconViewItemAccessibleInfo *info;
1232 items = view->items;
1235 info = (GtkIconViewItemAccessibleInfo *) items->data;
1236 g_object_unref (info->item);
1237 g_free (items->data);
1238 items = items->next;
1240 g_list_free (view->items);
1245 gtk_icon_view_accessible_notify_gtk (GObject *obj,
1248 GtkIconView *icon_view;
1251 GtkIconViewAccessible *view;
1253 if (strcmp (pspec->name, "model") == 0)
1255 widget = GTK_WIDGET (obj);
1256 atk_obj = gtk_widget_get_accessible (widget);
1257 view = (GtkIconViewAccessible*)atk_obj;
1260 g_object_remove_weak_pointer (G_OBJECT (view->model),
1261 (gpointer *)&view->model);
1262 gtk_icon_view_accessible_disconnect_model_signals (view->model, widget);
1264 gtk_icon_view_accessible_clear_cache (view);
1266 icon_view = GTK_ICON_VIEW (obj);
1267 view->model = icon_view->priv->model;
1268 /* If there is no model the GtkIconView is probably being destroyed */
1271 g_object_add_weak_pointer (G_OBJECT (view->model), (gpointer *)&view->model);
1272 gtk_icon_view_accessible_connect_model_signals (icon_view);
1280 gtk_icon_view_accessible_initialize (AtkObject *accessible,
1283 GtkIconViewAccessible *view;
1284 GtkIconView *icon_view;
1286 if (ATK_OBJECT_CLASS (_gtk_icon_view_accessible_parent_class)->initialize)
1287 ATK_OBJECT_CLASS (_gtk_icon_view_accessible_parent_class)->initialize (accessible, data);
1289 icon_view = (GtkIconView*)data;
1290 view = (GtkIconViewAccessible*)accessible;
1292 g_signal_connect (data, "notify",
1293 G_CALLBACK (gtk_icon_view_accessible_notify_gtk), NULL);
1295 view->model = icon_view->priv->model;
1298 g_object_add_weak_pointer (G_OBJECT (view->model), (gpointer *)&view->model);
1299 gtk_icon_view_accessible_connect_model_signals (icon_view);
1302 accessible->role = ATK_ROLE_LAYERED_PANE;
1306 gtk_icon_view_accessible_finalize (GObject *object)
1308 GtkIconViewAccessible *view = (GtkIconViewAccessible*)object;
1310 gtk_icon_view_accessible_clear_cache (view);
1312 G_OBJECT_CLASS (_gtk_icon_view_accessible_parent_class)->finalize (object);
1316 _gtk_icon_view_accessible_class_init (GtkIconViewAccessibleClass *klass)
1318 GObjectClass *gobject_class;
1319 AtkObjectClass *atk_class;
1321 gobject_class = (GObjectClass *)klass;
1322 atk_class = (AtkObjectClass *)klass;
1324 gobject_class->finalize = gtk_icon_view_accessible_finalize;
1326 atk_class->get_n_children = gtk_icon_view_accessible_get_n_children;
1327 atk_class->ref_child = gtk_icon_view_accessible_ref_child;
1328 atk_class->initialize = gtk_icon_view_accessible_initialize;
1332 _gtk_icon_view_accessible_init (GtkIconViewAccessible *accessible)
1337 gtk_icon_view_accessible_ref_accessible_at_point (AtkComponent *component,
1340 AtkCoordType coord_type)
1343 GtkIconView *icon_view;
1344 GtkIconViewItem *item;
1347 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
1351 icon_view = GTK_ICON_VIEW (widget);
1352 atk_component_get_extents (component, &x_pos, &y_pos, NULL, NULL, coord_type);
1353 item = _gtk_icon_view_get_item_at_coords (icon_view, x - x_pos, y - y_pos, TRUE, NULL);
1355 return gtk_icon_view_accessible_ref_child (ATK_OBJECT (component), item->index);
1361 atk_component_interface_init (AtkComponentIface *iface)
1363 iface->ref_accessible_at_point = gtk_icon_view_accessible_ref_accessible_at_point;
1367 gtk_icon_view_accessible_add_selection (AtkSelection *selection,
1371 GtkIconView *icon_view;
1372 GtkIconViewItem *item;
1374 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1378 icon_view = GTK_ICON_VIEW (widget);
1380 item = g_list_nth_data (icon_view->priv->items, i);
1384 _gtk_icon_view_select_item (icon_view, item);
1390 gtk_icon_view_accessible_clear_selection (AtkSelection *selection)
1393 GtkIconView *icon_view;
1395 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1399 icon_view = GTK_ICON_VIEW (widget);
1400 gtk_icon_view_unselect_all (icon_view);
1406 gtk_icon_view_accessible_ref_selection (AtkSelection *selection,
1411 GtkIconView *icon_view;
1412 GtkIconViewItem *item;
1414 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1418 icon_view = GTK_ICON_VIEW (widget);
1420 l = icon_view->priv->items;
1427 return atk_object_ref_accessible_child (gtk_widget_get_accessible (widget), item->index);
1438 gtk_icon_view_accessible_get_selection_count (AtkSelection *selection)
1441 GtkIconView *icon_view;
1442 GtkIconViewItem *item;
1446 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1450 icon_view = GTK_ICON_VIEW (widget);
1452 l = icon_view->priv->items;
1468 gtk_icon_view_accessible_is_child_selected (AtkSelection *selection,
1472 GtkIconView *icon_view;
1473 GtkIconViewItem *item;
1475 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1479 icon_view = GTK_ICON_VIEW (widget);
1481 item = g_list_nth_data (icon_view->priv->items, i);
1485 return item->selected;
1489 gtk_icon_view_accessible_remove_selection (AtkSelection *selection,
1493 GtkIconView *icon_view;
1494 GtkIconViewItem *item;
1498 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1502 icon_view = GTK_ICON_VIEW (widget);
1503 l = icon_view->priv->items;
1512 _gtk_icon_view_unselect_item (icon_view, item);
1524 gtk_icon_view_accessible_select_all_selection (AtkSelection *selection)
1527 GtkIconView *icon_view;
1529 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1533 icon_view = GTK_ICON_VIEW (widget);
1534 gtk_icon_view_select_all (icon_view);
1539 atk_selection_interface_init (AtkSelectionIface *iface)
1541 iface->add_selection = gtk_icon_view_accessible_add_selection;
1542 iface->clear_selection = gtk_icon_view_accessible_clear_selection;
1543 iface->ref_selection = gtk_icon_view_accessible_ref_selection;
1544 iface->get_selection_count = gtk_icon_view_accessible_get_selection_count;
1545 iface->is_child_selected = gtk_icon_view_accessible_is_child_selected;
1546 iface->remove_selection = gtk_icon_view_accessible_remove_selection;
1547 iface->select_all_selection = gtk_icon_view_accessible_select_all_selection;