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.
25 #include <gdk/gdkkeysyms.h>
28 #include "gtkiconview.h"
29 #include "gtkmarshalers.h"
30 #include "gtkbindings.h"
33 #include "gtksignal.h"
35 #include "gtkaccessible.h"
36 #include "gtkwindow.h"
37 #include "gtktextbuffer.h"
39 #undef DEBUG_ICON_VIEW
41 #define ICON_TEXT_PADDING 3
43 #define GTK_ICON_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ICON_VIEW, GtkIconViewPrivate))
44 #define VALID_MODEL_AND_COLUMNS(obj) ((obj)->priv->model != NULL && \
45 ((obj)->priv->pixbuf_column != -1 || \
46 (obj)->priv->text_column != -1 || \
47 (obj)->priv->markup_column != -1))
60 gint pixbuf_x, pixbuf_y;
61 gint pixbuf_height, pixbuf_width;
63 gint layout_x, layout_y;
64 gint layout_width, layout_height;
67 guint selected_before_rubberbanding : 1;
70 struct _GtkIconViewPrivate
78 GtkSelectionMode selection_mode;
80 GdkWindow *bin_window;
86 GtkAdjustment *hadjustment;
87 GtkAdjustment *vadjustment;
91 gboolean doing_rubberband;
92 gint rubberband_x1, rubberband_y1;
93 gint rubberband_x2, rubberband_y2;
95 guint scroll_timeout_id;
96 gint scroll_value_diff;
97 gint event_last_x, event_last_y;
99 GtkIconViewItem *anchor_item;
100 GtkIconViewItem *cursor_item;
102 guint ctrl_pressed : 1;
103 guint shift_pressed : 1;
105 GtkIconViewItem *last_single_clicked;
114 /* Layout used to draw icon text */
117 GtkOrientation orientation;
137 ACTIVATE_CURSOR_ITEM,
159 /* GObject signals */
160 static void gtk_icon_view_finalize (GObject *object);
161 static void gtk_icon_view_set_property (GObject *object,
165 static void gtk_icon_view_get_property (GObject *object,
171 /* GtkObject signals */
172 static void gtk_icon_view_destroy (GtkObject *object);
174 /* GtkWidget signals */
175 static void gtk_icon_view_realize (GtkWidget *widget);
176 static void gtk_icon_view_unrealize (GtkWidget *widget);
177 static void gtk_icon_view_map (GtkWidget *widget);
178 static void gtk_icon_view_size_request (GtkWidget *widget,
179 GtkRequisition *requisition);
180 static void gtk_icon_view_size_allocate (GtkWidget *widget,
181 GtkAllocation *allocation);
182 static gboolean gtk_icon_view_expose (GtkWidget *widget,
183 GdkEventExpose *expose);
184 static gboolean gtk_icon_view_motion (GtkWidget *widget,
185 GdkEventMotion *event);
186 static gboolean gtk_icon_view_button_press (GtkWidget *widget,
187 GdkEventButton *event);
188 static gboolean gtk_icon_view_button_release (GtkWidget *widget,
189 GdkEventButton *event);
190 /* GtkIconView signals */
191 static void gtk_icon_view_set_adjustments (GtkIconView *icon_view,
193 GtkAdjustment *vadj);
194 static void gtk_icon_view_real_select_all (GtkIconView *icon_view);
195 static void gtk_icon_view_real_unselect_all (GtkIconView *icon_view);
196 static void gtk_icon_view_real_select_cursor_item (GtkIconView *icon_view);
197 static void gtk_icon_view_real_toggle_cursor_item (GtkIconView *icon_view);
198 static gboolean gtk_icon_view_real_activate_cursor_item (GtkIconView *icon_view);
200 /* Internal functions */
201 static void gtk_icon_view_adjustment_changed (GtkAdjustment *adjustment,
202 GtkIconView *icon_view);
203 static void gtk_icon_view_layout (GtkIconView *icon_view);
204 static void gtk_icon_view_paint_item (GtkIconView *icon_view,
206 GtkIconViewItem *item,
208 static void gtk_icon_view_paint_rubberband (GtkIconView *icon_view,
211 static void gtk_icon_view_queue_draw_item (GtkIconView *icon_view,
212 GtkIconViewItem *item);
213 static void gtk_icon_view_queue_layout (GtkIconView *icon_view);
214 static void gtk_icon_view_set_cursor_item (GtkIconView *icon_view,
215 GtkIconViewItem *item);
216 static void gtk_icon_view_start_rubberbanding (GtkIconView *icon_view,
219 static void gtk_icon_view_stop_rubberbanding (GtkIconView *icon_view);
220 static void gtk_icon_view_update_rubberband_selection (GtkIconView *icon_view);
221 static gboolean gtk_icon_view_item_hit_test (GtkIconViewItem *item,
227 static gboolean gtk_icon_view_maybe_begin_dragging_items (GtkIconView *icon_view,
228 GdkEventMotion *event);
230 static gboolean gtk_icon_view_unselect_all_internal (GtkIconView *icon_view);
231 static void gtk_icon_view_calculate_item_size (GtkIconView *icon_view,
232 GtkIconViewItem *item,
234 static void gtk_icon_view_update_rubberband (gpointer data);
235 static void gtk_icon_view_item_invalidate_size (GtkIconViewItem *item);
236 static void gtk_icon_view_invalidate_sizes (GtkIconView *icon_view);
237 static void gtk_icon_view_add_move_binding (GtkBindingSet *binding_set,
240 GtkMovementStep step,
242 static gboolean gtk_icon_view_real_move_cursor (GtkIconView *icon_view,
243 GtkMovementStep step,
245 static void gtk_icon_view_move_cursor_up_down (GtkIconView *icon_view,
247 static void gtk_icon_view_move_cursor_page_up_down (GtkIconView *icon_view,
249 static void gtk_icon_view_move_cursor_left_right (GtkIconView *icon_view,
251 static void gtk_icon_view_move_cursor_start_end (GtkIconView *icon_view,
253 static void gtk_icon_view_scroll_to_item (GtkIconView *icon_view,
254 GtkIconViewItem *item);
255 static GdkPixbuf *gtk_icon_view_get_item_icon (GtkIconView *icon_view,
256 GtkIconViewItem *item);
257 static void gtk_icon_view_update_item_text (GtkIconView *icon_view,
258 GtkIconViewItem *item);
259 static void gtk_icon_view_select_item (GtkIconView *icon_view,
260 GtkIconViewItem *item);
261 static void gtk_icon_view_unselect_item (GtkIconView *icon_view,
262 GtkIconViewItem *item);
263 static gboolean gtk_icon_view_select_all_between (GtkIconView *icon_view,
264 GtkIconViewItem *anchor,
265 GtkIconViewItem *cursor);
267 static GtkIconViewItem *gtk_icon_view_get_item_at_pos (GtkIconView *icon_view,
272 /* Accessibility Support */
273 static AtkObject *gtk_icon_view_get_accessible (GtkWidget *widget);
275 static GtkContainerClass *parent_class = NULL;
276 static guint icon_view_signals[LAST_SIGNAL] = { 0 };
278 G_DEFINE_TYPE (GtkIconView, gtk_icon_view, GTK_TYPE_CONTAINER);
281 gtk_icon_view_class_init (GtkIconViewClass *klass)
283 GObjectClass *gobject_class;
284 GtkObjectClass *object_class;
285 GtkWidgetClass *widget_class;
286 GtkBindingSet *binding_set;
288 parent_class = g_type_class_peek_parent (klass);
289 binding_set = gtk_binding_set_by_class (klass);
291 g_type_class_add_private (klass, sizeof (GtkIconViewPrivate));
293 gobject_class = (GObjectClass *) klass;
294 object_class = (GtkObjectClass *) klass;
295 widget_class = (GtkWidgetClass *) klass;
297 gobject_class->finalize = gtk_icon_view_finalize;
298 gobject_class->set_property = gtk_icon_view_set_property;
299 gobject_class->get_property = gtk_icon_view_get_property;
301 object_class->destroy = gtk_icon_view_destroy;
303 widget_class->realize = gtk_icon_view_realize;
304 widget_class->unrealize = gtk_icon_view_unrealize;
305 widget_class->map = gtk_icon_view_map;
306 widget_class->size_request = gtk_icon_view_size_request;
307 widget_class->size_allocate = gtk_icon_view_size_allocate;
308 widget_class->expose_event = gtk_icon_view_expose;
309 widget_class->motion_notify_event = gtk_icon_view_motion;
310 widget_class->button_press_event = gtk_icon_view_button_press;
311 widget_class->button_release_event = gtk_icon_view_button_release;
312 widget_class->get_accessible = gtk_icon_view_get_accessible;
314 klass->set_scroll_adjustments = gtk_icon_view_set_adjustments;
315 klass->select_all = gtk_icon_view_real_select_all;
316 klass->unselect_all = gtk_icon_view_real_unselect_all;
317 klass->select_cursor_item = gtk_icon_view_real_select_cursor_item;
318 klass->toggle_cursor_item = gtk_icon_view_real_toggle_cursor_item;
319 klass->activate_cursor_item = gtk_icon_view_real_activate_cursor_item;
320 klass->move_cursor = gtk_icon_view_real_move_cursor;
324 * GtkIconView:selection-mode:
326 * The ::selection-mode property specifies the selection mode of
327 * icon view. If the mode is #GTK_SELECTION_MULTIPLE, rubberband selection
328 * is enabled, for the other modes, only keyboard selection is possible.
332 g_object_class_install_property (gobject_class,
334 g_param_spec_enum ("selection-mode",
335 P_("Selection mode"),
336 P_("The selection mode"),
337 GTK_TYPE_SELECTION_MODE,
338 GTK_SELECTION_SINGLE,
342 * GtkIconView:pixbuf-column:
344 * The ::pixbuf-column property contains the number of the model column
345 * containing the pixbufs which are displayed. The pixbuf column must be
346 * of type #GDK_TYPE_PIXBUF. Setting this property to -1 turns off the
347 * display of pixbufs.
351 g_object_class_install_property (gobject_class,
353 g_param_spec_int ("pixbuf-column",
355 P_("Model column used to retrieve the icon pixbuf from"),
360 * GtkIconView:text-column:
362 * The ::text-column property contains the number of the model column
363 * containing the texts which are displayed. The text column must be
364 * of type #G_TYPE_STRING. If this property and the :markup-column
365 * property are both set to -1, no texts are displayed.
369 g_object_class_install_property (gobject_class,
371 g_param_spec_int ("text-column",
373 P_("Model column used to retrieve the text from"),
379 * GtkIconView:markup-column:
381 * The ::markup-column property contains the number of the model column
382 * containing markup information to be displayed. The markup column must be
383 * of type #G_TYPE_STRING. If this property and the :text-column property
384 * are both set to column numbers, it overrides the text column.
385 * If both are set to -1, no texts are displayed.
389 g_object_class_install_property (gobject_class,
391 g_param_spec_int ("markup-column",
393 P_("Model column used to retrieve the text if using Pango markup"),
397 g_object_class_install_property (gobject_class,
399 g_param_spec_object ("model",
400 P_("Icon View Model"),
401 P_("The model for the icon view"),
406 * GtkIconView:columns:
408 * The columns property contains the number of the columns in which the
409 * items should be displayed. If it is -1, the number of columns will
410 * be chosen automatically to fill the available area.
414 g_object_class_install_property (gobject_class,
416 g_param_spec_int ("columns",
417 P_("Number of columns"),
418 P_("Number of columns to display"),
424 * GtkIconView::item-width:
426 * The item-width property specifies the width to use for each item.
427 * If it is set to -1, the icon view will automatically determine a
428 * suitable item size.
432 g_object_class_install_property (gobject_class,
434 g_param_spec_int ("item-width",
435 P_("Width for each item"),
436 P_("The width used for each item"),
441 * GtkIconView::spacing:
443 * The spacing property specifies the space which is inserted between
444 * the cells (i.e. the icon and the text) of an item.
448 g_object_class_install_property (gobject_class,
450 g_param_spec_int ("spacing",
452 P_("Space which is inserted between cells of an item"),
457 * GtkIconView::row-spacing:
459 * The row-spacing property specifies the space which is inserted between
460 * the rows of the icon view.
464 g_object_class_install_property (gobject_class,
466 g_param_spec_int ("row-spacing",
468 P_("Space which is inserted between grid rows"),
473 * GtkIconView::column-spacing:
475 * The column-spacing property specifies the space which is inserted between
476 * the columns of the icon view.
480 g_object_class_install_property (gobject_class,
482 g_param_spec_int ("column-spacing",
483 P_("Column Spacing"),
484 P_("Space which is inserted between grid column"),
489 * GtkIconView::margin:
491 * The margin property specifies the space which is inserted
492 * at the edges of the icon view.
496 g_object_class_install_property (gobject_class,
498 g_param_spec_int ("margin",
500 P_("Space which is inserted at the edges of the icon view"),
506 * GtkIconView::orientation:
508 * The orientation property specifies how the cells (i.e. the icon and
509 * the text) of the item are positioned relative to each other.
513 g_object_class_install_property (gobject_class,
515 g_param_spec_enum ("orientation",
517 P_("How the text and icon of each item are positioned relative to each other"),
518 GTK_TYPE_ORIENTATION,
519 GTK_ORIENTATION_VERTICAL,
522 /* Style properties */
523 gtk_widget_class_install_style_property (widget_class,
524 g_param_spec_boxed ("selection-box-color",
525 P_("Selection Box Color"),
526 P_("Color of the selection box"),
530 gtk_widget_class_install_style_property (widget_class,
531 g_param_spec_uchar ("selection-box-alpha",
532 P_("Selection Box Alpha"),
533 P_("Opacity of the selection box"),
539 widget_class->set_scroll_adjustments_signal =
540 g_signal_new ("set_scroll_adjustments",
541 G_TYPE_FROM_CLASS (gobject_class),
543 G_STRUCT_OFFSET (GtkIconViewClass, set_scroll_adjustments),
545 _gtk_marshal_VOID__OBJECT_OBJECT,
547 GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
549 icon_view_signals[ITEM_ACTIVATED] =
550 g_signal_new ("item_activated",
551 G_TYPE_FROM_CLASS (gobject_class),
553 G_STRUCT_OFFSET (GtkIconViewClass, item_activated),
555 g_cclosure_marshal_VOID__BOXED,
559 icon_view_signals[SELECTION_CHANGED] =
560 g_signal_new ("selection_changed",
561 G_TYPE_FROM_CLASS (gobject_class),
563 G_STRUCT_OFFSET (GtkIconViewClass, selection_changed),
565 g_cclosure_marshal_VOID__VOID,
568 icon_view_signals[SELECT_ALL] =
569 g_signal_new ("select_all",
570 G_TYPE_FROM_CLASS (gobject_class),
571 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
572 G_STRUCT_OFFSET (GtkIconViewClass, select_all),
574 g_cclosure_marshal_VOID__VOID,
577 icon_view_signals[UNSELECT_ALL] =
578 g_signal_new ("unselect_all",
579 G_TYPE_FROM_CLASS (gobject_class),
580 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
581 G_STRUCT_OFFSET (GtkIconViewClass, unselect_all),
583 g_cclosure_marshal_VOID__VOID,
586 icon_view_signals[SELECT_CURSOR_ITEM] =
587 g_signal_new ("select_cursor_item",
588 G_TYPE_FROM_CLASS (gobject_class),
589 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
590 G_STRUCT_OFFSET (GtkIconViewClass, select_cursor_item),
592 g_cclosure_marshal_VOID__VOID,
595 icon_view_signals[TOGGLE_CURSOR_ITEM] =
596 g_signal_new ("toggle_cursor_item",
597 G_TYPE_FROM_CLASS (gobject_class),
598 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
599 G_STRUCT_OFFSET (GtkIconViewClass, toggle_cursor_item),
601 g_cclosure_marshal_VOID__VOID,
604 icon_view_signals[ACTIVATE_CURSOR_ITEM] =
605 g_signal_new ("activate_cursor_item",
606 G_TYPE_FROM_CLASS (gobject_class),
607 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
608 G_STRUCT_OFFSET (GtkIconViewClass, activate_cursor_item),
610 _gtk_marshal_BOOLEAN__VOID,
613 icon_view_signals[MOVE_CURSOR] =
614 g_signal_new ("move_cursor",
615 G_TYPE_FROM_CLASS (gobject_class),
616 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
617 G_STRUCT_OFFSET (GtkIconViewClass, move_cursor),
619 _gtk_marshal_BOOLEAN__ENUM_INT,
621 GTK_TYPE_MOVEMENT_STEP,
625 gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK, "select_all", 0);
626 gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "unselect_all", 0);
627 gtk_binding_entry_add_signal (binding_set, GDK_space, 0, "select_cursor_item", 0);
628 gtk_binding_entry_add_signal (binding_set, GDK_space, GDK_CONTROL_MASK, "toggle_cursor_item", 0);
630 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, "activate_cursor_item", 0);
631 gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0, "activate_cursor_item", 0);
632 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, "activate_cursor_item", 0);
634 gtk_icon_view_add_move_binding (binding_set, GDK_Up, 0,
635 GTK_MOVEMENT_DISPLAY_LINES, -1);
636 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Up, 0,
637 GTK_MOVEMENT_DISPLAY_LINES, -1);
639 gtk_icon_view_add_move_binding (binding_set, GDK_Down, 0,
640 GTK_MOVEMENT_DISPLAY_LINES, 1);
641 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Down, 0,
642 GTK_MOVEMENT_DISPLAY_LINES, 1);
644 gtk_icon_view_add_move_binding (binding_set, GDK_p, GDK_CONTROL_MASK,
645 GTK_MOVEMENT_DISPLAY_LINES, -1);
647 gtk_icon_view_add_move_binding (binding_set, GDK_n, GDK_CONTROL_MASK,
648 GTK_MOVEMENT_DISPLAY_LINES, 1);
650 gtk_icon_view_add_move_binding (binding_set, GDK_Home, 0,
651 GTK_MOVEMENT_BUFFER_ENDS, -1);
652 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Home, 0,
653 GTK_MOVEMENT_BUFFER_ENDS, -1);
655 gtk_icon_view_add_move_binding (binding_set, GDK_End, 0,
656 GTK_MOVEMENT_BUFFER_ENDS, 1);
657 gtk_icon_view_add_move_binding (binding_set, GDK_KP_End, 0,
658 GTK_MOVEMENT_BUFFER_ENDS, 1);
660 gtk_icon_view_add_move_binding (binding_set, GDK_Page_Up, 0,
661 GTK_MOVEMENT_PAGES, -1);
662 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Page_Up, 0,
663 GTK_MOVEMENT_PAGES, -1);
665 gtk_icon_view_add_move_binding (binding_set, GDK_Page_Down, 0,
666 GTK_MOVEMENT_PAGES, 1);
667 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Page_Down, 0,
668 GTK_MOVEMENT_PAGES, 1);
670 gtk_icon_view_add_move_binding (binding_set, GDK_Right, 0,
671 GTK_MOVEMENT_VISUAL_POSITIONS, 1);
672 gtk_icon_view_add_move_binding (binding_set, GDK_Left, 0,
673 GTK_MOVEMENT_VISUAL_POSITIONS, -1);
675 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Right, 0,
676 GTK_MOVEMENT_VISUAL_POSITIONS, 1);
677 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Left, 0,
678 GTK_MOVEMENT_VISUAL_POSITIONS, -1);
682 gtk_icon_view_init (GtkIconView *icon_view)
684 icon_view->priv = GTK_ICON_VIEW_GET_PRIVATE (icon_view);
686 icon_view->priv->width = 0;
687 icon_view->priv->height = 0;
688 icon_view->priv->selection_mode = GTK_SELECTION_SINGLE;
690 icon_view->priv->pressed_button = -1;
691 icon_view->priv->press_start_x = -1;
692 icon_view->priv->press_start_y = -1;
694 icon_view->priv->text_column = -1;
695 icon_view->priv->markup_column = -1;
696 icon_view->priv->pixbuf_column = -1;
698 icon_view->priv->layout = gtk_widget_create_pango_layout (GTK_WIDGET (icon_view), NULL);
700 pango_layout_set_wrap (icon_view->priv->layout, PANGO_WRAP_WORD_CHAR);
702 GTK_WIDGET_SET_FLAGS (icon_view, GTK_CAN_FOCUS);
704 gtk_icon_view_set_adjustments (icon_view, NULL, NULL);
706 icon_view->priv->orientation = GTK_ORIENTATION_VERTICAL;
708 icon_view->priv->columns = -1;
709 icon_view->priv->item_width = -1;
710 icon_view->priv->spacing = 0;
711 icon_view->priv->row_spacing = 6;
712 icon_view->priv->column_spacing = 6;
713 icon_view->priv->margin = 6;
717 gtk_icon_view_destroy (GtkObject *object)
719 GtkIconView *icon_view;
721 icon_view = GTK_ICON_VIEW (object);
723 gtk_icon_view_set_model (icon_view, NULL);
725 if (icon_view->priv->layout_idle_id != 0)
726 g_source_remove (icon_view->priv->layout_idle_id);
728 if (icon_view->priv->scroll_timeout_id != 0)
729 g_source_remove (icon_view->priv->scroll_timeout_id);
731 (GTK_OBJECT_CLASS (parent_class)->destroy) (object);
734 /* GObject methods */
736 gtk_icon_view_finalize (GObject *object)
738 GtkIconView *icon_view;
740 icon_view = GTK_ICON_VIEW (object);
742 g_object_unref (icon_view->priv->layout);
744 (G_OBJECT_CLASS (parent_class)->finalize) (object);
749 gtk_icon_view_set_property (GObject *object,
754 GtkIconView *icon_view;
756 icon_view = GTK_ICON_VIEW (object);
760 case PROP_SELECTION_MODE:
761 gtk_icon_view_set_selection_mode (icon_view, g_value_get_enum (value));
763 case PROP_PIXBUF_COLUMN:
764 gtk_icon_view_set_pixbuf_column (icon_view, g_value_get_int (value));
766 case PROP_TEXT_COLUMN:
767 gtk_icon_view_set_text_column (icon_view, g_value_get_int (value));
769 case PROP_MARKUP_COLUMN:
770 gtk_icon_view_set_markup_column (icon_view, g_value_get_int (value));
773 gtk_icon_view_set_model (icon_view, g_value_get_object (value));
775 case PROP_ORIENTATION:
776 gtk_icon_view_set_orientation (icon_view, g_value_get_enum (value));
779 gtk_icon_view_set_columns (icon_view, g_value_get_int (value));
781 case PROP_ITEM_WIDTH:
782 gtk_icon_view_set_item_width (icon_view, g_value_get_int (value));
785 gtk_icon_view_set_spacing (icon_view, g_value_get_int (value));
787 case PROP_ROW_SPACING:
788 gtk_icon_view_set_row_spacing (icon_view, g_value_get_int (value));
790 case PROP_COLUMN_SPACING:
791 gtk_icon_view_set_column_spacing (icon_view, g_value_get_int (value));
794 gtk_icon_view_set_margin (icon_view, g_value_get_int (value));
798 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
804 gtk_icon_view_get_property (GObject *object,
809 GtkIconView *icon_view;
811 icon_view = GTK_ICON_VIEW (object);
815 case PROP_SELECTION_MODE:
816 g_value_set_enum (value, icon_view->priv->selection_mode);
818 case PROP_PIXBUF_COLUMN:
819 g_value_set_int (value, icon_view->priv->pixbuf_column);
821 case PROP_TEXT_COLUMN:
822 g_value_set_int (value, icon_view->priv->text_column);
824 case PROP_MARKUP_COLUMN:
825 g_value_set_int (value, icon_view->priv->markup_column);
828 g_value_set_object (value, icon_view->priv->model);
830 case PROP_ORIENTATION:
831 g_value_set_enum (value, icon_view->priv->orientation);
834 g_value_set_int (value, icon_view->priv->columns);
836 case PROP_ITEM_WIDTH:
837 g_value_set_int (value, icon_view->priv->item_width);
840 g_value_set_int (value, icon_view->priv->spacing);
842 case PROP_ROW_SPACING:
843 g_value_set_int (value, icon_view->priv->row_spacing);
845 case PROP_COLUMN_SPACING:
846 g_value_set_int (value, icon_view->priv->column_spacing);
849 g_value_set_int (value, icon_view->priv->margin);
853 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
858 /* GtkWidget signals */
860 gtk_icon_view_realize (GtkWidget *widget)
862 GtkIconView *icon_view;
863 GdkWindowAttr attributes;
864 gint attributes_mask;
866 icon_view = GTK_ICON_VIEW (widget);
868 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
870 /* Make the main, clipping window */
871 attributes.window_type = GDK_WINDOW_CHILD;
872 attributes.x = widget->allocation.x;
873 attributes.y = widget->allocation.y;
874 attributes.width = widget->allocation.width;
875 attributes.height = widget->allocation.height;
876 attributes.wclass = GDK_INPUT_OUTPUT;
877 attributes.visual = gtk_widget_get_visual (widget);
878 attributes.colormap = gtk_widget_get_colormap (widget);
879 attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
881 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
883 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
884 &attributes, attributes_mask);
885 gdk_window_set_user_data (widget->window, widget);
887 /* Make the window for the icon view */
890 attributes.width = MAX (icon_view->priv->width, widget->allocation.width);
891 attributes.height = MAX (icon_view->priv->height, widget->allocation.height);
892 attributes.event_mask = (GDK_EXPOSURE_MASK |
894 GDK_POINTER_MOTION_MASK |
895 GDK_BUTTON_PRESS_MASK |
896 GDK_BUTTON_RELEASE_MASK |
898 GDK_KEY_RELEASE_MASK) |
899 gtk_widget_get_events (widget);
901 icon_view->priv->bin_window = gdk_window_new (widget->window,
902 &attributes, attributes_mask);
903 gdk_window_set_user_data (icon_view->priv->bin_window, widget);
905 widget->style = gtk_style_attach (widget->style, widget->window);
906 gdk_window_set_background (icon_view->priv->bin_window, &widget->style->base[widget->state]);
907 gdk_window_set_background (widget->window, &widget->style->base[widget->state]);
911 gtk_icon_view_unrealize (GtkWidget *widget)
913 GtkIconView *icon_view;
915 icon_view = GTK_ICON_VIEW (widget);
917 gdk_window_set_user_data (icon_view->priv->bin_window, NULL);
918 gdk_window_destroy (icon_view->priv->bin_window);
919 icon_view->priv->bin_window = NULL;
921 /* GtkWidget::unrealize destroys children and widget->window */
922 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
923 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
927 gtk_icon_view_map (GtkWidget *widget)
929 GtkIconView *icon_view;
931 icon_view = GTK_ICON_VIEW (widget);
933 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
935 gdk_window_show (icon_view->priv->bin_window);
936 gdk_window_show (widget->window);
940 gtk_icon_view_size_request (GtkWidget *widget,
941 GtkRequisition *requisition)
943 GtkIconView *icon_view;
945 icon_view = GTK_ICON_VIEW (widget);
947 requisition->width = icon_view->priv->width;
948 requisition->height = icon_view->priv->height;
952 gtk_icon_view_size_allocate (GtkWidget *widget,
953 GtkAllocation *allocation)
955 GtkIconView *icon_view;
956 GtkAdjustment *hadjustment, *vadjustment;
958 widget->allocation = *allocation;
960 icon_view = GTK_ICON_VIEW (widget);
962 if (GTK_WIDGET_REALIZED (widget))
964 gdk_window_move_resize (widget->window,
965 allocation->x, allocation->y,
966 allocation->width, allocation->height);
967 gdk_window_resize (icon_view->priv->bin_window,
968 MAX (icon_view->priv->width, allocation->width),
969 MAX (icon_view->priv->height, allocation->height));
972 hadjustment = icon_view->priv->hadjustment;
973 vadjustment = icon_view->priv->vadjustment;
975 hadjustment->page_size = allocation->width;
976 hadjustment->page_increment = allocation->width * 0.9;
977 hadjustment->step_increment = allocation->width * 0.1;
978 hadjustment->lower = 0;
979 hadjustment->upper = MAX (allocation->width, icon_view->priv->width);
981 if (hadjustment->value > hadjustment->upper - hadjustment->page_size)
982 gtk_adjustment_set_value (hadjustment, MAX (0, hadjustment->upper - hadjustment->page_size));
984 gtk_adjustment_changed (hadjustment);
986 vadjustment->page_size = allocation->height;
987 vadjustment->page_increment = allocation->height * 0.9;
988 vadjustment->step_increment = allocation->height * 0.1;
989 vadjustment->lower = 0;
990 vadjustment->upper = MAX (allocation->height, icon_view->priv->height);
992 if (vadjustment->value > vadjustment->upper - vadjustment->page_size)
993 gtk_adjustment_set_value (vadjustment, MAX (0, vadjustment->upper - vadjustment->page_size));
995 gtk_adjustment_changed (vadjustment);
997 gtk_icon_view_layout (icon_view);
1001 gtk_icon_view_expose (GtkWidget *widget,
1002 GdkEventExpose *expose)
1004 GtkIconView *icon_view;
1008 icon_view = GTK_ICON_VIEW (widget);
1010 if (expose->window != icon_view->priv->bin_window)
1013 cr = gdk_drawable_create_cairo_context (icon_view->priv->bin_window);
1014 cairo_set_line_width (cr, 1.);
1016 for (icons = icon_view->priv->items; icons; icons = icons->next) {
1017 GtkIconViewItem *item = icons->data;
1018 GdkRectangle item_rectangle;
1020 item_rectangle.x = item->x;
1021 item_rectangle.y = item->y;
1022 item_rectangle.width = item->width;
1023 item_rectangle.height = item->height;
1025 if (gdk_region_rect_in (expose->region, &item_rectangle) == GDK_OVERLAP_RECTANGLE_OUT)
1028 #ifdef DEBUG_ICON_VIEW
1029 cairo_rectangle (cr,
1030 item->x + 0.5, item->y + 0.5,
1031 item->width - 1, item->height - 1);
1032 cairo_rectangle (cr,
1033 item->x + 0.5, item->y + 0.5,
1034 item->width - 1, item->height- 1);
1035 cairo_rectangle (cr,
1036 item->pixbuf_x + 0.5, item->pixbuf_y + 0.5,
1037 item->pixbuf_width - 1, item->pixbuf_height- 1);
1038 cairo_rectangle (cr,
1039 item->layout_x + 0.5, item->layout_y + 0.5,
1040 item->layout_width - 1, item->layout_height - 1);
1043 gtk_icon_view_paint_item (icon_view, cr, item, &expose->area);
1047 if (icon_view->priv->doing_rubberband)
1049 GdkRectangle *rectangles;
1052 gdk_region_get_rectangles (expose->region,
1056 while (n_rectangles--)
1057 gtk_icon_view_paint_rubberband (icon_view, cr, &rectangles[n_rectangles]);
1059 g_free (rectangles);
1068 scroll_timeout (gpointer data)
1070 GtkIconView *icon_view;
1073 GDK_THREADS_ENTER ();
1077 value = MIN (icon_view->priv->vadjustment->value +
1078 icon_view->priv->scroll_value_diff,
1079 icon_view->priv->vadjustment->upper -
1080 icon_view->priv->vadjustment->page_size);
1082 gtk_adjustment_set_value (icon_view->priv->vadjustment,
1085 gtk_icon_view_update_rubberband (icon_view);
1087 GDK_THREADS_LEAVE ();
1093 gtk_icon_view_motion (GtkWidget *widget,
1094 GdkEventMotion *event)
1096 GtkIconView *icon_view;
1099 icon_view = GTK_ICON_VIEW (widget);
1101 gtk_icon_view_maybe_begin_dragging_items (icon_view, event);
1103 if (icon_view->priv->doing_rubberband)
1105 gtk_icon_view_update_rubberband (widget);
1107 abs_y = event->y - icon_view->priv->height *
1108 (icon_view->priv->vadjustment->value /
1109 (icon_view->priv->vadjustment->upper -
1110 icon_view->priv->vadjustment->lower));
1112 if (abs_y < 0 || abs_y > widget->allocation.height)
1114 if (icon_view->priv->scroll_timeout_id == 0)
1115 icon_view->priv->scroll_timeout_id = g_timeout_add (30, scroll_timeout, icon_view);
1118 icon_view->priv->scroll_value_diff = abs_y;
1120 icon_view->priv->scroll_value_diff = abs_y - widget->allocation.height;
1122 icon_view->priv->event_last_x = event->x;
1123 icon_view->priv->event_last_y = event->y;
1125 else if (icon_view->priv->scroll_timeout_id != 0)
1127 g_source_remove (icon_view->priv->scroll_timeout_id);
1129 icon_view->priv->scroll_timeout_id = 0;
1137 gtk_icon_view_button_press (GtkWidget *widget,
1138 GdkEventButton *event)
1140 GtkIconView *icon_view;
1141 GtkIconViewItem *item;
1142 gboolean dirty = FALSE;
1144 icon_view = GTK_ICON_VIEW (widget);
1146 if (event->window != icon_view->priv->bin_window)
1149 if (!GTK_WIDGET_HAS_FOCUS (widget))
1150 gtk_widget_grab_focus (widget);
1152 if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
1155 item = gtk_icon_view_get_item_at_pos (icon_view,
1156 event->x, event->y);
1160 gtk_icon_view_scroll_to_item (icon_view, item);
1162 if (icon_view->priv->selection_mode == GTK_SELECTION_NONE)
1164 gtk_icon_view_set_cursor_item (icon_view, item);
1166 else if (icon_view->priv->selection_mode == GTK_SELECTION_MULTIPLE &&
1167 (event->state & GDK_SHIFT_MASK))
1169 gtk_icon_view_unselect_all_internal (icon_view);
1171 gtk_icon_view_set_cursor_item (icon_view, item);
1172 if (!icon_view->priv->anchor_item)
1173 icon_view->priv->anchor_item = item;
1175 gtk_icon_view_select_all_between (icon_view,
1176 icon_view->priv->anchor_item,
1182 if ((icon_view->priv->selection_mode == GTK_SELECTION_MULTIPLE ||
1183 ((icon_view->priv->selection_mode == GTK_SELECTION_SINGLE) && item->selected)) &&
1184 (event->state & GDK_CONTROL_MASK))
1186 item->selected = !item->selected;
1187 gtk_icon_view_queue_draw_item (icon_view, item);
1192 if (!item->selected)
1194 gtk_icon_view_unselect_all_internal (icon_view);
1196 item->selected = TRUE;
1197 gtk_icon_view_queue_draw_item (icon_view, item);
1201 gtk_icon_view_set_cursor_item (icon_view, item);
1202 icon_view->priv->anchor_item = item;
1205 /* Save press to possibly begin a drag */
1206 if (icon_view->priv->pressed_button < 0)
1208 icon_view->priv->pressed_button = event->button;
1209 icon_view->priv->press_start_x = event->x;
1210 icon_view->priv->press_start_y = event->y;
1213 if (!icon_view->priv->last_single_clicked)
1214 icon_view->priv->last_single_clicked = item;
1218 if (icon_view->priv->selection_mode != GTK_SELECTION_BROWSE &&
1219 !(event->state & GDK_CONTROL_MASK))
1221 dirty = gtk_icon_view_unselect_all_internal (icon_view);
1224 if (icon_view->priv->selection_mode == GTK_SELECTION_MULTIPLE)
1225 gtk_icon_view_start_rubberbanding (icon_view, event->x, event->y);
1230 if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
1232 item = gtk_icon_view_get_item_at_pos (icon_view,
1233 event->x, event->y);
1235 if (item && item == icon_view->priv->last_single_clicked)
1239 path = gtk_tree_path_new_from_indices (item->index, -1);
1240 gtk_icon_view_item_activated (icon_view, path);
1241 gtk_tree_path_free (path);
1244 icon_view->priv->last_single_clicked = NULL;
1248 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
1250 return event->button == 1;
1254 gtk_icon_view_button_release (GtkWidget *widget,
1255 GdkEventButton *event)
1257 GtkIconView *icon_view;
1259 icon_view = GTK_ICON_VIEW (widget);
1262 if (icon_view->priv->pressed_button == event->button)
1263 icon_view->priv->pressed_button = -1;
1265 gtk_icon_view_stop_rubberbanding (icon_view);
1267 if (icon_view->priv->scroll_timeout_id != 0)
1269 g_source_remove (icon_view->priv->scroll_timeout_id);
1270 icon_view->priv->scroll_timeout_id = 0;
1277 gtk_icon_view_update_rubberband (gpointer data)
1279 GtkIconView *icon_view;
1281 GdkRectangle old_area;
1282 GdkRectangle new_area;
1283 GdkRectangle common;
1284 GdkRegion *invalid_region;
1286 icon_view = GTK_ICON_VIEW (data);
1288 gdk_window_get_pointer (icon_view->priv->bin_window, &x, &y, NULL);
1293 old_area.x = MIN (icon_view->priv->rubberband_x1,
1294 icon_view->priv->rubberband_x2);
1295 old_area.y = MIN (icon_view->priv->rubberband_y1,
1296 icon_view->priv->rubberband_y2);
1297 old_area.width = ABS (icon_view->priv->rubberband_x2 -
1298 icon_view->priv->rubberband_x1) + 1;
1299 old_area.height = ABS (icon_view->priv->rubberband_y2 -
1300 icon_view->priv->rubberband_y1) + 1;
1302 new_area.x = MIN (icon_view->priv->rubberband_x1, x);
1303 new_area.y = MIN (icon_view->priv->rubberband_y1, y);
1304 new_area.width = ABS (x - icon_view->priv->rubberband_x1) + 1;
1305 new_area.height = ABS (y - icon_view->priv->rubberband_y1) + 1;
1307 invalid_region = gdk_region_rectangle (&old_area);
1308 gdk_region_union_with_rect (invalid_region, &new_area);
1310 gdk_rectangle_intersect (&old_area, &new_area, &common);
1311 if (common.width > 2 && common.height > 2)
1313 GdkRegion *common_region;
1315 /* make sure the border is invalidated */
1321 common_region = gdk_region_rectangle (&common);
1323 gdk_region_subtract (invalid_region, common_region);
1324 gdk_region_destroy (common_region);
1327 gdk_window_invalidate_region (icon_view->priv->bin_window, invalid_region, TRUE);
1329 gdk_region_destroy (invalid_region);
1331 icon_view->priv->rubberband_x2 = x;
1332 icon_view->priv->rubberband_y2 = y;
1334 gtk_icon_view_update_rubberband_selection (icon_view);
1338 gtk_icon_view_start_rubberbanding (GtkIconView *icon_view,
1344 g_assert (!icon_view->priv->doing_rubberband);
1346 for (items = icon_view->priv->items; items; items = items->next)
1348 GtkIconViewItem *item = items->data;
1350 item->selected_before_rubberbanding = item->selected;
1353 icon_view->priv->rubberband_x1 = x;
1354 icon_view->priv->rubberband_y1 = y;
1355 icon_view->priv->rubberband_x2 = x;
1356 icon_view->priv->rubberband_y2 = y;
1358 icon_view->priv->doing_rubberband = TRUE;
1360 gtk_grab_add (GTK_WIDGET (icon_view));
1364 gtk_icon_view_stop_rubberbanding (GtkIconView *icon_view)
1366 if (!icon_view->priv->doing_rubberband)
1369 icon_view->priv->doing_rubberband = FALSE;
1371 gtk_grab_remove (GTK_WIDGET (icon_view));
1373 gtk_widget_queue_draw (GTK_WIDGET (icon_view));
1377 gtk_icon_view_update_rubberband_selection (GtkIconView *icon_view)
1380 gint x, y, width, height;
1381 gboolean dirty = FALSE;
1383 x = MIN (icon_view->priv->rubberband_x1,
1384 icon_view->priv->rubberband_x2);
1385 y = MIN (icon_view->priv->rubberband_y1,
1386 icon_view->priv->rubberband_y2);
1387 width = ABS (icon_view->priv->rubberband_x1 -
1388 icon_view->priv->rubberband_x2);
1389 height = ABS (icon_view->priv->rubberband_y1 -
1390 icon_view->priv->rubberband_y2);
1392 for (items = icon_view->priv->items; items; items = items->next)
1394 GtkIconViewItem *item = items->data;
1398 is_in = gtk_icon_view_item_hit_test (item, x, y, width, height);
1400 selected = is_in ^ item->selected_before_rubberbanding;
1402 if (item->selected != selected)
1404 item->selected = selected;
1406 gtk_icon_view_queue_draw_item (icon_view, item);
1411 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
1415 gtk_icon_view_item_hit_test (GtkIconViewItem *item,
1421 /* First try the pixbuf */
1422 if (MIN (x + width, item->pixbuf_x + item->pixbuf_width) - MAX (x, item->pixbuf_x) > 0 &&
1423 MIN (y + height, item->pixbuf_y + item->pixbuf_height) - MAX (y, item->pixbuf_y) > 0)
1426 /* Then try the text */
1427 if (MIN (x + width, item->layout_x + item->layout_width) - MAX (x, item->layout_x) > 0 &&
1428 MIN (y + height, item->layout_y + item->layout_height) - MAX (y, item->layout_y) > 0)
1436 gtk_icon_view_maybe_begin_dragging_items (GtkIconView *icon_view,
1437 GdkEventMotion *event)
1439 gboolean retval = FALSE;
1441 if (icon_view->priv->pressed_button < 0)
1444 if (!gtk_drag_check_threshold (GTK_WIDGET (icon_view),
1445 icon_view->priv->press_start_x,
1446 icon_view->priv->press_start_y,
1447 event->x, event->y))
1450 button = icon_view->priv->pressed_button;
1451 icon_view->priv->pressed_button = -1;
1454 static GtkTargetEntry row_targets[] = {
1455 { "GTK_ICON_VIEW_ITEMS", GTK_TARGET_SAME_APP, 0 }
1457 GtkTargetList *target_list;
1458 GdkDragContext *context;
1459 GtkIconViewItem *item;
1463 target_list = gtk_target_list_new (row_targets, G_N_ELEMENTS (row_targets));
1465 context = gtk_drag_begin (GTK_WIDGET (icon_view),
1466 target_list, GDK_ACTION_MOVE,
1470 item = gtk_icon_view_get_item_at_pos (icon_view,
1471 icon_view->priv->press_start_x,
1472 icon_view->priv->press_start_y);
1473 g_assert (item != NULL);
1474 gtk_drag_set_icon_pixbuf (context, gtk_icon_view_get_item_icon (icon_view, item),
1476 event->y - item->y);
1484 gtk_icon_view_unselect_all_internal (GtkIconView *icon_view)
1486 gboolean dirty = FALSE;
1489 if (icon_view->priv->selection_mode == GTK_SELECTION_NONE)
1492 for (items = icon_view->priv->items; items; items = items->next)
1494 GtkIconViewItem *item = items->data;
1498 item->selected = FALSE;
1500 gtk_icon_view_queue_draw_item (icon_view, item);
1508 /* GtkIconView signals */
1510 gtk_icon_view_set_adjustments (GtkIconView *icon_view,
1511 GtkAdjustment *hadj,
1512 GtkAdjustment *vadj)
1514 gboolean need_adjust = FALSE;
1517 g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
1519 hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
1521 g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
1523 vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
1525 if (icon_view->priv->hadjustment && (icon_view->priv->hadjustment != hadj))
1527 g_signal_handlers_disconnect_matched (icon_view->priv->hadjustment, G_SIGNAL_MATCH_DATA,
1528 0, 0, NULL, NULL, icon_view);
1529 g_object_unref (icon_view->priv->hadjustment);
1532 if (icon_view->priv->vadjustment && (icon_view->priv->vadjustment != vadj))
1534 g_signal_handlers_disconnect_matched (icon_view->priv->vadjustment, G_SIGNAL_MATCH_DATA,
1535 0, 0, NULL, NULL, icon_view);
1536 g_object_unref (icon_view->priv->vadjustment);
1539 if (icon_view->priv->hadjustment != hadj)
1541 icon_view->priv->hadjustment = hadj;
1542 g_object_ref (icon_view->priv->hadjustment);
1543 gtk_object_sink (GTK_OBJECT (icon_view->priv->hadjustment));
1545 g_signal_connect (icon_view->priv->hadjustment, "value_changed",
1546 G_CALLBACK (gtk_icon_view_adjustment_changed),
1551 if (icon_view->priv->vadjustment != vadj)
1553 icon_view->priv->vadjustment = vadj;
1554 g_object_ref (icon_view->priv->vadjustment);
1555 gtk_object_sink (GTK_OBJECT (icon_view->priv->vadjustment));
1557 g_signal_connect (icon_view->priv->vadjustment, "value_changed",
1558 G_CALLBACK (gtk_icon_view_adjustment_changed),
1564 gtk_icon_view_adjustment_changed (NULL, icon_view);
1568 gtk_icon_view_real_select_all (GtkIconView *icon_view)
1570 gtk_icon_view_select_all (icon_view);
1574 gtk_icon_view_real_unselect_all (GtkIconView *icon_view)
1576 gtk_icon_view_unselect_all (icon_view);
1580 gtk_icon_view_real_select_cursor_item (GtkIconView *icon_view)
1582 gtk_icon_view_unselect_all (icon_view);
1584 if (icon_view->priv->cursor_item != NULL)
1585 gtk_icon_view_select_item (icon_view, icon_view->priv->cursor_item);
1589 gtk_icon_view_real_activate_cursor_item (GtkIconView *icon_view)
1593 if (!icon_view->priv->cursor_item)
1596 path = gtk_tree_path_new_from_indices (icon_view->priv->cursor_item->index, -1);
1598 gtk_icon_view_item_activated (icon_view, path);
1600 gtk_tree_path_free (path);
1606 gtk_icon_view_real_toggle_cursor_item (GtkIconView *icon_view)
1608 if (!icon_view->priv->cursor_item)
1611 switch (icon_view->priv->selection_mode)
1613 case GTK_SELECTION_NONE:
1615 case GTK_SELECTION_BROWSE:
1616 gtk_icon_view_select_item (icon_view, icon_view->priv->cursor_item);
1618 case GTK_SELECTION_SINGLE:
1619 if (icon_view->priv->cursor_item->selected)
1620 gtk_icon_view_unselect_item (icon_view, icon_view->priv->cursor_item);
1622 gtk_icon_view_select_item (icon_view, icon_view->priv->cursor_item);
1624 case GTK_SELECTION_MULTIPLE:
1625 icon_view->priv->cursor_item->selected = !icon_view->priv->cursor_item->selected;
1626 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
1628 gtk_icon_view_queue_draw_item (icon_view, icon_view->priv->cursor_item);
1633 /* Internal functions */
1635 gtk_icon_view_adjustment_changed (GtkAdjustment *adjustment,
1636 GtkIconView *icon_view)
1638 if (GTK_WIDGET_REALIZED (icon_view))
1640 gdk_window_move (icon_view->priv->bin_window,
1641 - icon_view->priv->hadjustment->value,
1642 - icon_view->priv->vadjustment->value);
1644 if (icon_view->priv->doing_rubberband)
1645 gtk_icon_view_update_rubberband (GTK_WIDGET (icon_view));
1647 gdk_window_process_updates (icon_view->priv->bin_window, TRUE);
1652 gtk_icon_view_layout_single_row (GtkIconView *icon_view,
1657 gint *maximum_width)
1659 gint focus_width, focus_pad;
1660 gint x, current_width, max_height, max_pixbuf_height;
1661 GList *items, *last_item;
1664 gboolean rtl = gtk_widget_get_direction (GTK_WIDGET (icon_view)) == GTK_TEXT_DIR_RTL;
1669 max_pixbuf_height = 0;
1673 gtk_widget_style_get (GTK_WIDGET (icon_view),
1674 "focus-line-width", &focus_width,
1675 "focus-padding", &focus_pad,
1678 x += icon_view->priv->margin;
1679 current_width += 2 * icon_view->priv->margin;
1684 GtkIconViewItem *item = items->data;
1686 gtk_icon_view_calculate_item_size (icon_view, item, item_width);
1688 colspan = 1 + (item->width - 1) / (item_width + icon_view->priv->column_spacing);
1689 current_width += colspan * (item_width + icon_view->priv->column_spacing);
1691 if (items != first_item)
1693 if ((icon_view->priv->columns <= 0 && current_width > GTK_WIDGET (icon_view)->allocation.width) ||
1694 (icon_view->priv->columns > 0 && col >= icon_view->priv->columns))
1699 item->x = rtl ? GTK_WIDGET (icon_view)->allocation.width - MAX (item_width, item->width) - x : x;
1701 if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
1705 item->layout_x = item->x + ICON_TEXT_PADDING + focus_width + focus_pad;
1706 if (icon_view->priv->text_column != -1 ||
1707 icon_view->priv->markup_column != -1)
1708 item->pixbuf_x = item->x + 2 * (ICON_TEXT_PADDING + focus_width + focus_pad) + icon_view->priv->spacing + item->layout_width;
1710 item->pixbuf_x = item->x;
1714 item->pixbuf_x = item->x;
1715 if (icon_view->priv->pixbuf_column != -1)
1716 item->layout_x = item->x + item->pixbuf_width + icon_view->priv->spacing + ICON_TEXT_PADDING + focus_width + focus_pad;
1718 item->layout_x = item->x + ICON_TEXT_PADDING + focus_width + focus_pad;
1723 if (item->width < colspan * item_width + (colspan - 1) * icon_view->priv->column_spacing)
1724 item->x += (colspan * item_width + (colspan - 1) * icon_view->priv->column_spacing - item->width) / 2;
1726 item->pixbuf_x = item->x + (item->width - item->pixbuf_width) / 2;
1727 item->layout_x = item->x + (item->width - item->layout_width) / 2;
1730 x = current_width - icon_view->priv->margin;
1732 max_height = MAX (max_height, item->height);
1733 max_pixbuf_height = MAX (max_pixbuf_height, item->pixbuf_height);
1735 if (current_width > *maximum_width)
1736 *maximum_width = current_width;
1742 items = items->next;
1747 *y += max_height + icon_view->priv->row_spacing;
1749 /* Now go through the row again and align the icons */
1750 for (items = first_item; items != last_item; items = items->next)
1752 GtkIconViewItem *item = items->data;
1754 if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
1756 item->pixbuf_y = item->y;
1757 item->layout_y = item->y + ICON_TEXT_PADDING + focus_width + focus_pad;
1761 item->pixbuf_y = item->y + (max_pixbuf_height - item->pixbuf_height);
1762 if (icon_view->priv->pixbuf_column != -1)
1763 item->layout_y = item->pixbuf_y + item->pixbuf_height + icon_view->priv->spacing + ICON_TEXT_PADDING + focus_width + focus_pad;
1765 item->layout_y = item->y + ICON_TEXT_PADDING + focus_width + focus_pad;
1767 /* Update the bounding box */
1768 item->y = item->pixbuf_y;
1770 /* We may want to readjust the new y coordinate. */
1771 if (item->y + item->height > *y)
1772 *y = item->y + item->height;
1775 item->col = col - 1 - item->col;
1782 gtk_icon_view_set_adjustment_upper (GtkAdjustment *adj,
1785 if (upper != adj->upper)
1787 gdouble min = MAX (0.0, upper - adj->page_size);
1788 gboolean value_changed = FALSE;
1792 if (adj->value > min)
1795 value_changed = TRUE;
1798 gtk_adjustment_changed (adj);
1801 gtk_adjustment_value_changed (adj);
1806 gtk_icon_view_layout (GtkIconView *icon_view)
1808 gint y = 0, maximum_width = 0;
1814 if (!VALID_MODEL_AND_COLUMNS (icon_view))
1817 widget = GTK_WIDGET (icon_view);
1819 item_width = icon_view->priv->item_width;
1823 for (icons = icon_view->priv->items; icons; icons = icons->next)
1825 GtkIconViewItem *item = icons->data;
1826 gtk_icon_view_calculate_item_size (icon_view, item, -1);
1827 item_width = MAX (item_width, item->width);
1828 gtk_icon_view_item_invalidate_size (item);
1832 icons = icon_view->priv->items;
1833 y += icon_view->priv->margin;
1838 icons = gtk_icon_view_layout_single_row (icon_view, icons,
1840 &y, &maximum_width);
1843 while (icons != NULL);
1845 if (maximum_width != icon_view->priv->width)
1847 icon_view->priv->width = maximum_width;
1849 y += icon_view->priv->margin;
1851 if (y != icon_view->priv->height)
1853 icon_view->priv->height = y;
1856 gtk_icon_view_set_adjustment_upper (icon_view->priv->hadjustment, icon_view->priv->width);
1857 gtk_icon_view_set_adjustment_upper (icon_view->priv->vadjustment, icon_view->priv->height);
1859 if (GTK_WIDGET_REALIZED (icon_view))
1861 gdk_window_resize (icon_view->priv->bin_window,
1862 MAX (icon_view->priv->width, widget->allocation.width),
1863 MAX (icon_view->priv->height, widget->allocation.height));
1866 if (icon_view->priv->layout_idle_id != 0)
1868 g_source_remove (icon_view->priv->layout_idle_id);
1869 icon_view->priv->layout_idle_id = 0;
1872 gtk_widget_queue_draw (GTK_WIDGET (icon_view));
1875 /* Updates the pango layout and calculates the size */
1877 gtk_icon_view_calculate_item_size (GtkIconView *icon_view,
1878 GtkIconViewItem *item,
1881 gint focus_width, focus_pad;
1882 gint layout_width, layout_height;
1883 gint maximum_layout_width;
1884 gint spacing, padding;
1888 if (item->width != -1 && item->height != -1)
1891 gtk_widget_style_get (GTK_WIDGET (icon_view),
1892 "focus-line-width", &focus_width,
1893 "focus-padding", &focus_pad,
1896 spacing = icon_view->priv->spacing;
1898 if (icon_view->priv->pixbuf_column != -1)
1900 pixbuf = gtk_icon_view_get_item_icon (icon_view, item);
1901 item->pixbuf_width = gdk_pixbuf_get_width (pixbuf);
1902 item->pixbuf_height = gdk_pixbuf_get_height (pixbuf);
1903 g_object_unref (pixbuf);
1907 item->pixbuf_width = 0;
1908 item->pixbuf_height = 0;
1912 if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
1915 colspan = item->pixbuf_width / item_width + 1;
1916 maximum_layout_width = MAX (colspan * item_width - item->pixbuf_width - icon_view->priv->spacing - 2 * (ICON_TEXT_PADDING + focus_width + focus_pad), 50);
1919 maximum_layout_width = MAX (item_width, item->pixbuf_width);
1921 if (icon_view->priv->markup_column != -1 ||
1922 icon_view->priv->text_column != -1)
1924 gtk_icon_view_update_item_text (icon_view, item);
1926 pango_layout_set_alignment (icon_view->priv->layout, PANGO_ALIGN_CENTER);
1927 pango_layout_set_width (icon_view->priv->layout, maximum_layout_width * PANGO_SCALE);
1929 pango_layout_get_pixel_size (icon_view->priv->layout, &layout_width, &layout_height);
1931 item->layout_width = layout_width;
1932 item->layout_height = layout_height;
1933 padding = 2 * (ICON_TEXT_PADDING + focus_width + focus_pad);
1937 item->layout_width = 0;
1938 item->layout_height = 0;
1943 if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
1945 item->width = item->layout_width + padding + spacing + item->pixbuf_width;
1946 item->height = MAX (item->layout_height + padding, item->pixbuf_height);
1950 item->width = MAX (item->layout_width + padding, item->pixbuf_width);
1951 item->height = item->layout_height + padding + spacing + item->pixbuf_height;
1956 gtk_icon_view_invalidate_sizes (GtkIconView *icon_view)
1958 g_list_foreach (icon_view->priv->items,
1959 (GFunc)gtk_icon_view_item_invalidate_size, NULL);
1963 gtk_icon_view_item_invalidate_size (GtkIconViewItem *item)
1970 create_colorized_pixbuf (GdkPixbuf *src, GdkColor *new_color)
1973 gint width, height, has_alpha, src_row_stride, dst_row_stride;
1974 gint red_value, green_value, blue_value;
1975 guchar *target_pixels;
1976 guchar *original_pixels;
1981 red_value = new_color->red / 255.0;
1982 green_value = new_color->green / 255.0;
1983 blue_value = new_color->blue / 255.0;
1985 dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src),
1986 gdk_pixbuf_get_has_alpha (src),
1987 gdk_pixbuf_get_bits_per_sample (src),
1988 gdk_pixbuf_get_width (src),
1989 gdk_pixbuf_get_height (src));
1991 has_alpha = gdk_pixbuf_get_has_alpha (src);
1992 width = gdk_pixbuf_get_width (src);
1993 height = gdk_pixbuf_get_height (src);
1994 src_row_stride = gdk_pixbuf_get_rowstride (src);
1995 dst_row_stride = gdk_pixbuf_get_rowstride (dest);
1996 target_pixels = gdk_pixbuf_get_pixels (dest);
1997 original_pixels = gdk_pixbuf_get_pixels (src);
1999 for (i = 0; i < height; i++) {
2000 pixdest = target_pixels + i*dst_row_stride;
2001 pixsrc = original_pixels + i*src_row_stride;
2002 for (j = 0; j < width; j++) {
2003 *pixdest++ = (*pixsrc++ * red_value) >> 8;
2004 *pixdest++ = (*pixsrc++ * green_value) >> 8;
2005 *pixdest++ = (*pixsrc++ * blue_value) >> 8;
2007 *pixdest++ = *pixsrc++;
2015 gtk_icon_view_paint_item (GtkIconView *icon_view,
2017 GtkIconViewItem *item,
2020 gint focus_width, focus_pad;
2021 GdkPixbuf *pixbuf, *tmp;
2023 gboolean rtl = gtk_widget_get_direction (GTK_WIDGET (icon_view)) == GTK_TEXT_DIR_RTL;
2025 if (!VALID_MODEL_AND_COLUMNS (icon_view))
2028 gtk_widget_style_get (GTK_WIDGET (icon_view),
2029 "focus-line-width", &focus_width,
2030 "focus-padding", &focus_pad,
2033 if (GTK_WIDGET_HAS_FOCUS (icon_view))
2034 state = GTK_STATE_SELECTED;
2036 state = GTK_STATE_ACTIVE;
2038 if (icon_view->priv->pixbuf_column != -1)
2040 tmp = gtk_icon_view_get_item_icon (icon_view, item);
2043 pixbuf = create_colorized_pixbuf (tmp,
2044 >K_WIDGET (icon_view)->style->base[state]);
2045 g_object_unref (tmp);
2050 cairo_move_to (cr, item->pixbuf_x, item->pixbuf_y);
2051 gdk_pixbuf_set_as_cairo_source (pixbuf, cr);
2052 g_object_unref (pixbuf);
2054 cairo_rectangle (cr,
2055 item->pixbuf_x, item->pixbuf_y,
2056 item->pixbuf_width, item->pixbuf_height);
2060 if (icon_view->priv->text_column != -1 ||
2061 icon_view->priv->markup_column != -1)
2065 gdk_cairo_set_source_color (cr, >K_WIDGET (icon_view)->style->base[state]);
2066 cairo_rectangle (cr,
2067 item->layout_x - ICON_TEXT_PADDING,
2068 item->layout_y - ICON_TEXT_PADDING,
2069 item->layout_width + 2 * ICON_TEXT_PADDING,
2070 item->layout_height + 2 * ICON_TEXT_PADDING);
2074 gtk_icon_view_update_item_text (icon_view, item);
2075 pango_layout_set_alignment (icon_view->priv->layout, rtl ? PANGO_ALIGN_RIGHT: PANGO_ALIGN_LEFT);
2076 pango_layout_set_width (icon_view->priv->layout, item->layout_width * PANGO_SCALE);
2077 gtk_paint_layout (GTK_WIDGET (icon_view)->style,
2078 icon_view->priv->bin_window,
2079 item->selected ? state : GTK_STATE_NORMAL,
2080 TRUE, area, GTK_WIDGET (icon_view), "icon_view",
2083 icon_view->priv->layout);
2085 if (GTK_WIDGET_HAS_FOCUS (icon_view) &&
2086 item == icon_view->priv->cursor_item)
2087 gtk_paint_focus (GTK_WIDGET (icon_view)->style,
2088 icon_view->priv->bin_window,
2091 GTK_WIDGET (icon_view),
2093 item->layout_x - ICON_TEXT_PADDING - focus_width - focus_pad,
2094 item->layout_y - ICON_TEXT_PADDING - focus_width - focus_pad,
2095 item->layout_width + 2 * (ICON_TEXT_PADDING + focus_width + focus_pad),
2096 item->layout_height + 2 * (ICON_TEXT_PADDING + focus_width + focus_pad));
2101 gtk_icon_view_paint_rubberband (GtkIconView *icon_view,
2106 GdkRectangle rubber_rect;
2107 GdkColor *fill_color_gdk;
2108 guchar fill_color_alpha;
2110 rubber_rect.x = MIN (icon_view->priv->rubberband_x1, icon_view->priv->rubberband_x2);
2111 rubber_rect.y = MIN (icon_view->priv->rubberband_y1, icon_view->priv->rubberband_y2);
2112 rubber_rect.width = ABS (icon_view->priv->rubberband_x1 - icon_view->priv->rubberband_x2) + 1;
2113 rubber_rect.height = ABS (icon_view->priv->rubberband_y1 - icon_view->priv->rubberband_y2) + 1;
2115 if (!gdk_rectangle_intersect (&rubber_rect, area, &rect))
2118 gtk_widget_style_get (GTK_WIDGET (icon_view),
2119 "selection_box_color", &fill_color_gdk,
2120 "selection_box_alpha", &fill_color_alpha,
2123 if (!fill_color_gdk)
2124 fill_color_gdk = gdk_color_copy (>K_WIDGET (icon_view)->style->base[GTK_STATE_SELECTED]);
2126 gdk_cairo_set_source_color (cr, fill_color_gdk);
2127 cairo_set_alpha (cr, fill_color_alpha / 255.);
2130 cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height);
2134 cairo_set_alpha (cr, 1.0);
2135 cairo_rectangle (cr,
2136 rubber_rect.x + 0.5, rubber_rect.y + 0.5,
2137 rubber_rect.width - 1, rubber_rect.height - 1);
2141 gdk_color_free (fill_color_gdk);
2145 gtk_icon_view_queue_draw_item (GtkIconView *icon_view,
2146 GtkIconViewItem *item)
2152 rect.width = item->width;
2153 rect.height = item->height;
2155 if (icon_view->priv->bin_window)
2156 gdk_window_invalidate_rect (icon_view->priv->bin_window, &rect, TRUE);
2160 layout_callback (gpointer user_data)
2162 GtkIconView *icon_view;
2164 GDK_THREADS_ENTER ();
2166 icon_view = GTK_ICON_VIEW (user_data);
2168 icon_view->priv->layout_idle_id = 0;
2170 gtk_icon_view_layout (icon_view);
2172 GDK_THREADS_LEAVE();
2178 gtk_icon_view_queue_layout (GtkIconView *icon_view)
2180 if (icon_view->priv->layout_idle_id != 0)
2183 icon_view->priv->layout_idle_id = g_idle_add (layout_callback, icon_view);
2187 gtk_icon_view_set_cursor_item (GtkIconView *icon_view,
2188 GtkIconViewItem *item)
2191 AtkObject *item_obj;
2193 if (icon_view->priv->cursor_item == item)
2196 if (icon_view->priv->cursor_item != NULL)
2197 gtk_icon_view_queue_draw_item (icon_view, icon_view->priv->cursor_item);
2199 icon_view->priv->cursor_item = item;
2200 gtk_icon_view_queue_draw_item (icon_view, item);
2202 /* Notify that accessible focus object has changed */
2203 obj = gtk_widget_get_accessible (GTK_WIDGET (icon_view));
2204 item_obj = atk_object_ref_accessible_child (obj, item->index);
2206 if (item_obj != NULL)
2208 atk_focus_tracker_notify (item_obj);
2209 g_object_unref (item_obj);
2214 static GtkIconViewItem *
2215 gtk_icon_view_item_new (void)
2217 GtkIconViewItem *item;
2219 item = g_new0 (GtkIconViewItem, 1);
2228 gtk_icon_view_item_free (GtkIconViewItem *item)
2230 g_return_if_fail (item != NULL);
2236 gtk_icon_view_update_item_text (GtkIconView *icon_view,
2237 GtkIconViewItem *item)
2239 gboolean iters_persist;
2244 iters_persist = gtk_tree_model_get_flags (icon_view->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST;
2248 path = gtk_tree_path_new_from_indices (item->index, -1);
2249 gtk_tree_model_get_iter (icon_view->priv->model, &iter, path);
2250 gtk_tree_path_free (path);
2255 if (icon_view->priv->markup_column != -1)
2257 gtk_tree_model_get (icon_view->priv->model, &iter,
2258 icon_view->priv->markup_column, &text,
2260 pango_layout_set_markup (icon_view->priv->layout, text, -1);
2263 else if (icon_view->priv->text_column != -1)
2265 gtk_tree_model_get (icon_view->priv->model, &iter,
2266 icon_view->priv->text_column, &text,
2268 pango_layout_set_text (icon_view->priv->layout, text, -1);
2272 pango_layout_set_text (icon_view->priv->layout, "", -1);
2276 gtk_icon_view_get_item_icon (GtkIconView *icon_view,
2277 GtkIconViewItem *item)
2279 gboolean iters_persist;
2284 g_return_val_if_fail (item != NULL, NULL);
2286 iters_persist = gtk_tree_model_get_flags (icon_view->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST;
2290 path = gtk_tree_path_new_from_indices (item->index, -1);
2291 gtk_tree_model_get_iter (icon_view->priv->model, &iter, path);
2292 gtk_tree_path_free (path);
2297 gtk_tree_model_get (icon_view->priv->model, &iter,
2298 icon_view->priv->pixbuf_column, &pixbuf,
2305 static GtkIconViewItem *
2306 gtk_icon_view_get_item_at_pos (GtkIconView *icon_view,
2312 for (items = icon_view->priv->items; items; items = items->next)
2314 GtkIconViewItem *item = items->data;
2316 if (x > item->x && x < item->x + item->width &&
2317 y > item->y && y < item->y + item->height)
2319 /* Check if the mouse is inside the icon or the label */
2320 if ((x > item->pixbuf_x && x < item->pixbuf_x + item->pixbuf_width &&
2321 y > item->pixbuf_y && y < item->pixbuf_y + item->pixbuf_height) ||
2322 (x > item->layout_x - ICON_TEXT_PADDING &&
2323 x < item->layout_x + item->layout_width + ICON_TEXT_PADDING &&
2324 y > item->layout_y - ICON_TEXT_PADDING &&
2325 y < item->layout_y + item->layout_height + ICON_TEXT_PADDING))
2334 gtk_icon_view_select_item (GtkIconView *icon_view,
2335 GtkIconViewItem *item)
2337 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
2338 g_return_if_fail (item != NULL);
2343 if (icon_view->priv->selection_mode == GTK_SELECTION_NONE)
2345 else if (icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
2346 gtk_icon_view_unselect_all_internal (icon_view);
2348 item->selected = TRUE;
2350 gtk_icon_view_queue_draw_item (icon_view, item);
2352 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2357 gtk_icon_view_unselect_item (GtkIconView *icon_view,
2358 GtkIconViewItem *item)
2360 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
2361 g_return_if_fail (item != NULL);
2363 if (!item->selected)
2366 if (icon_view->priv->selection_mode == GTK_SELECTION_NONE ||
2367 icon_view->priv->selection_mode == GTK_SELECTION_BROWSE)
2370 item->selected = FALSE;
2372 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2374 gtk_icon_view_queue_draw_item (icon_view, item);
2378 verify_items (GtkIconView *icon_view)
2383 for (items = icon_view->priv->items; items; items = items->next)
2385 GtkIconViewItem *item = items->data;
2387 if (item->index != i)
2388 g_error ("List item does not match its index: item index %d and list index %d\n", item->index, i);
2395 gtk_icon_view_row_changed (GtkTreeModel *model,
2400 GtkIconViewItem *item;
2402 GtkIconView *icon_view;
2404 icon_view = GTK_ICON_VIEW (data);
2406 index = gtk_tree_path_get_indices(path)[0];
2407 item = g_list_nth (icon_view->priv->items, index)->data;
2409 gtk_icon_view_item_invalidate_size (item);
2410 gtk_icon_view_queue_layout (icon_view);
2412 verify_items (icon_view);
2416 gtk_icon_view_row_inserted (GtkTreeModel *model,
2422 GtkIconViewItem *item;
2423 gboolean iters_persist;
2424 GtkIconView *icon_view;
2427 icon_view = GTK_ICON_VIEW (data);
2428 iters_persist = gtk_tree_model_get_flags (icon_view->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST;
2430 length = gtk_tree_model_iter_n_children (model, NULL);
2431 index = gtk_tree_path_get_indices(path)[0];
2433 item = gtk_icon_view_item_new ();
2438 item->index = index;
2440 /* FIXME: We can be more efficient here,
2441 we can store a tail pointer and use that when
2442 appending (which is a rather common operation)
2444 icon_view->priv->items = g_list_insert (icon_view->priv->items,
2447 list = g_list_nth (icon_view->priv->items, index + 1);
2448 for (; list; list = list->next)
2455 verify_items (icon_view);
2459 gtk_icon_view_row_deleted (GtkTreeModel *model,
2464 GtkIconView *icon_view;
2465 GtkIconViewItem *item;
2467 gboolean emit = FALSE;
2469 icon_view = GTK_ICON_VIEW (data);
2471 index = gtk_tree_path_get_indices(path)[0];
2473 list = g_list_nth (icon_view->priv->items, index);
2476 if (item == icon_view->priv->anchor_item)
2477 icon_view->priv->anchor_item = NULL;
2479 if (item == icon_view->priv->cursor_item)
2480 icon_view->priv->cursor_item = NULL;
2485 gtk_icon_view_item_free (item);
2487 for (next = list->next; next; next = next->next)
2494 icon_view->priv->items = g_list_delete_link (icon_view->priv->items, list);
2496 gtk_icon_view_queue_layout (icon_view);
2498 verify_items (icon_view);
2501 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2505 gtk_icon_view_rows_reordered (GtkTreeModel *model,
2506 GtkTreePath *parent,
2513 GtkIconView *icon_view;
2514 GList *items = NULL, *list;
2515 GtkIconViewItem **item_array;
2518 icon_view = GTK_ICON_VIEW (data);
2520 length = gtk_tree_model_iter_n_children (model, NULL);
2522 order = g_new (gint, length);
2523 for (i = 0; i < length; i++)
2524 order [new_order[i]] = i;
2526 item_array = g_new (GtkIconViewItem *, length);
2527 for (i = 0, list = icon_view->priv->items; list != NULL; list = list->next, i++)
2528 item_array[order[i]] = list->data;
2531 for (i = length - 1; i >= 0; i--)
2533 item_array[i]->index = i;
2534 items = g_list_prepend (items, item_array[i]);
2537 g_free (item_array);
2538 g_list_free (icon_view->priv->items);
2539 icon_view->priv->items = items;
2541 verify_items (icon_view);
2545 gtk_icon_view_build_items (GtkIconView *icon_view)
2549 gboolean iters_persist;
2550 GList *items = NULL;
2552 iters_persist = gtk_tree_model_get_flags (icon_view->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST;
2554 if (!gtk_tree_model_get_iter_first (icon_view->priv->model,
2562 GtkIconViewItem *item = gtk_icon_view_item_new ();
2571 items = g_list_prepend (items, item);
2573 } while (gtk_tree_model_iter_next (icon_view->priv->model, &iter));
2575 icon_view->priv->items = g_list_reverse (items);
2579 gtk_icon_view_add_move_binding (GtkBindingSet *binding_set,
2582 GtkMovementStep step,
2586 gtk_binding_entry_add_signal (binding_set, keyval, modmask,
2591 gtk_binding_entry_add_signal (binding_set, keyval, GDK_SHIFT_MASK,
2596 if ((modmask & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
2599 gtk_binding_entry_add_signal (binding_set, keyval, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
2604 gtk_binding_entry_add_signal (binding_set, keyval, GDK_CONTROL_MASK,
2611 gtk_icon_view_real_move_cursor (GtkIconView *icon_view,
2612 GtkMovementStep step,
2615 GdkModifierType state;
2617 g_return_val_if_fail (GTK_ICON_VIEW (icon_view), FALSE);
2618 g_return_val_if_fail (step == GTK_MOVEMENT_LOGICAL_POSITIONS ||
2619 step == GTK_MOVEMENT_VISUAL_POSITIONS ||
2620 step == GTK_MOVEMENT_DISPLAY_LINES ||
2621 step == GTK_MOVEMENT_PAGES ||
2622 step == GTK_MOVEMENT_BUFFER_ENDS, FALSE);
2624 if (!GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (icon_view)))
2627 gtk_widget_grab_focus (GTK_WIDGET (icon_view));
2629 if (gtk_get_current_event_state (&state))
2631 if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
2632 icon_view->priv->ctrl_pressed = TRUE;
2633 if ((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
2634 icon_view->priv->shift_pressed = TRUE;
2636 /* else we assume not pressed */
2640 case GTK_MOVEMENT_LOGICAL_POSITIONS:
2641 case GTK_MOVEMENT_VISUAL_POSITIONS:
2642 gtk_icon_view_move_cursor_left_right (icon_view, count);
2644 case GTK_MOVEMENT_DISPLAY_LINES:
2645 gtk_icon_view_move_cursor_up_down (icon_view, count);
2647 case GTK_MOVEMENT_PAGES:
2648 gtk_icon_view_move_cursor_page_up_down (icon_view, count);
2650 case GTK_MOVEMENT_BUFFER_ENDS:
2651 gtk_icon_view_move_cursor_start_end (icon_view, count);
2654 g_assert_not_reached ();
2657 icon_view->priv->ctrl_pressed = FALSE;
2658 icon_view->priv->shift_pressed = FALSE;
2663 static GtkIconViewItem *
2664 find_item (GtkIconView *icon_view,
2665 GtkIconViewItem *current,
2671 GtkIconViewItem *item;
2673 /* FIXME: this could be more efficient
2675 row = current->row + row_ofs;
2676 col = current->col + col_ofs;
2678 for (items = icon_view->priv->items; items; items = items->next)
2681 if (item->row == row && item->col == col)
2689 static GtkIconViewItem *
2690 find_item_page_up_down (GtkIconView *icon_view,
2691 GtkIconViewItem *current,
2698 y = current->y + count * icon_view->priv->vadjustment->page_size;
2700 item = g_list_find (icon_view->priv->items, current);
2705 for (next = item->next; next; next = next->next)
2707 if (((GtkIconViewItem *)next->data)->col == col)
2710 if (!next || ((GtkIconViewItem *)next->data)->y > y)
2720 for (next = item->prev; next; next = next->prev)
2722 if (((GtkIconViewItem *)next->data)->col == col)
2725 if (!next || ((GtkIconViewItem *)next->data)->y < y)
2739 gtk_icon_view_select_all_between (GtkIconView *icon_view,
2740 GtkIconViewItem *anchor,
2741 GtkIconViewItem *cursor)
2744 GtkIconViewItem *item;
2745 gint row1, row2, col1, col2;
2746 gboolean dirty = FALSE;
2748 if (anchor->row < cursor->row)
2759 if (anchor->col < cursor->col)
2770 for (items = icon_view->priv->items; items; items = items->next)
2774 if (row1 <= item->row && item->row <= row2 &&
2775 col1 <= item->col && item->col <= col2)
2777 if (!item->selected)
2780 item->selected = TRUE;
2782 gtk_icon_view_queue_draw_item (icon_view, item);
2790 gtk_icon_view_move_cursor_up_down (GtkIconView *icon_view,
2793 GtkIconViewItem *item;
2794 gboolean dirty = FALSE;
2796 if (!GTK_WIDGET_HAS_FOCUS (icon_view))
2799 if (!icon_view->priv->cursor_item)
2804 list = icon_view->priv->items;
2806 list = g_list_last (icon_view->priv->items);
2808 item = list ? list->data : NULL;
2811 item = find_item (icon_view,
2812 icon_view->priv->cursor_item,
2818 if (icon_view->priv->ctrl_pressed ||
2819 !icon_view->priv->shift_pressed ||
2820 !icon_view->priv->anchor_item ||
2821 icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
2822 icon_view->priv->anchor_item = item;
2824 gtk_icon_view_set_cursor_item (icon_view, item);
2826 if (!icon_view->priv->ctrl_pressed &&
2827 icon_view->priv->selection_mode != GTK_SELECTION_NONE)
2829 gtk_icon_view_unselect_all_internal (icon_view);
2830 dirty = gtk_icon_view_select_all_between (icon_view,
2831 icon_view->priv->anchor_item,
2835 gtk_icon_view_scroll_to_item (icon_view, item);
2838 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2842 gtk_icon_view_move_cursor_page_up_down (GtkIconView *icon_view,
2845 GtkIconViewItem *item;
2846 gboolean dirty = FALSE;
2848 if (!GTK_WIDGET_HAS_FOCUS (icon_view))
2851 if (!icon_view->priv->cursor_item)
2856 list = icon_view->priv->items;
2858 list = g_list_last (icon_view->priv->items);
2860 item = list ? list->data : NULL;
2863 item = find_item_page_up_down (icon_view,
2864 icon_view->priv->cursor_item,
2870 if (icon_view->priv->ctrl_pressed ||
2871 !icon_view->priv->shift_pressed ||
2872 !icon_view->priv->anchor_item ||
2873 icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
2874 icon_view->priv->anchor_item = item;
2876 gtk_icon_view_set_cursor_item (icon_view, item);
2878 if (!icon_view->priv->ctrl_pressed &&
2879 icon_view->priv->selection_mode != GTK_SELECTION_NONE)
2881 gtk_icon_view_unselect_all_internal (icon_view);
2882 dirty = gtk_icon_view_select_all_between (icon_view,
2883 icon_view->priv->anchor_item,
2887 gtk_icon_view_scroll_to_item (icon_view, item);
2890 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2894 gtk_icon_view_move_cursor_left_right (GtkIconView *icon_view,
2897 GtkIconViewItem *item;
2898 gboolean dirty = FALSE;
2900 if (!GTK_WIDGET_HAS_FOCUS (icon_view))
2903 if (!icon_view->priv->cursor_item)
2908 list = icon_view->priv->items;
2910 list = g_list_last (icon_view->priv->items);
2912 item = list ? list->data : NULL;
2915 item = find_item (icon_view,
2916 icon_view->priv->cursor_item,
2922 if (icon_view->priv->ctrl_pressed ||
2923 !icon_view->priv->shift_pressed ||
2924 !icon_view->priv->anchor_item ||
2925 icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
2926 icon_view->priv->anchor_item = item;
2928 gtk_icon_view_set_cursor_item (icon_view, item);
2930 if (!icon_view->priv->ctrl_pressed &&
2931 icon_view->priv->selection_mode != GTK_SELECTION_NONE)
2933 gtk_icon_view_unselect_all_internal (icon_view);
2934 dirty = gtk_icon_view_select_all_between (icon_view,
2935 icon_view->priv->anchor_item,
2939 gtk_icon_view_scroll_to_item (icon_view, item);
2942 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2946 gtk_icon_view_move_cursor_start_end (GtkIconView *icon_view,
2949 GtkIconViewItem *item;
2951 gboolean dirty = FALSE;
2953 if (!GTK_WIDGET_HAS_FOCUS (icon_view))
2957 list = icon_view->priv->items;
2959 list = g_list_last (icon_view->priv->items);
2961 item = list ? list->data : NULL;
2966 if (icon_view->priv->ctrl_pressed ||
2967 !icon_view->priv->shift_pressed ||
2968 !icon_view->priv->anchor_item ||
2969 icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
2970 icon_view->priv->anchor_item = item;
2972 gtk_icon_view_set_cursor_item (icon_view, item);
2974 if (!icon_view->priv->ctrl_pressed &&
2975 icon_view->priv->selection_mode != GTK_SELECTION_NONE)
2977 gtk_icon_view_unselect_all (icon_view);
2978 dirty = gtk_icon_view_select_all_between (icon_view,
2979 icon_view->priv->anchor_item,
2983 gtk_icon_view_scroll_to_item (icon_view, item);
2986 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2990 gtk_icon_view_scroll_to_item (GtkIconView *icon_view,
2991 GtkIconViewItem *item)
2996 gdk_drawable_get_size (GDK_DRAWABLE (icon_view->priv->bin_window), NULL, &height);
2997 gdk_window_get_position (icon_view->priv->bin_window, NULL, &y);
2999 if (y + item->y < 0)
3001 value = icon_view->priv->vadjustment->value + y + item->y;
3002 gtk_adjustment_set_value (icon_view->priv->vadjustment, value);
3004 else if (y + item->y + item->height > GTK_WIDGET (icon_view)->allocation.height)
3006 value = icon_view->priv->vadjustment->value + y + item->y + item->height
3007 - GTK_WIDGET (icon_view)->allocation.height;
3008 gtk_adjustment_set_value (icon_view->priv->vadjustment, value);
3016 * gtk_icon_view_new:
3018 * Creates a new #GtkIconView widget
3020 * Return value: A newly created #GtkIconView widget
3025 gtk_icon_view_new (void)
3027 return g_object_new (GTK_TYPE_ICON_VIEW, NULL);
3031 * gtk_icon_view_new_with_model:
3032 * @model: The model.
3034 * Creates a new #GtkIconView widget with the model @model.
3036 * Return value: A newly created #GtkIconView widget.
3041 gtk_icon_view_new_with_model (GtkTreeModel *model)
3043 return g_object_new (GTK_TYPE_ICON_VIEW, "model", model, NULL);
3048 * gtk_icon_view_get_path_at_pos:
3049 * @icon_view: A #GtkIconView.
3050 * @x: The x position to be identified
3051 * @y: The y position to be identified
3053 * Finds the path at the point (@x, @y), relative to widget coordinates.
3055 * Return value: The #GtkTreePath corresponding to the icon or %NULL
3056 * if no icon exists at that position.
3061 gtk_icon_view_get_path_at_pos (GtkIconView *icon_view,
3065 GtkIconViewItem *item;
3068 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), NULL);
3070 item = gtk_icon_view_get_item_at_pos (icon_view, x, y);
3075 path = gtk_tree_path_new_from_indices (item->index, -1);
3081 * gtk_icon_view_selected_foreach:
3082 * @icon_view: A #GtkIconView.
3083 * @func: The funcion to call for each selected icon.
3084 * @data: User data to pass to the function.
3086 * Calls a function for each selected icon. Note that the model or
3087 * selection cannot be modified from within this function.
3092 gtk_icon_view_selected_foreach (GtkIconView *icon_view,
3093 GtkIconViewForeachFunc func,
3098 for (list = icon_view->priv->items; list; list = list->next)
3100 GtkIconViewItem *item = list->data;
3101 GtkTreePath *path = gtk_tree_path_new_from_indices (item->index, -1);
3104 (* func) (icon_view, path, data);
3106 gtk_tree_path_free (path);
3111 * gtk_icon_view_set_selection_mode:
3112 * @icon_view: A #GtkIconView.
3113 * @mode: The selection mode
3115 * Sets the selection mode of the @icon_view.
3120 gtk_icon_view_set_selection_mode (GtkIconView *icon_view,
3121 GtkSelectionMode mode)
3123 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3125 if (mode == icon_view->priv->selection_mode)
3128 if (mode == GTK_SELECTION_NONE ||
3129 icon_view->priv->selection_mode == GTK_SELECTION_MULTIPLE)
3130 gtk_icon_view_unselect_all (icon_view);
3132 icon_view->priv->selection_mode = mode;
3134 g_object_notify (G_OBJECT (icon_view), "selection_mode");
3138 * gtk_icon_view_get_selection_mode:
3139 * @icon_view: A #GtkIconView.
3141 * Gets the selection mode of the @icon_view.
3143 * Return value: the current selection mode
3148 gtk_icon_view_get_selection_mode (GtkIconView *icon_view)
3150 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), GTK_SELECTION_SINGLE);
3152 return icon_view->priv->selection_mode;
3156 * gtk_icon_view_set_model:
3157 * @icon_view: A #GtkIconView.
3158 * @model: The model.
3160 * Sets the model for a #GtkIconView.
3161 * If the @icon_view already has a model set, it will remove
3162 * it before setting the new model. If @model is %NULL, then
3163 * it will unset the old model.
3168 gtk_icon_view_set_model (GtkIconView *icon_view,
3169 GtkTreeModel *model)
3171 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3172 g_return_if_fail (model == NULL || GTK_IS_TREE_MODEL (model));
3174 if (icon_view->priv->model == model)
3181 g_return_if_fail (gtk_tree_model_get_flags (model) & GTK_TREE_MODEL_LIST_ONLY);
3183 if (icon_view->priv->pixbuf_column != -1)
3185 column_type = gtk_tree_model_get_column_type (model,
3186 icon_view->priv->pixbuf_column);
3188 g_return_if_fail (column_type == GDK_TYPE_PIXBUF);
3191 if (icon_view->priv->text_column != -1)
3193 column_type = gtk_tree_model_get_column_type (model,
3194 icon_view->priv->text_column);
3196 g_return_if_fail (column_type == G_TYPE_STRING);
3199 if (icon_view->priv->markup_column != -1)
3201 column_type = gtk_tree_model_get_column_type (model,
3202 icon_view->priv->markup_column);
3204 g_return_if_fail (column_type == G_TYPE_STRING);
3209 if (icon_view->priv->model)
3211 g_signal_handlers_disconnect_by_func (icon_view->priv->model,
3212 gtk_icon_view_row_changed,
3214 g_signal_handlers_disconnect_by_func (icon_view->priv->model,
3215 gtk_icon_view_row_inserted,
3217 g_signal_handlers_disconnect_by_func (icon_view->priv->model,
3218 gtk_icon_view_row_deleted,
3220 g_signal_handlers_disconnect_by_func (icon_view->priv->model,
3221 gtk_icon_view_rows_reordered,
3224 g_object_unref (icon_view->priv->model);
3226 g_list_foreach (icon_view->priv->items, (GFunc)gtk_icon_view_item_free, NULL);
3227 g_list_free (icon_view->priv->items);
3228 icon_view->priv->items = NULL;
3229 icon_view->priv->anchor_item = NULL;
3230 icon_view->priv->cursor_item = NULL;
3231 icon_view->priv->last_single_clicked = NULL;
3232 icon_view->priv->width = 0;
3233 icon_view->priv->height = 0;
3236 icon_view->priv->model = model;
3238 if (icon_view->priv->model)
3240 g_object_ref (icon_view->priv->model);
3241 g_signal_connect (icon_view->priv->model,
3243 G_CALLBACK (gtk_icon_view_row_changed),
3245 g_signal_connect (icon_view->priv->model,
3247 G_CALLBACK (gtk_icon_view_row_inserted),
3249 g_signal_connect (icon_view->priv->model,
3251 G_CALLBACK (gtk_icon_view_row_deleted),
3253 g_signal_connect (icon_view->priv->model,
3255 G_CALLBACK (gtk_icon_view_rows_reordered),
3258 gtk_icon_view_build_items (icon_view);
3260 gtk_icon_view_queue_layout (icon_view);
3263 g_object_notify (G_OBJECT (icon_view), "model");
3265 if (GTK_WIDGET_REALIZED (icon_view))
3266 gtk_widget_queue_resize (GTK_WIDGET (icon_view));
3270 * gtk_icon_view_get_model:
3271 * @icon_view: a #GtkIconView
3273 * Returns the model the #GtkIconView is based on. Returns %NULL if the
3276 * Return value: A #GtkTreeModel, or %NULL if none is currently being used.
3281 gtk_icon_view_get_model (GtkIconView *icon_view)
3283 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), NULL);
3285 return icon_view->priv->model;
3289 * gtk_icon_view_set_text_column:
3290 * @icon_view: A #GtkIconView.
3291 * @column: A column in the currently used model.
3293 * Sets the column with text for @icon_view to be @column. The text
3294 * column must be of type #G_TYPE_STRING.
3299 gtk_icon_view_set_text_column (GtkIconView *icon_view,
3302 if (column == icon_view->priv->text_column)
3306 icon_view->priv->text_column = -1;
3309 if (icon_view->priv->model != NULL)
3313 column_type = gtk_tree_model_get_column_type (icon_view->priv->model, column);
3315 g_return_if_fail (column_type == G_TYPE_STRING);
3318 icon_view->priv->text_column = column;
3321 gtk_icon_view_invalidate_sizes (icon_view);
3322 gtk_icon_view_queue_layout (icon_view);
3324 g_object_notify (G_OBJECT (icon_view), "text_column");
3328 * gtk_icon_view_get_text_column:
3329 * @icon_view: A #GtkIconView.
3331 * Returns the column with text for @icon_view.
3333 * Returns: the text column, or -1 if it's unset.
3338 gtk_icon_view_get_text_column (GtkIconView *icon_view)
3340 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3342 return icon_view->priv->text_column;
3346 * gtk_icon_view_set_markup_column:
3347 * @icon_view: A #GtkIconView.
3348 * @column: A column in the currently used model.
3350 * Sets the column with markup information for @icon_view to be
3351 * @column. The markup column must be of type #G_TYPE_STRING.
3352 * If the markup column is set to something, it overrides
3353 * the text column set by gtk_icon_view_set_text_column().
3358 gtk_icon_view_set_markup_column (GtkIconView *icon_view,
3361 if (column == icon_view->priv->markup_column)
3365 icon_view->priv->markup_column = -1;
3368 if (icon_view->priv->model != NULL)
3372 column_type = gtk_tree_model_get_column_type (icon_view->priv->model, column);
3374 g_return_if_fail (column_type == G_TYPE_STRING);
3377 icon_view->priv->markup_column = column;
3380 gtk_icon_view_invalidate_sizes (icon_view);
3381 gtk_icon_view_queue_layout (icon_view);
3383 g_object_notify (G_OBJECT (icon_view), "markup_column");
3387 * gtk_icon_view_get_markup_column:
3388 * @icon_view: A #GtkIconView.
3390 * Returns the column with markup text for @icon_view.
3392 * Returns: the markup column, or -1 if it's unset.
3397 gtk_icon_view_get_markup_column (GtkIconView *icon_view)
3399 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3401 return icon_view->priv->markup_column;
3405 * gtk_icon_view_set_pixbuf_column:
3406 * @icon_view: A #GtkIconView.
3407 * @column: A column in the currently used model.
3409 * Sets the column with pixbufs for @icon_view to be @column. The pixbuf
3410 * column must be of type #GDK_TYPE_PIXBUF
3415 gtk_icon_view_set_pixbuf_column (GtkIconView *icon_view,
3418 if (column == icon_view->priv->pixbuf_column)
3422 icon_view->priv->pixbuf_column = -1;
3425 if (icon_view->priv->model != NULL)
3429 column_type = gtk_tree_model_get_column_type (icon_view->priv->model, column);
3431 g_return_if_fail (column_type == GDK_TYPE_PIXBUF);
3434 icon_view->priv->pixbuf_column = column;
3437 gtk_icon_view_invalidate_sizes (icon_view);
3438 gtk_icon_view_queue_layout (icon_view);
3440 g_object_notify (G_OBJECT (icon_view), "pixbuf_column");
3445 * gtk_icon_view_get_pixbuf_column:
3446 * @icon_view: A #GtkIconView.
3448 * Returns the column with pixbufs for @icon_view.
3450 * Returns: the pixbuf column, or -1 if it's unset.
3455 gtk_icon_view_get_pixbuf_column (GtkIconView *icon_view)
3457 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3459 return icon_view->priv->pixbuf_column;
3463 * gtk_icon_view_select_path:
3464 * @icon_view: A #GtkIconView.
3465 * @path: The #GtkTreePath to be selected.
3467 * Selects the row at @path.
3472 gtk_icon_view_select_path (GtkIconView *icon_view,
3475 GtkIconViewItem *item;
3477 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3478 g_return_if_fail (icon_view->priv->model != NULL);
3479 g_return_if_fail (path != NULL);
3481 item = g_list_nth (icon_view->priv->items,
3482 gtk_tree_path_get_indices(path)[0])->data;
3487 gtk_icon_view_select_item (icon_view, item);
3491 * gtk_icon_view_unselect_path:
3492 * @icon_view: A #GtkIconView.
3493 * @path: The #GtkTreePath to be unselected.
3495 * Unselects the row at @path.
3500 gtk_icon_view_unselect_path (GtkIconView *icon_view,
3503 GtkIconViewItem *item;
3505 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3506 g_return_if_fail (icon_view->priv->model != NULL);
3507 g_return_if_fail (path != NULL);
3509 item = g_list_nth (icon_view->priv->items,
3510 gtk_tree_path_get_indices(path)[0])->data;
3515 gtk_icon_view_unselect_item (icon_view, item);
3519 * gtk_icon_view_get_selected_items:
3520 * @icon_view: A #GtkIconView.
3522 * Creates a list of paths of all selected items. Additionally, if you are
3523 * planning on modifying the model after calling this function, you may
3524 * want to convert the returned list into a list of #GtkTreeRowReference<!-- -->s.
3525 * To do this, you can use gtk_tree_row_reference_new().
3527 * To free the return value, use:
3528 * <informalexample><programlisting>
3529 * g_list_foreach (list, gtk_tree_path_free, NULL);
3530 * g_list_free (list);
3531 * </programlisting></informalexample>
3533 * Return value: A #GList containing a #GtkTreePath for each selected row.
3538 gtk_icon_view_get_selected_items (GtkIconView *icon_view)
3541 GList *selected = NULL;
3543 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), NULL);
3545 for (list = icon_view->priv->items; list != NULL; list = list->next)
3547 GtkIconViewItem *item = list->data;
3551 GtkTreePath *path = gtk_tree_path_new_from_indices (item->index, -1);
3553 selected = g_list_prepend (selected, path);
3561 * gtk_icon_view_select_all:
3562 * @icon_view: A #GtkIconView.
3564 * Selects all the icons. @icon_view must has its selection mode set
3565 * to #GTK_SELECTION_MULTIPLE.
3570 gtk_icon_view_select_all (GtkIconView *icon_view)
3573 gboolean dirty = FALSE;
3575 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3577 if (icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
3580 for (items = icon_view->priv->items; items; items = items->next)
3582 GtkIconViewItem *item = items->data;
3584 if (!item->selected)
3587 item->selected = TRUE;
3588 gtk_icon_view_queue_draw_item (icon_view, item);
3593 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
3597 * gtk_icon_view_unselect_all:
3598 * @icon_view: A #GtkIconView.
3600 * Unselects all the icons.
3605 gtk_icon_view_unselect_all (GtkIconView *icon_view)
3607 gboolean dirty = FALSE;
3609 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3611 if (icon_view->priv->selection_mode == GTK_SELECTION_BROWSE)
3614 dirty = gtk_icon_view_unselect_all_internal (icon_view);
3617 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
3621 * gtk_icon_view_path_is_selected:
3622 * @icon_view: A #GtkIconView.
3623 * @path: A #GtkTreePath to check selection on.
3625 * Returns %TRUE if the icon pointed to by @path is currently
3626 * selected. If @icon does not point to a valid location, %FALSE is returned.
3628 * Return value: %TRUE if @path is selected.
3633 gtk_icon_view_path_is_selected (GtkIconView *icon_view,
3636 GtkIconViewItem *item;
3638 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), FALSE);
3639 g_return_val_if_fail (icon_view->priv->model != NULL, FALSE);
3640 g_return_val_if_fail (path != NULL, FALSE);
3642 item = g_list_nth (icon_view->priv->items,
3643 gtk_tree_path_get_indices(path)[0])->data;
3648 return item->selected;
3652 * gtk_icon_view_item_activated:
3653 * @icon_view: A #GtkIconView
3654 * @path: The #GtkTreePath to be activated
3656 * Activates the item determined by @path.
3661 gtk_icon_view_item_activated (GtkIconView *icon_view,
3664 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3665 g_return_if_fail (path != NULL);
3667 g_signal_emit (icon_view, icon_view_signals[ITEM_ACTIVATED], 0, path);
3671 * gtk_icon_view_set_orientation:
3672 * @icon_view: a #GtkIconView
3673 * @orientation: the relative position of texts and icons
3675 * Sets the ::orientation property which determines whether the labels
3676 * are drawn beside the icons instead of below.
3681 gtk_icon_view_set_orientation (GtkIconView *icon_view,
3682 GtkOrientation orientation)
3684 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3686 if (icon_view->priv->orientation != orientation)
3688 icon_view->priv->orientation = orientation;
3690 gtk_icon_view_invalidate_sizes (icon_view);
3691 gtk_icon_view_queue_layout (icon_view);
3693 g_object_notify (G_OBJECT (icon_view), "orientation");
3698 * gtk_icon_view_get_orientation:
3699 * @icon_view: a #GtkIconView
3701 * Returns the value of the ::orientation property which determines
3702 * whether the labels are drawn beside the icons instead of below.
3704 * Return value: the relative position of texts and icons
3709 gtk_icon_view_get_orientation (GtkIconView *icon_view)
3711 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view),
3712 GTK_ORIENTATION_VERTICAL);
3714 return icon_view->priv->orientation;
3718 * gtk_icon_view_set_columns:
3719 * @icon_view: a #GtkIconView
3720 * @columns: the number of columns
3722 * Sets the ::columns property which determines in how
3723 * many columns the icons are arranged. If @columns is
3724 * -1, the number of columns will be chosen automatically
3725 * to fill the available area.
3730 gtk_icon_view_set_columns (GtkIconView *icon_view,
3733 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3735 if (icon_view->priv->columns != columns)
3737 icon_view->priv->columns = columns;
3739 gtk_icon_view_queue_layout (icon_view);
3741 g_object_notify (G_OBJECT (icon_view), "columns");
3746 * gtk_icon_view_get_columns:
3747 * @icon_view: a #GtkIconView
3749 * Returns the value of the ::columns property.
3751 * Return value: the number of columns, or -1
3756 gtk_icon_view_get_columns (GtkIconView *icon_view)
3758 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3760 return icon_view->priv->columns;
3764 * gtk_icon_view_set_item_width:
3765 * @icon_view: a #GtkIconView
3766 * @item_width: the width for each item
3768 * Sets the ::item-width property which specifies the width
3769 * to use for each item. If it is set to -1, the icon view will
3770 * automatically determine a suitable item size.
3775 gtk_icon_view_set_item_width (GtkIconView *icon_view,
3778 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3780 if (icon_view->priv->item_width != item_width)
3782 icon_view->priv->item_width = item_width;
3784 gtk_icon_view_invalidate_sizes (icon_view);
3785 gtk_icon_view_queue_layout (icon_view);
3787 g_object_notify (G_OBJECT (icon_view), "item-width");
3792 * gtk_icon_view_get_item_width:
3793 * @icon_view: a #GtkIconView
3795 * Returns the value of the ::item-width property.
3797 * Return value: the width of a single item, or -1
3802 gtk_icon_view_get_item_width (GtkIconView *icon_view)
3804 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3806 return icon_view->priv->item_width;
3811 * gtk_icon_view_set_item_width:
3812 * @icon_view: a #GtkIconView
3813 * @spacing: the spacing
3815 * Sets the ::spacing property which specifies the space
3816 * which is inserted between the cells (i.e. the icon and
3817 * the text) of an item.
3822 gtk_icon_view_set_spacing (GtkIconView *icon_view,
3825 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3827 if (icon_view->priv->spacing != spacing)
3829 icon_view->priv->spacing = spacing;
3831 gtk_icon_view_invalidate_sizes (icon_view);
3832 gtk_icon_view_queue_layout (icon_view);
3834 g_object_notify (G_OBJECT (icon_view), "spacing");
3839 * gtk_icon_view_get_spacing:
3840 * @icon_view: a #GtkIconView
3842 * Returns the value of the ::spacing property.
3844 * Return value: the space between cells
3849 gtk_icon_view_get_spacing (GtkIconView *icon_view)
3851 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3853 return icon_view->priv->spacing;
3857 * gtk_icon_view_set_row_spacing:
3858 * @icon_view: a #GtkIconView
3859 * @spacing: the row spacing
3861 * Sets the ::row-spacing property which specifies the space
3862 * which is inserted between the rows of the icon view.
3867 gtk_icon_view_set_row_spacing (GtkIconView *icon_view,
3870 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3872 if (icon_view->priv->row_spacing != row_spacing)
3874 icon_view->priv->row_spacing = row_spacing;
3876 gtk_icon_view_invalidate_sizes (icon_view);
3877 gtk_icon_view_queue_layout (icon_view);
3879 g_object_notify (G_OBJECT (icon_view), "row-spacing");
3884 * gtk_icon_view_get_row_spacing:
3885 * @icon_view: a #GtkIconView
3887 * Returns the value of the ::row-spacing property.
3889 * Return value: the space between rows
3894 gtk_icon_view_get_row_spacing (GtkIconView *icon_view)
3896 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3898 return icon_view->priv->row_spacing;
3902 * gtk_icon_view_set_column_spacing:
3903 * @icon_view: a #GtkIconView
3904 * @spacing: the column spacing
3906 * Sets the ::column-spacing property which specifies the space
3907 * which is inserted between the columns of the icon view.
3912 gtk_icon_view_set_column_spacing (GtkIconView *icon_view,
3913 gint column_spacing)
3915 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3917 if (icon_view->priv->column_spacing != column_spacing)
3919 icon_view->priv->column_spacing = column_spacing;
3921 gtk_icon_view_invalidate_sizes (icon_view);
3922 gtk_icon_view_queue_layout (icon_view);
3924 g_object_notify (G_OBJECT (icon_view), "column-spacing");
3929 * gtk_icon_view_get_column_spacing:
3930 * @icon_view: a #GtkIconView
3932 * Returns the value of the ::column-spacing property.
3934 * Return value: the space between columns
3939 gtk_icon_view_get_column_spacing (GtkIconView *icon_view)
3941 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3943 return icon_view->priv->column_spacing;
3947 * gtk_icon_view_set_marging:
3948 * @icon_view: a #GtkIconView
3949 * @spacing: the margin
3951 * Sets the ::margin property which specifies the space
3952 * which is inserted at the top, bottom, left and right
3958 gtk_icon_view_set_margin (GtkIconView *icon_view,
3961 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3963 if (icon_view->priv->margin != margin)
3965 icon_view->priv->margin = margin;
3967 gtk_icon_view_invalidate_sizes (icon_view);
3968 gtk_icon_view_queue_layout (icon_view);
3970 g_object_notify (G_OBJECT (icon_view), "margin");
3975 * gtk_icon_view_get_margin:
3976 * @icon_view: a #GtkIconView
3978 * Returns the value of the ::margin property.
3980 * Return value: the space at the borders
3985 gtk_icon_view_get_margin (GtkIconView *icon_view)
3987 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3989 return icon_view->priv->margin;
3993 /* Accessibility Support */
3995 static gpointer accessible_parent_class;
3996 static gpointer accessible_item_parent_class;
3997 static GQuark accessible_private_data_quark = 0;
3999 #define GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE (gtk_icon_view_item_accessible_get_type ())
4000 #define GTK_ICON_VIEW_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE, GtkIconViewItemAccessible))
4001 #define GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE))
4003 static GType gtk_icon_view_item_accessible_get_type (void);
4014 GtkIconViewItem *item;
4018 AtkStateSet *state_set;
4022 GtkTextBuffer *text_buffer;
4024 gchar *action_descriptions[LAST_ACTION];
4025 gchar *image_description;
4026 guint action_idle_handler;
4027 } GtkIconViewItemAccessible;
4029 static const gchar *const gtk_icon_view_item_accessible_action_names[] =
4035 static const gchar *const gtk_icon_view_item_accessible_action_descriptions[] =
4040 typedef struct _GtkIconViewItemAccessibleClass
4042 AtkObjectClass parent_class;
4044 } GtkIconViewItemAccessibleClass;
4046 static gboolean gtk_icon_view_item_accessible_is_showing (GtkIconViewItemAccessible *item);
4049 gtk_icon_view_item_accessible_idle_do_action (gpointer data)
4051 GtkIconViewItemAccessible *item;
4052 GtkIconView *icon_view;
4055 GDK_THREADS_ENTER ();
4057 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (data);
4058 item->action_idle_handler = 0;
4060 if (item->widget != NULL)
4062 icon_view = GTK_ICON_VIEW (item->widget);
4063 path = gtk_tree_path_new_from_indices (item->item->index, -1);
4064 gtk_icon_view_item_activated (icon_view, path);
4065 gtk_tree_path_free (path);
4068 GDK_THREADS_LEAVE ();
4074 gtk_icon_view_item_accessible_action_do_action (AtkAction *action,
4077 GtkIconViewItemAccessible *item;
4078 GtkIconView *icon_view;
4080 if (i < 0 || i >= LAST_ACTION)
4083 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
4085 if (!GTK_IS_ICON_VIEW (item->widget))
4088 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4091 icon_view = GTK_ICON_VIEW (item->widget);
4095 case ACTION_ACTIVATE:
4096 if (!item->action_idle_handler)
4097 item->action_idle_handler = g_idle_add (gtk_icon_view_item_accessible_idle_do_action, item);
4100 g_assert_not_reached ();
4108 gtk_icon_view_item_accessible_action_get_n_actions (AtkAction *action)
4113 static const gchar *
4114 gtk_icon_view_item_accessible_action_get_description (AtkAction *action,
4117 GtkIconViewItemAccessible *item;
4119 if (i < 0 || i >= LAST_ACTION)
4122 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
4124 if (item->action_descriptions[i])
4125 return item->action_descriptions[i];
4127 return gtk_icon_view_item_accessible_action_descriptions[i];
4130 static const gchar *
4131 gtk_icon_view_item_accessible_action_get_name (AtkAction *action,
4134 if (i < 0 || i >= LAST_ACTION)
4137 return gtk_icon_view_item_accessible_action_names[i];
4141 gtk_icon_view_item_accessible_action_set_description (AtkAction *action,
4143 const gchar *description)
4145 GtkIconViewItemAccessible *item;
4147 if (i < 0 || i >= LAST_ACTION)
4150 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
4152 if (item->action_descriptions[i])
4153 g_free (item->action_descriptions[i]);
4155 item->action_descriptions[i] = g_strdup (description);
4161 atk_action_item_interface_init (AtkActionIface *iface)
4163 iface->do_action = gtk_icon_view_item_accessible_action_do_action;
4164 iface->get_n_actions = gtk_icon_view_item_accessible_action_get_n_actions;
4165 iface->get_description = gtk_icon_view_item_accessible_action_get_description;
4166 iface->get_name = gtk_icon_view_item_accessible_action_get_name;
4167 iface->set_description = gtk_icon_view_item_accessible_action_set_description;
4170 static const gchar *
4171 gtk_icon_view_item_accessible_image_get_image_description (AtkImage *image)
4173 GtkIconViewItemAccessible *item;
4175 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
4177 return item->image_description;
4181 gtk_icon_view_item_accessible_image_set_image_description (AtkImage *image,
4182 const gchar *description)
4184 GtkIconViewItemAccessible *item;
4186 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
4188 g_free (item->image_description);
4189 item->image_description = g_strdup (item->image_description);
4195 gtk_icon_view_item_accessible_image_get_image_size (AtkImage *image,
4199 GtkIconViewItemAccessible *item;
4201 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
4203 if (!GTK_IS_ICON_VIEW (item->widget))
4206 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4209 *width = item->item->pixbuf_width;
4210 *height = item->item->pixbuf_height;
4214 gtk_icon_view_item_accessible_image_get_image_position (AtkImage *image,
4217 AtkCoordType coord_type)
4219 GtkIconViewItemAccessible *item;
4221 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
4223 if (!GTK_IS_ICON_VIEW (item->widget))
4226 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4229 atk_component_get_position (ATK_COMPONENT (image), x, y, coord_type);
4230 *x+= item->item->pixbuf_x - item->item->x;
4231 *y+= item->item->pixbuf_y - item->item->y;
4235 atk_image_item_interface_init (AtkImageIface *iface)
4237 iface->get_image_description = gtk_icon_view_item_accessible_image_get_image_description;
4238 iface->set_image_description = gtk_icon_view_item_accessible_image_set_image_description;
4239 iface->get_image_size = gtk_icon_view_item_accessible_image_get_image_size;
4240 iface->get_image_position = gtk_icon_view_item_accessible_image_get_image_position;
4244 gtk_icon_view_item_accessible_text_get_text (AtkText *text,
4248 GtkIconViewItemAccessible *item;
4249 GtkTextIter start, end;
4250 GtkTextBuffer *buffer;
4252 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4254 if (!GTK_IS_ICON_VIEW (item->widget))
4257 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4260 buffer = item->text_buffer;
4261 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
4263 gtk_text_buffer_get_end_iter (buffer, &end);
4265 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
4267 return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
4271 gtk_icon_view_item_accessible_text_get_character_at_offset (AtkText *text,
4274 GtkIconViewItemAccessible *item;
4275 GtkTextIter start, end;
4276 GtkTextBuffer *buffer;
4280 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4282 if (!GTK_IS_ICON_VIEW (item->widget))
4285 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4288 buffer = item->text_buffer;
4289 if (offset >= gtk_text_buffer_get_char_count (buffer))
4292 gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
4294 gtk_text_iter_forward_char (&end);
4295 string = gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
4296 unichar = g_utf8_get_char (string);
4303 get_pango_text_offsets (PangoLayout *layout,
4304 GtkTextBuffer *buffer,
4306 AtkTextBoundary boundary_type,
4310 GtkTextIter *start_iter,
4311 GtkTextIter *end_iter)
4313 PangoLayoutIter *iter;
4314 PangoLayoutLine *line, *prev_line = NULL, *prev_prev_line = NULL;
4315 gint index, start_index, end_index;
4317 gboolean found = FALSE;
4319 text = pango_layout_get_text (layout);
4320 index = g_utf8_offset_to_pointer (text, offset) - text;
4321 iter = pango_layout_get_iter (layout);
4324 line = pango_layout_iter_get_line (iter);
4325 start_index = line->start_index;
4326 end_index = start_index + line->length;
4328 if (index >= start_index && index <= end_index)
4331 * Found line for offset
4337 * We want the previous line
4341 switch (boundary_type)
4343 case ATK_TEXT_BOUNDARY_LINE_START:
4344 end_index = start_index;
4345 start_index = prev_line->start_index;
4347 case ATK_TEXT_BOUNDARY_LINE_END:
4349 start_index = prev_prev_line->start_index +
4350 prev_prev_line->length;
4351 end_index = prev_line->start_index + prev_line->length;
4354 g_assert_not_reached();
4358 start_index = end_index = 0;
4361 switch (boundary_type)
4363 case ATK_TEXT_BOUNDARY_LINE_START:
4364 if (pango_layout_iter_next_line (iter))
4365 end_index = pango_layout_iter_get_line (iter)->start_index;
4367 case ATK_TEXT_BOUNDARY_LINE_END:
4369 start_index = prev_line->start_index +
4373 g_assert_not_reached();
4378 * We want the next line
4380 if (pango_layout_iter_next_line (iter))
4382 line = pango_layout_iter_get_line (iter);
4383 switch (boundary_type)
4385 case ATK_TEXT_BOUNDARY_LINE_START:
4386 start_index = line->start_index;
4387 if (pango_layout_iter_next_line (iter))
4388 end_index = pango_layout_iter_get_line (iter)->start_index;
4390 end_index = start_index + line->length;
4392 case ATK_TEXT_BOUNDARY_LINE_END:
4393 start_index = end_index;
4394 end_index = line->start_index + line->length;
4397 g_assert_not_reached();
4401 start_index = end_index;
4407 prev_prev_line = prev_line;
4410 while (pango_layout_iter_next_line (iter));
4414 start_index = prev_line->start_index + prev_line->length;
4415 end_index = start_index;
4417 pango_layout_iter_free (iter);
4418 *start_offset = g_utf8_pointer_to_offset (text, text + start_index);
4419 *end_offset = g_utf8_pointer_to_offset (text, text + end_index);
4421 gtk_text_buffer_get_iter_at_offset (buffer, start_iter, *start_offset);
4422 gtk_text_buffer_get_iter_at_offset (buffer, end_iter, *end_offset);
4426 gtk_icon_view_item_accessible_text_get_text_before_offset (AtkText *text,
4428 AtkTextBoundary boundary_type,
4432 GtkIconViewItemAccessible *item;
4433 GtkTextIter start, end;
4434 GtkTextBuffer *buffer;
4435 GtkIconView *icon_view;
4437 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4439 if (!GTK_IS_ICON_VIEW (item->widget))
4442 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4445 buffer = item->text_buffer;
4447 if (!gtk_text_buffer_get_char_count (buffer))
4451 return g_strdup ("");
4453 gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
4457 switch (boundary_type)
4459 case ATK_TEXT_BOUNDARY_CHAR:
4460 gtk_text_iter_backward_char(&start);
4462 case ATK_TEXT_BOUNDARY_WORD_START:
4463 if (!gtk_text_iter_starts_word (&start))
4464 gtk_text_iter_backward_word_start (&start);
4466 gtk_text_iter_backward_word_start(&start);
4468 case ATK_TEXT_BOUNDARY_WORD_END:
4469 if (gtk_text_iter_inside_word (&start) &&
4470 !gtk_text_iter_starts_word (&start))
4471 gtk_text_iter_backward_word_start (&start);
4472 while (!gtk_text_iter_ends_word (&start))
4474 if (!gtk_text_iter_backward_char (&start))
4478 gtk_text_iter_backward_word_start(&start);
4479 while (!gtk_text_iter_ends_word (&start))
4481 if (!gtk_text_iter_backward_char (&start))
4485 case ATK_TEXT_BOUNDARY_SENTENCE_START:
4486 if (!gtk_text_iter_starts_sentence (&start))
4487 gtk_text_iter_backward_sentence_start (&start);
4489 gtk_text_iter_backward_sentence_start (&start);
4491 case ATK_TEXT_BOUNDARY_SENTENCE_END:
4492 if (gtk_text_iter_inside_sentence (&start) &&
4493 !gtk_text_iter_starts_sentence (&start))
4494 gtk_text_iter_backward_sentence_start (&start);
4495 while (!gtk_text_iter_ends_sentence (&start))
4497 if (!gtk_text_iter_backward_char (&start))
4501 gtk_text_iter_backward_sentence_start (&start);
4502 while (!gtk_text_iter_ends_sentence (&start))
4504 if (!gtk_text_iter_backward_char (&start))
4508 case ATK_TEXT_BOUNDARY_LINE_START:
4509 case ATK_TEXT_BOUNDARY_LINE_END:
4510 icon_view = GTK_ICON_VIEW (item->widget);
4511 gtk_icon_view_update_item_text (icon_view, item->item);
4512 get_pango_text_offsets (icon_view->priv->layout,
4524 *start_offset = gtk_text_iter_get_offset (&start);
4525 *end_offset = gtk_text_iter_get_offset (&end);
4527 return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
4531 gtk_icon_view_item_accessible_text_get_text_at_offset (AtkText *text,
4533 AtkTextBoundary boundary_type,
4537 GtkIconViewItemAccessible *item;
4538 GtkTextIter start, end;
4539 GtkTextBuffer *buffer;
4540 GtkIconView *icon_view;
4542 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4544 if (!GTK_IS_ICON_VIEW (item->widget))
4547 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4550 buffer = item->text_buffer;
4552 if (!gtk_text_buffer_get_char_count (buffer))
4556 return g_strdup ("");
4558 gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
4562 switch (boundary_type)
4564 case ATK_TEXT_BOUNDARY_CHAR:
4565 gtk_text_iter_forward_char (&end);
4567 case ATK_TEXT_BOUNDARY_WORD_START:
4568 if (!gtk_text_iter_starts_word (&start))
4569 gtk_text_iter_backward_word_start (&start);
4570 if (gtk_text_iter_inside_word (&end))
4571 gtk_text_iter_forward_word_end (&end);
4572 while (!gtk_text_iter_starts_word (&end))
4574 if (!gtk_text_iter_forward_char (&end))
4578 case ATK_TEXT_BOUNDARY_WORD_END:
4579 if (gtk_text_iter_inside_word (&start) &&
4580 !gtk_text_iter_starts_word (&start))
4581 gtk_text_iter_backward_word_start (&start);
4582 while (!gtk_text_iter_ends_word (&start))
4584 if (!gtk_text_iter_backward_char (&start))
4587 gtk_text_iter_forward_word_end (&end);
4589 case ATK_TEXT_BOUNDARY_SENTENCE_START:
4590 if (!gtk_text_iter_starts_sentence (&start))
4591 gtk_text_iter_backward_sentence_start (&start);
4592 if (gtk_text_iter_inside_sentence (&end))
4593 gtk_text_iter_forward_sentence_end (&end);
4594 while (!gtk_text_iter_starts_sentence (&end))
4596 if (!gtk_text_iter_forward_char (&end))
4600 case ATK_TEXT_BOUNDARY_SENTENCE_END:
4601 if (gtk_text_iter_inside_sentence (&start) &&
4602 !gtk_text_iter_starts_sentence (&start))
4603 gtk_text_iter_backward_sentence_start (&start);
4604 while (!gtk_text_iter_ends_sentence (&start))
4606 if (!gtk_text_iter_backward_char (&start))
4609 gtk_text_iter_forward_sentence_end (&end);
4611 case ATK_TEXT_BOUNDARY_LINE_START:
4612 case ATK_TEXT_BOUNDARY_LINE_END:
4613 icon_view = GTK_ICON_VIEW (item->widget);
4614 gtk_icon_view_update_item_text (icon_view, item->item);
4615 get_pango_text_offsets (icon_view->priv->layout,
4628 *start_offset = gtk_text_iter_get_offset (&start);
4629 *end_offset = gtk_text_iter_get_offset (&end);
4631 return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
4635 gtk_icon_view_item_accessible_text_get_text_after_offset (AtkText *text,
4637 AtkTextBoundary boundary_type,
4641 GtkIconViewItemAccessible *item;
4642 GtkTextIter start, end;
4643 GtkTextBuffer *buffer;
4644 GtkIconView *icon_view;
4646 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4648 if (!GTK_IS_ICON_VIEW (item->widget))
4651 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4654 buffer = item->text_buffer;
4656 if (!gtk_text_buffer_get_char_count (buffer))
4660 return g_strdup ("");
4662 gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
4666 switch (boundary_type)
4668 case ATK_TEXT_BOUNDARY_CHAR:
4669 gtk_text_iter_forward_char(&start);
4670 gtk_text_iter_forward_chars(&end, 2);
4672 case ATK_TEXT_BOUNDARY_WORD_START:
4673 if (gtk_text_iter_inside_word (&end))
4674 gtk_text_iter_forward_word_end (&end);
4675 while (!gtk_text_iter_starts_word (&end))
4677 if (!gtk_text_iter_forward_char (&end))
4681 if (!gtk_text_iter_is_end (&end))
4683 gtk_text_iter_forward_word_end (&end);
4684 while (!gtk_text_iter_starts_word (&end))
4686 if (!gtk_text_iter_forward_char (&end))
4691 case ATK_TEXT_BOUNDARY_WORD_END:
4692 gtk_text_iter_forward_word_end (&end);
4694 if (!gtk_text_iter_is_end (&end))
4695 gtk_text_iter_forward_word_end (&end);
4697 case ATK_TEXT_BOUNDARY_SENTENCE_START:
4698 if (gtk_text_iter_inside_sentence (&end))
4699 gtk_text_iter_forward_sentence_end (&end);
4700 while (!gtk_text_iter_starts_sentence (&end))
4702 if (!gtk_text_iter_forward_char (&end))
4706 if (!gtk_text_iter_is_end (&end))
4708 gtk_text_iter_forward_sentence_end (&end);
4709 while (!gtk_text_iter_starts_sentence (&end))
4711 if (!gtk_text_iter_forward_char (&end))
4716 case ATK_TEXT_BOUNDARY_SENTENCE_END:
4717 gtk_text_iter_forward_sentence_end (&end);
4719 if (!gtk_text_iter_is_end (&end))
4720 gtk_text_iter_forward_sentence_end (&end);
4722 case ATK_TEXT_BOUNDARY_LINE_START:
4723 case ATK_TEXT_BOUNDARY_LINE_END:
4724 icon_view = GTK_ICON_VIEW (item->widget);
4725 gtk_icon_view_update_item_text (icon_view, item->item);
4726 get_pango_text_offsets (icon_view->priv->layout,
4737 *start_offset = gtk_text_iter_get_offset (&start);
4738 *end_offset = gtk_text_iter_get_offset (&end);
4740 return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
4744 gtk_icon_view_item_accessible_text_get_character_count (AtkText *text)
4746 GtkIconViewItemAccessible *item;
4748 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4750 if (!GTK_IS_ICON_VIEW (item->widget))
4753 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4756 return gtk_text_buffer_get_char_count (item->text_buffer);
4760 gtk_icon_view_item_accessible_text_get_character_extents (AtkText *text,
4766 AtkCoordType coord_type)
4768 GtkIconViewItemAccessible *item;
4769 GtkIconView *icon_view;
4770 PangoRectangle char_rect;
4771 const gchar *item_text;
4774 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4776 if (!GTK_IS_ICON_VIEW (item->widget))
4779 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4782 icon_view = GTK_ICON_VIEW (item->widget);
4783 gtk_icon_view_update_item_text (icon_view, item->item);
4784 item_text = pango_layout_get_text (icon_view->priv->layout);
4785 index = g_utf8_offset_to_pointer (item_text, offset) - item_text;
4786 pango_layout_index_to_pos (icon_view->priv->layout, index, &char_rect);
4788 atk_component_get_position (ATK_COMPONENT (text), x, y, coord_type);
4789 *x += item->item->layout_x - item->item->x + char_rect.x / PANGO_SCALE;
4790 /* Look at gtk_icon_view_paint_item() to see where the text is. */
4791 *x -= ((item->item->width - item->item->layout_width) / 2) + (MAX (item->item->pixbuf_width, icon_view->priv->item_width) - item->item->width) / 2,
4792 *y += item->item->layout_y - item->item->y + char_rect.y / PANGO_SCALE;
4793 *width = char_rect.width / PANGO_SCALE;
4794 *height = char_rect.height / PANGO_SCALE;
4798 gtk_icon_view_item_accessible_text_get_offset_at_point (AtkText *text,
4801 AtkCoordType coord_type)
4803 GtkIconViewItemAccessible *item;
4804 GtkIconView *icon_view;
4805 const gchar *item_text;
4810 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4812 if (!GTK_IS_ICON_VIEW (item->widget))
4815 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4818 icon_view = GTK_ICON_VIEW (item->widget);
4819 gtk_icon_view_update_item_text (icon_view, item->item);
4820 atk_component_get_position (ATK_COMPONENT (text), &l_x, &l_y, coord_type);
4821 x -= l_x + item->item->layout_x - item->item->x;
4822 x += ((item->item->width - item->item->layout_width) / 2) + (MAX (item->item->pixbuf_width, icon_view->priv->item_width) - item->item->width) / 2,
4823 y -= l_y + item->item->layout_y - item->item->y;
4824 item_text = pango_layout_get_text (icon_view->priv->layout);
4825 if (!pango_layout_xy_to_index (icon_view->priv->layout,
4836 offset = g_utf8_strlen (item_text, -1);
4838 offset = g_utf8_pointer_to_offset (item_text, item_text + index);
4844 atk_text_item_interface_init (AtkTextIface *iface)
4846 iface->get_text = gtk_icon_view_item_accessible_text_get_text;
4847 iface->get_character_at_offset = gtk_icon_view_item_accessible_text_get_character_at_offset;
4848 iface->get_text_before_offset = gtk_icon_view_item_accessible_text_get_text_before_offset;
4849 iface->get_text_at_offset = gtk_icon_view_item_accessible_text_get_text_at_offset;
4850 iface->get_text_after_offset = gtk_icon_view_item_accessible_text_get_text_after_offset;
4851 iface->get_character_count = gtk_icon_view_item_accessible_text_get_character_count;
4852 iface->get_character_extents = gtk_icon_view_item_accessible_text_get_character_extents;
4853 iface->get_offset_at_point = gtk_icon_view_item_accessible_text_get_offset_at_point;
4857 gtk_icon_view_item_accessible_get_extents (AtkComponent *component,
4862 AtkCoordType coord_type)
4864 GtkIconViewItemAccessible *item;
4865 AtkObject *parent_obj;
4868 g_return_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component));
4870 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (component);
4871 if (!GTK_IS_WIDGET (item->widget))
4874 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4877 *width = item->item->width;
4878 *height = item->item->height;
4879 if (gtk_icon_view_item_accessible_is_showing (item))
4881 parent_obj = gtk_widget_get_accessible (item->widget);
4882 atk_component_get_position (ATK_COMPONENT (parent_obj), &l_x, &l_y, coord_type);
4883 *x = l_x + item->item->x;
4884 *y = l_y + item->item->y;
4894 gtk_icon_view_item_accessible_grab_focus (AtkComponent *component)
4896 GtkIconViewItemAccessible *item;
4897 GtkWidget *toplevel;
4899 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component), FALSE);
4901 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (component);
4902 if (!GTK_IS_WIDGET (item->widget))
4905 gtk_widget_grab_focus (item->widget);
4906 gtk_icon_view_set_cursor_item (GTK_ICON_VIEW (item->widget), item->item);
4907 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item->widget));
4908 if (GTK_WIDGET_TOPLEVEL (toplevel))
4909 gtk_window_present (GTK_WINDOW (toplevel));
4915 atk_component_item_interface_init (AtkComponentIface *iface)
4917 iface->get_extents = gtk_icon_view_item_accessible_get_extents;
4918 iface->grab_focus = gtk_icon_view_item_accessible_grab_focus;
4922 gtk_icon_view_item_accessible_add_state (GtkIconViewItemAccessible *item,
4923 AtkStateType state_type,
4924 gboolean emit_signal)
4928 rc = atk_state_set_add_state (item->state_set, state_type);
4930 * The signal should only be generated if the value changed,
4931 * not when the item is set up. So states that are set
4932 * initially should pass FALSE as the emit_signal argument.
4937 atk_object_notify_state_change (ATK_OBJECT (item), state_type, TRUE);
4938 /* If state_type is ATK_STATE_VISIBLE, additional notification */
4939 if (state_type == ATK_STATE_VISIBLE)
4940 g_signal_emit_by_name (item, "visible_data_changed");
4947 gtk_icon_view_item_accessible_remove_state (GtkIconViewItemAccessible *item,
4948 AtkStateType state_type,
4949 gboolean emit_signal)
4951 if (atk_state_set_contains_state (item->state_set, state_type))
4955 rc = atk_state_set_remove_state (item->state_set, state_type);
4957 * The signal should only be generated if the value changed,
4958 * not when the item is set up. So states that are set
4959 * initially should pass FALSE as the emit_signal argument.
4964 atk_object_notify_state_change (ATK_OBJECT (item), state_type, FALSE);
4965 /* If state_type is ATK_STATE_VISIBLE, additional notification */
4966 if (state_type == ATK_STATE_VISIBLE)
4967 g_signal_emit_by_name (item, "visible_data_changed");
4977 gtk_icon_view_item_accessible_is_showing (GtkIconViewItemAccessible *item)
4979 GtkIconView *icon_view;
4980 GdkRectangle visible_rect;
4981 gboolean is_showing;
4984 * An item is considered "SHOWING" if any part of the item is in the
4985 * visible rectangle.
4988 if (!GTK_IS_ICON_VIEW (item->widget))
4991 if (item->item == NULL)
4994 icon_view = GTK_ICON_VIEW (item->widget);
4996 if (icon_view->priv->hadjustment)
4997 visible_rect.x += icon_view->priv->hadjustment->value;
4999 if (icon_view->priv->hadjustment)
5000 visible_rect.y += icon_view->priv->vadjustment->value;
5001 visible_rect.width = item->widget->allocation.width;
5002 visible_rect.height = item->widget->allocation.height;
5004 if (((item->item->x + item->item->width) < visible_rect.x) ||
5005 ((item->item->y + item->item->height) < (visible_rect.y)) ||
5006 (item->item->x > (visible_rect.x + visible_rect.width)) ||
5007 (item->item->y > (visible_rect.y + visible_rect.height)))
5016 gtk_icon_view_item_accessible_set_visibility (GtkIconViewItemAccessible *item,
5017 gboolean emit_signal)
5019 if (gtk_icon_view_item_accessible_is_showing (item))
5020 return gtk_icon_view_item_accessible_add_state (item, ATK_STATE_SHOWING,
5023 return gtk_icon_view_item_accessible_remove_state (item, ATK_STATE_SHOWING,
5028 gtk_icon_view_item_accessible_object_init (GtkIconViewItemAccessible *item)
5032 item->state_set = atk_state_set_new ();
5034 atk_state_set_add_state (item->state_set, ATK_STATE_ENABLED);
5035 atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSABLE);
5036 atk_state_set_add_state (item->state_set, ATK_STATE_SENSITIVE);
5037 atk_state_set_add_state (item->state_set, ATK_STATE_SELECTABLE);
5038 atk_state_set_add_state (item->state_set, ATK_STATE_VISIBLE);
5040 for (i = 0; i < LAST_ACTION; i++)
5041 item->action_descriptions[i] = NULL;
5043 item->image_description = NULL;
5045 item->action_idle_handler = 0;
5049 gtk_icon_view_item_accessible_finalize (GObject *object)
5051 GtkIconViewItemAccessible *item;
5054 g_return_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (object));
5056 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (object);
5059 g_object_remove_weak_pointer (G_OBJECT (item->widget), (gpointer) &item->widget);
5061 if (item->state_set)
5062 g_object_unref (item->state_set);
5064 if (item->text_buffer)
5065 g_object_unref (item->text_buffer);
5067 for (i = 0; i < LAST_ACTION; i++)
5068 g_free (item->action_descriptions[i]);
5070 g_free (item->image_description);
5072 if (item->action_idle_handler)
5074 g_source_remove (item->action_idle_handler);
5075 item->action_idle_handler = 0;
5078 G_OBJECT_CLASS (accessible_item_parent_class)->finalize (object);
5081 static G_CONST_RETURN gchar*
5082 gtk_icon_view_item_accessible_get_name (AtkObject *obj)
5088 GtkIconViewItemAccessible *item;
5089 GtkTextIter start_iter;
5090 GtkTextIter end_iter;
5092 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
5094 gtk_text_buffer_get_start_iter (item->text_buffer, &start_iter);
5095 gtk_text_buffer_get_end_iter (item->text_buffer, &end_iter);
5097 return gtk_text_buffer_get_text (item->text_buffer, &start_iter, &end_iter, FALSE);
5102 gtk_icon_view_item_accessible_get_parent (AtkObject *obj)
5104 GtkIconViewItemAccessible *item;
5106 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (obj), NULL);
5107 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
5110 return gtk_widget_get_accessible (item->widget);
5116 gtk_icon_view_item_accessible_get_index_in_parent (AtkObject *obj)
5118 GtkIconViewItemAccessible *item;
5120 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (obj), 0);
5121 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
5123 return item->item->index;
5126 static AtkStateSet *
5127 gtk_icon_view_item_accessible_ref_state_set (AtkObject *obj)
5129 GtkIconViewItemAccessible *item;
5130 GtkIconView *icon_view;
5132 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
5133 g_return_val_if_fail (item->state_set, NULL);
5138 icon_view = GTK_ICON_VIEW (item->widget);
5139 if (icon_view->priv->cursor_item == item->item)
5140 atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSED);
5142 atk_state_set_remove_state (item->state_set, ATK_STATE_FOCUSED);
5144 return g_object_ref (item->state_set);
5148 gtk_icon_view_item_accessible_class_init (AtkObjectClass *klass)
5150 GObjectClass *gobject_class;
5152 accessible_item_parent_class = g_type_class_peek_parent (klass);
5154 gobject_class = (GObjectClass *)klass;
5156 gobject_class->finalize = gtk_icon_view_item_accessible_finalize;
5158 klass->get_index_in_parent = gtk_icon_view_item_accessible_get_index_in_parent;
5159 klass->get_name = gtk_icon_view_item_accessible_get_name;
5160 klass->get_parent = gtk_icon_view_item_accessible_get_parent;
5161 klass->ref_state_set = gtk_icon_view_item_accessible_ref_state_set;
5165 gtk_icon_view_item_accessible_get_type (void)
5167 static GType type = 0;
5171 static const GTypeInfo tinfo =
5173 sizeof (GtkIconViewItemAccessibleClass),
5174 (GBaseInitFunc) NULL, /* base init */
5175 (GBaseFinalizeFunc) NULL, /* base finalize */
5176 (GClassInitFunc) gtk_icon_view_item_accessible_class_init, /* class init */
5177 (GClassFinalizeFunc) NULL, /* class finalize */
5178 NULL, /* class data */
5179 sizeof (GtkIconViewItemAccessible), /* instance size */
5180 0, /* nb preallocs */
5181 (GInstanceInitFunc) gtk_icon_view_item_accessible_object_init, /* instance init */
5182 NULL /* value table */
5185 static const GInterfaceInfo atk_component_info =
5187 (GInterfaceInitFunc) atk_component_item_interface_init,
5188 (GInterfaceFinalizeFunc) NULL,
5191 static const GInterfaceInfo atk_action_info =
5193 (GInterfaceInitFunc) atk_action_item_interface_init,
5194 (GInterfaceFinalizeFunc) NULL,
5197 static const GInterfaceInfo atk_image_info =
5199 (GInterfaceInitFunc) atk_image_item_interface_init,
5200 (GInterfaceFinalizeFunc) NULL,
5203 static const GInterfaceInfo atk_text_info =
5205 (GInterfaceInitFunc) atk_text_item_interface_init,
5206 (GInterfaceFinalizeFunc) NULL,
5210 type = g_type_register_static (ATK_TYPE_OBJECT,
5211 "GtkIconViewItemAccessible", &tinfo, 0);
5212 g_type_add_interface_static (type, ATK_TYPE_COMPONENT,
5213 &atk_component_info);
5214 g_type_add_interface_static (type, ATK_TYPE_ACTION,
5216 g_type_add_interface_static (type, ATK_TYPE_IMAGE,
5218 g_type_add_interface_static (type, ATK_TYPE_TEXT,
5225 #define GTK_TYPE_ICON_VIEW_ACCESSIBLE (gtk_icon_view_accessible_get_type ())
5226 #define GTK_ICON_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ICON_VIEW_ACCESSIBLE, GtkIconViewAccessible))
5227 #define GTK_IS_ICON_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ICON_VIEW_ACCESSIBLE))
5229 static GType gtk_icon_view_accessible_get_type (void);
5234 } GtkIconViewAccessible;
5240 } GtkIconViewItemAccessibleInfo;
5246 GtkAdjustment *old_hadj;
5247 GtkAdjustment *old_vadj;
5249 GtkTreeModel *model;
5251 } GtkIconViewAccessiblePrivate;
5253 static GtkIconViewAccessiblePrivate *
5254 gtk_icon_view_accessible_get_priv (AtkObject *accessible)
5256 return g_object_get_qdata (G_OBJECT (accessible),
5257 accessible_private_data_quark);
5261 gtk_icon_view_item_accessible_info_new (AtkObject *accessible,
5265 GtkIconViewItemAccessibleInfo *info;
5266 GtkIconViewItemAccessibleInfo *tmp_info;
5267 GtkIconViewAccessiblePrivate *priv;
5270 info = g_new (GtkIconViewItemAccessibleInfo, 1);
5272 info->index = index;
5274 priv = gtk_icon_view_accessible_get_priv (accessible);
5275 items = priv->items;
5278 tmp_info = items->data;
5279 if (tmp_info->index > index)
5281 items = items->next;
5283 priv->items = g_list_insert_before (priv->items, items, info);
5284 priv->old_hadj = NULL;
5285 priv->old_vadj = NULL;
5289 gtk_icon_view_accessible_get_n_children (AtkObject *accessible)
5291 GtkIconView *icon_view;
5294 widget = GTK_ACCESSIBLE (accessible)->widget;
5298 icon_view = GTK_ICON_VIEW (widget);
5300 return g_list_length (icon_view->priv->items);
5304 gtk_icon_view_accessible_find_child (AtkObject *accessible,
5307 GtkIconViewAccessiblePrivate *priv;
5308 GtkIconViewItemAccessibleInfo *info;
5311 priv = gtk_icon_view_accessible_get_priv (accessible);
5312 items = priv->items;
5317 if (info->index == index)
5319 items = items->next;
5325 gtk_icon_view_accessible_ref_child (AtkObject *accessible,
5328 GtkIconView *icon_view;
5332 GtkIconViewItemAccessible *a11y_item;
5334 widget = GTK_ACCESSIBLE (accessible)->widget;
5338 icon_view = GTK_ICON_VIEW (widget);
5339 icons = g_list_nth (icon_view->priv->items, index);
5343 GtkIconViewItem *item = icons->data;
5345 g_return_val_if_fail (item->index == index, NULL);
5346 obj = gtk_icon_view_accessible_find_child (accessible, index);
5349 obj = g_object_new (gtk_icon_view_item_accessible_get_type (), NULL);
5350 gtk_icon_view_item_accessible_info_new (accessible,
5353 obj->role = ATK_ROLE_ICON;
5354 a11y_item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
5355 a11y_item->item = item;
5356 a11y_item->widget = widget;
5357 a11y_item->text_buffer = gtk_text_buffer_new (NULL);
5358 gtk_icon_view_update_item_text (icon_view, item);
5359 gtk_text_buffer_set_text (a11y_item->text_buffer,
5360 pango_layout_get_text (icon_view->priv->layout),
5362 gtk_icon_view_item_accessible_set_visibility (a11y_item, FALSE);
5363 g_object_add_weak_pointer (G_OBJECT (widget), (gpointer) &(a11y_item->widget));
5371 gtk_icon_view_accessible_traverse_items (GtkIconViewAccessible *view,
5374 GtkIconViewAccessiblePrivate *priv;
5375 GtkIconViewItemAccessibleInfo *info;
5376 GtkIconViewItemAccessible *item;
5379 priv = gtk_icon_view_accessible_get_priv (ATK_OBJECT (view));
5383 gboolean act_on_item;
5385 widget = GTK_ACCESSIBLE (view)->widget;
5389 items = priv->items;
5391 act_on_item = (list == NULL);
5396 info = (GtkIconViewItemAccessibleInfo *)items->data;
5397 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
5399 if (act_on_item == FALSE && list == items)
5403 gtk_icon_view_item_accessible_set_visibility (item, TRUE);
5405 items = items->next;
5411 gtk_icon_view_accessible_adjustment_changed (GtkAdjustment *adjustment,
5412 GtkIconView *icon_view)
5415 GtkIconViewAccessible *view;
5418 * The scrollbars have changed
5420 obj = gtk_widget_get_accessible (GTK_WIDGET (icon_view));
5421 view = GTK_ICON_VIEW_ACCESSIBLE (obj);
5423 gtk_icon_view_accessible_traverse_items (view, NULL);
5427 gtk_icon_view_accessible_set_scroll_adjustments (GtkWidget *widget,
5428 GtkAdjustment *hadj,
5429 GtkAdjustment *vadj)
5432 GtkIconViewAccessiblePrivate *priv;
5434 atk_obj = gtk_widget_get_accessible (widget);
5435 priv = gtk_icon_view_accessible_get_priv (atk_obj);
5437 if (priv->old_hadj != hadj)
5441 g_object_remove_weak_pointer (G_OBJECT (priv->old_hadj),
5442 (gpointer *)&priv->old_hadj);
5444 g_signal_handlers_disconnect_by_func (priv->old_hadj,
5445 (gpointer) gtk_icon_view_accessible_adjustment_changed,
5448 priv->old_hadj = hadj;
5451 g_object_add_weak_pointer (G_OBJECT (priv->old_hadj),
5452 (gpointer *)&priv->old_hadj);
5453 g_signal_connect (hadj,
5455 G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
5459 if (priv->old_vadj != vadj)
5463 g_object_remove_weak_pointer (G_OBJECT (priv->old_vadj),
5464 (gpointer *)&priv->old_vadj);
5466 g_signal_handlers_disconnect_by_func (priv->old_vadj,
5467 (gpointer) gtk_icon_view_accessible_adjustment_changed,
5470 priv->old_vadj = vadj;
5473 g_object_add_weak_pointer (G_OBJECT (priv->old_vadj),
5474 (gpointer *)&priv->old_vadj);
5475 g_signal_connect (vadj,
5477 G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
5484 gtk_icon_view_accessible_model_row_changed (GtkTreeModel *tree_model,
5491 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
5492 g_signal_emit_by_name (atk_obj, "visible-data-changed");
5498 gtk_icon_view_accessible_model_row_inserted (GtkTreeModel *tree_model,
5503 GtkIconViewAccessiblePrivate *priv;
5504 GtkIconViewItemAccessibleInfo *info;
5505 GtkIconViewAccessible *view;
5506 GtkIconViewItemAccessible *item;
5512 index = gtk_tree_path_get_indices(path)[0];
5513 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
5514 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
5515 priv = gtk_icon_view_accessible_get_priv (atk_obj);
5517 items = priv->items;
5522 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
5523 if (info->index != item->item->index)
5525 if (info->index < index)
5526 g_warning ("Unexpected index value on insertion %d %d", index, info->index);
5528 if (tmp_list == NULL)
5531 info->index = item->item->index;
5534 items = items->next;
5536 gtk_icon_view_accessible_traverse_items (view, tmp_list);
5537 g_signal_emit_by_name (atk_obj, "children_changed::add",
5543 gtk_icon_view_accessible_model_row_deleted (GtkTreeModel *tree_model,
5547 GtkIconViewAccessiblePrivate *priv;
5548 GtkIconViewItemAccessibleInfo *info;
5549 GtkIconViewAccessible *view;
5550 GtkIconViewItemAccessible *item;
5553 GList *deleted_item;
5557 index = gtk_tree_path_get_indices(path)[0];
5558 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
5559 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
5560 priv = gtk_icon_view_accessible_get_priv (atk_obj);
5562 items = priv->items;
5564 deleted_item = NULL;
5569 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
5570 if (info->index == index)
5572 deleted_item = items;
5574 if (info->index != item->item->index)
5576 if (tmp_list == NULL)
5579 info->index = item->item->index;
5582 items = items->next;
5584 gtk_icon_view_accessible_traverse_items (view, tmp_list);
5587 info = deleted_item->data;
5588 gtk_icon_view_item_accessible_add_state (GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item), ATK_STATE_DEFUNCT, TRUE);
5590 g_signal_emit_by_name (atk_obj, "children_changed::remove",
5594 priv->items = g_list_remove_link (priv->items, deleted_item);
5602 gtk_icon_view_accessible_item_compare (GtkIconViewItemAccessibleInfo *i1,
5603 GtkIconViewItemAccessibleInfo *i2)
5605 return i1->index - i2->index;
5609 gtk_icon_view_accessible_model_rows_reordered (GtkTreeModel *tree_model,
5615 GtkIconViewAccessiblePrivate *priv;
5616 GtkIconViewItemAccessibleInfo *info;
5617 GtkIconViewAccessible *view;
5618 GtkIconView *icon_view;
5619 GtkIconViewItemAccessible *item;
5624 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
5625 icon_view = GTK_ICON_VIEW (user_data);
5626 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
5627 priv = gtk_icon_view_accessible_get_priv (atk_obj);
5629 items = priv->items;
5634 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
5635 info->index = new_order[info->index];
5636 tmp_list = g_list_nth (icon_view->priv->items, info->index);
5637 item->item = tmp_list->data;
5638 items = items->next;
5640 priv->items = g_list_sort (priv->items,
5641 (GCompareFunc)gtk_icon_view_accessible_item_compare);
5647 gtk_icon_view_accessible_disconnect_model_signals (GtkTreeModel *model,
5652 obj = G_OBJECT (model);
5653 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_changed, widget);
5654 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_inserted, widget);
5655 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_deleted, widget);
5656 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_rows_reordered, widget);
5660 gtk_icon_view_accessible_connect_model_signals (GtkIconView *icon_view)
5664 obj = G_OBJECT (icon_view->priv->model);
5665 g_signal_connect_data (obj, "row-changed",
5666 (GCallback) gtk_icon_view_accessible_model_row_changed,
5667 icon_view, NULL, 0);
5668 g_signal_connect_data (obj, "row-inserted",
5669 (GCallback) gtk_icon_view_accessible_model_row_inserted,
5670 icon_view, NULL, G_CONNECT_AFTER);
5671 g_signal_connect_data (obj, "row-deleted",
5672 (GCallback) gtk_icon_view_accessible_model_row_deleted,
5673 icon_view, NULL, G_CONNECT_AFTER);
5674 g_signal_connect_data (obj, "rows-reordered",
5675 (GCallback) gtk_icon_view_accessible_model_rows_reordered,
5676 icon_view, NULL, G_CONNECT_AFTER);
5680 gtk_icon_view_accessible_clear_cache (GtkIconViewAccessiblePrivate *priv)
5682 GtkIconViewItemAccessibleInfo *info;
5685 items = priv->items;
5688 info = (GtkIconViewItemAccessibleInfo *) items->data;
5689 g_object_unref (info->item);
5690 g_free (items->data);
5691 items = items->next;
5693 g_list_free (priv->items);
5698 gtk_icon_view_accessible_notify_gtk (GObject *obj,
5701 GtkIconView *icon_view;
5704 GtkIconViewAccessible *view;
5705 GtkIconViewAccessiblePrivate *priv;
5707 if (strcmp (pspec->name, "model") == 0)
5709 widget = GTK_WIDGET (obj);
5710 atk_obj = gtk_widget_get_accessible (widget);
5711 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
5712 priv = gtk_icon_view_accessible_get_priv (atk_obj);
5715 g_object_remove_weak_pointer (G_OBJECT (priv->model),
5716 (gpointer *)&priv->model);
5717 gtk_icon_view_accessible_disconnect_model_signals (priv->model, widget);
5719 gtk_icon_view_accessible_clear_cache (priv);
5721 icon_view = GTK_ICON_VIEW (obj);
5722 priv->model = icon_view->priv->model;
5723 /* If there is no model the GtkIconView is probably being destroyed */
5726 g_object_add_weak_pointer (G_OBJECT (priv->model), (gpointer *)&priv->model);
5727 gtk_icon_view_accessible_connect_model_signals (icon_view);
5735 gtk_icon_view_accessible_initialize (AtkObject *accessible,
5738 GtkIconViewAccessiblePrivate *priv;
5739 GtkIconView *icon_view;
5741 if (ATK_OBJECT_CLASS (accessible_parent_class)->initialize)
5742 ATK_OBJECT_CLASS (accessible_parent_class)->initialize (accessible, data);
5744 priv = g_new0 (GtkIconViewAccessiblePrivate, 1);
5745 g_object_set_qdata (G_OBJECT (accessible),
5746 accessible_private_data_quark,
5749 icon_view = GTK_ICON_VIEW (data);
5750 if (icon_view->priv->hadjustment)
5752 priv->old_hadj = icon_view->priv->hadjustment;
5753 g_object_add_weak_pointer (G_OBJECT (priv->old_hadj), (gpointer *)&priv->old_hadj);
5754 g_signal_connect (icon_view->priv->hadjustment,
5756 G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
5759 if (icon_view->priv->vadjustment)
5761 priv->old_vadj = icon_view->priv->vadjustment;
5762 g_object_add_weak_pointer (G_OBJECT (priv->old_vadj), (gpointer *)&priv->old_vadj);
5763 g_signal_connect (icon_view->priv->vadjustment,
5765 G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
5768 g_signal_connect_after (data,
5769 "set_scroll_adjustments",
5770 G_CALLBACK (gtk_icon_view_accessible_set_scroll_adjustments),
5772 g_signal_connect (data,
5774 G_CALLBACK (gtk_icon_view_accessible_notify_gtk),
5777 priv->model = icon_view->priv->model;
5780 g_object_add_weak_pointer (G_OBJECT (priv->model), (gpointer *)&priv->model);
5781 gtk_icon_view_accessible_connect_model_signals (icon_view);
5784 accessible->role = ATK_ROLE_LAYERED_PANE;
5788 gtk_icon_view_accessible_finalize (GObject *object)
5790 GtkIconViewAccessiblePrivate *priv;
5792 priv = gtk_icon_view_accessible_get_priv (ATK_OBJECT (object));
5793 gtk_icon_view_accessible_clear_cache (priv);
5797 G_OBJECT_CLASS (accessible_parent_class)->finalize (object);
5801 gtk_icon_view_accessible_destroyed (GtkWidget *widget,
5802 GtkAccessible *accessible)
5805 GtkIconViewAccessiblePrivate *priv;
5807 atk_obj = ATK_OBJECT (accessible);
5808 priv = gtk_icon_view_accessible_get_priv (atk_obj);
5811 g_object_remove_weak_pointer (G_OBJECT (priv->old_hadj),
5812 (gpointer *)&priv->old_hadj);
5814 g_signal_handlers_disconnect_by_func (priv->old_hadj,
5815 (gpointer) gtk_icon_view_accessible_adjustment_changed,
5817 priv->old_hadj = NULL;
5821 g_object_remove_weak_pointer (G_OBJECT (priv->old_vadj),
5822 (gpointer *)&priv->old_vadj);
5824 g_signal_handlers_disconnect_by_func (priv->old_vadj,
5825 (gpointer) gtk_icon_view_accessible_adjustment_changed,
5827 priv->old_vadj = NULL;
5832 gtk_icon_view_accessible_connect_widget_destroyed (GtkAccessible *accessible)
5834 if (accessible->widget)
5836 g_signal_connect_after (accessible->widget,
5838 G_CALLBACK (gtk_icon_view_accessible_destroyed),
5841 GTK_ACCESSIBLE_CLASS (accessible_parent_class)->connect_widget_destroyed (accessible);
5845 gtk_icon_view_accessible_class_init (AtkObjectClass *klass)
5847 GObjectClass *gobject_class;
5848 GtkAccessibleClass *accessible_class;
5850 accessible_parent_class = g_type_class_peek_parent (klass);
5852 gobject_class = (GObjectClass *)klass;
5853 accessible_class = (GtkAccessibleClass *)klass;
5855 gobject_class->finalize = gtk_icon_view_accessible_finalize;
5857 klass->get_n_children = gtk_icon_view_accessible_get_n_children;
5858 klass->ref_child = gtk_icon_view_accessible_ref_child;
5859 klass->initialize = gtk_icon_view_accessible_initialize;
5861 accessible_class->connect_widget_destroyed = gtk_icon_view_accessible_connect_widget_destroyed;
5863 accessible_private_data_quark = g_quark_from_static_string ("icon_view-accessible-private-data");
5867 gtk_icon_view_accessible_ref_accessible_at_point (AtkComponent *component,
5870 AtkCoordType coord_type)
5873 GtkIconView *icon_view;
5874 GtkIconViewItem *item;
5877 widget = GTK_ACCESSIBLE (component)->widget;
5879 /* State is defunct */
5882 icon_view = GTK_ICON_VIEW (widget);
5883 atk_component_get_extents (component, &x_pos, &y_pos, NULL, NULL, coord_type);
5884 item = gtk_icon_view_get_item_at_pos (icon_view, x - x_pos, y - y_pos);
5886 return gtk_icon_view_accessible_ref_child (ATK_OBJECT (component), item->index);
5892 atk_component_interface_init (AtkComponentIface *iface)
5894 iface->ref_accessible_at_point = gtk_icon_view_accessible_ref_accessible_at_point;
5898 gtk_icon_view_accessible_add_selection (AtkSelection *selection,
5902 GtkIconView *icon_view;
5903 GtkIconViewItem *item;
5906 widget = GTK_ACCESSIBLE (selection)->widget;
5910 icon_view = GTK_ICON_VIEW (widget);
5912 l = g_list_nth (icon_view->priv->items, i);
5917 gtk_icon_view_select_item (icon_view, item);
5923 gtk_icon_view_accessible_clear_selection (AtkSelection *selection)
5926 GtkIconView *icon_view;
5928 widget = GTK_ACCESSIBLE (selection)->widget;
5932 icon_view = GTK_ICON_VIEW (widget);
5933 gtk_icon_view_unselect_all (icon_view);
5939 gtk_icon_view_accessible_ref_selection (AtkSelection *selection,
5943 GtkIconView *icon_view;
5944 GtkIconViewItem *item;
5947 widget = GTK_ACCESSIBLE (selection)->widget;
5951 icon_view = GTK_ICON_VIEW (widget);
5953 l = icon_view->priv->items;
5960 return atk_object_ref_accessible_child (gtk_widget_get_accessible (widget), item->index);
5971 gtk_icon_view_accessible_get_selection_count (AtkSelection *selection)
5974 GtkIconView *icon_view;
5975 GtkIconViewItem *item;
5979 widget = GTK_ACCESSIBLE (selection)->widget;
5983 icon_view = GTK_ICON_VIEW (widget);
5985 l = icon_view->priv->items;
6001 gtk_icon_view_accessible_is_child_selected (AtkSelection *selection,
6005 GtkIconView *icon_view;
6006 GtkIconViewItem *item;
6009 widget = GTK_ACCESSIBLE (selection)->widget;
6013 icon_view = GTK_ICON_VIEW (widget);
6014 l = g_list_nth (icon_view->priv->items, i);
6020 return item->selected;
6024 gtk_icon_view_accessible_remove_selection (AtkSelection *selection,
6028 GtkIconView *icon_view;
6029 GtkIconViewItem *item;
6033 widget = GTK_ACCESSIBLE (selection)->widget;
6037 icon_view = GTK_ICON_VIEW (widget);
6038 l = icon_view->priv->items;
6047 gtk_icon_view_unselect_item (icon_view, item);
6059 gtk_icon_view_accessible_select_all_selection (AtkSelection *selection)
6062 GtkIconView *icon_view;
6064 widget = GTK_ACCESSIBLE (selection)->widget;
6068 icon_view = GTK_ICON_VIEW (widget);
6069 gtk_icon_view_select_all (icon_view);
6074 gtk_icon_view_accessible_selection_interface_init (AtkSelectionIface *iface)
6076 iface->add_selection = gtk_icon_view_accessible_add_selection;
6077 iface->clear_selection = gtk_icon_view_accessible_clear_selection;
6078 iface->ref_selection = gtk_icon_view_accessible_ref_selection;
6079 iface->get_selection_count = gtk_icon_view_accessible_get_selection_count;
6080 iface->is_child_selected = gtk_icon_view_accessible_is_child_selected;
6081 iface->remove_selection = gtk_icon_view_accessible_remove_selection;
6082 iface->select_all_selection = gtk_icon_view_accessible_select_all_selection;
6086 gtk_icon_view_accessible_get_type (void)
6088 static GType type = 0;
6092 static GTypeInfo tinfo =
6095 (GBaseInitFunc) NULL, /* base init */
6096 (GBaseFinalizeFunc) NULL, /* base finalize */
6097 (GClassInitFunc) gtk_icon_view_accessible_class_init,
6098 (GClassFinalizeFunc) NULL, /* class finalize */
6099 NULL, /* class data */
6100 0, /* instance size */
6101 0, /* nb preallocs */
6102 (GInstanceInitFunc) NULL, /* instance init */
6103 NULL /* value table */
6105 static const GInterfaceInfo atk_component_info =
6107 (GInterfaceInitFunc) atk_component_interface_init,
6108 (GInterfaceFinalizeFunc) NULL,
6111 static const GInterfaceInfo atk_selection_info =
6113 (GInterfaceInitFunc) gtk_icon_view_accessible_selection_interface_init,
6114 (GInterfaceFinalizeFunc) NULL,
6119 * Figure out the size of the class and instance
6120 * we are deriving from
6122 AtkObjectFactory *factory;
6125 GType derived_atk_type;
6127 derived_type = g_type_parent (GTK_TYPE_ICON_VIEW);
6128 factory = atk_registry_get_factory (atk_get_default_registry (),
6130 derived_atk_type = atk_object_factory_get_accessible_type (factory);
6131 g_type_query (derived_atk_type, &query);
6132 tinfo.class_size = query.class_size;
6133 tinfo.instance_size = query.instance_size;
6135 type = g_type_register_static (derived_atk_type,
6136 "GtkIconViewAccessible",
6138 g_type_add_interface_static (type, ATK_TYPE_COMPONENT,
6139 &atk_component_info);
6140 g_type_add_interface_static (type, ATK_TYPE_SELECTION,
6141 &atk_selection_info);
6147 gtk_icon_view_accessible_new (GObject *obj)
6149 AtkObject *accessible;
6151 g_return_val_if_fail (GTK_IS_WIDGET (obj), NULL);
6153 accessible = g_object_new (gtk_icon_view_accessible_get_type (), NULL);
6154 atk_object_initialize (accessible, obj);
6160 gtk_icon_view_accessible_factory_get_accessible_type (void)
6162 return gtk_icon_view_accessible_get_type ();
6166 gtk_icon_view_accessible_factory_create_accessible (GObject *obj)
6168 return gtk_icon_view_accessible_new (obj);
6172 gtk_icon_view_accessible_factory_class_init (AtkObjectFactoryClass *klass)
6174 klass->create_accessible = gtk_icon_view_accessible_factory_create_accessible;
6175 klass->get_accessible_type = gtk_icon_view_accessible_factory_get_accessible_type;
6179 gtk_icon_view_accessible_factory_get_type (void)
6181 static GType type = 0;
6185 static const GTypeInfo tinfo =
6187 sizeof (AtkObjectFactoryClass),
6188 NULL, /* base_init */
6189 NULL, /* base_finalize */
6190 (GClassInitFunc) gtk_icon_view_accessible_factory_class_init,
6191 NULL, /* class_finalize */
6192 NULL, /* class_data */
6193 sizeof (AtkObjectFactory),
6194 0, /* n_preallocs */
6198 type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY,
6199 "GtkIconViewAccessibleFactory",
6206 gtk_icon_view_get_accessible (GtkWidget *widget)
6208 static gboolean first_time = TRUE;
6212 AtkObjectFactory *factory;
6213 AtkRegistry *registry;
6215 GType derived_atk_type;
6218 * Figure out whether accessibility is enabled by looking at the
6219 * type of the accessible object which would be created for
6220 * the parent type of GtkIconView.
6222 derived_type = g_type_parent (GTK_TYPE_ICON_VIEW);
6224 registry = atk_get_default_registry ();
6225 factory = atk_registry_get_factory (registry,
6227 derived_atk_type = atk_object_factory_get_accessible_type (factory);
6228 if (g_type_is_a (derived_atk_type, GTK_TYPE_ACCESSIBLE))
6229 atk_registry_set_factory_type (registry,
6231 gtk_icon_view_accessible_factory_get_type ());
6234 return GTK_WIDGET_CLASS (parent_class)->get_accessible (widget);