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>
27 #include "gtkiconview.h"
28 #include "gtkmarshalers.h"
29 #include "gtkbindings.h"
32 #include "gtksignal.h"
34 #include "gtkaccessible.h"
35 #include "gtkwindow.h"
36 #include "gtktextbuffer.h"
37 #include "gtkprivate.h"
40 #undef DEBUG_ICON_VIEW
42 #define ICON_TEXT_PADDING 3
44 #define GTK_ICON_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ICON_VIEW, GtkIconViewPrivate))
45 #define VALID_MODEL_AND_COLUMNS(obj) ((obj)->priv->model != NULL && \
46 ((obj)->priv->pixbuf_column != -1 || \
47 (obj)->priv->text_column != -1 || \
48 (obj)->priv->markup_column != -1))
61 gint pixbuf_x, pixbuf_y;
62 gint pixbuf_height, pixbuf_width;
64 gint layout_x, layout_y;
65 gint layout_width, layout_height;
68 guint selected_before_rubberbanding : 1;
71 struct _GtkIconViewPrivate
79 GtkSelectionMode selection_mode;
81 GdkWindow *bin_window;
87 GtkAdjustment *hadjustment;
88 GtkAdjustment *vadjustment;
92 gboolean doing_rubberband;
93 gint rubberband_x1, rubberband_y1;
94 gint rubberband_x2, rubberband_y2;
96 guint scroll_timeout_id;
97 gint scroll_value_diff;
98 gint event_last_x, event_last_y;
100 GtkIconViewItem *anchor_item;
101 GtkIconViewItem *cursor_item;
103 guint ctrl_pressed : 1;
104 guint shift_pressed : 1;
106 GtkIconViewItem *last_single_clicked;
115 /* Layout used to draw icon text */
118 GtkOrientation orientation;
138 ACTIVATE_CURSOR_ITEM,
160 /* GObject signals */
161 static void gtk_icon_view_finalize (GObject *object);
162 static void gtk_icon_view_set_property (GObject *object,
166 static void gtk_icon_view_get_property (GObject *object,
172 /* GtkObject signals */
173 static void gtk_icon_view_destroy (GtkObject *object);
175 /* GtkWidget signals */
176 static void gtk_icon_view_realize (GtkWidget *widget);
177 static void gtk_icon_view_unrealize (GtkWidget *widget);
178 static void gtk_icon_view_map (GtkWidget *widget);
179 static void gtk_icon_view_size_request (GtkWidget *widget,
180 GtkRequisition *requisition);
181 static void gtk_icon_view_size_allocate (GtkWidget *widget,
182 GtkAllocation *allocation);
183 static gboolean gtk_icon_view_expose (GtkWidget *widget,
184 GdkEventExpose *expose);
185 static gboolean gtk_icon_view_motion (GtkWidget *widget,
186 GdkEventMotion *event);
187 static gboolean gtk_icon_view_button_press (GtkWidget *widget,
188 GdkEventButton *event);
189 static gboolean gtk_icon_view_button_release (GtkWidget *widget,
190 GdkEventButton *event);
191 /* GtkIconView signals */
192 static void gtk_icon_view_set_adjustments (GtkIconView *icon_view,
194 GtkAdjustment *vadj);
195 static void gtk_icon_view_real_select_all (GtkIconView *icon_view);
196 static void gtk_icon_view_real_unselect_all (GtkIconView *icon_view);
197 static void gtk_icon_view_real_select_cursor_item (GtkIconView *icon_view);
198 static void gtk_icon_view_real_toggle_cursor_item (GtkIconView *icon_view);
199 static gboolean gtk_icon_view_real_activate_cursor_item (GtkIconView *icon_view);
201 /* Internal functions */
202 static void gtk_icon_view_adjustment_changed (GtkAdjustment *adjustment,
203 GtkIconView *icon_view);
204 static void gtk_icon_view_layout (GtkIconView *icon_view);
205 static void gtk_icon_view_paint_item (GtkIconView *icon_view,
207 GtkIconViewItem *item,
209 static void gtk_icon_view_paint_rubberband (GtkIconView *icon_view,
212 static void gtk_icon_view_queue_draw_item (GtkIconView *icon_view,
213 GtkIconViewItem *item);
214 static void gtk_icon_view_queue_layout (GtkIconView *icon_view);
215 static void gtk_icon_view_set_cursor_item (GtkIconView *icon_view,
216 GtkIconViewItem *item);
217 static void gtk_icon_view_start_rubberbanding (GtkIconView *icon_view,
220 static void gtk_icon_view_stop_rubberbanding (GtkIconView *icon_view);
221 static void gtk_icon_view_update_rubberband_selection (GtkIconView *icon_view);
222 static gboolean gtk_icon_view_item_hit_test (GtkIconViewItem *item,
228 static gboolean gtk_icon_view_maybe_begin_dragging_items (GtkIconView *icon_view,
229 GdkEventMotion *event);
231 static gboolean gtk_icon_view_unselect_all_internal (GtkIconView *icon_view);
232 static void gtk_icon_view_calculate_item_size (GtkIconView *icon_view,
233 GtkIconViewItem *item,
235 static void gtk_icon_view_update_rubberband (gpointer data);
236 static void gtk_icon_view_item_invalidate_size (GtkIconViewItem *item);
237 static void gtk_icon_view_invalidate_sizes (GtkIconView *icon_view);
238 static void gtk_icon_view_add_move_binding (GtkBindingSet *binding_set,
241 GtkMovementStep step,
243 static gboolean gtk_icon_view_real_move_cursor (GtkIconView *icon_view,
244 GtkMovementStep step,
246 static void gtk_icon_view_move_cursor_up_down (GtkIconView *icon_view,
248 static void gtk_icon_view_move_cursor_page_up_down (GtkIconView *icon_view,
250 static void gtk_icon_view_move_cursor_left_right (GtkIconView *icon_view,
252 static void gtk_icon_view_move_cursor_start_end (GtkIconView *icon_view,
254 static void gtk_icon_view_scroll_to_item (GtkIconView *icon_view,
255 GtkIconViewItem *item);
256 static GdkPixbuf *gtk_icon_view_get_item_icon (GtkIconView *icon_view,
257 GtkIconViewItem *item);
258 static void gtk_icon_view_update_item_text (GtkIconView *icon_view,
259 GtkIconViewItem *item);
260 static void gtk_icon_view_select_item (GtkIconView *icon_view,
261 GtkIconViewItem *item);
262 static void gtk_icon_view_unselect_item (GtkIconView *icon_view,
263 GtkIconViewItem *item);
264 static gboolean gtk_icon_view_select_all_between (GtkIconView *icon_view,
265 GtkIconViewItem *anchor,
266 GtkIconViewItem *cursor);
268 static GtkIconViewItem *gtk_icon_view_get_item_at_pos (GtkIconView *icon_view,
273 /* Accessibility Support */
274 static AtkObject *gtk_icon_view_get_accessible (GtkWidget *widget);
276 static GtkContainerClass *parent_class = NULL;
277 static guint icon_view_signals[LAST_SIGNAL] = { 0 };
279 G_DEFINE_TYPE (GtkIconView, gtk_icon_view, GTK_TYPE_CONTAINER);
282 gtk_icon_view_class_init (GtkIconViewClass *klass)
284 GObjectClass *gobject_class;
285 GtkObjectClass *object_class;
286 GtkWidgetClass *widget_class;
287 GtkBindingSet *binding_set;
289 parent_class = g_type_class_peek_parent (klass);
290 binding_set = gtk_binding_set_by_class (klass);
292 g_type_class_add_private (klass, sizeof (GtkIconViewPrivate));
294 gobject_class = (GObjectClass *) klass;
295 object_class = (GtkObjectClass *) klass;
296 widget_class = (GtkWidgetClass *) klass;
298 gobject_class->finalize = gtk_icon_view_finalize;
299 gobject_class->set_property = gtk_icon_view_set_property;
300 gobject_class->get_property = gtk_icon_view_get_property;
302 object_class->destroy = gtk_icon_view_destroy;
304 widget_class->realize = gtk_icon_view_realize;
305 widget_class->unrealize = gtk_icon_view_unrealize;
306 widget_class->map = gtk_icon_view_map;
307 widget_class->size_request = gtk_icon_view_size_request;
308 widget_class->size_allocate = gtk_icon_view_size_allocate;
309 widget_class->expose_event = gtk_icon_view_expose;
310 widget_class->motion_notify_event = gtk_icon_view_motion;
311 widget_class->button_press_event = gtk_icon_view_button_press;
312 widget_class->button_release_event = gtk_icon_view_button_release;
313 widget_class->get_accessible = gtk_icon_view_get_accessible;
315 klass->set_scroll_adjustments = gtk_icon_view_set_adjustments;
316 klass->select_all = gtk_icon_view_real_select_all;
317 klass->unselect_all = gtk_icon_view_real_unselect_all;
318 klass->select_cursor_item = gtk_icon_view_real_select_cursor_item;
319 klass->toggle_cursor_item = gtk_icon_view_real_toggle_cursor_item;
320 klass->activate_cursor_item = gtk_icon_view_real_activate_cursor_item;
321 klass->move_cursor = gtk_icon_view_real_move_cursor;
325 * GtkIconView:selection-mode:
327 * The ::selection-mode property specifies the selection mode of
328 * icon view. If the mode is #GTK_SELECTION_MULTIPLE, rubberband selection
329 * is enabled, for the other modes, only keyboard selection is possible.
333 g_object_class_install_property (gobject_class,
335 g_param_spec_enum ("selection-mode",
336 P_("Selection mode"),
337 P_("The selection mode"),
338 GTK_TYPE_SELECTION_MODE,
339 GTK_SELECTION_SINGLE,
340 GTK_PARAM_READWRITE));
343 * GtkIconView:pixbuf-column:
345 * The ::pixbuf-column property contains the number of the model column
346 * containing the pixbufs which are displayed. The pixbuf column must be
347 * of type #GDK_TYPE_PIXBUF. Setting this property to -1 turns off the
348 * display of pixbufs.
352 g_object_class_install_property (gobject_class,
354 g_param_spec_int ("pixbuf-column",
356 P_("Model column used to retrieve the icon pixbuf from"),
358 GTK_PARAM_READWRITE));
361 * GtkIconView:text-column:
363 * The ::text-column property contains the number of the model column
364 * containing the texts which are displayed. The text column must be
365 * of type #G_TYPE_STRING. If this property and the :markup-column
366 * property are both set to -1, no texts are displayed.
370 g_object_class_install_property (gobject_class,
372 g_param_spec_int ("text-column",
374 P_("Model column used to retrieve the text from"),
376 GTK_PARAM_READWRITE));
380 * GtkIconView:markup-column:
382 * The ::markup-column property contains the number of the model column
383 * containing markup information to be displayed. The markup column must be
384 * of type #G_TYPE_STRING. If this property and the :text-column property
385 * are both set to column numbers, it overrides the text column.
386 * If both are set to -1, no texts are displayed.
390 g_object_class_install_property (gobject_class,
392 g_param_spec_int ("markup-column",
394 P_("Model column used to retrieve the text if using Pango markup"),
396 GTK_PARAM_READWRITE));
398 g_object_class_install_property (gobject_class,
400 g_param_spec_object ("model",
401 P_("Icon View Model"),
402 P_("The model for the icon view"),
404 GTK_PARAM_READWRITE));
407 * GtkIconView:columns:
409 * The columns property contains the number of the columns in which the
410 * items should be displayed. If it is -1, the number of columns will
411 * be chosen automatically to fill the available area.
415 g_object_class_install_property (gobject_class,
417 g_param_spec_int ("columns",
418 P_("Number of columns"),
419 P_("Number of columns to display"),
421 GTK_PARAM_READWRITE));
425 * GtkIconView::item-width:
427 * The item-width property specifies the width to use for each item.
428 * If it is set to -1, the icon view will automatically determine a
429 * suitable item size.
433 g_object_class_install_property (gobject_class,
435 g_param_spec_int ("item-width",
436 P_("Width for each item"),
437 P_("The width used for each item"),
439 GTK_PARAM_READWRITE));
442 * GtkIconView::spacing:
444 * The spacing property specifies the space which is inserted between
445 * the cells (i.e. the icon and the text) of an item.
449 g_object_class_install_property (gobject_class,
451 g_param_spec_int ("spacing",
453 P_("Space which is inserted between cells of an item"),
455 GTK_PARAM_READWRITE));
458 * GtkIconView::row-spacing:
460 * The row-spacing property specifies the space which is inserted between
461 * the rows of the icon view.
465 g_object_class_install_property (gobject_class,
467 g_param_spec_int ("row-spacing",
469 P_("Space which is inserted between grid rows"),
471 GTK_PARAM_READWRITE));
474 * GtkIconView::column-spacing:
476 * The column-spacing property specifies the space which is inserted between
477 * the columns of the icon view.
481 g_object_class_install_property (gobject_class,
483 g_param_spec_int ("column-spacing",
484 P_("Column Spacing"),
485 P_("Space which is inserted between grid column"),
487 GTK_PARAM_READWRITE));
490 * GtkIconView::margin:
492 * The margin property specifies the space which is inserted
493 * at the edges of the icon view.
497 g_object_class_install_property (gobject_class,
499 g_param_spec_int ("margin",
501 P_("Space which is inserted at the edges of the icon view"),
503 GTK_PARAM_READWRITE));
507 * GtkIconView::orientation:
509 * The orientation property specifies how the cells (i.e. the icon and
510 * the text) of the item are positioned relative to each other.
514 g_object_class_install_property (gobject_class,
516 g_param_spec_enum ("orientation",
518 P_("How the text and icon of each item are positioned relative to each other"),
519 GTK_TYPE_ORIENTATION,
520 GTK_ORIENTATION_VERTICAL,
521 GTK_PARAM_READWRITE));
523 /* Style properties */
524 gtk_widget_class_install_style_property (widget_class,
525 g_param_spec_boxed ("selection-box-color",
526 P_("Selection Box Color"),
527 P_("Color of the selection box"),
529 GTK_PARAM_READABLE));
531 gtk_widget_class_install_style_property (widget_class,
532 g_param_spec_uchar ("selection-box-alpha",
533 P_("Selection Box Alpha"),
534 P_("Opacity of the selection box"),
537 GTK_PARAM_READABLE));
540 widget_class->set_scroll_adjustments_signal =
541 g_signal_new ("set_scroll_adjustments",
542 G_TYPE_FROM_CLASS (gobject_class),
544 G_STRUCT_OFFSET (GtkIconViewClass, set_scroll_adjustments),
546 _gtk_marshal_VOID__OBJECT_OBJECT,
548 GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
550 icon_view_signals[ITEM_ACTIVATED] =
551 g_signal_new ("item_activated",
552 G_TYPE_FROM_CLASS (gobject_class),
554 G_STRUCT_OFFSET (GtkIconViewClass, item_activated),
556 g_cclosure_marshal_VOID__BOXED,
560 icon_view_signals[SELECTION_CHANGED] =
561 g_signal_new ("selection_changed",
562 G_TYPE_FROM_CLASS (gobject_class),
564 G_STRUCT_OFFSET (GtkIconViewClass, selection_changed),
566 g_cclosure_marshal_VOID__VOID,
569 icon_view_signals[SELECT_ALL] =
570 g_signal_new ("select_all",
571 G_TYPE_FROM_CLASS (gobject_class),
572 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
573 G_STRUCT_OFFSET (GtkIconViewClass, select_all),
575 g_cclosure_marshal_VOID__VOID,
578 icon_view_signals[UNSELECT_ALL] =
579 g_signal_new ("unselect_all",
580 G_TYPE_FROM_CLASS (gobject_class),
581 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
582 G_STRUCT_OFFSET (GtkIconViewClass, unselect_all),
584 g_cclosure_marshal_VOID__VOID,
587 icon_view_signals[SELECT_CURSOR_ITEM] =
588 g_signal_new ("select_cursor_item",
589 G_TYPE_FROM_CLASS (gobject_class),
590 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
591 G_STRUCT_OFFSET (GtkIconViewClass, select_cursor_item),
593 g_cclosure_marshal_VOID__VOID,
596 icon_view_signals[TOGGLE_CURSOR_ITEM] =
597 g_signal_new ("toggle_cursor_item",
598 G_TYPE_FROM_CLASS (gobject_class),
599 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
600 G_STRUCT_OFFSET (GtkIconViewClass, toggle_cursor_item),
602 g_cclosure_marshal_VOID__VOID,
605 icon_view_signals[ACTIVATE_CURSOR_ITEM] =
606 g_signal_new ("activate_cursor_item",
607 G_TYPE_FROM_CLASS (gobject_class),
608 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
609 G_STRUCT_OFFSET (GtkIconViewClass, activate_cursor_item),
611 _gtk_marshal_BOOLEAN__VOID,
614 icon_view_signals[MOVE_CURSOR] =
615 g_signal_new ("move_cursor",
616 G_TYPE_FROM_CLASS (gobject_class),
617 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
618 G_STRUCT_OFFSET (GtkIconViewClass, move_cursor),
620 _gtk_marshal_BOOLEAN__ENUM_INT,
622 GTK_TYPE_MOVEMENT_STEP,
626 gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK, "select_all", 0);
627 gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "unselect_all", 0);
628 gtk_binding_entry_add_signal (binding_set, GDK_space, 0, "select_cursor_item", 0);
629 gtk_binding_entry_add_signal (binding_set, GDK_space, GDK_CONTROL_MASK, "toggle_cursor_item", 0);
631 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, "activate_cursor_item", 0);
632 gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0, "activate_cursor_item", 0);
633 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, "activate_cursor_item", 0);
635 gtk_icon_view_add_move_binding (binding_set, GDK_Up, 0,
636 GTK_MOVEMENT_DISPLAY_LINES, -1);
637 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Up, 0,
638 GTK_MOVEMENT_DISPLAY_LINES, -1);
640 gtk_icon_view_add_move_binding (binding_set, GDK_Down, 0,
641 GTK_MOVEMENT_DISPLAY_LINES, 1);
642 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Down, 0,
643 GTK_MOVEMENT_DISPLAY_LINES, 1);
645 gtk_icon_view_add_move_binding (binding_set, GDK_p, GDK_CONTROL_MASK,
646 GTK_MOVEMENT_DISPLAY_LINES, -1);
648 gtk_icon_view_add_move_binding (binding_set, GDK_n, GDK_CONTROL_MASK,
649 GTK_MOVEMENT_DISPLAY_LINES, 1);
651 gtk_icon_view_add_move_binding (binding_set, GDK_Home, 0,
652 GTK_MOVEMENT_BUFFER_ENDS, -1);
653 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Home, 0,
654 GTK_MOVEMENT_BUFFER_ENDS, -1);
656 gtk_icon_view_add_move_binding (binding_set, GDK_End, 0,
657 GTK_MOVEMENT_BUFFER_ENDS, 1);
658 gtk_icon_view_add_move_binding (binding_set, GDK_KP_End, 0,
659 GTK_MOVEMENT_BUFFER_ENDS, 1);
661 gtk_icon_view_add_move_binding (binding_set, GDK_Page_Up, 0,
662 GTK_MOVEMENT_PAGES, -1);
663 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Page_Up, 0,
664 GTK_MOVEMENT_PAGES, -1);
666 gtk_icon_view_add_move_binding (binding_set, GDK_Page_Down, 0,
667 GTK_MOVEMENT_PAGES, 1);
668 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Page_Down, 0,
669 GTK_MOVEMENT_PAGES, 1);
671 gtk_icon_view_add_move_binding (binding_set, GDK_Right, 0,
672 GTK_MOVEMENT_VISUAL_POSITIONS, 1);
673 gtk_icon_view_add_move_binding (binding_set, GDK_Left, 0,
674 GTK_MOVEMENT_VISUAL_POSITIONS, -1);
676 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Right, 0,
677 GTK_MOVEMENT_VISUAL_POSITIONS, 1);
678 gtk_icon_view_add_move_binding (binding_set, GDK_KP_Left, 0,
679 GTK_MOVEMENT_VISUAL_POSITIONS, -1);
683 gtk_icon_view_init (GtkIconView *icon_view)
685 icon_view->priv = GTK_ICON_VIEW_GET_PRIVATE (icon_view);
687 icon_view->priv->width = 0;
688 icon_view->priv->height = 0;
689 icon_view->priv->selection_mode = GTK_SELECTION_SINGLE;
691 icon_view->priv->pressed_button = -1;
692 icon_view->priv->press_start_x = -1;
693 icon_view->priv->press_start_y = -1;
695 icon_view->priv->text_column = -1;
696 icon_view->priv->markup_column = -1;
697 icon_view->priv->pixbuf_column = -1;
699 icon_view->priv->layout = gtk_widget_create_pango_layout (GTK_WIDGET (icon_view), NULL);
701 pango_layout_set_wrap (icon_view->priv->layout, PANGO_WRAP_WORD_CHAR);
703 GTK_WIDGET_SET_FLAGS (icon_view, GTK_CAN_FOCUS);
705 gtk_icon_view_set_adjustments (icon_view, NULL, NULL);
707 icon_view->priv->orientation = GTK_ORIENTATION_VERTICAL;
709 icon_view->priv->columns = -1;
710 icon_view->priv->item_width = -1;
711 icon_view->priv->spacing = 0;
712 icon_view->priv->row_spacing = 6;
713 icon_view->priv->column_spacing = 6;
714 icon_view->priv->margin = 6;
718 gtk_icon_view_destroy (GtkObject *object)
720 GtkIconView *icon_view;
722 icon_view = GTK_ICON_VIEW (object);
724 gtk_icon_view_set_model (icon_view, NULL);
726 if (icon_view->priv->layout_idle_id != 0)
727 g_source_remove (icon_view->priv->layout_idle_id);
729 if (icon_view->priv->scroll_timeout_id != 0)
730 g_source_remove (icon_view->priv->scroll_timeout_id);
732 (GTK_OBJECT_CLASS (parent_class)->destroy) (object);
735 /* GObject methods */
737 gtk_icon_view_finalize (GObject *object)
739 GtkIconView *icon_view;
741 icon_view = GTK_ICON_VIEW (object);
743 g_object_unref (icon_view->priv->layout);
745 (G_OBJECT_CLASS (parent_class)->finalize) (object);
750 gtk_icon_view_set_property (GObject *object,
755 GtkIconView *icon_view;
757 icon_view = GTK_ICON_VIEW (object);
761 case PROP_SELECTION_MODE:
762 gtk_icon_view_set_selection_mode (icon_view, g_value_get_enum (value));
764 case PROP_PIXBUF_COLUMN:
765 gtk_icon_view_set_pixbuf_column (icon_view, g_value_get_int (value));
767 case PROP_TEXT_COLUMN:
768 gtk_icon_view_set_text_column (icon_view, g_value_get_int (value));
770 case PROP_MARKUP_COLUMN:
771 gtk_icon_view_set_markup_column (icon_view, g_value_get_int (value));
774 gtk_icon_view_set_model (icon_view, g_value_get_object (value));
776 case PROP_ORIENTATION:
777 gtk_icon_view_set_orientation (icon_view, g_value_get_enum (value));
780 gtk_icon_view_set_columns (icon_view, g_value_get_int (value));
782 case PROP_ITEM_WIDTH:
783 gtk_icon_view_set_item_width (icon_view, g_value_get_int (value));
786 gtk_icon_view_set_spacing (icon_view, g_value_get_int (value));
788 case PROP_ROW_SPACING:
789 gtk_icon_view_set_row_spacing (icon_view, g_value_get_int (value));
791 case PROP_COLUMN_SPACING:
792 gtk_icon_view_set_column_spacing (icon_view, g_value_get_int (value));
795 gtk_icon_view_set_margin (icon_view, g_value_get_int (value));
799 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
805 gtk_icon_view_get_property (GObject *object,
810 GtkIconView *icon_view;
812 icon_view = GTK_ICON_VIEW (object);
816 case PROP_SELECTION_MODE:
817 g_value_set_enum (value, icon_view->priv->selection_mode);
819 case PROP_PIXBUF_COLUMN:
820 g_value_set_int (value, icon_view->priv->pixbuf_column);
822 case PROP_TEXT_COLUMN:
823 g_value_set_int (value, icon_view->priv->text_column);
825 case PROP_MARKUP_COLUMN:
826 g_value_set_int (value, icon_view->priv->markup_column);
829 g_value_set_object (value, icon_view->priv->model);
831 case PROP_ORIENTATION:
832 g_value_set_enum (value, icon_view->priv->orientation);
835 g_value_set_int (value, icon_view->priv->columns);
837 case PROP_ITEM_WIDTH:
838 g_value_set_int (value, icon_view->priv->item_width);
841 g_value_set_int (value, icon_view->priv->spacing);
843 case PROP_ROW_SPACING:
844 g_value_set_int (value, icon_view->priv->row_spacing);
846 case PROP_COLUMN_SPACING:
847 g_value_set_int (value, icon_view->priv->column_spacing);
850 g_value_set_int (value, icon_view->priv->margin);
854 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
859 /* GtkWidget signals */
861 gtk_icon_view_realize (GtkWidget *widget)
863 GtkIconView *icon_view;
864 GdkWindowAttr attributes;
865 gint attributes_mask;
867 icon_view = GTK_ICON_VIEW (widget);
869 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
871 /* Make the main, clipping window */
872 attributes.window_type = GDK_WINDOW_CHILD;
873 attributes.x = widget->allocation.x;
874 attributes.y = widget->allocation.y;
875 attributes.width = widget->allocation.width;
876 attributes.height = widget->allocation.height;
877 attributes.wclass = GDK_INPUT_OUTPUT;
878 attributes.visual = gtk_widget_get_visual (widget);
879 attributes.colormap = gtk_widget_get_colormap (widget);
880 attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
882 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
884 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
885 &attributes, attributes_mask);
886 gdk_window_set_user_data (widget->window, widget);
888 /* Make the window for the icon view */
891 attributes.width = MAX (icon_view->priv->width, widget->allocation.width);
892 attributes.height = MAX (icon_view->priv->height, widget->allocation.height);
893 attributes.event_mask = (GDK_EXPOSURE_MASK |
895 GDK_POINTER_MOTION_MASK |
896 GDK_BUTTON_PRESS_MASK |
897 GDK_BUTTON_RELEASE_MASK |
899 GDK_KEY_RELEASE_MASK) |
900 gtk_widget_get_events (widget);
902 icon_view->priv->bin_window = gdk_window_new (widget->window,
903 &attributes, attributes_mask);
904 gdk_window_set_user_data (icon_view->priv->bin_window, widget);
906 widget->style = gtk_style_attach (widget->style, widget->window);
907 gdk_window_set_background (icon_view->priv->bin_window, &widget->style->base[widget->state]);
908 gdk_window_set_background (widget->window, &widget->style->base[widget->state]);
912 gtk_icon_view_unrealize (GtkWidget *widget)
914 GtkIconView *icon_view;
916 icon_view = GTK_ICON_VIEW (widget);
918 gdk_window_set_user_data (icon_view->priv->bin_window, NULL);
919 gdk_window_destroy (icon_view->priv->bin_window);
920 icon_view->priv->bin_window = NULL;
922 /* GtkWidget::unrealize destroys children and widget->window */
923 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
924 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
928 gtk_icon_view_map (GtkWidget *widget)
930 GtkIconView *icon_view;
932 icon_view = GTK_ICON_VIEW (widget);
934 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
936 gdk_window_show (icon_view->priv->bin_window);
937 gdk_window_show (widget->window);
941 gtk_icon_view_size_request (GtkWidget *widget,
942 GtkRequisition *requisition)
944 GtkIconView *icon_view;
946 icon_view = GTK_ICON_VIEW (widget);
948 requisition->width = icon_view->priv->width;
949 requisition->height = icon_view->priv->height;
953 gtk_icon_view_size_allocate (GtkWidget *widget,
954 GtkAllocation *allocation)
956 GtkIconView *icon_view;
957 GtkAdjustment *hadjustment, *vadjustment;
959 widget->allocation = *allocation;
961 icon_view = GTK_ICON_VIEW (widget);
963 if (GTK_WIDGET_REALIZED (widget))
965 gdk_window_move_resize (widget->window,
966 allocation->x, allocation->y,
967 allocation->width, allocation->height);
968 gdk_window_resize (icon_view->priv->bin_window,
969 MAX (icon_view->priv->width, allocation->width),
970 MAX (icon_view->priv->height, allocation->height));
973 hadjustment = icon_view->priv->hadjustment;
974 vadjustment = icon_view->priv->vadjustment;
976 hadjustment->page_size = allocation->width;
977 hadjustment->page_increment = allocation->width * 0.9;
978 hadjustment->step_increment = allocation->width * 0.1;
979 hadjustment->lower = 0;
980 hadjustment->upper = MAX (allocation->width, icon_view->priv->width);
982 if (hadjustment->value > hadjustment->upper - hadjustment->page_size)
983 gtk_adjustment_set_value (hadjustment, MAX (0, hadjustment->upper - hadjustment->page_size));
985 gtk_adjustment_changed (hadjustment);
987 vadjustment->page_size = allocation->height;
988 vadjustment->page_increment = allocation->height * 0.9;
989 vadjustment->step_increment = allocation->height * 0.1;
990 vadjustment->lower = 0;
991 vadjustment->upper = MAX (allocation->height, icon_view->priv->height);
993 if (vadjustment->value > vadjustment->upper - vadjustment->page_size)
994 gtk_adjustment_set_value (vadjustment, MAX (0, vadjustment->upper - vadjustment->page_size));
996 gtk_adjustment_changed (vadjustment);
998 gtk_icon_view_layout (icon_view);
1002 gtk_icon_view_expose (GtkWidget *widget,
1003 GdkEventExpose *expose)
1005 GtkIconView *icon_view;
1009 icon_view = GTK_ICON_VIEW (widget);
1011 if (expose->window != icon_view->priv->bin_window)
1014 cr = gdk_drawable_create_cairo_context (icon_view->priv->bin_window);
1015 cairo_set_line_width (cr, 1.);
1017 for (icons = icon_view->priv->items; icons; icons = icons->next) {
1018 GtkIconViewItem *item = icons->data;
1019 GdkRectangle item_rectangle;
1021 item_rectangle.x = item->x;
1022 item_rectangle.y = item->y;
1023 item_rectangle.width = item->width;
1024 item_rectangle.height = item->height;
1026 if (gdk_region_rect_in (expose->region, &item_rectangle) == GDK_OVERLAP_RECTANGLE_OUT)
1029 #ifdef DEBUG_ICON_VIEW
1030 cairo_rectangle (cr,
1031 item->x + 0.5, item->y + 0.5,
1032 item->width - 1, item->height - 1);
1033 cairo_rectangle (cr,
1034 item->x + 0.5, item->y + 0.5,
1035 item->width - 1, item->height- 1);
1036 cairo_rectangle (cr,
1037 item->pixbuf_x + 0.5, item->pixbuf_y + 0.5,
1038 item->pixbuf_width - 1, item->pixbuf_height- 1);
1039 cairo_rectangle (cr,
1040 item->layout_x + 0.5, item->layout_y + 0.5,
1041 item->layout_width - 1, item->layout_height - 1);
1044 gtk_icon_view_paint_item (icon_view, cr, item, &expose->area);
1048 if (icon_view->priv->doing_rubberband)
1050 GdkRectangle *rectangles;
1053 gdk_region_get_rectangles (expose->region,
1057 while (n_rectangles--)
1058 gtk_icon_view_paint_rubberband (icon_view, cr, &rectangles[n_rectangles]);
1060 g_free (rectangles);
1069 scroll_timeout (gpointer data)
1071 GtkIconView *icon_view;
1074 GDK_THREADS_ENTER ();
1078 value = MIN (icon_view->priv->vadjustment->value +
1079 icon_view->priv->scroll_value_diff,
1080 icon_view->priv->vadjustment->upper -
1081 icon_view->priv->vadjustment->page_size);
1083 gtk_adjustment_set_value (icon_view->priv->vadjustment,
1086 gtk_icon_view_update_rubberband (icon_view);
1088 GDK_THREADS_LEAVE ();
1094 gtk_icon_view_motion (GtkWidget *widget,
1095 GdkEventMotion *event)
1097 GtkIconView *icon_view;
1100 icon_view = GTK_ICON_VIEW (widget);
1102 gtk_icon_view_maybe_begin_dragging_items (icon_view, event);
1104 if (icon_view->priv->doing_rubberband)
1106 gtk_icon_view_update_rubberband (widget);
1108 abs_y = event->y - icon_view->priv->height *
1109 (icon_view->priv->vadjustment->value /
1110 (icon_view->priv->vadjustment->upper -
1111 icon_view->priv->vadjustment->lower));
1113 if (abs_y < 0 || abs_y > widget->allocation.height)
1115 if (icon_view->priv->scroll_timeout_id == 0)
1116 icon_view->priv->scroll_timeout_id = g_timeout_add (30, scroll_timeout, icon_view);
1119 icon_view->priv->scroll_value_diff = abs_y;
1121 icon_view->priv->scroll_value_diff = abs_y - widget->allocation.height;
1123 icon_view->priv->event_last_x = event->x;
1124 icon_view->priv->event_last_y = event->y;
1126 else if (icon_view->priv->scroll_timeout_id != 0)
1128 g_source_remove (icon_view->priv->scroll_timeout_id);
1130 icon_view->priv->scroll_timeout_id = 0;
1138 gtk_icon_view_button_press (GtkWidget *widget,
1139 GdkEventButton *event)
1141 GtkIconView *icon_view;
1142 GtkIconViewItem *item;
1143 gboolean dirty = FALSE;
1145 icon_view = GTK_ICON_VIEW (widget);
1147 if (event->window != icon_view->priv->bin_window)
1150 if (!GTK_WIDGET_HAS_FOCUS (widget))
1151 gtk_widget_grab_focus (widget);
1153 if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
1156 item = gtk_icon_view_get_item_at_pos (icon_view,
1157 event->x, event->y);
1161 gtk_icon_view_scroll_to_item (icon_view, item);
1163 if (icon_view->priv->selection_mode == GTK_SELECTION_NONE)
1165 gtk_icon_view_set_cursor_item (icon_view, item);
1167 else if (icon_view->priv->selection_mode == GTK_SELECTION_MULTIPLE &&
1168 (event->state & GDK_SHIFT_MASK))
1170 gtk_icon_view_unselect_all_internal (icon_view);
1172 gtk_icon_view_set_cursor_item (icon_view, item);
1173 if (!icon_view->priv->anchor_item)
1174 icon_view->priv->anchor_item = item;
1176 gtk_icon_view_select_all_between (icon_view,
1177 icon_view->priv->anchor_item,
1183 if ((icon_view->priv->selection_mode == GTK_SELECTION_MULTIPLE ||
1184 ((icon_view->priv->selection_mode == GTK_SELECTION_SINGLE) && item->selected)) &&
1185 (event->state & GDK_CONTROL_MASK))
1187 item->selected = !item->selected;
1188 gtk_icon_view_queue_draw_item (icon_view, item);
1193 if (!item->selected)
1195 gtk_icon_view_unselect_all_internal (icon_view);
1197 item->selected = TRUE;
1198 gtk_icon_view_queue_draw_item (icon_view, item);
1202 gtk_icon_view_set_cursor_item (icon_view, item);
1203 icon_view->priv->anchor_item = item;
1206 /* Save press to possibly begin a drag */
1207 if (icon_view->priv->pressed_button < 0)
1209 icon_view->priv->pressed_button = event->button;
1210 icon_view->priv->press_start_x = event->x;
1211 icon_view->priv->press_start_y = event->y;
1214 if (!icon_view->priv->last_single_clicked)
1215 icon_view->priv->last_single_clicked = item;
1219 if (icon_view->priv->selection_mode != GTK_SELECTION_BROWSE &&
1220 !(event->state & GDK_CONTROL_MASK))
1222 dirty = gtk_icon_view_unselect_all_internal (icon_view);
1225 if (icon_view->priv->selection_mode == GTK_SELECTION_MULTIPLE)
1226 gtk_icon_view_start_rubberbanding (icon_view, event->x, event->y);
1231 if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
1233 item = gtk_icon_view_get_item_at_pos (icon_view,
1234 event->x, event->y);
1236 if (item && item == icon_view->priv->last_single_clicked)
1240 path = gtk_tree_path_new_from_indices (item->index, -1);
1241 gtk_icon_view_item_activated (icon_view, path);
1242 gtk_tree_path_free (path);
1245 icon_view->priv->last_single_clicked = NULL;
1249 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
1251 return event->button == 1;
1255 gtk_icon_view_button_release (GtkWidget *widget,
1256 GdkEventButton *event)
1258 GtkIconView *icon_view;
1260 icon_view = GTK_ICON_VIEW (widget);
1263 if (icon_view->priv->pressed_button == event->button)
1264 icon_view->priv->pressed_button = -1;
1266 gtk_icon_view_stop_rubberbanding (icon_view);
1268 if (icon_view->priv->scroll_timeout_id != 0)
1270 g_source_remove (icon_view->priv->scroll_timeout_id);
1271 icon_view->priv->scroll_timeout_id = 0;
1278 gtk_icon_view_update_rubberband (gpointer data)
1280 GtkIconView *icon_view;
1282 GdkRectangle old_area;
1283 GdkRectangle new_area;
1284 GdkRectangle common;
1285 GdkRegion *invalid_region;
1287 icon_view = GTK_ICON_VIEW (data);
1289 gdk_window_get_pointer (icon_view->priv->bin_window, &x, &y, NULL);
1294 old_area.x = MIN (icon_view->priv->rubberband_x1,
1295 icon_view->priv->rubberband_x2);
1296 old_area.y = MIN (icon_view->priv->rubberband_y1,
1297 icon_view->priv->rubberband_y2);
1298 old_area.width = ABS (icon_view->priv->rubberband_x2 -
1299 icon_view->priv->rubberband_x1) + 1;
1300 old_area.height = ABS (icon_view->priv->rubberband_y2 -
1301 icon_view->priv->rubberband_y1) + 1;
1303 new_area.x = MIN (icon_view->priv->rubberband_x1, x);
1304 new_area.y = MIN (icon_view->priv->rubberband_y1, y);
1305 new_area.width = ABS (x - icon_view->priv->rubberband_x1) + 1;
1306 new_area.height = ABS (y - icon_view->priv->rubberband_y1) + 1;
1308 invalid_region = gdk_region_rectangle (&old_area);
1309 gdk_region_union_with_rect (invalid_region, &new_area);
1311 gdk_rectangle_intersect (&old_area, &new_area, &common);
1312 if (common.width > 2 && common.height > 2)
1314 GdkRegion *common_region;
1316 /* make sure the border is invalidated */
1322 common_region = gdk_region_rectangle (&common);
1324 gdk_region_subtract (invalid_region, common_region);
1325 gdk_region_destroy (common_region);
1328 gdk_window_invalidate_region (icon_view->priv->bin_window, invalid_region, TRUE);
1330 gdk_region_destroy (invalid_region);
1332 icon_view->priv->rubberband_x2 = x;
1333 icon_view->priv->rubberband_y2 = y;
1335 gtk_icon_view_update_rubberband_selection (icon_view);
1339 gtk_icon_view_start_rubberbanding (GtkIconView *icon_view,
1345 g_assert (!icon_view->priv->doing_rubberband);
1347 for (items = icon_view->priv->items; items; items = items->next)
1349 GtkIconViewItem *item = items->data;
1351 item->selected_before_rubberbanding = item->selected;
1354 icon_view->priv->rubberband_x1 = x;
1355 icon_view->priv->rubberband_y1 = y;
1356 icon_view->priv->rubberband_x2 = x;
1357 icon_view->priv->rubberband_y2 = y;
1359 icon_view->priv->doing_rubberband = TRUE;
1361 gtk_grab_add (GTK_WIDGET (icon_view));
1365 gtk_icon_view_stop_rubberbanding (GtkIconView *icon_view)
1367 if (!icon_view->priv->doing_rubberband)
1370 icon_view->priv->doing_rubberband = FALSE;
1372 gtk_grab_remove (GTK_WIDGET (icon_view));
1374 gtk_widget_queue_draw (GTK_WIDGET (icon_view));
1378 gtk_icon_view_update_rubberband_selection (GtkIconView *icon_view)
1381 gint x, y, width, height;
1382 gboolean dirty = FALSE;
1384 x = MIN (icon_view->priv->rubberband_x1,
1385 icon_view->priv->rubberband_x2);
1386 y = MIN (icon_view->priv->rubberband_y1,
1387 icon_view->priv->rubberband_y2);
1388 width = ABS (icon_view->priv->rubberband_x1 -
1389 icon_view->priv->rubberband_x2);
1390 height = ABS (icon_view->priv->rubberband_y1 -
1391 icon_view->priv->rubberband_y2);
1393 for (items = icon_view->priv->items; items; items = items->next)
1395 GtkIconViewItem *item = items->data;
1399 is_in = gtk_icon_view_item_hit_test (item, x, y, width, height);
1401 selected = is_in ^ item->selected_before_rubberbanding;
1403 if (item->selected != selected)
1405 item->selected = selected;
1407 gtk_icon_view_queue_draw_item (icon_view, item);
1412 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
1416 gtk_icon_view_item_hit_test (GtkIconViewItem *item,
1422 /* First try the pixbuf */
1423 if (MIN (x + width, item->pixbuf_x + item->pixbuf_width) - MAX (x, item->pixbuf_x) > 0 &&
1424 MIN (y + height, item->pixbuf_y + item->pixbuf_height) - MAX (y, item->pixbuf_y) > 0)
1427 /* Then try the text */
1428 if (MIN (x + width, item->layout_x + item->layout_width) - MAX (x, item->layout_x) > 0 &&
1429 MIN (y + height, item->layout_y + item->layout_height) - MAX (y, item->layout_y) > 0)
1437 gtk_icon_view_maybe_begin_dragging_items (GtkIconView *icon_view,
1438 GdkEventMotion *event)
1440 gboolean retval = FALSE;
1442 if (icon_view->priv->pressed_button < 0)
1445 if (!gtk_drag_check_threshold (GTK_WIDGET (icon_view),
1446 icon_view->priv->press_start_x,
1447 icon_view->priv->press_start_y,
1448 event->x, event->y))
1451 button = icon_view->priv->pressed_button;
1452 icon_view->priv->pressed_button = -1;
1455 static GtkTargetEntry row_targets[] = {
1456 { "GTK_ICON_VIEW_ITEMS", GTK_TARGET_SAME_APP, 0 }
1458 GtkTargetList *target_list;
1459 GdkDragContext *context;
1460 GtkIconViewItem *item;
1464 target_list = gtk_target_list_new (row_targets, G_N_ELEMENTS (row_targets));
1466 context = gtk_drag_begin (GTK_WIDGET (icon_view),
1467 target_list, GDK_ACTION_MOVE,
1471 item = gtk_icon_view_get_item_at_pos (icon_view,
1472 icon_view->priv->press_start_x,
1473 icon_view->priv->press_start_y);
1474 g_assert (item != NULL);
1475 gtk_drag_set_icon_pixbuf (context, gtk_icon_view_get_item_icon (icon_view, item),
1477 event->y - item->y);
1485 gtk_icon_view_unselect_all_internal (GtkIconView *icon_view)
1487 gboolean dirty = FALSE;
1490 if (icon_view->priv->selection_mode == GTK_SELECTION_NONE)
1493 for (items = icon_view->priv->items; items; items = items->next)
1495 GtkIconViewItem *item = items->data;
1499 item->selected = FALSE;
1501 gtk_icon_view_queue_draw_item (icon_view, item);
1509 /* GtkIconView signals */
1511 gtk_icon_view_set_adjustments (GtkIconView *icon_view,
1512 GtkAdjustment *hadj,
1513 GtkAdjustment *vadj)
1515 gboolean need_adjust = FALSE;
1518 g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
1520 hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
1522 g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
1524 vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
1526 if (icon_view->priv->hadjustment && (icon_view->priv->hadjustment != hadj))
1528 g_signal_handlers_disconnect_matched (icon_view->priv->hadjustment, G_SIGNAL_MATCH_DATA,
1529 0, 0, NULL, NULL, icon_view);
1530 g_object_unref (icon_view->priv->hadjustment);
1533 if (icon_view->priv->vadjustment && (icon_view->priv->vadjustment != vadj))
1535 g_signal_handlers_disconnect_matched (icon_view->priv->vadjustment, G_SIGNAL_MATCH_DATA,
1536 0, 0, NULL, NULL, icon_view);
1537 g_object_unref (icon_view->priv->vadjustment);
1540 if (icon_view->priv->hadjustment != hadj)
1542 icon_view->priv->hadjustment = hadj;
1543 g_object_ref (icon_view->priv->hadjustment);
1544 gtk_object_sink (GTK_OBJECT (icon_view->priv->hadjustment));
1546 g_signal_connect (icon_view->priv->hadjustment, "value_changed",
1547 G_CALLBACK (gtk_icon_view_adjustment_changed),
1552 if (icon_view->priv->vadjustment != vadj)
1554 icon_view->priv->vadjustment = vadj;
1555 g_object_ref (icon_view->priv->vadjustment);
1556 gtk_object_sink (GTK_OBJECT (icon_view->priv->vadjustment));
1558 g_signal_connect (icon_view->priv->vadjustment, "value_changed",
1559 G_CALLBACK (gtk_icon_view_adjustment_changed),
1565 gtk_icon_view_adjustment_changed (NULL, icon_view);
1569 gtk_icon_view_real_select_all (GtkIconView *icon_view)
1571 gtk_icon_view_select_all (icon_view);
1575 gtk_icon_view_real_unselect_all (GtkIconView *icon_view)
1577 gtk_icon_view_unselect_all (icon_view);
1581 gtk_icon_view_real_select_cursor_item (GtkIconView *icon_view)
1583 gtk_icon_view_unselect_all (icon_view);
1585 if (icon_view->priv->cursor_item != NULL)
1586 gtk_icon_view_select_item (icon_view, icon_view->priv->cursor_item);
1590 gtk_icon_view_real_activate_cursor_item (GtkIconView *icon_view)
1594 if (!icon_view->priv->cursor_item)
1597 path = gtk_tree_path_new_from_indices (icon_view->priv->cursor_item->index, -1);
1599 gtk_icon_view_item_activated (icon_view, path);
1601 gtk_tree_path_free (path);
1607 gtk_icon_view_real_toggle_cursor_item (GtkIconView *icon_view)
1609 if (!icon_view->priv->cursor_item)
1612 switch (icon_view->priv->selection_mode)
1614 case GTK_SELECTION_NONE:
1616 case GTK_SELECTION_BROWSE:
1617 gtk_icon_view_select_item (icon_view, icon_view->priv->cursor_item);
1619 case GTK_SELECTION_SINGLE:
1620 if (icon_view->priv->cursor_item->selected)
1621 gtk_icon_view_unselect_item (icon_view, icon_view->priv->cursor_item);
1623 gtk_icon_view_select_item (icon_view, icon_view->priv->cursor_item);
1625 case GTK_SELECTION_MULTIPLE:
1626 icon_view->priv->cursor_item->selected = !icon_view->priv->cursor_item->selected;
1627 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
1629 gtk_icon_view_queue_draw_item (icon_view, icon_view->priv->cursor_item);
1634 /* Internal functions */
1636 gtk_icon_view_adjustment_changed (GtkAdjustment *adjustment,
1637 GtkIconView *icon_view)
1639 if (GTK_WIDGET_REALIZED (icon_view))
1641 gdk_window_move (icon_view->priv->bin_window,
1642 - icon_view->priv->hadjustment->value,
1643 - icon_view->priv->vadjustment->value);
1645 if (icon_view->priv->doing_rubberband)
1646 gtk_icon_view_update_rubberband (GTK_WIDGET (icon_view));
1648 gdk_window_process_updates (icon_view->priv->bin_window, TRUE);
1653 gtk_icon_view_layout_single_row (GtkIconView *icon_view,
1658 gint *maximum_width)
1660 gint focus_width, focus_pad;
1661 gint x, current_width, max_height, max_pixbuf_height;
1662 GList *items, *last_item;
1665 gboolean rtl = gtk_widget_get_direction (GTK_WIDGET (icon_view)) == GTK_TEXT_DIR_RTL;
1670 max_pixbuf_height = 0;
1674 gtk_widget_style_get (GTK_WIDGET (icon_view),
1675 "focus-line-width", &focus_width,
1676 "focus-padding", &focus_pad,
1679 x += icon_view->priv->margin;
1680 current_width += 2 * icon_view->priv->margin;
1685 GtkIconViewItem *item = items->data;
1687 gtk_icon_view_calculate_item_size (icon_view, item, item_width);
1689 colspan = 1 + (item->width - 1) / (item_width + icon_view->priv->column_spacing);
1690 current_width += colspan * (item_width + icon_view->priv->column_spacing);
1692 if (items != first_item)
1694 if ((icon_view->priv->columns <= 0 && current_width > GTK_WIDGET (icon_view)->allocation.width) ||
1695 (icon_view->priv->columns > 0 && col >= icon_view->priv->columns))
1700 item->x = rtl ? GTK_WIDGET (icon_view)->allocation.width - MAX (item_width, item->width) - x : x;
1702 if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
1706 item->layout_x = item->x + ICON_TEXT_PADDING + focus_width + focus_pad;
1707 if (icon_view->priv->text_column != -1 ||
1708 icon_view->priv->markup_column != -1)
1709 item->pixbuf_x = item->x + 2 * (ICON_TEXT_PADDING + focus_width + focus_pad) + icon_view->priv->spacing + item->layout_width;
1711 item->pixbuf_x = item->x;
1715 item->pixbuf_x = item->x;
1716 if (icon_view->priv->pixbuf_column != -1)
1717 item->layout_x = item->x + item->pixbuf_width + icon_view->priv->spacing + ICON_TEXT_PADDING + focus_width + focus_pad;
1719 item->layout_x = item->x + ICON_TEXT_PADDING + focus_width + focus_pad;
1724 if (item->width < colspan * item_width + (colspan - 1) * icon_view->priv->column_spacing)
1725 item->x += (colspan * item_width + (colspan - 1) * icon_view->priv->column_spacing - item->width) / 2;
1727 item->pixbuf_x = item->x + (item->width - item->pixbuf_width) / 2;
1728 item->layout_x = item->x + (item->width - item->layout_width) / 2;
1731 x = current_width - icon_view->priv->margin;
1733 max_height = MAX (max_height, item->height);
1734 max_pixbuf_height = MAX (max_pixbuf_height, item->pixbuf_height);
1736 if (current_width > *maximum_width)
1737 *maximum_width = current_width;
1743 items = items->next;
1748 *y += max_height + icon_view->priv->row_spacing;
1750 /* Now go through the row again and align the icons */
1751 for (items = first_item; items != last_item; items = items->next)
1753 GtkIconViewItem *item = items->data;
1755 if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
1757 item->pixbuf_y = item->y;
1758 item->layout_y = item->y + ICON_TEXT_PADDING + focus_width + focus_pad;
1762 item->pixbuf_y = item->y + (max_pixbuf_height - item->pixbuf_height);
1763 if (icon_view->priv->pixbuf_column != -1)
1764 item->layout_y = item->pixbuf_y + item->pixbuf_height + icon_view->priv->spacing + ICON_TEXT_PADDING + focus_width + focus_pad;
1766 item->layout_y = item->y + ICON_TEXT_PADDING + focus_width + focus_pad;
1768 /* Update the bounding box */
1769 item->y = item->pixbuf_y;
1771 /* We may want to readjust the new y coordinate. */
1772 if (item->y + item->height > *y)
1773 *y = item->y + item->height;
1776 item->col = col - 1 - item->col;
1783 gtk_icon_view_set_adjustment_upper (GtkAdjustment *adj,
1786 if (upper != adj->upper)
1788 gdouble min = MAX (0.0, upper - adj->page_size);
1789 gboolean value_changed = FALSE;
1793 if (adj->value > min)
1796 value_changed = TRUE;
1799 gtk_adjustment_changed (adj);
1802 gtk_adjustment_value_changed (adj);
1807 gtk_icon_view_layout (GtkIconView *icon_view)
1809 gint y = 0, maximum_width = 0;
1815 if (!VALID_MODEL_AND_COLUMNS (icon_view))
1818 widget = GTK_WIDGET (icon_view);
1820 item_width = icon_view->priv->item_width;
1824 for (icons = icon_view->priv->items; icons; icons = icons->next)
1826 GtkIconViewItem *item = icons->data;
1827 gtk_icon_view_calculate_item_size (icon_view, item, -1);
1828 item_width = MAX (item_width, item->width);
1829 gtk_icon_view_item_invalidate_size (item);
1833 icons = icon_view->priv->items;
1834 y += icon_view->priv->margin;
1839 icons = gtk_icon_view_layout_single_row (icon_view, icons,
1841 &y, &maximum_width);
1844 while (icons != NULL);
1846 if (maximum_width != icon_view->priv->width)
1848 icon_view->priv->width = maximum_width;
1850 y += icon_view->priv->margin;
1852 if (y != icon_view->priv->height)
1854 icon_view->priv->height = y;
1857 gtk_icon_view_set_adjustment_upper (icon_view->priv->hadjustment, icon_view->priv->width);
1858 gtk_icon_view_set_adjustment_upper (icon_view->priv->vadjustment, icon_view->priv->height);
1860 if (GTK_WIDGET_REALIZED (icon_view))
1862 gdk_window_resize (icon_view->priv->bin_window,
1863 MAX (icon_view->priv->width, widget->allocation.width),
1864 MAX (icon_view->priv->height, widget->allocation.height));
1867 if (icon_view->priv->layout_idle_id != 0)
1869 g_source_remove (icon_view->priv->layout_idle_id);
1870 icon_view->priv->layout_idle_id = 0;
1873 gtk_widget_queue_draw (GTK_WIDGET (icon_view));
1876 /* Updates the pango layout and calculates the size */
1878 gtk_icon_view_calculate_item_size (GtkIconView *icon_view,
1879 GtkIconViewItem *item,
1882 gint focus_width, focus_pad;
1883 gint layout_width, layout_height;
1884 gint maximum_layout_width;
1885 gint spacing, padding;
1889 if (item->width != -1 && item->height != -1)
1892 gtk_widget_style_get (GTK_WIDGET (icon_view),
1893 "focus-line-width", &focus_width,
1894 "focus-padding", &focus_pad,
1897 spacing = icon_view->priv->spacing;
1899 if (icon_view->priv->pixbuf_column != -1)
1901 pixbuf = gtk_icon_view_get_item_icon (icon_view, item);
1902 item->pixbuf_width = gdk_pixbuf_get_width (pixbuf);
1903 item->pixbuf_height = gdk_pixbuf_get_height (pixbuf);
1904 g_object_unref (pixbuf);
1908 item->pixbuf_width = 0;
1909 item->pixbuf_height = 0;
1913 if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
1916 colspan = item->pixbuf_width / item_width + 1;
1917 maximum_layout_width = MAX (colspan * item_width - item->pixbuf_width - icon_view->priv->spacing - 2 * (ICON_TEXT_PADDING + focus_width + focus_pad), 50);
1920 maximum_layout_width = MAX (item_width, item->pixbuf_width);
1922 if (icon_view->priv->markup_column != -1 ||
1923 icon_view->priv->text_column != -1)
1925 gtk_icon_view_update_item_text (icon_view, item);
1927 pango_layout_set_alignment (icon_view->priv->layout, PANGO_ALIGN_CENTER);
1928 pango_layout_set_width (icon_view->priv->layout, maximum_layout_width * PANGO_SCALE);
1930 pango_layout_get_pixel_size (icon_view->priv->layout, &layout_width, &layout_height);
1932 item->layout_width = layout_width;
1933 item->layout_height = layout_height;
1934 padding = 2 * (ICON_TEXT_PADDING + focus_width + focus_pad);
1938 item->layout_width = 0;
1939 item->layout_height = 0;
1944 if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
1946 item->width = item->layout_width + padding + spacing + item->pixbuf_width;
1947 item->height = MAX (item->layout_height + padding, item->pixbuf_height);
1951 item->width = MAX (item->layout_width + padding, item->pixbuf_width);
1952 item->height = item->layout_height + padding + spacing + item->pixbuf_height;
1957 gtk_icon_view_invalidate_sizes (GtkIconView *icon_view)
1959 g_list_foreach (icon_view->priv->items,
1960 (GFunc)gtk_icon_view_item_invalidate_size, NULL);
1964 gtk_icon_view_item_invalidate_size (GtkIconViewItem *item)
1971 create_colorized_pixbuf (GdkPixbuf *src, GdkColor *new_color)
1974 gint width, height, has_alpha, src_row_stride, dst_row_stride;
1975 gint red_value, green_value, blue_value;
1976 guchar *target_pixels;
1977 guchar *original_pixels;
1982 red_value = new_color->red / 255.0;
1983 green_value = new_color->green / 255.0;
1984 blue_value = new_color->blue / 255.0;
1986 dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src),
1987 gdk_pixbuf_get_has_alpha (src),
1988 gdk_pixbuf_get_bits_per_sample (src),
1989 gdk_pixbuf_get_width (src),
1990 gdk_pixbuf_get_height (src));
1992 has_alpha = gdk_pixbuf_get_has_alpha (src);
1993 width = gdk_pixbuf_get_width (src);
1994 height = gdk_pixbuf_get_height (src);
1995 src_row_stride = gdk_pixbuf_get_rowstride (src);
1996 dst_row_stride = gdk_pixbuf_get_rowstride (dest);
1997 target_pixels = gdk_pixbuf_get_pixels (dest);
1998 original_pixels = gdk_pixbuf_get_pixels (src);
2000 for (i = 0; i < height; i++) {
2001 pixdest = target_pixels + i*dst_row_stride;
2002 pixsrc = original_pixels + i*src_row_stride;
2003 for (j = 0; j < width; j++) {
2004 *pixdest++ = (*pixsrc++ * red_value) >> 8;
2005 *pixdest++ = (*pixsrc++ * green_value) >> 8;
2006 *pixdest++ = (*pixsrc++ * blue_value) >> 8;
2008 *pixdest++ = *pixsrc++;
2016 gtk_icon_view_paint_item (GtkIconView *icon_view,
2018 GtkIconViewItem *item,
2021 gint focus_width, focus_pad;
2022 GdkPixbuf *pixbuf, *tmp;
2024 gboolean rtl = gtk_widget_get_direction (GTK_WIDGET (icon_view)) == GTK_TEXT_DIR_RTL;
2026 if (!VALID_MODEL_AND_COLUMNS (icon_view))
2029 gtk_widget_style_get (GTK_WIDGET (icon_view),
2030 "focus-line-width", &focus_width,
2031 "focus-padding", &focus_pad,
2034 if (GTK_WIDGET_HAS_FOCUS (icon_view))
2035 state = GTK_STATE_SELECTED;
2037 state = GTK_STATE_ACTIVE;
2039 if (icon_view->priv->pixbuf_column != -1)
2041 tmp = gtk_icon_view_get_item_icon (icon_view, item);
2044 pixbuf = create_colorized_pixbuf (tmp,
2045 >K_WIDGET (icon_view)->style->base[state]);
2046 g_object_unref (tmp);
2051 cairo_move_to (cr, item->pixbuf_x, item->pixbuf_y);
2052 gdk_pixbuf_set_as_cairo_source (pixbuf, cr);
2053 g_object_unref (pixbuf);
2055 cairo_rectangle (cr,
2056 item->pixbuf_x, item->pixbuf_y,
2057 item->pixbuf_width, item->pixbuf_height);
2061 if (icon_view->priv->text_column != -1 ||
2062 icon_view->priv->markup_column != -1)
2066 gdk_cairo_set_source_color (cr, >K_WIDGET (icon_view)->style->base[state]);
2067 cairo_rectangle (cr,
2068 item->layout_x - ICON_TEXT_PADDING,
2069 item->layout_y - ICON_TEXT_PADDING,
2070 item->layout_width + 2 * ICON_TEXT_PADDING,
2071 item->layout_height + 2 * ICON_TEXT_PADDING);
2075 gtk_icon_view_update_item_text (icon_view, item);
2076 pango_layout_set_alignment (icon_view->priv->layout, rtl ? PANGO_ALIGN_RIGHT: PANGO_ALIGN_LEFT);
2077 pango_layout_set_width (icon_view->priv->layout, item->layout_width * PANGO_SCALE);
2078 gtk_paint_layout (GTK_WIDGET (icon_view)->style,
2079 icon_view->priv->bin_window,
2080 item->selected ? state : GTK_STATE_NORMAL,
2081 TRUE, area, GTK_WIDGET (icon_view), "icon_view",
2084 icon_view->priv->layout);
2086 if (GTK_WIDGET_HAS_FOCUS (icon_view) &&
2087 item == icon_view->priv->cursor_item)
2088 gtk_paint_focus (GTK_WIDGET (icon_view)->style,
2089 icon_view->priv->bin_window,
2092 GTK_WIDGET (icon_view),
2094 item->layout_x - ICON_TEXT_PADDING - focus_width - focus_pad,
2095 item->layout_y - ICON_TEXT_PADDING - focus_width - focus_pad,
2096 item->layout_width + 2 * (ICON_TEXT_PADDING + focus_width + focus_pad),
2097 item->layout_height + 2 * (ICON_TEXT_PADDING + focus_width + focus_pad));
2102 gtk_icon_view_paint_rubberband (GtkIconView *icon_view,
2107 GdkRectangle rubber_rect;
2108 GdkColor *fill_color_gdk;
2109 guchar fill_color_alpha;
2111 rubber_rect.x = MIN (icon_view->priv->rubberband_x1, icon_view->priv->rubberband_x2);
2112 rubber_rect.y = MIN (icon_view->priv->rubberband_y1, icon_view->priv->rubberband_y2);
2113 rubber_rect.width = ABS (icon_view->priv->rubberband_x1 - icon_view->priv->rubberband_x2) + 1;
2114 rubber_rect.height = ABS (icon_view->priv->rubberband_y1 - icon_view->priv->rubberband_y2) + 1;
2116 if (!gdk_rectangle_intersect (&rubber_rect, area, &rect))
2119 gtk_widget_style_get (GTK_WIDGET (icon_view),
2120 "selection-box-color", &fill_color_gdk,
2121 "selection-box-alpha", &fill_color_alpha,
2124 if (!fill_color_gdk)
2125 fill_color_gdk = gdk_color_copy (>K_WIDGET (icon_view)->style->base[GTK_STATE_SELECTED]);
2127 cairo_set_source_rgba (cr,
2128 fill_color_gdk->red / 65535.,
2129 fill_color_gdk->green / 65535.,
2130 fill_color_gdk->blue / 65535.,
2131 fill_color_alpha / 255.);
2134 cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height);
2138 /* Draw the border without alpha */
2139 cairo_set_source_rgb (cr,
2140 fill_color_gdk->red / 65535.,
2141 fill_color_gdk->green / 65535.,
2142 fill_color_gdk->blue / 65535.);
2143 cairo_rectangle (cr,
2144 rubber_rect.x + 0.5, rubber_rect.y + 0.5,
2145 rubber_rect.width - 1, rubber_rect.height - 1);
2149 gdk_color_free (fill_color_gdk);
2153 gtk_icon_view_queue_draw_item (GtkIconView *icon_view,
2154 GtkIconViewItem *item)
2160 rect.width = item->width;
2161 rect.height = item->height;
2163 if (icon_view->priv->bin_window)
2164 gdk_window_invalidate_rect (icon_view->priv->bin_window, &rect, TRUE);
2168 layout_callback (gpointer user_data)
2170 GtkIconView *icon_view;
2172 GDK_THREADS_ENTER ();
2174 icon_view = GTK_ICON_VIEW (user_data);
2176 icon_view->priv->layout_idle_id = 0;
2178 gtk_icon_view_layout (icon_view);
2180 GDK_THREADS_LEAVE();
2186 gtk_icon_view_queue_layout (GtkIconView *icon_view)
2188 if (icon_view->priv->layout_idle_id != 0)
2191 icon_view->priv->layout_idle_id = g_idle_add (layout_callback, icon_view);
2195 gtk_icon_view_set_cursor_item (GtkIconView *icon_view,
2196 GtkIconViewItem *item)
2199 AtkObject *item_obj;
2201 if (icon_view->priv->cursor_item == item)
2204 if (icon_view->priv->cursor_item != NULL)
2205 gtk_icon_view_queue_draw_item (icon_view, icon_view->priv->cursor_item);
2207 icon_view->priv->cursor_item = item;
2208 gtk_icon_view_queue_draw_item (icon_view, item);
2210 /* Notify that accessible focus object has changed */
2211 obj = gtk_widget_get_accessible (GTK_WIDGET (icon_view));
2212 item_obj = atk_object_ref_accessible_child (obj, item->index);
2214 if (item_obj != NULL)
2216 atk_focus_tracker_notify (item_obj);
2217 g_object_unref (item_obj);
2222 static GtkIconViewItem *
2223 gtk_icon_view_item_new (void)
2225 GtkIconViewItem *item;
2227 item = g_new0 (GtkIconViewItem, 1);
2236 gtk_icon_view_item_free (GtkIconViewItem *item)
2238 g_return_if_fail (item != NULL);
2244 gtk_icon_view_update_item_text (GtkIconView *icon_view,
2245 GtkIconViewItem *item)
2247 gboolean iters_persist;
2252 iters_persist = gtk_tree_model_get_flags (icon_view->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST;
2256 path = gtk_tree_path_new_from_indices (item->index, -1);
2257 gtk_tree_model_get_iter (icon_view->priv->model, &iter, path);
2258 gtk_tree_path_free (path);
2263 if (icon_view->priv->markup_column != -1)
2265 gtk_tree_model_get (icon_view->priv->model, &iter,
2266 icon_view->priv->markup_column, &text,
2268 pango_layout_set_markup (icon_view->priv->layout, text, -1);
2271 else if (icon_view->priv->text_column != -1)
2273 gtk_tree_model_get (icon_view->priv->model, &iter,
2274 icon_view->priv->text_column, &text,
2276 pango_layout_set_text (icon_view->priv->layout, text, -1);
2280 pango_layout_set_text (icon_view->priv->layout, "", -1);
2284 gtk_icon_view_get_item_icon (GtkIconView *icon_view,
2285 GtkIconViewItem *item)
2287 gboolean iters_persist;
2292 g_return_val_if_fail (item != NULL, NULL);
2294 iters_persist = gtk_tree_model_get_flags (icon_view->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST;
2298 path = gtk_tree_path_new_from_indices (item->index, -1);
2299 gtk_tree_model_get_iter (icon_view->priv->model, &iter, path);
2300 gtk_tree_path_free (path);
2305 gtk_tree_model_get (icon_view->priv->model, &iter,
2306 icon_view->priv->pixbuf_column, &pixbuf,
2313 static GtkIconViewItem *
2314 gtk_icon_view_get_item_at_pos (GtkIconView *icon_view,
2320 for (items = icon_view->priv->items; items; items = items->next)
2322 GtkIconViewItem *item = items->data;
2324 if (x > item->x && x < item->x + item->width &&
2325 y > item->y && y < item->y + item->height)
2327 /* Check if the mouse is inside the icon or the label */
2328 if ((x > item->pixbuf_x && x < item->pixbuf_x + item->pixbuf_width &&
2329 y > item->pixbuf_y && y < item->pixbuf_y + item->pixbuf_height) ||
2330 (x > item->layout_x - ICON_TEXT_PADDING &&
2331 x < item->layout_x + item->layout_width + ICON_TEXT_PADDING &&
2332 y > item->layout_y - ICON_TEXT_PADDING &&
2333 y < item->layout_y + item->layout_height + ICON_TEXT_PADDING))
2342 gtk_icon_view_select_item (GtkIconView *icon_view,
2343 GtkIconViewItem *item)
2345 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
2346 g_return_if_fail (item != NULL);
2351 if (icon_view->priv->selection_mode == GTK_SELECTION_NONE)
2353 else if (icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
2354 gtk_icon_view_unselect_all_internal (icon_view);
2356 item->selected = TRUE;
2358 gtk_icon_view_queue_draw_item (icon_view, item);
2360 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2365 gtk_icon_view_unselect_item (GtkIconView *icon_view,
2366 GtkIconViewItem *item)
2368 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
2369 g_return_if_fail (item != NULL);
2371 if (!item->selected)
2374 if (icon_view->priv->selection_mode == GTK_SELECTION_NONE ||
2375 icon_view->priv->selection_mode == GTK_SELECTION_BROWSE)
2378 item->selected = FALSE;
2380 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2382 gtk_icon_view_queue_draw_item (icon_view, item);
2386 verify_items (GtkIconView *icon_view)
2391 for (items = icon_view->priv->items; items; items = items->next)
2393 GtkIconViewItem *item = items->data;
2395 if (item->index != i)
2396 g_error ("List item does not match its index: item index %d and list index %d\n", item->index, i);
2403 gtk_icon_view_row_changed (GtkTreeModel *model,
2408 GtkIconViewItem *item;
2410 GtkIconView *icon_view;
2412 icon_view = GTK_ICON_VIEW (data);
2414 index = gtk_tree_path_get_indices(path)[0];
2415 item = g_list_nth (icon_view->priv->items, index)->data;
2417 gtk_icon_view_item_invalidate_size (item);
2418 gtk_icon_view_queue_layout (icon_view);
2420 verify_items (icon_view);
2424 gtk_icon_view_row_inserted (GtkTreeModel *model,
2430 GtkIconViewItem *item;
2431 gboolean iters_persist;
2432 GtkIconView *icon_view;
2435 icon_view = GTK_ICON_VIEW (data);
2436 iters_persist = gtk_tree_model_get_flags (icon_view->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST;
2438 length = gtk_tree_model_iter_n_children (model, NULL);
2439 index = gtk_tree_path_get_indices(path)[0];
2441 item = gtk_icon_view_item_new ();
2446 item->index = index;
2448 /* FIXME: We can be more efficient here,
2449 we can store a tail pointer and use that when
2450 appending (which is a rather common operation)
2452 icon_view->priv->items = g_list_insert (icon_view->priv->items,
2455 list = g_list_nth (icon_view->priv->items, index + 1);
2456 for (; list; list = list->next)
2463 verify_items (icon_view);
2467 gtk_icon_view_row_deleted (GtkTreeModel *model,
2472 GtkIconView *icon_view;
2473 GtkIconViewItem *item;
2475 gboolean emit = FALSE;
2477 icon_view = GTK_ICON_VIEW (data);
2479 index = gtk_tree_path_get_indices(path)[0];
2481 list = g_list_nth (icon_view->priv->items, index);
2484 if (item == icon_view->priv->anchor_item)
2485 icon_view->priv->anchor_item = NULL;
2487 if (item == icon_view->priv->cursor_item)
2488 icon_view->priv->cursor_item = NULL;
2493 gtk_icon_view_item_free (item);
2495 for (next = list->next; next; next = next->next)
2502 icon_view->priv->items = g_list_delete_link (icon_view->priv->items, list);
2504 gtk_icon_view_queue_layout (icon_view);
2506 verify_items (icon_view);
2509 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2513 gtk_icon_view_rows_reordered (GtkTreeModel *model,
2514 GtkTreePath *parent,
2521 GtkIconView *icon_view;
2522 GList *items = NULL, *list;
2523 GtkIconViewItem **item_array;
2526 icon_view = GTK_ICON_VIEW (data);
2528 length = gtk_tree_model_iter_n_children (model, NULL);
2530 order = g_new (gint, length);
2531 for (i = 0; i < length; i++)
2532 order [new_order[i]] = i;
2534 item_array = g_new (GtkIconViewItem *, length);
2535 for (i = 0, list = icon_view->priv->items; list != NULL; list = list->next, i++)
2536 item_array[order[i]] = list->data;
2539 for (i = length - 1; i >= 0; i--)
2541 item_array[i]->index = i;
2542 items = g_list_prepend (items, item_array[i]);
2545 g_free (item_array);
2546 g_list_free (icon_view->priv->items);
2547 icon_view->priv->items = items;
2549 verify_items (icon_view);
2553 gtk_icon_view_build_items (GtkIconView *icon_view)
2557 gboolean iters_persist;
2558 GList *items = NULL;
2560 iters_persist = gtk_tree_model_get_flags (icon_view->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST;
2562 if (!gtk_tree_model_get_iter_first (icon_view->priv->model,
2570 GtkIconViewItem *item = gtk_icon_view_item_new ();
2579 items = g_list_prepend (items, item);
2581 } while (gtk_tree_model_iter_next (icon_view->priv->model, &iter));
2583 icon_view->priv->items = g_list_reverse (items);
2587 gtk_icon_view_add_move_binding (GtkBindingSet *binding_set,
2590 GtkMovementStep step,
2594 gtk_binding_entry_add_signal (binding_set, keyval, modmask,
2599 gtk_binding_entry_add_signal (binding_set, keyval, GDK_SHIFT_MASK,
2604 if ((modmask & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
2607 gtk_binding_entry_add_signal (binding_set, keyval, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
2612 gtk_binding_entry_add_signal (binding_set, keyval, GDK_CONTROL_MASK,
2619 gtk_icon_view_real_move_cursor (GtkIconView *icon_view,
2620 GtkMovementStep step,
2623 GdkModifierType state;
2625 g_return_val_if_fail (GTK_ICON_VIEW (icon_view), FALSE);
2626 g_return_val_if_fail (step == GTK_MOVEMENT_LOGICAL_POSITIONS ||
2627 step == GTK_MOVEMENT_VISUAL_POSITIONS ||
2628 step == GTK_MOVEMENT_DISPLAY_LINES ||
2629 step == GTK_MOVEMENT_PAGES ||
2630 step == GTK_MOVEMENT_BUFFER_ENDS, FALSE);
2632 if (!GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (icon_view)))
2635 gtk_widget_grab_focus (GTK_WIDGET (icon_view));
2637 if (gtk_get_current_event_state (&state))
2639 if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
2640 icon_view->priv->ctrl_pressed = TRUE;
2641 if ((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
2642 icon_view->priv->shift_pressed = TRUE;
2644 /* else we assume not pressed */
2648 case GTK_MOVEMENT_LOGICAL_POSITIONS:
2649 case GTK_MOVEMENT_VISUAL_POSITIONS:
2650 gtk_icon_view_move_cursor_left_right (icon_view, count);
2652 case GTK_MOVEMENT_DISPLAY_LINES:
2653 gtk_icon_view_move_cursor_up_down (icon_view, count);
2655 case GTK_MOVEMENT_PAGES:
2656 gtk_icon_view_move_cursor_page_up_down (icon_view, count);
2658 case GTK_MOVEMENT_BUFFER_ENDS:
2659 gtk_icon_view_move_cursor_start_end (icon_view, count);
2662 g_assert_not_reached ();
2665 icon_view->priv->ctrl_pressed = FALSE;
2666 icon_view->priv->shift_pressed = FALSE;
2671 static GtkIconViewItem *
2672 find_item (GtkIconView *icon_view,
2673 GtkIconViewItem *current,
2679 GtkIconViewItem *item;
2681 /* FIXME: this could be more efficient
2683 row = current->row + row_ofs;
2684 col = current->col + col_ofs;
2686 for (items = icon_view->priv->items; items; items = items->next)
2689 if (item->row == row && item->col == col)
2697 static GtkIconViewItem *
2698 find_item_page_up_down (GtkIconView *icon_view,
2699 GtkIconViewItem *current,
2706 y = current->y + count * icon_view->priv->vadjustment->page_size;
2708 item = g_list_find (icon_view->priv->items, current);
2713 for (next = item->next; next; next = next->next)
2715 if (((GtkIconViewItem *)next->data)->col == col)
2718 if (!next || ((GtkIconViewItem *)next->data)->y > y)
2728 for (next = item->prev; next; next = next->prev)
2730 if (((GtkIconViewItem *)next->data)->col == col)
2733 if (!next || ((GtkIconViewItem *)next->data)->y < y)
2747 gtk_icon_view_select_all_between (GtkIconView *icon_view,
2748 GtkIconViewItem *anchor,
2749 GtkIconViewItem *cursor)
2752 GtkIconViewItem *item;
2753 gint row1, row2, col1, col2;
2754 gboolean dirty = FALSE;
2756 if (anchor->row < cursor->row)
2767 if (anchor->col < cursor->col)
2778 for (items = icon_view->priv->items; items; items = items->next)
2782 if (row1 <= item->row && item->row <= row2 &&
2783 col1 <= item->col && item->col <= col2)
2785 if (!item->selected)
2788 item->selected = TRUE;
2790 gtk_icon_view_queue_draw_item (icon_view, item);
2798 gtk_icon_view_move_cursor_up_down (GtkIconView *icon_view,
2801 GtkIconViewItem *item;
2802 gboolean dirty = FALSE;
2804 if (!GTK_WIDGET_HAS_FOCUS (icon_view))
2807 if (!icon_view->priv->cursor_item)
2812 list = icon_view->priv->items;
2814 list = g_list_last (icon_view->priv->items);
2816 item = list ? list->data : NULL;
2819 item = find_item (icon_view,
2820 icon_view->priv->cursor_item,
2826 if (icon_view->priv->ctrl_pressed ||
2827 !icon_view->priv->shift_pressed ||
2828 !icon_view->priv->anchor_item ||
2829 icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
2830 icon_view->priv->anchor_item = item;
2832 gtk_icon_view_set_cursor_item (icon_view, item);
2834 if (!icon_view->priv->ctrl_pressed &&
2835 icon_view->priv->selection_mode != GTK_SELECTION_NONE)
2837 gtk_icon_view_unselect_all_internal (icon_view);
2838 dirty = gtk_icon_view_select_all_between (icon_view,
2839 icon_view->priv->anchor_item,
2843 gtk_icon_view_scroll_to_item (icon_view, item);
2846 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2850 gtk_icon_view_move_cursor_page_up_down (GtkIconView *icon_view,
2853 GtkIconViewItem *item;
2854 gboolean dirty = FALSE;
2856 if (!GTK_WIDGET_HAS_FOCUS (icon_view))
2859 if (!icon_view->priv->cursor_item)
2864 list = icon_view->priv->items;
2866 list = g_list_last (icon_view->priv->items);
2868 item = list ? list->data : NULL;
2871 item = find_item_page_up_down (icon_view,
2872 icon_view->priv->cursor_item,
2878 if (icon_view->priv->ctrl_pressed ||
2879 !icon_view->priv->shift_pressed ||
2880 !icon_view->priv->anchor_item ||
2881 icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
2882 icon_view->priv->anchor_item = item;
2884 gtk_icon_view_set_cursor_item (icon_view, item);
2886 if (!icon_view->priv->ctrl_pressed &&
2887 icon_view->priv->selection_mode != GTK_SELECTION_NONE)
2889 gtk_icon_view_unselect_all_internal (icon_view);
2890 dirty = gtk_icon_view_select_all_between (icon_view,
2891 icon_view->priv->anchor_item,
2895 gtk_icon_view_scroll_to_item (icon_view, item);
2898 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2902 gtk_icon_view_move_cursor_left_right (GtkIconView *icon_view,
2905 GtkIconViewItem *item;
2906 gboolean dirty = FALSE;
2908 if (!GTK_WIDGET_HAS_FOCUS (icon_view))
2911 if (!icon_view->priv->cursor_item)
2916 list = icon_view->priv->items;
2918 list = g_list_last (icon_view->priv->items);
2920 item = list ? list->data : NULL;
2923 item = find_item (icon_view,
2924 icon_view->priv->cursor_item,
2930 if (icon_view->priv->ctrl_pressed ||
2931 !icon_view->priv->shift_pressed ||
2932 !icon_view->priv->anchor_item ||
2933 icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
2934 icon_view->priv->anchor_item = item;
2936 gtk_icon_view_set_cursor_item (icon_view, item);
2938 if (!icon_view->priv->ctrl_pressed &&
2939 icon_view->priv->selection_mode != GTK_SELECTION_NONE)
2941 gtk_icon_view_unselect_all_internal (icon_view);
2942 dirty = gtk_icon_view_select_all_between (icon_view,
2943 icon_view->priv->anchor_item,
2947 gtk_icon_view_scroll_to_item (icon_view, item);
2950 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2954 gtk_icon_view_move_cursor_start_end (GtkIconView *icon_view,
2957 GtkIconViewItem *item;
2959 gboolean dirty = FALSE;
2961 if (!GTK_WIDGET_HAS_FOCUS (icon_view))
2965 list = icon_view->priv->items;
2967 list = g_list_last (icon_view->priv->items);
2969 item = list ? list->data : NULL;
2974 if (icon_view->priv->ctrl_pressed ||
2975 !icon_view->priv->shift_pressed ||
2976 !icon_view->priv->anchor_item ||
2977 icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
2978 icon_view->priv->anchor_item = item;
2980 gtk_icon_view_set_cursor_item (icon_view, item);
2982 if (!icon_view->priv->ctrl_pressed &&
2983 icon_view->priv->selection_mode != GTK_SELECTION_NONE)
2985 gtk_icon_view_unselect_all (icon_view);
2986 dirty = gtk_icon_view_select_all_between (icon_view,
2987 icon_view->priv->anchor_item,
2991 gtk_icon_view_scroll_to_item (icon_view, item);
2994 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2998 gtk_icon_view_scroll_to_item (GtkIconView *icon_view,
2999 GtkIconViewItem *item)
3004 gdk_drawable_get_size (GDK_DRAWABLE (icon_view->priv->bin_window), NULL, &height);
3005 gdk_window_get_position (icon_view->priv->bin_window, NULL, &y);
3007 if (y + item->y < 0)
3009 value = icon_view->priv->vadjustment->value + y + item->y;
3010 gtk_adjustment_set_value (icon_view->priv->vadjustment, value);
3012 else if (y + item->y + item->height > GTK_WIDGET (icon_view)->allocation.height)
3014 value = icon_view->priv->vadjustment->value + y + item->y + item->height
3015 - GTK_WIDGET (icon_view)->allocation.height;
3016 gtk_adjustment_set_value (icon_view->priv->vadjustment, value);
3024 * gtk_icon_view_new:
3026 * Creates a new #GtkIconView widget
3028 * Return value: A newly created #GtkIconView widget
3033 gtk_icon_view_new (void)
3035 return g_object_new (GTK_TYPE_ICON_VIEW, NULL);
3039 * gtk_icon_view_new_with_model:
3040 * @model: The model.
3042 * Creates a new #GtkIconView widget with the model @model.
3044 * Return value: A newly created #GtkIconView widget.
3049 gtk_icon_view_new_with_model (GtkTreeModel *model)
3051 return g_object_new (GTK_TYPE_ICON_VIEW, "model", model, NULL);
3056 * gtk_icon_view_get_path_at_pos:
3057 * @icon_view: A #GtkIconView.
3058 * @x: The x position to be identified
3059 * @y: The y position to be identified
3061 * Finds the path at the point (@x, @y), relative to widget coordinates.
3063 * Return value: The #GtkTreePath corresponding to the icon or %NULL
3064 * if no icon exists at that position.
3069 gtk_icon_view_get_path_at_pos (GtkIconView *icon_view,
3073 GtkIconViewItem *item;
3076 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), NULL);
3078 item = gtk_icon_view_get_item_at_pos (icon_view, x, y);
3083 path = gtk_tree_path_new_from_indices (item->index, -1);
3089 * gtk_icon_view_selected_foreach:
3090 * @icon_view: A #GtkIconView.
3091 * @func: The funcion to call for each selected icon.
3092 * @data: User data to pass to the function.
3094 * Calls a function for each selected icon. Note that the model or
3095 * selection cannot be modified from within this function.
3100 gtk_icon_view_selected_foreach (GtkIconView *icon_view,
3101 GtkIconViewForeachFunc func,
3106 for (list = icon_view->priv->items; list; list = list->next)
3108 GtkIconViewItem *item = list->data;
3109 GtkTreePath *path = gtk_tree_path_new_from_indices (item->index, -1);
3112 (* func) (icon_view, path, data);
3114 gtk_tree_path_free (path);
3119 * gtk_icon_view_set_selection_mode:
3120 * @icon_view: A #GtkIconView.
3121 * @mode: The selection mode
3123 * Sets the selection mode of the @icon_view.
3128 gtk_icon_view_set_selection_mode (GtkIconView *icon_view,
3129 GtkSelectionMode mode)
3131 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3133 if (mode == icon_view->priv->selection_mode)
3136 if (mode == GTK_SELECTION_NONE ||
3137 icon_view->priv->selection_mode == GTK_SELECTION_MULTIPLE)
3138 gtk_icon_view_unselect_all (icon_view);
3140 icon_view->priv->selection_mode = mode;
3142 g_object_notify (G_OBJECT (icon_view), "selection-mode");
3146 * gtk_icon_view_get_selection_mode:
3147 * @icon_view: A #GtkIconView.
3149 * Gets the selection mode of the @icon_view.
3151 * Return value: the current selection mode
3156 gtk_icon_view_get_selection_mode (GtkIconView *icon_view)
3158 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), GTK_SELECTION_SINGLE);
3160 return icon_view->priv->selection_mode;
3164 * gtk_icon_view_set_model:
3165 * @icon_view: A #GtkIconView.
3166 * @model: The model.
3168 * Sets the model for a #GtkIconView.
3169 * If the @icon_view already has a model set, it will remove
3170 * it before setting the new model. If @model is %NULL, then
3171 * it will unset the old model.
3176 gtk_icon_view_set_model (GtkIconView *icon_view,
3177 GtkTreeModel *model)
3179 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3180 g_return_if_fail (model == NULL || GTK_IS_TREE_MODEL (model));
3182 if (icon_view->priv->model == model)
3189 g_return_if_fail (gtk_tree_model_get_flags (model) & GTK_TREE_MODEL_LIST_ONLY);
3191 if (icon_view->priv->pixbuf_column != -1)
3193 column_type = gtk_tree_model_get_column_type (model,
3194 icon_view->priv->pixbuf_column);
3196 g_return_if_fail (column_type == GDK_TYPE_PIXBUF);
3199 if (icon_view->priv->text_column != -1)
3201 column_type = gtk_tree_model_get_column_type (model,
3202 icon_view->priv->text_column);
3204 g_return_if_fail (column_type == G_TYPE_STRING);
3207 if (icon_view->priv->markup_column != -1)
3209 column_type = gtk_tree_model_get_column_type (model,
3210 icon_view->priv->markup_column);
3212 g_return_if_fail (column_type == G_TYPE_STRING);
3217 if (icon_view->priv->model)
3219 g_signal_handlers_disconnect_by_func (icon_view->priv->model,
3220 gtk_icon_view_row_changed,
3222 g_signal_handlers_disconnect_by_func (icon_view->priv->model,
3223 gtk_icon_view_row_inserted,
3225 g_signal_handlers_disconnect_by_func (icon_view->priv->model,
3226 gtk_icon_view_row_deleted,
3228 g_signal_handlers_disconnect_by_func (icon_view->priv->model,
3229 gtk_icon_view_rows_reordered,
3232 g_object_unref (icon_view->priv->model);
3234 g_list_foreach (icon_view->priv->items, (GFunc)gtk_icon_view_item_free, NULL);
3235 g_list_free (icon_view->priv->items);
3236 icon_view->priv->items = NULL;
3237 icon_view->priv->anchor_item = NULL;
3238 icon_view->priv->cursor_item = NULL;
3239 icon_view->priv->last_single_clicked = NULL;
3240 icon_view->priv->width = 0;
3241 icon_view->priv->height = 0;
3244 icon_view->priv->model = model;
3246 if (icon_view->priv->model)
3248 g_object_ref (icon_view->priv->model);
3249 g_signal_connect (icon_view->priv->model,
3251 G_CALLBACK (gtk_icon_view_row_changed),
3253 g_signal_connect (icon_view->priv->model,
3255 G_CALLBACK (gtk_icon_view_row_inserted),
3257 g_signal_connect (icon_view->priv->model,
3259 G_CALLBACK (gtk_icon_view_row_deleted),
3261 g_signal_connect (icon_view->priv->model,
3263 G_CALLBACK (gtk_icon_view_rows_reordered),
3266 gtk_icon_view_build_items (icon_view);
3268 gtk_icon_view_queue_layout (icon_view);
3271 g_object_notify (G_OBJECT (icon_view), "model");
3273 if (GTK_WIDGET_REALIZED (icon_view))
3274 gtk_widget_queue_resize (GTK_WIDGET (icon_view));
3278 * gtk_icon_view_get_model:
3279 * @icon_view: a #GtkIconView
3281 * Returns the model the #GtkIconView is based on. Returns %NULL if the
3284 * Return value: A #GtkTreeModel, or %NULL if none is currently being used.
3289 gtk_icon_view_get_model (GtkIconView *icon_view)
3291 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), NULL);
3293 return icon_view->priv->model;
3297 * gtk_icon_view_set_text_column:
3298 * @icon_view: A #GtkIconView.
3299 * @column: A column in the currently used model.
3301 * Sets the column with text for @icon_view to be @column. The text
3302 * column must be of type #G_TYPE_STRING.
3307 gtk_icon_view_set_text_column (GtkIconView *icon_view,
3310 if (column == icon_view->priv->text_column)
3314 icon_view->priv->text_column = -1;
3317 if (icon_view->priv->model != NULL)
3321 column_type = gtk_tree_model_get_column_type (icon_view->priv->model, column);
3323 g_return_if_fail (column_type == G_TYPE_STRING);
3326 icon_view->priv->text_column = column;
3329 gtk_icon_view_invalidate_sizes (icon_view);
3330 gtk_icon_view_queue_layout (icon_view);
3332 g_object_notify (G_OBJECT (icon_view), "text-column");
3336 * gtk_icon_view_get_text_column:
3337 * @icon_view: A #GtkIconView.
3339 * Returns the column with text for @icon_view.
3341 * Returns: the text column, or -1 if it's unset.
3346 gtk_icon_view_get_text_column (GtkIconView *icon_view)
3348 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3350 return icon_view->priv->text_column;
3354 * gtk_icon_view_set_markup_column:
3355 * @icon_view: A #GtkIconView.
3356 * @column: A column in the currently used model.
3358 * Sets the column with markup information for @icon_view to be
3359 * @column. The markup column must be of type #G_TYPE_STRING.
3360 * If the markup column is set to something, it overrides
3361 * the text column set by gtk_icon_view_set_text_column().
3366 gtk_icon_view_set_markup_column (GtkIconView *icon_view,
3369 if (column == icon_view->priv->markup_column)
3373 icon_view->priv->markup_column = -1;
3376 if (icon_view->priv->model != NULL)
3380 column_type = gtk_tree_model_get_column_type (icon_view->priv->model, column);
3382 g_return_if_fail (column_type == G_TYPE_STRING);
3385 icon_view->priv->markup_column = column;
3388 gtk_icon_view_invalidate_sizes (icon_view);
3389 gtk_icon_view_queue_layout (icon_view);
3391 g_object_notify (G_OBJECT (icon_view), "markup-column");
3395 * gtk_icon_view_get_markup_column:
3396 * @icon_view: A #GtkIconView.
3398 * Returns the column with markup text for @icon_view.
3400 * Returns: the markup column, or -1 if it's unset.
3405 gtk_icon_view_get_markup_column (GtkIconView *icon_view)
3407 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3409 return icon_view->priv->markup_column;
3413 * gtk_icon_view_set_pixbuf_column:
3414 * @icon_view: A #GtkIconView.
3415 * @column: A column in the currently used model.
3417 * Sets the column with pixbufs for @icon_view to be @column. The pixbuf
3418 * column must be of type #GDK_TYPE_PIXBUF
3423 gtk_icon_view_set_pixbuf_column (GtkIconView *icon_view,
3426 if (column == icon_view->priv->pixbuf_column)
3430 icon_view->priv->pixbuf_column = -1;
3433 if (icon_view->priv->model != NULL)
3437 column_type = gtk_tree_model_get_column_type (icon_view->priv->model, column);
3439 g_return_if_fail (column_type == GDK_TYPE_PIXBUF);
3442 icon_view->priv->pixbuf_column = column;
3445 gtk_icon_view_invalidate_sizes (icon_view);
3446 gtk_icon_view_queue_layout (icon_view);
3448 g_object_notify (G_OBJECT (icon_view), "pixbuf-column");
3453 * gtk_icon_view_get_pixbuf_column:
3454 * @icon_view: A #GtkIconView.
3456 * Returns the column with pixbufs for @icon_view.
3458 * Returns: the pixbuf column, or -1 if it's unset.
3463 gtk_icon_view_get_pixbuf_column (GtkIconView *icon_view)
3465 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3467 return icon_view->priv->pixbuf_column;
3471 * gtk_icon_view_select_path:
3472 * @icon_view: A #GtkIconView.
3473 * @path: The #GtkTreePath to be selected.
3475 * Selects the row at @path.
3480 gtk_icon_view_select_path (GtkIconView *icon_view,
3485 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3486 g_return_if_fail (icon_view->priv->model != NULL);
3487 g_return_if_fail (path != NULL);
3489 l = g_list_nth (icon_view->priv->items,
3490 gtk_tree_path_get_indices(path)[0]);
3493 gtk_icon_view_select_item (icon_view, l->data);
3497 * gtk_icon_view_unselect_path:
3498 * @icon_view: A #GtkIconView.
3499 * @path: The #GtkTreePath to be unselected.
3501 * Unselects the row at @path.
3506 gtk_icon_view_unselect_path (GtkIconView *icon_view,
3509 GtkIconViewItem *item;
3511 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3512 g_return_if_fail (icon_view->priv->model != NULL);
3513 g_return_if_fail (path != NULL);
3515 item = g_list_nth (icon_view->priv->items,
3516 gtk_tree_path_get_indices(path)[0])->data;
3521 gtk_icon_view_unselect_item (icon_view, item);
3525 * gtk_icon_view_get_selected_items:
3526 * @icon_view: A #GtkIconView.
3528 * Creates a list of paths of all selected items. Additionally, if you are
3529 * planning on modifying the model after calling this function, you may
3530 * want to convert the returned list into a list of #GtkTreeRowReference<!-- -->s.
3531 * To do this, you can use gtk_tree_row_reference_new().
3533 * To free the return value, use:
3534 * <informalexample><programlisting>
3535 * g_list_foreach (list, gtk_tree_path_free, NULL);
3536 * g_list_free (list);
3537 * </programlisting></informalexample>
3539 * Return value: A #GList containing a #GtkTreePath for each selected row.
3544 gtk_icon_view_get_selected_items (GtkIconView *icon_view)
3547 GList *selected = NULL;
3549 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), NULL);
3551 for (list = icon_view->priv->items; list != NULL; list = list->next)
3553 GtkIconViewItem *item = list->data;
3557 GtkTreePath *path = gtk_tree_path_new_from_indices (item->index, -1);
3559 selected = g_list_prepend (selected, path);
3567 * gtk_icon_view_select_all:
3568 * @icon_view: A #GtkIconView.
3570 * Selects all the icons. @icon_view must has its selection mode set
3571 * to #GTK_SELECTION_MULTIPLE.
3576 gtk_icon_view_select_all (GtkIconView *icon_view)
3579 gboolean dirty = FALSE;
3581 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3583 if (icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
3586 for (items = icon_view->priv->items; items; items = items->next)
3588 GtkIconViewItem *item = items->data;
3590 if (!item->selected)
3593 item->selected = TRUE;
3594 gtk_icon_view_queue_draw_item (icon_view, item);
3599 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
3603 * gtk_icon_view_unselect_all:
3604 * @icon_view: A #GtkIconView.
3606 * Unselects all the icons.
3611 gtk_icon_view_unselect_all (GtkIconView *icon_view)
3613 gboolean dirty = FALSE;
3615 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3617 if (icon_view->priv->selection_mode == GTK_SELECTION_BROWSE)
3620 dirty = gtk_icon_view_unselect_all_internal (icon_view);
3623 g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
3627 * gtk_icon_view_path_is_selected:
3628 * @icon_view: A #GtkIconView.
3629 * @path: A #GtkTreePath to check selection on.
3631 * Returns %TRUE if the icon pointed to by @path is currently
3632 * selected. If @icon does not point to a valid location, %FALSE is returned.
3634 * Return value: %TRUE if @path is selected.
3639 gtk_icon_view_path_is_selected (GtkIconView *icon_view,
3642 GtkIconViewItem *item;
3644 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), FALSE);
3645 g_return_val_if_fail (icon_view->priv->model != NULL, FALSE);
3646 g_return_val_if_fail (path != NULL, FALSE);
3648 item = g_list_nth (icon_view->priv->items,
3649 gtk_tree_path_get_indices(path)[0])->data;
3654 return item->selected;
3658 * gtk_icon_view_item_activated:
3659 * @icon_view: A #GtkIconView
3660 * @path: The #GtkTreePath to be activated
3662 * Activates the item determined by @path.
3667 gtk_icon_view_item_activated (GtkIconView *icon_view,
3670 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3671 g_return_if_fail (path != NULL);
3673 g_signal_emit (icon_view, icon_view_signals[ITEM_ACTIVATED], 0, path);
3677 * gtk_icon_view_set_orientation:
3678 * @icon_view: a #GtkIconView
3679 * @orientation: the relative position of texts and icons
3681 * Sets the ::orientation property which determines whether the labels
3682 * are drawn beside the icons instead of below.
3687 gtk_icon_view_set_orientation (GtkIconView *icon_view,
3688 GtkOrientation orientation)
3690 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3692 if (icon_view->priv->orientation != orientation)
3694 icon_view->priv->orientation = orientation;
3696 gtk_icon_view_invalidate_sizes (icon_view);
3697 gtk_icon_view_queue_layout (icon_view);
3699 g_object_notify (G_OBJECT (icon_view), "orientation");
3704 * gtk_icon_view_get_orientation:
3705 * @icon_view: a #GtkIconView
3707 * Returns the value of the ::orientation property which determines
3708 * whether the labels are drawn beside the icons instead of below.
3710 * Return value: the relative position of texts and icons
3715 gtk_icon_view_get_orientation (GtkIconView *icon_view)
3717 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view),
3718 GTK_ORIENTATION_VERTICAL);
3720 return icon_view->priv->orientation;
3724 * gtk_icon_view_set_columns:
3725 * @icon_view: a #GtkIconView
3726 * @columns: the number of columns
3728 * Sets the ::columns property which determines in how
3729 * many columns the icons are arranged. If @columns is
3730 * -1, the number of columns will be chosen automatically
3731 * to fill the available area.
3736 gtk_icon_view_set_columns (GtkIconView *icon_view,
3739 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3741 if (icon_view->priv->columns != columns)
3743 icon_view->priv->columns = columns;
3745 gtk_icon_view_queue_layout (icon_view);
3747 g_object_notify (G_OBJECT (icon_view), "columns");
3752 * gtk_icon_view_get_columns:
3753 * @icon_view: a #GtkIconView
3755 * Returns the value of the ::columns property.
3757 * Return value: the number of columns, or -1
3762 gtk_icon_view_get_columns (GtkIconView *icon_view)
3764 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3766 return icon_view->priv->columns;
3770 * gtk_icon_view_set_item_width:
3771 * @icon_view: a #GtkIconView
3772 * @item_width: the width for each item
3774 * Sets the ::item-width property which specifies the width
3775 * to use for each item. If it is set to -1, the icon view will
3776 * automatically determine a suitable item size.
3781 gtk_icon_view_set_item_width (GtkIconView *icon_view,
3784 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3786 if (icon_view->priv->item_width != item_width)
3788 icon_view->priv->item_width = item_width;
3790 gtk_icon_view_invalidate_sizes (icon_view);
3791 gtk_icon_view_queue_layout (icon_view);
3793 g_object_notify (G_OBJECT (icon_view), "item-width");
3798 * gtk_icon_view_get_item_width:
3799 * @icon_view: a #GtkIconView
3801 * Returns the value of the ::item-width property.
3803 * Return value: the width of a single item, or -1
3808 gtk_icon_view_get_item_width (GtkIconView *icon_view)
3810 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3812 return icon_view->priv->item_width;
3817 * gtk_icon_view_set_spacing:
3818 * @icon_view: a #GtkIconView
3819 * @spacing: the spacing
3821 * Sets the ::spacing property which specifies the space
3822 * which is inserted between the cells (i.e. the icon and
3823 * the text) of an item.
3828 gtk_icon_view_set_spacing (GtkIconView *icon_view,
3831 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3833 if (icon_view->priv->spacing != spacing)
3835 icon_view->priv->spacing = spacing;
3837 gtk_icon_view_invalidate_sizes (icon_view);
3838 gtk_icon_view_queue_layout (icon_view);
3840 g_object_notify (G_OBJECT (icon_view), "spacing");
3845 * gtk_icon_view_get_spacing:
3846 * @icon_view: a #GtkIconView
3848 * Returns the value of the ::spacing property.
3850 * Return value: the space between cells
3855 gtk_icon_view_get_spacing (GtkIconView *icon_view)
3857 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3859 return icon_view->priv->spacing;
3863 * gtk_icon_view_set_row_spacing:
3864 * @icon_view: a #GtkIconView
3865 * @row_spacing: the row spacing
3867 * Sets the ::row-spacing property which specifies the space
3868 * which is inserted between the rows of the icon view.
3873 gtk_icon_view_set_row_spacing (GtkIconView *icon_view,
3876 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3878 if (icon_view->priv->row_spacing != row_spacing)
3880 icon_view->priv->row_spacing = row_spacing;
3882 gtk_icon_view_invalidate_sizes (icon_view);
3883 gtk_icon_view_queue_layout (icon_view);
3885 g_object_notify (G_OBJECT (icon_view), "row-spacing");
3890 * gtk_icon_view_get_row_spacing:
3891 * @icon_view: a #GtkIconView
3893 * Returns the value of the ::row-spacing property.
3895 * Return value: the space between rows
3900 gtk_icon_view_get_row_spacing (GtkIconView *icon_view)
3902 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3904 return icon_view->priv->row_spacing;
3908 * gtk_icon_view_set_column_spacing:
3909 * @icon_view: a #GtkIconView
3910 * @column_spacing: the column spacing
3912 * Sets the ::column-spacing property which specifies the space
3913 * which is inserted between the columns of the icon view.
3918 gtk_icon_view_set_column_spacing (GtkIconView *icon_view,
3919 gint column_spacing)
3921 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3923 if (icon_view->priv->column_spacing != column_spacing)
3925 icon_view->priv->column_spacing = column_spacing;
3927 gtk_icon_view_invalidate_sizes (icon_view);
3928 gtk_icon_view_queue_layout (icon_view);
3930 g_object_notify (G_OBJECT (icon_view), "column-spacing");
3935 * gtk_icon_view_get_column_spacing:
3936 * @icon_view: a #GtkIconView
3938 * Returns the value of the ::column-spacing property.
3940 * Return value: the space between columns
3945 gtk_icon_view_get_column_spacing (GtkIconView *icon_view)
3947 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3949 return icon_view->priv->column_spacing;
3953 * gtk_icon_view_set_marging:
3954 * @icon_view: a #GtkIconView
3955 * @spacing: the margin
3957 * Sets the ::margin property which specifies the space
3958 * which is inserted at the top, bottom, left and right
3964 gtk_icon_view_set_margin (GtkIconView *icon_view,
3967 g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3969 if (icon_view->priv->margin != margin)
3971 icon_view->priv->margin = margin;
3973 gtk_icon_view_invalidate_sizes (icon_view);
3974 gtk_icon_view_queue_layout (icon_view);
3976 g_object_notify (G_OBJECT (icon_view), "margin");
3981 * gtk_icon_view_get_margin:
3982 * @icon_view: a #GtkIconView
3984 * Returns the value of the ::margin property.
3986 * Return value: the space at the borders
3991 gtk_icon_view_get_margin (GtkIconView *icon_view)
3993 g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
3995 return icon_view->priv->margin;
3999 /* Accessibility Support */
4001 static gpointer accessible_parent_class;
4002 static gpointer accessible_item_parent_class;
4003 static GQuark accessible_private_data_quark = 0;
4005 #define GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE (gtk_icon_view_item_accessible_get_type ())
4006 #define GTK_ICON_VIEW_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE, GtkIconViewItemAccessible))
4007 #define GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE))
4009 static GType gtk_icon_view_item_accessible_get_type (void);
4020 GtkIconViewItem *item;
4024 AtkStateSet *state_set;
4028 GtkTextBuffer *text_buffer;
4030 gchar *action_descriptions[LAST_ACTION];
4031 gchar *image_description;
4032 guint action_idle_handler;
4033 } GtkIconViewItemAccessible;
4035 static const gchar *const gtk_icon_view_item_accessible_action_names[] =
4041 static const gchar *const gtk_icon_view_item_accessible_action_descriptions[] =
4046 typedef struct _GtkIconViewItemAccessibleClass
4048 AtkObjectClass parent_class;
4050 } GtkIconViewItemAccessibleClass;
4052 static gboolean gtk_icon_view_item_accessible_is_showing (GtkIconViewItemAccessible *item);
4055 gtk_icon_view_item_accessible_idle_do_action (gpointer data)
4057 GtkIconViewItemAccessible *item;
4058 GtkIconView *icon_view;
4061 GDK_THREADS_ENTER ();
4063 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (data);
4064 item->action_idle_handler = 0;
4066 if (item->widget != NULL)
4068 icon_view = GTK_ICON_VIEW (item->widget);
4069 path = gtk_tree_path_new_from_indices (item->item->index, -1);
4070 gtk_icon_view_item_activated (icon_view, path);
4071 gtk_tree_path_free (path);
4074 GDK_THREADS_LEAVE ();
4080 gtk_icon_view_item_accessible_action_do_action (AtkAction *action,
4083 GtkIconViewItemAccessible *item;
4084 GtkIconView *icon_view;
4086 if (i < 0 || i >= LAST_ACTION)
4089 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
4091 if (!GTK_IS_ICON_VIEW (item->widget))
4094 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4097 icon_view = GTK_ICON_VIEW (item->widget);
4101 case ACTION_ACTIVATE:
4102 if (!item->action_idle_handler)
4103 item->action_idle_handler = g_idle_add (gtk_icon_view_item_accessible_idle_do_action, item);
4106 g_assert_not_reached ();
4114 gtk_icon_view_item_accessible_action_get_n_actions (AtkAction *action)
4119 static const gchar *
4120 gtk_icon_view_item_accessible_action_get_description (AtkAction *action,
4123 GtkIconViewItemAccessible *item;
4125 if (i < 0 || i >= LAST_ACTION)
4128 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
4130 if (item->action_descriptions[i])
4131 return item->action_descriptions[i];
4133 return gtk_icon_view_item_accessible_action_descriptions[i];
4136 static const gchar *
4137 gtk_icon_view_item_accessible_action_get_name (AtkAction *action,
4140 if (i < 0 || i >= LAST_ACTION)
4143 return gtk_icon_view_item_accessible_action_names[i];
4147 gtk_icon_view_item_accessible_action_set_description (AtkAction *action,
4149 const gchar *description)
4151 GtkIconViewItemAccessible *item;
4153 if (i < 0 || i >= LAST_ACTION)
4156 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
4158 if (item->action_descriptions[i])
4159 g_free (item->action_descriptions[i]);
4161 item->action_descriptions[i] = g_strdup (description);
4167 atk_action_item_interface_init (AtkActionIface *iface)
4169 iface->do_action = gtk_icon_view_item_accessible_action_do_action;
4170 iface->get_n_actions = gtk_icon_view_item_accessible_action_get_n_actions;
4171 iface->get_description = gtk_icon_view_item_accessible_action_get_description;
4172 iface->get_name = gtk_icon_view_item_accessible_action_get_name;
4173 iface->set_description = gtk_icon_view_item_accessible_action_set_description;
4176 static const gchar *
4177 gtk_icon_view_item_accessible_image_get_image_description (AtkImage *image)
4179 GtkIconViewItemAccessible *item;
4181 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
4183 return item->image_description;
4187 gtk_icon_view_item_accessible_image_set_image_description (AtkImage *image,
4188 const gchar *description)
4190 GtkIconViewItemAccessible *item;
4192 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
4194 g_free (item->image_description);
4195 item->image_description = g_strdup (item->image_description);
4201 gtk_icon_view_item_accessible_image_get_image_size (AtkImage *image,
4205 GtkIconViewItemAccessible *item;
4207 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
4209 if (!GTK_IS_ICON_VIEW (item->widget))
4212 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4215 *width = item->item->pixbuf_width;
4216 *height = item->item->pixbuf_height;
4220 gtk_icon_view_item_accessible_image_get_image_position (AtkImage *image,
4223 AtkCoordType coord_type)
4225 GtkIconViewItemAccessible *item;
4227 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
4229 if (!GTK_IS_ICON_VIEW (item->widget))
4232 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4235 atk_component_get_position (ATK_COMPONENT (image), x, y, coord_type);
4236 *x+= item->item->pixbuf_x - item->item->x;
4237 *y+= item->item->pixbuf_y - item->item->y;
4241 atk_image_item_interface_init (AtkImageIface *iface)
4243 iface->get_image_description = gtk_icon_view_item_accessible_image_get_image_description;
4244 iface->set_image_description = gtk_icon_view_item_accessible_image_set_image_description;
4245 iface->get_image_size = gtk_icon_view_item_accessible_image_get_image_size;
4246 iface->get_image_position = gtk_icon_view_item_accessible_image_get_image_position;
4250 gtk_icon_view_item_accessible_text_get_text (AtkText *text,
4254 GtkIconViewItemAccessible *item;
4255 GtkTextIter start, end;
4256 GtkTextBuffer *buffer;
4258 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4260 if (!GTK_IS_ICON_VIEW (item->widget))
4263 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4266 buffer = item->text_buffer;
4267 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
4269 gtk_text_buffer_get_end_iter (buffer, &end);
4271 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
4273 return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
4277 gtk_icon_view_item_accessible_text_get_character_at_offset (AtkText *text,
4280 GtkIconViewItemAccessible *item;
4281 GtkTextIter start, end;
4282 GtkTextBuffer *buffer;
4286 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4288 if (!GTK_IS_ICON_VIEW (item->widget))
4291 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4294 buffer = item->text_buffer;
4295 if (offset >= gtk_text_buffer_get_char_count (buffer))
4298 gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
4300 gtk_text_iter_forward_char (&end);
4301 string = gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
4302 unichar = g_utf8_get_char (string);
4309 get_pango_text_offsets (PangoLayout *layout,
4310 GtkTextBuffer *buffer,
4312 AtkTextBoundary boundary_type,
4316 GtkTextIter *start_iter,
4317 GtkTextIter *end_iter)
4319 PangoLayoutIter *iter;
4320 PangoLayoutLine *line, *prev_line = NULL, *prev_prev_line = NULL;
4321 gint index, start_index, end_index;
4323 gboolean found = FALSE;
4325 text = pango_layout_get_text (layout);
4326 index = g_utf8_offset_to_pointer (text, offset) - text;
4327 iter = pango_layout_get_iter (layout);
4330 line = pango_layout_iter_get_line (iter);
4331 start_index = line->start_index;
4332 end_index = start_index + line->length;
4334 if (index >= start_index && index <= end_index)
4337 * Found line for offset
4343 * We want the previous line
4347 switch (boundary_type)
4349 case ATK_TEXT_BOUNDARY_LINE_START:
4350 end_index = start_index;
4351 start_index = prev_line->start_index;
4353 case ATK_TEXT_BOUNDARY_LINE_END:
4355 start_index = prev_prev_line->start_index +
4356 prev_prev_line->length;
4357 end_index = prev_line->start_index + prev_line->length;
4360 g_assert_not_reached();
4364 start_index = end_index = 0;
4367 switch (boundary_type)
4369 case ATK_TEXT_BOUNDARY_LINE_START:
4370 if (pango_layout_iter_next_line (iter))
4371 end_index = pango_layout_iter_get_line (iter)->start_index;
4373 case ATK_TEXT_BOUNDARY_LINE_END:
4375 start_index = prev_line->start_index +
4379 g_assert_not_reached();
4384 * We want the next line
4386 if (pango_layout_iter_next_line (iter))
4388 line = pango_layout_iter_get_line (iter);
4389 switch (boundary_type)
4391 case ATK_TEXT_BOUNDARY_LINE_START:
4392 start_index = line->start_index;
4393 if (pango_layout_iter_next_line (iter))
4394 end_index = pango_layout_iter_get_line (iter)->start_index;
4396 end_index = start_index + line->length;
4398 case ATK_TEXT_BOUNDARY_LINE_END:
4399 start_index = end_index;
4400 end_index = line->start_index + line->length;
4403 g_assert_not_reached();
4407 start_index = end_index;
4413 prev_prev_line = prev_line;
4416 while (pango_layout_iter_next_line (iter));
4420 start_index = prev_line->start_index + prev_line->length;
4421 end_index = start_index;
4423 pango_layout_iter_free (iter);
4424 *start_offset = g_utf8_pointer_to_offset (text, text + start_index);
4425 *end_offset = g_utf8_pointer_to_offset (text, text + end_index);
4427 gtk_text_buffer_get_iter_at_offset (buffer, start_iter, *start_offset);
4428 gtk_text_buffer_get_iter_at_offset (buffer, end_iter, *end_offset);
4432 gtk_icon_view_item_accessible_text_get_text_before_offset (AtkText *text,
4434 AtkTextBoundary boundary_type,
4438 GtkIconViewItemAccessible *item;
4439 GtkTextIter start, end;
4440 GtkTextBuffer *buffer;
4441 GtkIconView *icon_view;
4443 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4445 if (!GTK_IS_ICON_VIEW (item->widget))
4448 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4451 buffer = item->text_buffer;
4453 if (!gtk_text_buffer_get_char_count (buffer))
4457 return g_strdup ("");
4459 gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
4463 switch (boundary_type)
4465 case ATK_TEXT_BOUNDARY_CHAR:
4466 gtk_text_iter_backward_char(&start);
4468 case ATK_TEXT_BOUNDARY_WORD_START:
4469 if (!gtk_text_iter_starts_word (&start))
4470 gtk_text_iter_backward_word_start (&start);
4472 gtk_text_iter_backward_word_start(&start);
4474 case ATK_TEXT_BOUNDARY_WORD_END:
4475 if (gtk_text_iter_inside_word (&start) &&
4476 !gtk_text_iter_starts_word (&start))
4477 gtk_text_iter_backward_word_start (&start);
4478 while (!gtk_text_iter_ends_word (&start))
4480 if (!gtk_text_iter_backward_char (&start))
4484 gtk_text_iter_backward_word_start(&start);
4485 while (!gtk_text_iter_ends_word (&start))
4487 if (!gtk_text_iter_backward_char (&start))
4491 case ATK_TEXT_BOUNDARY_SENTENCE_START:
4492 if (!gtk_text_iter_starts_sentence (&start))
4493 gtk_text_iter_backward_sentence_start (&start);
4495 gtk_text_iter_backward_sentence_start (&start);
4497 case ATK_TEXT_BOUNDARY_SENTENCE_END:
4498 if (gtk_text_iter_inside_sentence (&start) &&
4499 !gtk_text_iter_starts_sentence (&start))
4500 gtk_text_iter_backward_sentence_start (&start);
4501 while (!gtk_text_iter_ends_sentence (&start))
4503 if (!gtk_text_iter_backward_char (&start))
4507 gtk_text_iter_backward_sentence_start (&start);
4508 while (!gtk_text_iter_ends_sentence (&start))
4510 if (!gtk_text_iter_backward_char (&start))
4514 case ATK_TEXT_BOUNDARY_LINE_START:
4515 case ATK_TEXT_BOUNDARY_LINE_END:
4516 icon_view = GTK_ICON_VIEW (item->widget);
4517 gtk_icon_view_update_item_text (icon_view, item->item);
4518 get_pango_text_offsets (icon_view->priv->layout,
4530 *start_offset = gtk_text_iter_get_offset (&start);
4531 *end_offset = gtk_text_iter_get_offset (&end);
4533 return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
4537 gtk_icon_view_item_accessible_text_get_text_at_offset (AtkText *text,
4539 AtkTextBoundary boundary_type,
4543 GtkIconViewItemAccessible *item;
4544 GtkTextIter start, end;
4545 GtkTextBuffer *buffer;
4546 GtkIconView *icon_view;
4548 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4550 if (!GTK_IS_ICON_VIEW (item->widget))
4553 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4556 buffer = item->text_buffer;
4558 if (!gtk_text_buffer_get_char_count (buffer))
4562 return g_strdup ("");
4564 gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
4568 switch (boundary_type)
4570 case ATK_TEXT_BOUNDARY_CHAR:
4571 gtk_text_iter_forward_char (&end);
4573 case ATK_TEXT_BOUNDARY_WORD_START:
4574 if (!gtk_text_iter_starts_word (&start))
4575 gtk_text_iter_backward_word_start (&start);
4576 if (gtk_text_iter_inside_word (&end))
4577 gtk_text_iter_forward_word_end (&end);
4578 while (!gtk_text_iter_starts_word (&end))
4580 if (!gtk_text_iter_forward_char (&end))
4584 case ATK_TEXT_BOUNDARY_WORD_END:
4585 if (gtk_text_iter_inside_word (&start) &&
4586 !gtk_text_iter_starts_word (&start))
4587 gtk_text_iter_backward_word_start (&start);
4588 while (!gtk_text_iter_ends_word (&start))
4590 if (!gtk_text_iter_backward_char (&start))
4593 gtk_text_iter_forward_word_end (&end);
4595 case ATK_TEXT_BOUNDARY_SENTENCE_START:
4596 if (!gtk_text_iter_starts_sentence (&start))
4597 gtk_text_iter_backward_sentence_start (&start);
4598 if (gtk_text_iter_inside_sentence (&end))
4599 gtk_text_iter_forward_sentence_end (&end);
4600 while (!gtk_text_iter_starts_sentence (&end))
4602 if (!gtk_text_iter_forward_char (&end))
4606 case ATK_TEXT_BOUNDARY_SENTENCE_END:
4607 if (gtk_text_iter_inside_sentence (&start) &&
4608 !gtk_text_iter_starts_sentence (&start))
4609 gtk_text_iter_backward_sentence_start (&start);
4610 while (!gtk_text_iter_ends_sentence (&start))
4612 if (!gtk_text_iter_backward_char (&start))
4615 gtk_text_iter_forward_sentence_end (&end);
4617 case ATK_TEXT_BOUNDARY_LINE_START:
4618 case ATK_TEXT_BOUNDARY_LINE_END:
4619 icon_view = GTK_ICON_VIEW (item->widget);
4620 gtk_icon_view_update_item_text (icon_view, item->item);
4621 get_pango_text_offsets (icon_view->priv->layout,
4634 *start_offset = gtk_text_iter_get_offset (&start);
4635 *end_offset = gtk_text_iter_get_offset (&end);
4637 return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
4641 gtk_icon_view_item_accessible_text_get_text_after_offset (AtkText *text,
4643 AtkTextBoundary boundary_type,
4647 GtkIconViewItemAccessible *item;
4648 GtkTextIter start, end;
4649 GtkTextBuffer *buffer;
4650 GtkIconView *icon_view;
4652 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4654 if (!GTK_IS_ICON_VIEW (item->widget))
4657 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4660 buffer = item->text_buffer;
4662 if (!gtk_text_buffer_get_char_count (buffer))
4666 return g_strdup ("");
4668 gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
4672 switch (boundary_type)
4674 case ATK_TEXT_BOUNDARY_CHAR:
4675 gtk_text_iter_forward_char(&start);
4676 gtk_text_iter_forward_chars(&end, 2);
4678 case ATK_TEXT_BOUNDARY_WORD_START:
4679 if (gtk_text_iter_inside_word (&end))
4680 gtk_text_iter_forward_word_end (&end);
4681 while (!gtk_text_iter_starts_word (&end))
4683 if (!gtk_text_iter_forward_char (&end))
4687 if (!gtk_text_iter_is_end (&end))
4689 gtk_text_iter_forward_word_end (&end);
4690 while (!gtk_text_iter_starts_word (&end))
4692 if (!gtk_text_iter_forward_char (&end))
4697 case ATK_TEXT_BOUNDARY_WORD_END:
4698 gtk_text_iter_forward_word_end (&end);
4700 if (!gtk_text_iter_is_end (&end))
4701 gtk_text_iter_forward_word_end (&end);
4703 case ATK_TEXT_BOUNDARY_SENTENCE_START:
4704 if (gtk_text_iter_inside_sentence (&end))
4705 gtk_text_iter_forward_sentence_end (&end);
4706 while (!gtk_text_iter_starts_sentence (&end))
4708 if (!gtk_text_iter_forward_char (&end))
4712 if (!gtk_text_iter_is_end (&end))
4714 gtk_text_iter_forward_sentence_end (&end);
4715 while (!gtk_text_iter_starts_sentence (&end))
4717 if (!gtk_text_iter_forward_char (&end))
4722 case ATK_TEXT_BOUNDARY_SENTENCE_END:
4723 gtk_text_iter_forward_sentence_end (&end);
4725 if (!gtk_text_iter_is_end (&end))
4726 gtk_text_iter_forward_sentence_end (&end);
4728 case ATK_TEXT_BOUNDARY_LINE_START:
4729 case ATK_TEXT_BOUNDARY_LINE_END:
4730 icon_view = GTK_ICON_VIEW (item->widget);
4731 gtk_icon_view_update_item_text (icon_view, item->item);
4732 get_pango_text_offsets (icon_view->priv->layout,
4743 *start_offset = gtk_text_iter_get_offset (&start);
4744 *end_offset = gtk_text_iter_get_offset (&end);
4746 return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
4750 gtk_icon_view_item_accessible_text_get_character_count (AtkText *text)
4752 GtkIconViewItemAccessible *item;
4754 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4756 if (!GTK_IS_ICON_VIEW (item->widget))
4759 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4762 return gtk_text_buffer_get_char_count (item->text_buffer);
4766 gtk_icon_view_item_accessible_text_get_character_extents (AtkText *text,
4772 AtkCoordType coord_type)
4774 GtkIconViewItemAccessible *item;
4775 GtkIconView *icon_view;
4776 PangoRectangle char_rect;
4777 const gchar *item_text;
4780 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4782 if (!GTK_IS_ICON_VIEW (item->widget))
4785 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4788 icon_view = GTK_ICON_VIEW (item->widget);
4789 gtk_icon_view_update_item_text (icon_view, item->item);
4790 item_text = pango_layout_get_text (icon_view->priv->layout);
4791 index = g_utf8_offset_to_pointer (item_text, offset) - item_text;
4792 pango_layout_index_to_pos (icon_view->priv->layout, index, &char_rect);
4794 atk_component_get_position (ATK_COMPONENT (text), x, y, coord_type);
4795 *x += item->item->layout_x - item->item->x + char_rect.x / PANGO_SCALE;
4796 /* Look at gtk_icon_view_paint_item() to see where the text is. */
4797 *x -= ((item->item->width - item->item->layout_width) / 2) + (MAX (item->item->pixbuf_width, icon_view->priv->item_width) - item->item->width) / 2,
4798 *y += item->item->layout_y - item->item->y + char_rect.y / PANGO_SCALE;
4799 *width = char_rect.width / PANGO_SCALE;
4800 *height = char_rect.height / PANGO_SCALE;
4804 gtk_icon_view_item_accessible_text_get_offset_at_point (AtkText *text,
4807 AtkCoordType coord_type)
4809 GtkIconViewItemAccessible *item;
4810 GtkIconView *icon_view;
4811 const gchar *item_text;
4816 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
4818 if (!GTK_IS_ICON_VIEW (item->widget))
4821 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4824 icon_view = GTK_ICON_VIEW (item->widget);
4825 gtk_icon_view_update_item_text (icon_view, item->item);
4826 atk_component_get_position (ATK_COMPONENT (text), &l_x, &l_y, coord_type);
4827 x -= l_x + item->item->layout_x - item->item->x;
4828 x += ((item->item->width - item->item->layout_width) / 2) + (MAX (item->item->pixbuf_width, icon_view->priv->item_width) - item->item->width) / 2,
4829 y -= l_y + item->item->layout_y - item->item->y;
4830 item_text = pango_layout_get_text (icon_view->priv->layout);
4831 if (!pango_layout_xy_to_index (icon_view->priv->layout,
4842 offset = g_utf8_strlen (item_text, -1);
4844 offset = g_utf8_pointer_to_offset (item_text, item_text + index);
4850 atk_text_item_interface_init (AtkTextIface *iface)
4852 iface->get_text = gtk_icon_view_item_accessible_text_get_text;
4853 iface->get_character_at_offset = gtk_icon_view_item_accessible_text_get_character_at_offset;
4854 iface->get_text_before_offset = gtk_icon_view_item_accessible_text_get_text_before_offset;
4855 iface->get_text_at_offset = gtk_icon_view_item_accessible_text_get_text_at_offset;
4856 iface->get_text_after_offset = gtk_icon_view_item_accessible_text_get_text_after_offset;
4857 iface->get_character_count = gtk_icon_view_item_accessible_text_get_character_count;
4858 iface->get_character_extents = gtk_icon_view_item_accessible_text_get_character_extents;
4859 iface->get_offset_at_point = gtk_icon_view_item_accessible_text_get_offset_at_point;
4863 gtk_icon_view_item_accessible_get_extents (AtkComponent *component,
4868 AtkCoordType coord_type)
4870 GtkIconViewItemAccessible *item;
4871 AtkObject *parent_obj;
4874 g_return_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component));
4876 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (component);
4877 if (!GTK_IS_WIDGET (item->widget))
4880 if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
4883 *width = item->item->width;
4884 *height = item->item->height;
4885 if (gtk_icon_view_item_accessible_is_showing (item))
4887 parent_obj = gtk_widget_get_accessible (item->widget);
4888 atk_component_get_position (ATK_COMPONENT (parent_obj), &l_x, &l_y, coord_type);
4889 *x = l_x + item->item->x;
4890 *y = l_y + item->item->y;
4900 gtk_icon_view_item_accessible_grab_focus (AtkComponent *component)
4902 GtkIconViewItemAccessible *item;
4903 GtkWidget *toplevel;
4905 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component), FALSE);
4907 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (component);
4908 if (!GTK_IS_WIDGET (item->widget))
4911 gtk_widget_grab_focus (item->widget);
4912 gtk_icon_view_set_cursor_item (GTK_ICON_VIEW (item->widget), item->item);
4913 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item->widget));
4914 if (GTK_WIDGET_TOPLEVEL (toplevel))
4915 gtk_window_present (GTK_WINDOW (toplevel));
4921 atk_component_item_interface_init (AtkComponentIface *iface)
4923 iface->get_extents = gtk_icon_view_item_accessible_get_extents;
4924 iface->grab_focus = gtk_icon_view_item_accessible_grab_focus;
4928 gtk_icon_view_item_accessible_add_state (GtkIconViewItemAccessible *item,
4929 AtkStateType state_type,
4930 gboolean emit_signal)
4934 rc = atk_state_set_add_state (item->state_set, state_type);
4936 * The signal should only be generated if the value changed,
4937 * not when the item is set up. So states that are set
4938 * initially should pass FALSE as the emit_signal argument.
4943 atk_object_notify_state_change (ATK_OBJECT (item), state_type, TRUE);
4944 /* If state_type is ATK_STATE_VISIBLE, additional notification */
4945 if (state_type == ATK_STATE_VISIBLE)
4946 g_signal_emit_by_name (item, "visible_data_changed");
4953 gtk_icon_view_item_accessible_remove_state (GtkIconViewItemAccessible *item,
4954 AtkStateType state_type,
4955 gboolean emit_signal)
4957 if (atk_state_set_contains_state (item->state_set, state_type))
4961 rc = atk_state_set_remove_state (item->state_set, state_type);
4963 * The signal should only be generated if the value changed,
4964 * not when the item is set up. So states that are set
4965 * initially should pass FALSE as the emit_signal argument.
4970 atk_object_notify_state_change (ATK_OBJECT (item), state_type, FALSE);
4971 /* If state_type is ATK_STATE_VISIBLE, additional notification */
4972 if (state_type == ATK_STATE_VISIBLE)
4973 g_signal_emit_by_name (item, "visible_data_changed");
4983 gtk_icon_view_item_accessible_is_showing (GtkIconViewItemAccessible *item)
4985 GtkIconView *icon_view;
4986 GdkRectangle visible_rect;
4987 gboolean is_showing;
4990 * An item is considered "SHOWING" if any part of the item is in the
4991 * visible rectangle.
4994 if (!GTK_IS_ICON_VIEW (item->widget))
4997 if (item->item == NULL)
5000 icon_view = GTK_ICON_VIEW (item->widget);
5002 if (icon_view->priv->hadjustment)
5003 visible_rect.x += icon_view->priv->hadjustment->value;
5005 if (icon_view->priv->hadjustment)
5006 visible_rect.y += icon_view->priv->vadjustment->value;
5007 visible_rect.width = item->widget->allocation.width;
5008 visible_rect.height = item->widget->allocation.height;
5010 if (((item->item->x + item->item->width) < visible_rect.x) ||
5011 ((item->item->y + item->item->height) < (visible_rect.y)) ||
5012 (item->item->x > (visible_rect.x + visible_rect.width)) ||
5013 (item->item->y > (visible_rect.y + visible_rect.height)))
5022 gtk_icon_view_item_accessible_set_visibility (GtkIconViewItemAccessible *item,
5023 gboolean emit_signal)
5025 if (gtk_icon_view_item_accessible_is_showing (item))
5026 return gtk_icon_view_item_accessible_add_state (item, ATK_STATE_SHOWING,
5029 return gtk_icon_view_item_accessible_remove_state (item, ATK_STATE_SHOWING,
5034 gtk_icon_view_item_accessible_object_init (GtkIconViewItemAccessible *item)
5038 item->state_set = atk_state_set_new ();
5040 atk_state_set_add_state (item->state_set, ATK_STATE_ENABLED);
5041 atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSABLE);
5042 atk_state_set_add_state (item->state_set, ATK_STATE_SENSITIVE);
5043 atk_state_set_add_state (item->state_set, ATK_STATE_SELECTABLE);
5044 atk_state_set_add_state (item->state_set, ATK_STATE_VISIBLE);
5046 for (i = 0; i < LAST_ACTION; i++)
5047 item->action_descriptions[i] = NULL;
5049 item->image_description = NULL;
5051 item->action_idle_handler = 0;
5055 gtk_icon_view_item_accessible_finalize (GObject *object)
5057 GtkIconViewItemAccessible *item;
5060 g_return_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (object));
5062 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (object);
5065 g_object_remove_weak_pointer (G_OBJECT (item->widget), (gpointer) &item->widget);
5067 if (item->state_set)
5068 g_object_unref (item->state_set);
5070 if (item->text_buffer)
5071 g_object_unref (item->text_buffer);
5073 for (i = 0; i < LAST_ACTION; i++)
5074 g_free (item->action_descriptions[i]);
5076 g_free (item->image_description);
5078 if (item->action_idle_handler)
5080 g_source_remove (item->action_idle_handler);
5081 item->action_idle_handler = 0;
5084 G_OBJECT_CLASS (accessible_item_parent_class)->finalize (object);
5087 static G_CONST_RETURN gchar*
5088 gtk_icon_view_item_accessible_get_name (AtkObject *obj)
5094 GtkIconViewItemAccessible *item;
5095 GtkTextIter start_iter;
5096 GtkTextIter end_iter;
5098 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
5100 gtk_text_buffer_get_start_iter (item->text_buffer, &start_iter);
5101 gtk_text_buffer_get_end_iter (item->text_buffer, &end_iter);
5103 return gtk_text_buffer_get_text (item->text_buffer, &start_iter, &end_iter, FALSE);
5108 gtk_icon_view_item_accessible_get_parent (AtkObject *obj)
5110 GtkIconViewItemAccessible *item;
5112 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (obj), NULL);
5113 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
5116 return gtk_widget_get_accessible (item->widget);
5122 gtk_icon_view_item_accessible_get_index_in_parent (AtkObject *obj)
5124 GtkIconViewItemAccessible *item;
5126 g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (obj), 0);
5127 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
5129 return item->item->index;
5132 static AtkStateSet *
5133 gtk_icon_view_item_accessible_ref_state_set (AtkObject *obj)
5135 GtkIconViewItemAccessible *item;
5136 GtkIconView *icon_view;
5138 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
5139 g_return_val_if_fail (item->state_set, NULL);
5144 icon_view = GTK_ICON_VIEW (item->widget);
5145 if (icon_view->priv->cursor_item == item->item)
5146 atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSED);
5148 atk_state_set_remove_state (item->state_set, ATK_STATE_FOCUSED);
5150 return g_object_ref (item->state_set);
5154 gtk_icon_view_item_accessible_class_init (AtkObjectClass *klass)
5156 GObjectClass *gobject_class;
5158 accessible_item_parent_class = g_type_class_peek_parent (klass);
5160 gobject_class = (GObjectClass *)klass;
5162 gobject_class->finalize = gtk_icon_view_item_accessible_finalize;
5164 klass->get_index_in_parent = gtk_icon_view_item_accessible_get_index_in_parent;
5165 klass->get_name = gtk_icon_view_item_accessible_get_name;
5166 klass->get_parent = gtk_icon_view_item_accessible_get_parent;
5167 klass->ref_state_set = gtk_icon_view_item_accessible_ref_state_set;
5171 gtk_icon_view_item_accessible_get_type (void)
5173 static GType type = 0;
5177 static const GTypeInfo tinfo =
5179 sizeof (GtkIconViewItemAccessibleClass),
5180 (GBaseInitFunc) NULL, /* base init */
5181 (GBaseFinalizeFunc) NULL, /* base finalize */
5182 (GClassInitFunc) gtk_icon_view_item_accessible_class_init, /* class init */
5183 (GClassFinalizeFunc) NULL, /* class finalize */
5184 NULL, /* class data */
5185 sizeof (GtkIconViewItemAccessible), /* instance size */
5186 0, /* nb preallocs */
5187 (GInstanceInitFunc) gtk_icon_view_item_accessible_object_init, /* instance init */
5188 NULL /* value table */
5191 static const GInterfaceInfo atk_component_info =
5193 (GInterfaceInitFunc) atk_component_item_interface_init,
5194 (GInterfaceFinalizeFunc) NULL,
5197 static const GInterfaceInfo atk_action_info =
5199 (GInterfaceInitFunc) atk_action_item_interface_init,
5200 (GInterfaceFinalizeFunc) NULL,
5203 static const GInterfaceInfo atk_image_info =
5205 (GInterfaceInitFunc) atk_image_item_interface_init,
5206 (GInterfaceFinalizeFunc) NULL,
5209 static const GInterfaceInfo atk_text_info =
5211 (GInterfaceInitFunc) atk_text_item_interface_init,
5212 (GInterfaceFinalizeFunc) NULL,
5216 type = g_type_register_static (ATK_TYPE_OBJECT,
5217 "GtkIconViewItemAccessible", &tinfo, 0);
5218 g_type_add_interface_static (type, ATK_TYPE_COMPONENT,
5219 &atk_component_info);
5220 g_type_add_interface_static (type, ATK_TYPE_ACTION,
5222 g_type_add_interface_static (type, ATK_TYPE_IMAGE,
5224 g_type_add_interface_static (type, ATK_TYPE_TEXT,
5231 #define GTK_TYPE_ICON_VIEW_ACCESSIBLE (gtk_icon_view_accessible_get_type ())
5232 #define GTK_ICON_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ICON_VIEW_ACCESSIBLE, GtkIconViewAccessible))
5233 #define GTK_IS_ICON_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ICON_VIEW_ACCESSIBLE))
5235 static GType gtk_icon_view_accessible_get_type (void);
5240 } GtkIconViewAccessible;
5246 } GtkIconViewItemAccessibleInfo;
5252 GtkAdjustment *old_hadj;
5253 GtkAdjustment *old_vadj;
5255 GtkTreeModel *model;
5257 } GtkIconViewAccessiblePrivate;
5259 static GtkIconViewAccessiblePrivate *
5260 gtk_icon_view_accessible_get_priv (AtkObject *accessible)
5262 return g_object_get_qdata (G_OBJECT (accessible),
5263 accessible_private_data_quark);
5267 gtk_icon_view_item_accessible_info_new (AtkObject *accessible,
5271 GtkIconViewItemAccessibleInfo *info;
5272 GtkIconViewItemAccessibleInfo *tmp_info;
5273 GtkIconViewAccessiblePrivate *priv;
5276 info = g_new (GtkIconViewItemAccessibleInfo, 1);
5278 info->index = index;
5280 priv = gtk_icon_view_accessible_get_priv (accessible);
5281 items = priv->items;
5284 tmp_info = items->data;
5285 if (tmp_info->index > index)
5287 items = items->next;
5289 priv->items = g_list_insert_before (priv->items, items, info);
5290 priv->old_hadj = NULL;
5291 priv->old_vadj = NULL;
5295 gtk_icon_view_accessible_get_n_children (AtkObject *accessible)
5297 GtkIconView *icon_view;
5300 widget = GTK_ACCESSIBLE (accessible)->widget;
5304 icon_view = GTK_ICON_VIEW (widget);
5306 return g_list_length (icon_view->priv->items);
5310 gtk_icon_view_accessible_find_child (AtkObject *accessible,
5313 GtkIconViewAccessiblePrivate *priv;
5314 GtkIconViewItemAccessibleInfo *info;
5317 priv = gtk_icon_view_accessible_get_priv (accessible);
5318 items = priv->items;
5323 if (info->index == index)
5325 items = items->next;
5331 gtk_icon_view_accessible_ref_child (AtkObject *accessible,
5334 GtkIconView *icon_view;
5338 GtkIconViewItemAccessible *a11y_item;
5340 widget = GTK_ACCESSIBLE (accessible)->widget;
5344 icon_view = GTK_ICON_VIEW (widget);
5345 icons = g_list_nth (icon_view->priv->items, index);
5349 GtkIconViewItem *item = icons->data;
5351 g_return_val_if_fail (item->index == index, NULL);
5352 obj = gtk_icon_view_accessible_find_child (accessible, index);
5355 obj = g_object_new (gtk_icon_view_item_accessible_get_type (), NULL);
5356 gtk_icon_view_item_accessible_info_new (accessible,
5359 obj->role = ATK_ROLE_ICON;
5360 a11y_item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
5361 a11y_item->item = item;
5362 a11y_item->widget = widget;
5363 a11y_item->text_buffer = gtk_text_buffer_new (NULL);
5364 gtk_icon_view_update_item_text (icon_view, item);
5365 gtk_text_buffer_set_text (a11y_item->text_buffer,
5366 pango_layout_get_text (icon_view->priv->layout),
5368 gtk_icon_view_item_accessible_set_visibility (a11y_item, FALSE);
5369 g_object_add_weak_pointer (G_OBJECT (widget), (gpointer) &(a11y_item->widget));
5377 gtk_icon_view_accessible_traverse_items (GtkIconViewAccessible *view,
5380 GtkIconViewAccessiblePrivate *priv;
5381 GtkIconViewItemAccessibleInfo *info;
5382 GtkIconViewItemAccessible *item;
5385 priv = gtk_icon_view_accessible_get_priv (ATK_OBJECT (view));
5389 gboolean act_on_item;
5391 widget = GTK_ACCESSIBLE (view)->widget;
5395 items = priv->items;
5397 act_on_item = (list == NULL);
5402 info = (GtkIconViewItemAccessibleInfo *)items->data;
5403 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
5405 if (act_on_item == FALSE && list == items)
5409 gtk_icon_view_item_accessible_set_visibility (item, TRUE);
5411 items = items->next;
5417 gtk_icon_view_accessible_adjustment_changed (GtkAdjustment *adjustment,
5418 GtkIconView *icon_view)
5421 GtkIconViewAccessible *view;
5424 * The scrollbars have changed
5426 obj = gtk_widget_get_accessible (GTK_WIDGET (icon_view));
5427 view = GTK_ICON_VIEW_ACCESSIBLE (obj);
5429 gtk_icon_view_accessible_traverse_items (view, NULL);
5433 gtk_icon_view_accessible_set_scroll_adjustments (GtkWidget *widget,
5434 GtkAdjustment *hadj,
5435 GtkAdjustment *vadj)
5438 GtkIconViewAccessiblePrivate *priv;
5440 atk_obj = gtk_widget_get_accessible (widget);
5441 priv = gtk_icon_view_accessible_get_priv (atk_obj);
5443 if (priv->old_hadj != hadj)
5447 g_object_remove_weak_pointer (G_OBJECT (priv->old_hadj),
5448 (gpointer *)&priv->old_hadj);
5450 g_signal_handlers_disconnect_by_func (priv->old_hadj,
5451 (gpointer) gtk_icon_view_accessible_adjustment_changed,
5454 priv->old_hadj = hadj;
5457 g_object_add_weak_pointer (G_OBJECT (priv->old_hadj),
5458 (gpointer *)&priv->old_hadj);
5459 g_signal_connect (hadj,
5461 G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
5465 if (priv->old_vadj != vadj)
5469 g_object_remove_weak_pointer (G_OBJECT (priv->old_vadj),
5470 (gpointer *)&priv->old_vadj);
5472 g_signal_handlers_disconnect_by_func (priv->old_vadj,
5473 (gpointer) gtk_icon_view_accessible_adjustment_changed,
5476 priv->old_vadj = vadj;
5479 g_object_add_weak_pointer (G_OBJECT (priv->old_vadj),
5480 (gpointer *)&priv->old_vadj);
5481 g_signal_connect (vadj,
5483 G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
5490 gtk_icon_view_accessible_model_row_changed (GtkTreeModel *tree_model,
5497 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
5498 g_signal_emit_by_name (atk_obj, "visible-data-changed");
5504 gtk_icon_view_accessible_model_row_inserted (GtkTreeModel *tree_model,
5509 GtkIconViewAccessiblePrivate *priv;
5510 GtkIconViewItemAccessibleInfo *info;
5511 GtkIconViewAccessible *view;
5512 GtkIconViewItemAccessible *item;
5518 index = gtk_tree_path_get_indices(path)[0];
5519 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
5520 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
5521 priv = gtk_icon_view_accessible_get_priv (atk_obj);
5523 items = priv->items;
5528 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
5529 if (info->index != item->item->index)
5531 if (info->index < index)
5532 g_warning ("Unexpected index value on insertion %d %d", index, info->index);
5534 if (tmp_list == NULL)
5537 info->index = item->item->index;
5540 items = items->next;
5542 gtk_icon_view_accessible_traverse_items (view, tmp_list);
5543 g_signal_emit_by_name (atk_obj, "children_changed::add",
5549 gtk_icon_view_accessible_model_row_deleted (GtkTreeModel *tree_model,
5553 GtkIconViewAccessiblePrivate *priv;
5554 GtkIconViewItemAccessibleInfo *info;
5555 GtkIconViewAccessible *view;
5556 GtkIconViewItemAccessible *item;
5559 GList *deleted_item;
5563 index = gtk_tree_path_get_indices(path)[0];
5564 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
5565 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
5566 priv = gtk_icon_view_accessible_get_priv (atk_obj);
5568 items = priv->items;
5570 deleted_item = NULL;
5575 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
5576 if (info->index == index)
5578 deleted_item = items;
5580 if (info->index != item->item->index)
5582 if (tmp_list == NULL)
5585 info->index = item->item->index;
5588 items = items->next;
5590 gtk_icon_view_accessible_traverse_items (view, tmp_list);
5593 info = deleted_item->data;
5594 gtk_icon_view_item_accessible_add_state (GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item), ATK_STATE_DEFUNCT, TRUE);
5596 g_signal_emit_by_name (atk_obj, "children_changed::remove",
5600 priv->items = g_list_remove_link (priv->items, deleted_item);
5608 gtk_icon_view_accessible_item_compare (GtkIconViewItemAccessibleInfo *i1,
5609 GtkIconViewItemAccessibleInfo *i2)
5611 return i1->index - i2->index;
5615 gtk_icon_view_accessible_model_rows_reordered (GtkTreeModel *tree_model,
5621 GtkIconViewAccessiblePrivate *priv;
5622 GtkIconViewItemAccessibleInfo *info;
5623 GtkIconViewAccessible *view;
5624 GtkIconView *icon_view;
5625 GtkIconViewItemAccessible *item;
5630 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
5631 icon_view = GTK_ICON_VIEW (user_data);
5632 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
5633 priv = gtk_icon_view_accessible_get_priv (atk_obj);
5635 items = priv->items;
5640 item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
5641 info->index = new_order[info->index];
5642 tmp_list = g_list_nth (icon_view->priv->items, info->index);
5643 item->item = tmp_list->data;
5644 items = items->next;
5646 priv->items = g_list_sort (priv->items,
5647 (GCompareFunc)gtk_icon_view_accessible_item_compare);
5653 gtk_icon_view_accessible_disconnect_model_signals (GtkTreeModel *model,
5658 obj = G_OBJECT (model);
5659 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_changed, widget);
5660 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_inserted, widget);
5661 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_deleted, widget);
5662 g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_rows_reordered, widget);
5666 gtk_icon_view_accessible_connect_model_signals (GtkIconView *icon_view)
5670 obj = G_OBJECT (icon_view->priv->model);
5671 g_signal_connect_data (obj, "row-changed",
5672 (GCallback) gtk_icon_view_accessible_model_row_changed,
5673 icon_view, NULL, 0);
5674 g_signal_connect_data (obj, "row-inserted",
5675 (GCallback) gtk_icon_view_accessible_model_row_inserted,
5676 icon_view, NULL, G_CONNECT_AFTER);
5677 g_signal_connect_data (obj, "row-deleted",
5678 (GCallback) gtk_icon_view_accessible_model_row_deleted,
5679 icon_view, NULL, G_CONNECT_AFTER);
5680 g_signal_connect_data (obj, "rows-reordered",
5681 (GCallback) gtk_icon_view_accessible_model_rows_reordered,
5682 icon_view, NULL, G_CONNECT_AFTER);
5686 gtk_icon_view_accessible_clear_cache (GtkIconViewAccessiblePrivate *priv)
5688 GtkIconViewItemAccessibleInfo *info;
5691 items = priv->items;
5694 info = (GtkIconViewItemAccessibleInfo *) items->data;
5695 g_object_unref (info->item);
5696 g_free (items->data);
5697 items = items->next;
5699 g_list_free (priv->items);
5704 gtk_icon_view_accessible_notify_gtk (GObject *obj,
5707 GtkIconView *icon_view;
5710 GtkIconViewAccessible *view;
5711 GtkIconViewAccessiblePrivate *priv;
5713 if (strcmp (pspec->name, "model") == 0)
5715 widget = GTK_WIDGET (obj);
5716 atk_obj = gtk_widget_get_accessible (widget);
5717 view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
5718 priv = gtk_icon_view_accessible_get_priv (atk_obj);
5721 g_object_remove_weak_pointer (G_OBJECT (priv->model),
5722 (gpointer *)&priv->model);
5723 gtk_icon_view_accessible_disconnect_model_signals (priv->model, widget);
5725 gtk_icon_view_accessible_clear_cache (priv);
5727 icon_view = GTK_ICON_VIEW (obj);
5728 priv->model = icon_view->priv->model;
5729 /* If there is no model the GtkIconView is probably being destroyed */
5732 g_object_add_weak_pointer (G_OBJECT (priv->model), (gpointer *)&priv->model);
5733 gtk_icon_view_accessible_connect_model_signals (icon_view);
5741 gtk_icon_view_accessible_initialize (AtkObject *accessible,
5744 GtkIconViewAccessiblePrivate *priv;
5745 GtkIconView *icon_view;
5747 if (ATK_OBJECT_CLASS (accessible_parent_class)->initialize)
5748 ATK_OBJECT_CLASS (accessible_parent_class)->initialize (accessible, data);
5750 priv = g_new0 (GtkIconViewAccessiblePrivate, 1);
5751 g_object_set_qdata (G_OBJECT (accessible),
5752 accessible_private_data_quark,
5755 icon_view = GTK_ICON_VIEW (data);
5756 if (icon_view->priv->hadjustment)
5758 priv->old_hadj = icon_view->priv->hadjustment;
5759 g_object_add_weak_pointer (G_OBJECT (priv->old_hadj), (gpointer *)&priv->old_hadj);
5760 g_signal_connect (icon_view->priv->hadjustment,
5762 G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
5765 if (icon_view->priv->vadjustment)
5767 priv->old_vadj = icon_view->priv->vadjustment;
5768 g_object_add_weak_pointer (G_OBJECT (priv->old_vadj), (gpointer *)&priv->old_vadj);
5769 g_signal_connect (icon_view->priv->vadjustment,
5771 G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
5774 g_signal_connect_after (data,
5775 "set_scroll_adjustments",
5776 G_CALLBACK (gtk_icon_view_accessible_set_scroll_adjustments),
5778 g_signal_connect (data,
5780 G_CALLBACK (gtk_icon_view_accessible_notify_gtk),
5783 priv->model = icon_view->priv->model;
5786 g_object_add_weak_pointer (G_OBJECT (priv->model), (gpointer *)&priv->model);
5787 gtk_icon_view_accessible_connect_model_signals (icon_view);
5790 accessible->role = ATK_ROLE_LAYERED_PANE;
5794 gtk_icon_view_accessible_finalize (GObject *object)
5796 GtkIconViewAccessiblePrivate *priv;
5798 priv = gtk_icon_view_accessible_get_priv (ATK_OBJECT (object));
5799 gtk_icon_view_accessible_clear_cache (priv);
5803 G_OBJECT_CLASS (accessible_parent_class)->finalize (object);
5807 gtk_icon_view_accessible_destroyed (GtkWidget *widget,
5808 GtkAccessible *accessible)
5811 GtkIconViewAccessiblePrivate *priv;
5813 atk_obj = ATK_OBJECT (accessible);
5814 priv = gtk_icon_view_accessible_get_priv (atk_obj);
5817 g_object_remove_weak_pointer (G_OBJECT (priv->old_hadj),
5818 (gpointer *)&priv->old_hadj);
5820 g_signal_handlers_disconnect_by_func (priv->old_hadj,
5821 (gpointer) gtk_icon_view_accessible_adjustment_changed,
5823 priv->old_hadj = NULL;
5827 g_object_remove_weak_pointer (G_OBJECT (priv->old_vadj),
5828 (gpointer *)&priv->old_vadj);
5830 g_signal_handlers_disconnect_by_func (priv->old_vadj,
5831 (gpointer) gtk_icon_view_accessible_adjustment_changed,
5833 priv->old_vadj = NULL;
5838 gtk_icon_view_accessible_connect_widget_destroyed (GtkAccessible *accessible)
5840 if (accessible->widget)
5842 g_signal_connect_after (accessible->widget,
5844 G_CALLBACK (gtk_icon_view_accessible_destroyed),
5847 GTK_ACCESSIBLE_CLASS (accessible_parent_class)->connect_widget_destroyed (accessible);
5851 gtk_icon_view_accessible_class_init (AtkObjectClass *klass)
5853 GObjectClass *gobject_class;
5854 GtkAccessibleClass *accessible_class;
5856 accessible_parent_class = g_type_class_peek_parent (klass);
5858 gobject_class = (GObjectClass *)klass;
5859 accessible_class = (GtkAccessibleClass *)klass;
5861 gobject_class->finalize = gtk_icon_view_accessible_finalize;
5863 klass->get_n_children = gtk_icon_view_accessible_get_n_children;
5864 klass->ref_child = gtk_icon_view_accessible_ref_child;
5865 klass->initialize = gtk_icon_view_accessible_initialize;
5867 accessible_class->connect_widget_destroyed = gtk_icon_view_accessible_connect_widget_destroyed;
5869 accessible_private_data_quark = g_quark_from_static_string ("icon_view-accessible-private-data");
5873 gtk_icon_view_accessible_ref_accessible_at_point (AtkComponent *component,
5876 AtkCoordType coord_type)
5879 GtkIconView *icon_view;
5880 GtkIconViewItem *item;
5883 widget = GTK_ACCESSIBLE (component)->widget;
5885 /* State is defunct */
5888 icon_view = GTK_ICON_VIEW (widget);
5889 atk_component_get_extents (component, &x_pos, &y_pos, NULL, NULL, coord_type);
5890 item = gtk_icon_view_get_item_at_pos (icon_view, x - x_pos, y - y_pos);
5892 return gtk_icon_view_accessible_ref_child (ATK_OBJECT (component), item->index);
5898 atk_component_interface_init (AtkComponentIface *iface)
5900 iface->ref_accessible_at_point = gtk_icon_view_accessible_ref_accessible_at_point;
5904 gtk_icon_view_accessible_add_selection (AtkSelection *selection,
5908 GtkIconView *icon_view;
5909 GtkIconViewItem *item;
5912 widget = GTK_ACCESSIBLE (selection)->widget;
5916 icon_view = GTK_ICON_VIEW (widget);
5918 l = g_list_nth (icon_view->priv->items, i);
5923 gtk_icon_view_select_item (icon_view, item);
5929 gtk_icon_view_accessible_clear_selection (AtkSelection *selection)
5932 GtkIconView *icon_view;
5934 widget = GTK_ACCESSIBLE (selection)->widget;
5938 icon_view = GTK_ICON_VIEW (widget);
5939 gtk_icon_view_unselect_all (icon_view);
5945 gtk_icon_view_accessible_ref_selection (AtkSelection *selection,
5949 GtkIconView *icon_view;
5950 GtkIconViewItem *item;
5953 widget = GTK_ACCESSIBLE (selection)->widget;
5957 icon_view = GTK_ICON_VIEW (widget);
5959 l = icon_view->priv->items;
5966 return atk_object_ref_accessible_child (gtk_widget_get_accessible (widget), item->index);
5977 gtk_icon_view_accessible_get_selection_count (AtkSelection *selection)
5980 GtkIconView *icon_view;
5981 GtkIconViewItem *item;
5985 widget = GTK_ACCESSIBLE (selection)->widget;
5989 icon_view = GTK_ICON_VIEW (widget);
5991 l = icon_view->priv->items;
6007 gtk_icon_view_accessible_is_child_selected (AtkSelection *selection,
6011 GtkIconView *icon_view;
6012 GtkIconViewItem *item;
6015 widget = GTK_ACCESSIBLE (selection)->widget;
6019 icon_view = GTK_ICON_VIEW (widget);
6020 l = g_list_nth (icon_view->priv->items, i);
6026 return item->selected;
6030 gtk_icon_view_accessible_remove_selection (AtkSelection *selection,
6034 GtkIconView *icon_view;
6035 GtkIconViewItem *item;
6039 widget = GTK_ACCESSIBLE (selection)->widget;
6043 icon_view = GTK_ICON_VIEW (widget);
6044 l = icon_view->priv->items;
6053 gtk_icon_view_unselect_item (icon_view, item);
6065 gtk_icon_view_accessible_select_all_selection (AtkSelection *selection)
6068 GtkIconView *icon_view;
6070 widget = GTK_ACCESSIBLE (selection)->widget;
6074 icon_view = GTK_ICON_VIEW (widget);
6075 gtk_icon_view_select_all (icon_view);
6080 gtk_icon_view_accessible_selection_interface_init (AtkSelectionIface *iface)
6082 iface->add_selection = gtk_icon_view_accessible_add_selection;
6083 iface->clear_selection = gtk_icon_view_accessible_clear_selection;
6084 iface->ref_selection = gtk_icon_view_accessible_ref_selection;
6085 iface->get_selection_count = gtk_icon_view_accessible_get_selection_count;
6086 iface->is_child_selected = gtk_icon_view_accessible_is_child_selected;
6087 iface->remove_selection = gtk_icon_view_accessible_remove_selection;
6088 iface->select_all_selection = gtk_icon_view_accessible_select_all_selection;
6092 gtk_icon_view_accessible_get_type (void)
6094 static GType type = 0;
6098 static GTypeInfo tinfo =
6101 (GBaseInitFunc) NULL, /* base init */
6102 (GBaseFinalizeFunc) NULL, /* base finalize */
6103 (GClassInitFunc) gtk_icon_view_accessible_class_init,
6104 (GClassFinalizeFunc) NULL, /* class finalize */
6105 NULL, /* class data */
6106 0, /* instance size */
6107 0, /* nb preallocs */
6108 (GInstanceInitFunc) NULL, /* instance init */
6109 NULL /* value table */
6111 static const GInterfaceInfo atk_component_info =
6113 (GInterfaceInitFunc) atk_component_interface_init,
6114 (GInterfaceFinalizeFunc) NULL,
6117 static const GInterfaceInfo atk_selection_info =
6119 (GInterfaceInitFunc) gtk_icon_view_accessible_selection_interface_init,
6120 (GInterfaceFinalizeFunc) NULL,
6125 * Figure out the size of the class and instance
6126 * we are deriving from
6128 AtkObjectFactory *factory;
6131 GType derived_atk_type;
6133 derived_type = g_type_parent (GTK_TYPE_ICON_VIEW);
6134 factory = atk_registry_get_factory (atk_get_default_registry (),
6136 derived_atk_type = atk_object_factory_get_accessible_type (factory);
6137 g_type_query (derived_atk_type, &query);
6138 tinfo.class_size = query.class_size;
6139 tinfo.instance_size = query.instance_size;
6141 type = g_type_register_static (derived_atk_type,
6142 "GtkIconViewAccessible",
6144 g_type_add_interface_static (type, ATK_TYPE_COMPONENT,
6145 &atk_component_info);
6146 g_type_add_interface_static (type, ATK_TYPE_SELECTION,
6147 &atk_selection_info);
6153 gtk_icon_view_accessible_new (GObject *obj)
6155 AtkObject *accessible;
6157 g_return_val_if_fail (GTK_IS_WIDGET (obj), NULL);
6159 accessible = g_object_new (gtk_icon_view_accessible_get_type (), NULL);
6160 atk_object_initialize (accessible, obj);
6166 gtk_icon_view_accessible_factory_get_accessible_type (void)
6168 return gtk_icon_view_accessible_get_type ();
6172 gtk_icon_view_accessible_factory_create_accessible (GObject *obj)
6174 return gtk_icon_view_accessible_new (obj);
6178 gtk_icon_view_accessible_factory_class_init (AtkObjectFactoryClass *klass)
6180 klass->create_accessible = gtk_icon_view_accessible_factory_create_accessible;
6181 klass->get_accessible_type = gtk_icon_view_accessible_factory_get_accessible_type;
6185 gtk_icon_view_accessible_factory_get_type (void)
6187 static GType type = 0;
6191 static const GTypeInfo tinfo =
6193 sizeof (AtkObjectFactoryClass),
6194 NULL, /* base_init */
6195 NULL, /* base_finalize */
6196 (GClassInitFunc) gtk_icon_view_accessible_factory_class_init,
6197 NULL, /* class_finalize */
6198 NULL, /* class_data */
6199 sizeof (AtkObjectFactory),
6200 0, /* n_preallocs */
6204 type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY,
6205 "GtkIconViewAccessibleFactory",
6212 gtk_icon_view_get_accessible (GtkWidget *widget)
6214 static gboolean first_time = TRUE;
6218 AtkObjectFactory *factory;
6219 AtkRegistry *registry;
6221 GType derived_atk_type;
6224 * Figure out whether accessibility is enabled by looking at the
6225 * type of the accessible object which would be created for
6226 * the parent type of GtkIconView.
6228 derived_type = g_type_parent (GTK_TYPE_ICON_VIEW);
6230 registry = atk_get_default_registry ();
6231 factory = atk_registry_get_factory (registry,
6233 derived_atk_type = atk_object_factory_get_accessible_type (factory);
6234 if (g_type_is_a (derived_atk_type, GTK_TYPE_ACCESSIBLE))
6235 atk_registry_set_factory_type (registry,
6237 gtk_icon_view_accessible_factory_get_type ());
6240 return GTK_WIDGET_CLASS (parent_class)->get_accessible (widget);
6243 #define __GTK_ICON_VIEW_C__
6244 #include "gtkaliasdef.c"