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, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
22 #include "gtkiconviewaccessible.h"
26 #include "gtk/gtkiconviewprivate.h"
27 #include "gtk/gtkcellrendererpixbuf.h"
28 #include "gtk/gtkcellrenderertext.h"
29 #include "gtk/gtkpango.h"
30 #include "gtk/gtkwidgetprivate.h"
32 #define GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE (_gtk_icon_view_item_accessible_get_type ())
33 #define GTK_ICON_VIEW_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE, GtkIconViewItemAccessible))
34 #define GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE))
40 GtkIconViewItem *item;
42 AtkStateSet *state_set;
44 gchar *action_description;
45 gchar *image_description;
46 guint action_idle_handler;
47 } GtkIconViewItemAccessible;
51 AtkObjectClass parent_class;
53 } GtkIconViewItemAccessibleClass;
55 static gboolean gtk_icon_view_item_accessible_is_showing (GtkIconViewItemAccessible *item);
57 static void atk_component_item_interface_init (AtkComponentIface *iface);
58 static void atk_action_item_interface_init (AtkActionIface *iface);
59 static void atk_text_item_interface_init (AtkTextIface *iface);
60 static void atk_image_item_interface_init (AtkImageIface *iface);
62 G_DEFINE_TYPE_WITH_CODE (GtkIconViewItemAccessible, _gtk_icon_view_item_accessible, ATK_TYPE_OBJECT,
63 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_item_interface_init)
64 G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_item_interface_init)
65 G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_item_interface_init)
66 G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_item_interface_init))
70 idle_do_action (gpointer data)
72 GtkIconViewItemAccessible *item;
73 GtkIconView *icon_view;
76 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (data);
77 item->action_idle_handler = 0;
79 if (item->widget != NULL)
81 icon_view = GTK_ICON_VIEW (item->widget);
82 path = gtk_tree_path_new_from_indices (item->item->index, -1);
83 gtk_icon_view_item_activated (icon_view, path);
84 gtk_tree_path_free (path);
91 gtk_icon_view_item_accessible_do_action (AtkAction *action,
94 GtkIconViewItemAccessible *item;
99 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
101 if (!GTK_IS_ICON_VIEW (item->widget))
104 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
107 if (!item->action_idle_handler)
108 item->action_idle_handler = gdk_threads_add_idle (idle_do_action, item);
114 gtk_icon_view_item_accessible_get_n_actions (AtkAction *action)
120 gtk_icon_view_item_accessible_get_description (AtkAction *action,
123 GtkIconViewItemAccessible *item;
128 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
130 if (item->action_description)
131 return item->action_description;
133 return "Activate item";
137 gtk_icon_view_item_accessible_get_name (AtkAction *action,
147 gtk_icon_view_item_accessible_set_description (AtkAction *action,
149 const gchar *description)
151 GtkIconViewItemAccessible *item;
156 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
158 g_free (item->action_description);
159 item->action_description = g_strdup (description);
165 atk_action_item_interface_init (AtkActionIface *iface)
167 iface->do_action = gtk_icon_view_item_accessible_do_action;
168 iface->set_description = gtk_icon_view_item_accessible_set_description;
169 iface->get_name = gtk_icon_view_item_accessible_get_name;
170 iface->get_n_actions = gtk_icon_view_item_accessible_get_n_actions;
171 iface->get_description = gtk_icon_view_item_accessible_get_description;
175 gtk_icon_view_item_accessible_get_image_description (AtkImage *image)
177 GtkIconViewItemAccessible *item;
179 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
181 return item->image_description;
185 gtk_icon_view_item_accessible_set_image_description (AtkImage *image,
186 const gchar *description)
188 GtkIconViewItemAccessible *item;
190 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
192 g_free (item->image_description);
193 item->image_description = g_strdup (description);
200 gboolean pixbuf_found;
204 get_pixbuf_foreach (GtkCellRenderer *renderer,
205 const GdkRectangle *cell_area,
206 const GdkRectangle *cell_background,
207 GetPixbufBoxData *data)
209 if (GTK_IS_CELL_RENDERER_PIXBUF (renderer))
211 data->box = *cell_area;
212 data->pixbuf_found = TRUE;
214 return (data->pixbuf_found != FALSE);
218 get_pixbuf_box (GtkIconView *icon_view,
219 GtkIconViewItem *item,
222 GetPixbufBoxData data = { { 0, }, FALSE };
223 GtkCellAreaContext *context;
225 context = g_ptr_array_index (icon_view->priv->row_contexts, item->row);
227 _gtk_icon_view_set_cell_data (icon_view, item);
228 gtk_cell_area_foreach_alloc (icon_view->priv->cell_area, context,
229 GTK_WIDGET (icon_view),
230 (GdkRectangle *)item, (GdkRectangle *)item,
231 (GtkCellAllocCallback)get_pixbuf_foreach, &data);
233 return data.pixbuf_found;
237 get_text_foreach (GtkCellRenderer *renderer,
240 if (GTK_IS_CELL_RENDERER_TEXT (renderer))
242 g_object_get (renderer, "text", text, NULL);
249 get_text (GtkIconView *icon_view,
250 GtkIconViewItem *item)
254 _gtk_icon_view_set_cell_data (icon_view, item);
255 gtk_cell_area_foreach (icon_view->priv->cell_area,
256 (GtkCellCallback)get_text_foreach, &text);
262 gtk_icon_view_item_accessible_get_image_size (AtkImage *image,
266 GtkIconViewItemAccessible *item;
269 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
271 if (!GTK_IS_ICON_VIEW (item->widget))
274 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
280 if (get_pixbuf_box (GTK_ICON_VIEW (item->widget), item->item, &box))
283 *height = box.height;
288 gtk_icon_view_item_accessible_get_image_position (AtkImage *image,
291 AtkCoordType coord_type)
293 GtkIconViewItemAccessible *item;
296 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
298 if (!GTK_IS_ICON_VIEW (item->widget))
301 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
304 atk_component_get_position (ATK_COMPONENT (image), x, y, coord_type);
306 if (get_pixbuf_box (GTK_ICON_VIEW (item->widget), item->item, &box))
308 *x+= box.x - item->item->cell_area.x;
309 *y+= box.y - item->item->cell_area.y;
315 atk_image_item_interface_init (AtkImageIface *iface)
317 iface->get_image_description = gtk_icon_view_item_accessible_get_image_description;
318 iface->set_image_description = gtk_icon_view_item_accessible_set_image_description;
319 iface->get_image_size = gtk_icon_view_item_accessible_get_image_size;
320 iface->get_image_position = gtk_icon_view_item_accessible_get_image_position;
324 gtk_icon_view_item_accessible_get_text (AtkText *text,
328 GtkIconViewItemAccessible *item;
330 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
331 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
335 return g_utf8_substring (item->text, start_pos, end_pos > -1 ? end_pos : g_utf8_strlen (item->text, -1));
337 return g_strdup ("");
341 gtk_icon_view_item_accessible_get_character_at_offset (AtkText *text,
344 GtkIconViewItemAccessible *item;
348 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
349 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
357 if (offset >= g_utf8_strlen (string, -1))
360 index = g_utf8_offset_to_pointer (string, offset);
362 return g_utf8_get_char (index);
366 create_pango_layout (GtkIconViewItemAccessible *item)
370 layout = gtk_widget_create_pango_layout (item->widget, item->text);
376 gtk_icon_view_item_accessible_get_text_before_offset (AtkText *atk_text,
378 AtkTextBoundary boundary_type,
382 GtkIconViewItemAccessible *item;
386 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (atk_text);
387 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
390 layout = create_pango_layout (item);
391 text = _gtk_pango_get_text_before (layout, boundary_type, offset, start_offset, end_offset);
392 g_object_unref (layout);
398 gtk_icon_view_item_accessible_get_text_at_offset (AtkText *atk_text,
400 AtkTextBoundary boundary_type,
404 GtkIconViewItemAccessible *item;
408 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (atk_text);
409 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
412 layout = create_pango_layout (item);
413 text = _gtk_pango_get_text_at (layout, boundary_type, offset, start_offset, end_offset);
414 g_object_unref (layout);
420 gtk_icon_view_item_accessible_get_text_after_offset (AtkText *atk_text,
422 AtkTextBoundary boundary_type,
426 GtkIconViewItemAccessible *item;
430 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (atk_text);
431 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
434 layout = create_pango_layout (item);
435 text = _gtk_pango_get_text_after (layout, boundary_type, offset, start_offset, end_offset);
436 g_object_unref (layout);
442 gtk_icon_view_item_accessible_get_character_count (AtkText *text)
444 GtkIconViewItemAccessible *item;
446 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
447 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
451 return g_utf8_strlen (item->text, -1);
457 gtk_icon_view_item_accessible_get_character_extents (AtkText *text,
463 AtkCoordType coord_type)
465 GtkIconViewItemAccessible *item;
467 GtkIconView *icon_view;
468 PangoRectangle char_rect;
469 const gchar *item_text;
473 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
475 if (!GTK_IS_ICON_VIEW (item->widget))
478 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
482 icon_view = GTK_ICON_VIEW (item->widget);
483 /* FIXME we probably have to use GailTextCell to salvage this */
484 gtk_icon_view_update_item_text (icon_view, item->item);
485 item_text = pango_layout_get_text (icon_view->priv->layout);
486 index = g_utf8_offset_to_pointer (item_text, offset) - item_text;
487 pango_layout_index_to_pos (icon_view->priv->layout, index, &char_rect);
489 atk_component_get_position (ATK_COMPONENT (text), x, y, coord_type);
490 *x += item->item->layout_x - item->item->x + char_rect.x / PANGO_SCALE;
491 /* Look at gtk_icon_view_paint_item() to see where the text is. */
492 *x -= ((item->item->width - item->item->layout_width) / 2) + (MAX (item->item->pixbuf_width, icon_view->priv->item_width) - item->item->width) / 2,
493 *y += item->item->layout_y - item->item->y + char_rect.y / PANGO_SCALE;
494 *width = char_rect.width / PANGO_SCALE;
495 *height = char_rect.height / PANGO_SCALE;
500 gtk_icon_view_item_accessible_get_offset_at_point (AtkText *text,
503 AtkCoordType coord_type)
505 GtkIconViewItemAccessible *item;
508 GtkIconView *icon_view;
509 const gchar *item_text;
514 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
516 if (!GTK_IS_ICON_VIEW (item->widget))
519 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
523 icon_view = GTK_ICON_VIEW (item->widget);
524 /* FIXME we probably have to use GailTextCell to salvage this */
525 gtk_icon_view_update_item_text (icon_view, item->item);
526 atk_component_get_position (ATK_COMPONENT (text), &l_x, &l_y, coord_type);
527 x -= l_x + item->item->layout_x - item->item->x;
528 x += ((item->item->width - item->item->layout_width) / 2) + (MAX (item->item->pixbuf_width, icon_view->priv->item_width) - item->item->width) / 2,
529 y -= l_y + item->item->layout_y - item->item->y;
530 item_text = pango_layout_get_text (icon_view->priv->layout);
531 if (!pango_layout_xy_to_index (icon_view->priv->layout,
542 offset = g_utf8_strlen (item_text, -1);
544 offset = g_utf8_pointer_to_offset (item_text, item_text + index);
550 atk_text_item_interface_init (AtkTextIface *iface)
552 iface->get_text = gtk_icon_view_item_accessible_get_text;
553 iface->get_character_at_offset = gtk_icon_view_item_accessible_get_character_at_offset;
554 iface->get_text_before_offset = gtk_icon_view_item_accessible_get_text_before_offset;
555 iface->get_text_at_offset = gtk_icon_view_item_accessible_get_text_at_offset;
556 iface->get_text_after_offset = gtk_icon_view_item_accessible_get_text_after_offset;
557 iface->get_character_count = gtk_icon_view_item_accessible_get_character_count;
558 iface->get_character_extents = gtk_icon_view_item_accessible_get_character_extents;
559 iface->get_offset_at_point = gtk_icon_view_item_accessible_get_offset_at_point;
563 gtk_icon_view_item_accessible_get_extents (AtkComponent *component,
568 AtkCoordType coord_type)
570 GtkIconViewItemAccessible *item;
571 AtkObject *parent_obj;
574 g_return_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component));
576 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (component);
577 if (!GTK_IS_WIDGET (item->widget))
580 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
583 *width = item->item->cell_area.width;
584 *height = item->item->cell_area.height;
585 if (gtk_icon_view_item_accessible_is_showing (item))
587 parent_obj = gtk_widget_get_accessible (item->widget);
588 atk_component_get_position (ATK_COMPONENT (parent_obj), &l_x, &l_y, coord_type);
589 *x = l_x + item->item->cell_area.x;
590 *y = l_y + item->item->cell_area.y;
600 gtk_icon_view_item_accessible_grab_focus (AtkComponent *component)
602 GtkIconViewItemAccessible *item;
605 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component), FALSE);
607 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (component);
608 if (!GTK_IS_WIDGET (item->widget))
611 gtk_widget_grab_focus (item->widget);
612 _gtk_icon_view_set_cursor_item (GTK_ICON_VIEW (item->widget), item->item, NULL);
613 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item->widget));
614 if (gtk_widget_is_toplevel (toplevel))
615 gtk_window_present (GTK_WINDOW (toplevel));
621 atk_component_item_interface_init (AtkComponentIface *iface)
623 iface->get_extents = gtk_icon_view_item_accessible_get_extents;
624 iface->grab_focus = gtk_icon_view_item_accessible_grab_focus;
628 gtk_icon_view_item_accessible_add_state (GtkIconViewItemAccessible *item,
629 AtkStateType state_type,
630 gboolean emit_signal)
634 rc = atk_state_set_add_state (item->state_set, state_type);
636 /* The signal should only be generated if the value changed,
637 * not when the item is set up. So states that are set
638 * initially should pass FALSE as the emit_signal argument.
642 atk_object_notify_state_change (ATK_OBJECT (item), state_type, TRUE);
643 /* If state_type is ATK_STATE_VISIBLE, additional notification */
644 if (state_type == ATK_STATE_VISIBLE)
645 g_signal_emit_by_name (item, "visible-data-changed");
652 gtk_icon_view_item_accessible_remove_state (GtkIconViewItemAccessible *item,
653 AtkStateType state_type,
654 gboolean emit_signal)
656 if (atk_state_set_contains_state (item->state_set, state_type))
660 rc = atk_state_set_remove_state (item->state_set, state_type);
662 /* The signal should only be generated if the value changed,
663 * not when the item is set up. So states that are set
664 * initially should pass FALSE as the emit_signal argument.
668 atk_object_notify_state_change (ATK_OBJECT (item), state_type, FALSE);
669 /* If state_type is ATK_STATE_VISIBLE, additional notification */
670 if (state_type == ATK_STATE_VISIBLE)
671 g_signal_emit_by_name (item, "visible-data-changed");
681 gtk_icon_view_item_accessible_is_showing (GtkIconViewItemAccessible *item)
683 GtkAllocation allocation;
684 GtkIconView *icon_view;
685 GdkRectangle visible_rect;
688 /* An item is considered "SHOWING" if any part of the item
689 * is in the visible rectangle.
691 if (!GTK_IS_ICON_VIEW (item->widget))
694 if (item->item == NULL)
697 gtk_widget_get_allocation (item->widget, &allocation);
699 icon_view = GTK_ICON_VIEW (item->widget);
701 if (icon_view->priv->hadjustment)
702 visible_rect.x += gtk_adjustment_get_value (icon_view->priv->hadjustment);
704 if (icon_view->priv->hadjustment)
705 visible_rect.y += gtk_adjustment_get_value (icon_view->priv->vadjustment);
706 visible_rect.width = allocation.width;
707 visible_rect.height = allocation.height;
709 if (((item->item->cell_area.x + item->item->cell_area.width) < visible_rect.x) ||
710 ((item->item->cell_area.y + item->item->cell_area.height) < (visible_rect.y)) ||
711 (item->item->cell_area.x > (visible_rect.x + visible_rect.width)) ||
712 (item->item->cell_area.y > (visible_rect.y + visible_rect.height)))
721 gtk_icon_view_item_accessible_set_visibility (GtkIconViewItemAccessible *item,
722 gboolean emit_signal)
724 if (gtk_icon_view_item_accessible_is_showing (item))
725 return gtk_icon_view_item_accessible_add_state (item, ATK_STATE_SHOWING,
728 return gtk_icon_view_item_accessible_remove_state (item, ATK_STATE_SHOWING,
733 _gtk_icon_view_item_accessible_init (GtkIconViewItemAccessible *item)
735 item->state_set = atk_state_set_new ();
737 atk_state_set_add_state (item->state_set, ATK_STATE_ENABLED);
738 atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSABLE);
739 atk_state_set_add_state (item->state_set, ATK_STATE_SENSITIVE);
740 atk_state_set_add_state (item->state_set, ATK_STATE_SELECTABLE);
741 atk_state_set_add_state (item->state_set, ATK_STATE_VISIBLE);
743 item->action_description = NULL;
744 item->image_description = NULL;
746 item->action_idle_handler = 0;
750 gtk_icon_view_item_accessible_finalize (GObject *object)
752 GtkIconViewItemAccessible *item;
754 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (object);
757 g_object_remove_weak_pointer (G_OBJECT (item->widget), (gpointer) &item->widget);
760 g_object_unref (item->state_set);
764 g_free (item->action_description);
765 g_free (item->image_description);
767 if (item->action_idle_handler)
769 g_source_remove (item->action_idle_handler);
770 item->action_idle_handler = 0;
773 G_OBJECT_CLASS (_gtk_icon_view_item_accessible_parent_class)->finalize (object);
777 gtk_icon_view_item_accessible_get_parent (AtkObject *obj)
779 GtkIconViewItemAccessible *item;
781 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (obj), NULL);
782 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
785 return gtk_widget_get_accessible (item->widget);
791 gtk_icon_view_item_accessible_get_index_in_parent (AtkObject *obj)
793 GtkIconViewItemAccessible *item;
795 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (obj), 0);
796 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
798 return item->item->index;
802 gtk_icon_view_item_accessible_ref_state_set (AtkObject *obj)
804 GtkIconViewItemAccessible *item;
805 GtkIconView *icon_view;
807 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
808 g_return_val_if_fail (item->state_set, NULL);
813 icon_view = GTK_ICON_VIEW (item->widget);
814 if (icon_view->priv->cursor_item == item->item)
815 atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSED);
817 atk_state_set_remove_state (item->state_set, ATK_STATE_FOCUSED);
818 if (item->item->selected)
819 atk_state_set_add_state (item->state_set, ATK_STATE_SELECTED);
821 atk_state_set_remove_state (item->state_set, ATK_STATE_SELECTED);
823 return g_object_ref (item->state_set);
827 _gtk_icon_view_item_accessible_class_init (GtkIconViewItemAccessibleClass *klass)
829 GObjectClass *gobject_class;
830 AtkObjectClass *atk_class;
832 gobject_class = (GObjectClass *)klass;
833 atk_class = (AtkObjectClass *)klass;
835 gobject_class->finalize = gtk_icon_view_item_accessible_finalize;
837 atk_class->get_index_in_parent = gtk_icon_view_item_accessible_get_index_in_parent;
838 atk_class->get_parent = gtk_icon_view_item_accessible_get_parent;
839 atk_class->ref_state_set = gtk_icon_view_item_accessible_ref_state_set;
842 static void atk_component_interface_init (AtkComponentIface *iface);
843 static void atk_selection_interface_init (AtkSelectionIface *iface);
845 G_DEFINE_TYPE_WITH_CODE (GtkIconViewAccessible, _gtk_icon_view_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
846 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)
847 G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
853 } GtkIconViewItemAccessibleInfo;
857 gtk_icon_view_item_accessible_info_new (AtkObject *accessible,
861 GtkIconViewAccessible *view = (GtkIconViewAccessible *)accessible;
862 GtkIconViewItemAccessibleInfo *info;
863 GtkIconViewItemAccessibleInfo *tmp_info;
866 info = g_new (GtkIconViewItemAccessibleInfo, 1);
873 tmp_info = items->data;
874 if (tmp_info->index > index)
878 view->items = g_list_insert_before (view->items, items, info);
882 gtk_icon_view_accessible_get_n_children (AtkObject *accessible)
884 GtkIconView *icon_view;
887 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
891 icon_view = GTK_ICON_VIEW (widget);
893 return g_list_length (icon_view->priv->items);
897 gtk_icon_view_accessible_find_child (AtkObject *accessible,
900 GtkIconViewAccessible *view = (GtkIconViewAccessible*)accessible;
901 GtkIconViewItemAccessibleInfo *info;
909 if (info->index == index)
918 gtk_icon_view_accessible_ref_child (AtkObject *accessible,
921 GtkIconView *icon_view;
925 GtkIconViewItemAccessible *a11y_item;
927 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
931 icon_view = GTK_ICON_VIEW (widget);
932 icons = g_list_nth (icon_view->priv->items, index);
936 GtkIconViewItem *item = icons->data;
938 g_return_val_if_fail (item->index == index, NULL);
939 obj = gtk_icon_view_accessible_find_child (accessible, index);
942 obj = g_object_new (GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE, NULL);
943 gtk_icon_view_item_accessible_info_new (accessible, obj, index);
944 obj->role = ATK_ROLE_ICON;
945 a11y_item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
946 a11y_item->item = item;
947 a11y_item->widget = widget;
949 g_free (a11y_item->text);
950 a11y_item->text = get_text (icon_view, item);
952 gtk_icon_view_item_accessible_set_visibility (a11y_item, FALSE);
953 g_object_add_weak_pointer (G_OBJECT (widget), (gpointer) &(a11y_item->widget));
961 gtk_icon_view_accessible_traverse_items (GtkIconViewAccessible *view,
964 GtkIconViewItemAccessibleInfo *info;
965 GtkIconViewItemAccessible *item;
971 gboolean act_on_item;
973 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (view));
979 act_on_item = (list == NULL);
984 info = (GtkIconViewItemAccessibleInfo *)items->data;
985 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
987 if (act_on_item == FALSE && list == items)
991 gtk_icon_view_item_accessible_set_visibility (item, TRUE);
999 _gtk_icon_view_accessible_adjustment_changed (GtkIconView *icon_view)
1001 GtkIconViewAccessible *view;
1003 view = GTK_ICON_VIEW_ACCESSIBLE (_gtk_widget_peek_accessible (GTK_WIDGET (icon_view)));
1007 gtk_icon_view_accessible_traverse_items (view, NULL);
1011 gtk_icon_view_accessible_model_row_changed (GtkTreeModel *tree_model,
1019 GtkIconView *icon_view;
1020 GtkIconViewItem *item;
1021 GtkIconViewItemAccessible *a11y_item;
1024 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
1025 index = gtk_tree_path_get_indices(path)[0];
1026 a11y_item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (
1027 gtk_icon_view_accessible_find_child (atk_obj, index));
1031 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_obj));
1032 icon_view = GTK_ICON_VIEW (widget);
1033 item = a11y_item->item;
1035 name = atk_object_get_name (ATK_OBJECT (a11y_item));
1036 if (!name || strcmp (name, "") == 0)
1038 g_free (a11y_item->text);
1039 a11y_item->text = get_text (icon_view, item);
1043 g_signal_emit_by_name (atk_obj, "visible-data-changed");
1049 gtk_icon_view_accessible_model_row_inserted (GtkTreeModel *tree_model,
1054 GtkIconViewItemAccessibleInfo *info;
1055 GtkIconViewAccessible *view;
1056 GtkIconViewItemAccessible *item;
1062 index = gtk_tree_path_get_indices(path)[0];
1063 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
1064 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
1066 items = view->items;
1071 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
1072 if (info->index != item->item->index)
1074 if (info->index < index)
1075 g_warning ("Unexpected index value on insertion %d %d", index, info->index);
1077 if (tmp_list == NULL)
1080 info->index = item->item->index;
1083 items = items->next;
1085 gtk_icon_view_accessible_traverse_items (view, tmp_list);
1086 g_signal_emit_by_name (atk_obj, "children-changed::add",
1092 gtk_icon_view_accessible_model_row_deleted (GtkTreeModel *tree_model,
1096 GtkIconViewItemAccessibleInfo *info;
1097 GtkIconViewAccessible *view;
1098 GtkIconViewItemAccessible *item;
1101 GList *deleted_item;
1105 index = gtk_tree_path_get_indices(path)[0];
1106 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
1107 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
1109 items = view->items;
1111 deleted_item = NULL;
1116 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
1117 if (info->index == index)
1119 deleted_item = items;
1121 if (info->index != item->item->index)
1123 if (tmp_list == NULL)
1126 info->index = item->item->index;
1129 items = items->next;
1131 gtk_icon_view_accessible_traverse_items (view, tmp_list);
1134 info = deleted_item->data;
1135 gtk_icon_view_item_accessible_add_state (GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item), ATK_STATE_DEFUNCT, TRUE);
1136 g_signal_emit_by_name (atk_obj, "children-changed::remove",
1138 view->items = g_list_remove_link (view->items, deleted_item);
1146 gtk_icon_view_accessible_item_compare (GtkIconViewItemAccessibleInfo *i1,
1147 GtkIconViewItemAccessibleInfo *i2)
1149 return i1->index - i2->index;
1153 gtk_icon_view_accessible_model_rows_reordered (GtkTreeModel *tree_model,
1159 GtkIconViewAccessible *view;
1160 GtkIconViewItemAccessibleInfo *info;
1161 GtkIconView *icon_view;
1162 GtkIconViewItemAccessible *item;
1168 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
1169 icon_view = GTK_ICON_VIEW (user_data);
1170 view = (GtkIconViewAccessible*)atk_obj;
1172 length = gtk_tree_model_iter_n_children (tree_model, NULL);
1174 order = g_new (gint, length);
1175 for (i = 0; i < length; i++)
1176 order [new_order[i]] = i;
1178 items = view->items;
1182 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
1183 info->index = order[info->index];
1184 item->item = g_list_nth_data (icon_view->priv->items, info->index);
1185 items = items->next;
1188 view->items = g_list_sort (view->items,
1189 (GCompareFunc)gtk_icon_view_accessible_item_compare);
1195 gtk_icon_view_accessible_disconnect_model_signals (GtkTreeModel *model,
1200 obj = G_OBJECT (model);
1201 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_changed, widget);
1202 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_inserted, widget);
1203 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_deleted, widget);
1204 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_rows_reordered, widget);
1208 gtk_icon_view_accessible_connect_model_signals (GtkIconView *icon_view)
1212 obj = G_OBJECT (icon_view->priv->model);
1213 g_signal_connect_data (obj, "row-changed",
1214 (GCallback) gtk_icon_view_accessible_model_row_changed,
1215 icon_view, NULL, 0);
1216 g_signal_connect_data (obj, "row-inserted",
1217 (GCallback) gtk_icon_view_accessible_model_row_inserted,
1218 icon_view, NULL, G_CONNECT_AFTER);
1219 g_signal_connect_data (obj, "row-deleted",
1220 (GCallback) gtk_icon_view_accessible_model_row_deleted,
1221 icon_view, NULL, G_CONNECT_AFTER);
1222 g_signal_connect_data (obj, "rows-reordered",
1223 (GCallback) gtk_icon_view_accessible_model_rows_reordered,
1224 icon_view, NULL, G_CONNECT_AFTER);
1228 gtk_icon_view_accessible_clear_cache (GtkIconViewAccessible *view)
1230 GtkIconViewItemAccessibleInfo *info;
1233 items = view->items;
1236 info = (GtkIconViewItemAccessibleInfo *) items->data;
1237 g_object_unref (info->item);
1238 g_free (items->data);
1239 items = items->next;
1241 g_list_free (view->items);
1246 gtk_icon_view_accessible_notify_gtk (GObject *obj,
1249 GtkIconView *icon_view;
1252 GtkIconViewAccessible *view;
1254 if (strcmp (pspec->name, "model") == 0)
1256 widget = GTK_WIDGET (obj);
1257 atk_obj = gtk_widget_get_accessible (widget);
1258 view = (GtkIconViewAccessible*)atk_obj;
1261 g_object_remove_weak_pointer (G_OBJECT (view->model),
1262 (gpointer *)&view->model);
1263 gtk_icon_view_accessible_disconnect_model_signals (view->model, widget);
1265 gtk_icon_view_accessible_clear_cache (view);
1267 icon_view = GTK_ICON_VIEW (obj);
1268 view->model = icon_view->priv->model;
1269 /* If there is no model the GtkIconView is probably being destroyed */
1272 g_object_add_weak_pointer (G_OBJECT (view->model), (gpointer *)&view->model);
1273 gtk_icon_view_accessible_connect_model_signals (icon_view);
1281 gtk_icon_view_accessible_initialize (AtkObject *accessible,
1284 GtkIconViewAccessible *view;
1285 GtkIconView *icon_view;
1287 if (ATK_OBJECT_CLASS (_gtk_icon_view_accessible_parent_class)->initialize)
1288 ATK_OBJECT_CLASS (_gtk_icon_view_accessible_parent_class)->initialize (accessible, data);
1290 icon_view = (GtkIconView*)data;
1291 view = (GtkIconViewAccessible*)accessible;
1293 g_signal_connect (data, "notify",
1294 G_CALLBACK (gtk_icon_view_accessible_notify_gtk), NULL);
1296 view->model = icon_view->priv->model;
1299 g_object_add_weak_pointer (G_OBJECT (view->model), (gpointer *)&view->model);
1300 gtk_icon_view_accessible_connect_model_signals (icon_view);
1303 accessible->role = ATK_ROLE_LAYERED_PANE;
1307 gtk_icon_view_accessible_finalize (GObject *object)
1309 GtkIconViewAccessible *view = (GtkIconViewAccessible*)object;
1311 gtk_icon_view_accessible_clear_cache (view);
1313 G_OBJECT_CLASS (_gtk_icon_view_accessible_parent_class)->finalize (object);
1317 _gtk_icon_view_accessible_class_init (GtkIconViewAccessibleClass *klass)
1319 GObjectClass *gobject_class;
1320 AtkObjectClass *atk_class;
1322 gobject_class = (GObjectClass *)klass;
1323 atk_class = (AtkObjectClass *)klass;
1325 gobject_class->finalize = gtk_icon_view_accessible_finalize;
1327 atk_class->get_n_children = gtk_icon_view_accessible_get_n_children;
1328 atk_class->ref_child = gtk_icon_view_accessible_ref_child;
1329 atk_class->initialize = gtk_icon_view_accessible_initialize;
1333 _gtk_icon_view_accessible_init (GtkIconViewAccessible *accessible)
1338 gtk_icon_view_accessible_ref_accessible_at_point (AtkComponent *component,
1341 AtkCoordType coord_type)
1344 GtkIconView *icon_view;
1345 GtkIconViewItem *item;
1348 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
1352 icon_view = GTK_ICON_VIEW (widget);
1353 atk_component_get_extents (component, &x_pos, &y_pos, NULL, NULL, coord_type);
1354 item = _gtk_icon_view_get_item_at_coords (icon_view, x - x_pos, y - y_pos, TRUE, NULL);
1356 return gtk_icon_view_accessible_ref_child (ATK_OBJECT (component), item->index);
1362 atk_component_interface_init (AtkComponentIface *iface)
1364 iface->ref_accessible_at_point = gtk_icon_view_accessible_ref_accessible_at_point;
1368 gtk_icon_view_accessible_add_selection (AtkSelection *selection,
1372 GtkIconView *icon_view;
1373 GtkIconViewItem *item;
1375 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1379 icon_view = GTK_ICON_VIEW (widget);
1381 item = g_list_nth_data (icon_view->priv->items, i);
1385 _gtk_icon_view_select_item (icon_view, item);
1391 gtk_icon_view_accessible_clear_selection (AtkSelection *selection)
1394 GtkIconView *icon_view;
1396 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1400 icon_view = GTK_ICON_VIEW (widget);
1401 gtk_icon_view_unselect_all (icon_view);
1407 gtk_icon_view_accessible_ref_selection (AtkSelection *selection,
1412 GtkIconView *icon_view;
1413 GtkIconViewItem *item;
1415 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1419 icon_view = GTK_ICON_VIEW (widget);
1421 l = icon_view->priv->items;
1428 return atk_object_ref_accessible_child (gtk_widget_get_accessible (widget), item->index);
1439 gtk_icon_view_accessible_get_selection_count (AtkSelection *selection)
1442 GtkIconView *icon_view;
1443 GtkIconViewItem *item;
1447 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1451 icon_view = GTK_ICON_VIEW (widget);
1453 l = icon_view->priv->items;
1469 gtk_icon_view_accessible_is_child_selected (AtkSelection *selection,
1473 GtkIconView *icon_view;
1474 GtkIconViewItem *item;
1476 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1480 icon_view = GTK_ICON_VIEW (widget);
1482 item = g_list_nth_data (icon_view->priv->items, i);
1486 return item->selected;
1490 gtk_icon_view_accessible_remove_selection (AtkSelection *selection,
1494 GtkIconView *icon_view;
1495 GtkIconViewItem *item;
1499 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1503 icon_view = GTK_ICON_VIEW (widget);
1504 l = icon_view->priv->items;
1513 _gtk_icon_view_unselect_item (icon_view, item);
1525 gtk_icon_view_accessible_select_all_selection (AtkSelection *selection)
1528 GtkIconView *icon_view;
1530 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
1534 icon_view = GTK_ICON_VIEW (widget);
1535 gtk_icon_view_select_all (icon_view);
1540 atk_selection_interface_init (AtkSelectionIface *iface)
1542 iface->add_selection = gtk_icon_view_accessible_add_selection;
1543 iface->clear_selection = gtk_icon_view_accessible_clear_selection;
1544 iface->ref_selection = gtk_icon_view_accessible_ref_selection;
1545 iface->get_selection_count = gtk_icon_view_accessible_get_selection_count;
1546 iface->is_child_selected = gtk_icon_view_accessible_is_child_selected;
1547 iface->remove_selection = gtk_icon_view_accessible_remove_selection;
1548 iface->select_all_selection = gtk_icon_view_accessible_select_all_selection;