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 "gtkcelllayout.h"
29
#include "gtkcellrenderer.h"
30
#include "gtkcellrenderertext.h"
31
#include "gtkcellrendererpixbuf.h"
32
#include "gtkmarshalers.h"
33
#include "gtkbindings.h"
37
#include "gtkaccessible.h"
38
#include "gtkwindow.h"
40
#include "gtkcombobox.h"
41
#include "gtktextbuffer.h"
42
#include "gtktreednd.h"
43
#include "gtkprivate.h"
46
#undef DEBUG_ICON_VIEW
48
#define SCROLL_EDGE_SIZE 15
50
#define GTK_ICON_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ICON_VIEW, GtkIconViewPrivate))
52
typedef struct _GtkIconViewItem GtkIconViewItem;
53
struct _GtkIconViewItem
61
gint x, y, width, height;
64
* box[i] is the actual area occupied by cell i,
65
* before, after are used to calculate the cell
66
* area relative to the box.
67
* See gtk_icon_view_get_cell_area().
75
guint selected_before_rubberbanding : 1;
79
typedef struct _GtkIconViewCellInfo GtkIconViewCellInfo;
80
struct _GtkIconViewCellInfo
82
GtkCellRenderer *cell;
92
GtkCellLayoutDataFunc func;
94
GDestroyNotify destroy;
97
typedef struct _GtkIconViewChild GtkIconViewChild;
98
struct _GtkIconViewChild
101
GtkIconViewItem *item;
105
struct _GtkIconViewPrivate
109
GtkSelectionMode selection_mode;
111
GdkWindow *bin_window;
119
GtkAdjustment *hadjustment;
120
GtkAdjustment *vadjustment;
122
guint layout_idle_id;
124
gboolean doing_rubberband;
125
gint rubberband_x1, rubberband_y1;
126
gint rubberband_x2, rubberband_y2;
128
guint scroll_timeout_id;
129
gint scroll_value_diff;
130
gint event_last_x, event_last_y;
132
GtkIconViewItem *anchor_item;
133
GtkIconViewItem *cursor_item;
134
GtkIconViewItem *edited_item;
135
GtkCellEditable *editable;
137
GtkIconViewItem *last_single_clicked;
144
GtkOrientation item_orientation;
164
GdkModifierType start_button_mask;
169
GdkDragAction source_actions;
170
GdkDragAction dest_actions;
172
GtkTreeRowReference *dest_item;
173
GtkIconViewDropPosition dest_pos;
176
GtkTreeRowReference *scroll_to_path;
177
gfloat scroll_to_row_align;
178
gfloat scroll_to_col_align;
179
guint scroll_to_use_align : 1;
181
guint source_set : 1;
183
guint reorderable : 1;
184
guint empty_view_drop :1;
186
guint modify_selection_pressed : 1;
187
guint extend_selection_pressed : 1;
189
guint draw_focus : 1;
202
ACTIVATE_CURSOR_ITEM,
215
PROP_ITEM_ORIENTATION,
229
static void gtk_icon_view_cell_layout_init (GtkCellLayoutIface *iface);
230
static void gtk_icon_view_finalize (GObject *object);
231
static void gtk_icon_view_set_property (GObject *object,
235
static void gtk_icon_view_get_property (GObject *object,
240
/* GtkObject vfuncs */
241
static void gtk_icon_view_destroy (GtkObject *object);
243
/* GtkWidget vfuncs */
244
static void gtk_icon_view_realize (GtkWidget *widget);
245
static void gtk_icon_view_unrealize (GtkWidget *widget);
246
static void gtk_icon_view_style_set (GtkWidget *widget,
247
GtkStyle *previous_style);
248
static void gtk_icon_view_state_changed (GtkWidget *widget,
249
GtkStateType previous_state);
250
static void gtk_icon_view_size_request (GtkWidget *widget,
251
GtkRequisition *requisition);
252
static void gtk_icon_view_size_allocate (GtkWidget *widget,
253
GtkAllocation *allocation);
254
static gboolean gtk_icon_view_expose (GtkWidget *widget,
255
GdkEventExpose *expose);
256
static gboolean gtk_icon_view_motion (GtkWidget *widget,
257
GdkEventMotion *event);
258
static gboolean gtk_icon_view_button_press (GtkWidget *widget,
259
GdkEventButton *event);
260
static gboolean gtk_icon_view_button_release (GtkWidget *widget,
261
GdkEventButton *event);
262
static gboolean gtk_icon_view_key_press (GtkWidget *widget,
264
static gboolean gtk_icon_view_key_release (GtkWidget *widget,
266
static AtkObject *gtk_icon_view_get_accessible (GtkWidget *widget);
269
/* GtkContainer vfuncs */
270
static void gtk_icon_view_remove (GtkContainer *container,
272
static void gtk_icon_view_forall (GtkContainer *container,
273
gboolean include_internals,
274
GtkCallback callback,
275
gpointer callback_data);
277
/* GtkIconView vfuncs */
278
static void gtk_icon_view_set_adjustments (GtkIconView *icon_view,
280
GtkAdjustment *vadj);
281
static void gtk_icon_view_real_select_all (GtkIconView *icon_view);
282
static void gtk_icon_view_real_unselect_all (GtkIconView *icon_view);
283
static void gtk_icon_view_real_select_cursor_item (GtkIconView *icon_view);
284
static void gtk_icon_view_real_toggle_cursor_item (GtkIconView *icon_view);
285
static gboolean gtk_icon_view_real_activate_cursor_item (GtkIconView *icon_view);
287
/* Internal functions */
288
static void gtk_icon_view_adjustment_changed (GtkAdjustment *adjustment,
289
GtkIconView *icon_view);
290
static void gtk_icon_view_layout (GtkIconView *icon_view);
291
static void gtk_icon_view_paint_item (GtkIconView *icon_view,
294
GtkIconViewItem *item,
296
GdkDrawable *drawable,
299
gboolean draw_focus);
300
static void gtk_icon_view_paint_rubberband (GtkIconView *icon_view,
303
static void gtk_icon_view_queue_draw_path (GtkIconView *icon_view,
305
static void gtk_icon_view_queue_draw_item (GtkIconView *icon_view,
306
GtkIconViewItem *item);
307
static void gtk_icon_view_queue_layout (GtkIconView *icon_view);
308
static void gtk_icon_view_set_cursor_item (GtkIconView *icon_view,
309
GtkIconViewItem *item,
311
static void gtk_icon_view_start_rubberbanding (GtkIconView *icon_view,
314
static void gtk_icon_view_stop_rubberbanding (GtkIconView *icon_view);
315
static void gtk_icon_view_update_rubberband_selection (GtkIconView *icon_view);
316
static gboolean gtk_icon_view_item_hit_test (GtkIconView *icon_view,
317
GtkIconViewItem *item,
322
static gboolean gtk_icon_view_unselect_all_internal (GtkIconView *icon_view);
323
static void gtk_icon_view_calculate_item_size (GtkIconView *icon_view,
324
GtkIconViewItem *item);
325
static void gtk_icon_view_calculate_item_size2 (GtkIconView *icon_view,
326
GtkIconViewItem *item,
328
static void gtk_icon_view_update_rubberband (gpointer data);
329
static void gtk_icon_view_item_invalidate_size (GtkIconViewItem *item);
330
static void gtk_icon_view_invalidate_sizes (GtkIconView *icon_view);
331
static void gtk_icon_view_add_move_binding (GtkBindingSet *binding_set,
334
GtkMovementStep step,
336
static gboolean gtk_icon_view_real_move_cursor (GtkIconView *icon_view,
337
GtkMovementStep step,
339
static void gtk_icon_view_move_cursor_up_down (GtkIconView *icon_view,
341
static void gtk_icon_view_move_cursor_page_up_down (GtkIconView *icon_view,
343
static void gtk_icon_view_move_cursor_left_right (GtkIconView *icon_view,
345
static void gtk_icon_view_move_cursor_start_end (GtkIconView *icon_view,
347
static void gtk_icon_view_scroll_to_item (GtkIconView *icon_view,
348
GtkIconViewItem *item);
349
static void gtk_icon_view_select_item (GtkIconView *icon_view,
350
GtkIconViewItem *item);
351
static void gtk_icon_view_unselect_item (GtkIconView *icon_view,
352
GtkIconViewItem *item);
353
static gboolean gtk_icon_view_select_all_between (GtkIconView *icon_view,
354
GtkIconViewItem *anchor,
355
GtkIconViewItem *cursor);
356
static GtkIconViewItem * gtk_icon_view_get_item_at_coords (GtkIconView *icon_view,
359
gboolean only_in_cell,
360
GtkIconViewCellInfo **cell_at_pos);
361
static void gtk_icon_view_get_cell_area (GtkIconView *icon_view,
362
GtkIconViewItem *item,
363
GtkIconViewCellInfo *cell_info,
364
GdkRectangle *cell_area);
365
static void gtk_icon_view_get_cell_box (GtkIconView *icon_view,
366
GtkIconViewItem *item,
367
GtkIconViewCellInfo *info,
369
static GtkIconViewCellInfo *gtk_icon_view_get_cell_info (GtkIconView *icon_view,
370
GtkCellRenderer *renderer);
371
static void gtk_icon_view_set_cell_data (GtkIconView *icon_view,
372
GtkIconViewItem *item);
373
static void gtk_icon_view_cell_layout_pack_start (GtkCellLayout *layout,
374
GtkCellRenderer *renderer,
376
static void gtk_icon_view_cell_layout_pack_end (GtkCellLayout *layout,
377
GtkCellRenderer *renderer,
379
static void gtk_icon_view_cell_layout_add_attribute (GtkCellLayout *layout,
380
GtkCellRenderer *renderer,
381
const gchar *attribute,
383
static void gtk_icon_view_cell_layout_clear (GtkCellLayout *layout);
384
static void gtk_icon_view_cell_layout_clear_attributes (GtkCellLayout *layout,
385
GtkCellRenderer *renderer);
386
static void gtk_icon_view_cell_layout_set_cell_data_func (GtkCellLayout *layout,
387
GtkCellRenderer *cell,
388
GtkCellLayoutDataFunc func,
390
GDestroyNotify destroy);
391
static void gtk_icon_view_cell_layout_reorder (GtkCellLayout *layout,
392
GtkCellRenderer *cell,
394
static GList * gtk_icon_view_cell_layout_get_cells (GtkCellLayout *layout);
396
static void gtk_icon_view_item_activate_cell (GtkIconView *icon_view,
397
GtkIconViewItem *item,
398
GtkIconViewCellInfo *cell_info,
400
static void gtk_icon_view_item_selected_changed (GtkIconView *icon_view,
401
GtkIconViewItem *item);
402
static void gtk_icon_view_put (GtkIconView *icon_view,
404
GtkIconViewItem *item,
406
static void gtk_icon_view_remove_widget (GtkCellEditable *editable,
407
GtkIconView *icon_view);
408
static void gtk_icon_view_start_editing (GtkIconView *icon_view,
409
GtkIconViewItem *item,
410
GtkIconViewCellInfo *cell_info,
412
static void gtk_icon_view_stop_editing (GtkIconView *icon_view,
413
gboolean cancel_editing);
415
/* Source side drag signals */
416
static void gtk_icon_view_drag_begin (GtkWidget *widget,
417
GdkDragContext *context);
418
static void gtk_icon_view_drag_end (GtkWidget *widget,
419
GdkDragContext *context);
420
static void gtk_icon_view_drag_data_get (GtkWidget *widget,
421
GdkDragContext *context,
422
GtkSelectionData *selection_data,
425
static void gtk_icon_view_drag_data_delete (GtkWidget *widget,
426
GdkDragContext *context);
428
/* Target side drag signals */
429
static void gtk_icon_view_drag_leave (GtkWidget *widget,
430
GdkDragContext *context,
432
static gboolean gtk_icon_view_drag_motion (GtkWidget *widget,
433
GdkDragContext *context,
437
static gboolean gtk_icon_view_drag_drop (GtkWidget *widget,
438
GdkDragContext *context,
442
static void gtk_icon_view_drag_data_received (GtkWidget *widget,
443
GdkDragContext *context,
446
GtkSelectionData *selection_data,
449
static gboolean gtk_icon_view_maybe_begin_drag (GtkIconView *icon_view,
450
GdkEventMotion *event);
452
static void remove_scroll_timeout (GtkIconView *icon_view);
454
static void adjust_wrap_width (GtkIconView *icon_view,
455
GtkIconViewItem *item);
458
static GtkBuildableIface *parent_buildable_iface;
459
static void gtk_icon_view_buildable_init (GtkBuildableIface *iface);
460
static gboolean gtk_icon_view_buildable_custom_tag_start (GtkBuildable *buildable,
463
const gchar *tagname,
464
GMarkupParser *parser,
466
static void gtk_icon_view_buildable_custom_tag_end (GtkBuildable *buildable,
469
const gchar *tagname,
472
static guint icon_view_signals[LAST_SIGNAL] = { 0 };
474
G_DEFINE_TYPE_WITH_CODE (GtkIconView, gtk_icon_view, GTK_TYPE_CONTAINER,
475
G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
476
gtk_icon_view_cell_layout_init)
477
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
478
gtk_icon_view_buildable_init))
481
gtk_icon_view_class_init (GtkIconViewClass *klass)
483
GObjectClass *gobject_class;
484
GtkObjectClass *object_class;
485
GtkWidgetClass *widget_class;
486
GtkContainerClass *container_class;
487
GtkBindingSet *binding_set;
489
binding_set = gtk_binding_set_by_class (klass);
491
g_type_class_add_private (klass, sizeof (GtkIconViewPrivate));
493
gobject_class = (GObjectClass *) klass;
494
object_class = (GtkObjectClass *) klass;
495
widget_class = (GtkWidgetClass *) klass;
496
container_class = (GtkContainerClass *) klass;
498
gobject_class->finalize = gtk_icon_view_finalize;
499
gobject_class->set_property = gtk_icon_view_set_property;
500
gobject_class->get_property = gtk_icon_view_get_property;
502
object_class->destroy = gtk_icon_view_destroy;
504
widget_class->realize = gtk_icon_view_realize;
505
widget_class->unrealize = gtk_icon_view_unrealize;
506
widget_class->style_set = gtk_icon_view_style_set;
507
widget_class->get_accessible = gtk_icon_view_get_accessible;
508
widget_class->size_request = gtk_icon_view_size_request;
509
widget_class->size_allocate = gtk_icon_view_size_allocate;
510
widget_class->expose_event = gtk_icon_view_expose;
511
widget_class->motion_notify_event = gtk_icon_view_motion;
512
widget_class->button_press_event = gtk_icon_view_button_press;
513
widget_class->button_release_event = gtk_icon_view_button_release;
514
widget_class->key_press_event = gtk_icon_view_key_press;
515
widget_class->key_release_event = gtk_icon_view_key_release;
516
widget_class->drag_begin = gtk_icon_view_drag_begin;
517
widget_class->drag_end = gtk_icon_view_drag_end;
518
widget_class->drag_data_get = gtk_icon_view_drag_data_get;
519
widget_class->drag_data_delete = gtk_icon_view_drag_data_delete;
520
widget_class->drag_leave = gtk_icon_view_drag_leave;
521
widget_class->drag_motion = gtk_icon_view_drag_motion;
522
widget_class->drag_drop = gtk_icon_view_drag_drop;
523
widget_class->drag_data_received = gtk_icon_view_drag_data_received;
524
widget_class->state_changed = gtk_icon_view_state_changed;
526
container_class->remove = gtk_icon_view_remove;
527
container_class->forall = gtk_icon_view_forall;
529
klass->set_scroll_adjustments = gtk_icon_view_set_adjustments;
530
klass->select_all = gtk_icon_view_real_select_all;
531
klass->unselect_all = gtk_icon_view_real_unselect_all;
532
klass->select_cursor_item = gtk_icon_view_real_select_cursor_item;
533
klass->toggle_cursor_item = gtk_icon_view_real_toggle_cursor_item;
534
klass->activate_cursor_item = gtk_icon_view_real_activate_cursor_item;
535
klass->move_cursor = gtk_icon_view_real_move_cursor;
539
* GtkIconView:selection-mode:
541
* The ::selection-mode property specifies the selection mode of
542
* icon view. If the mode is #GTK_SELECTION_MULTIPLE, rubberband selection
543
* is enabled, for the other modes, only keyboard selection is possible.
547
g_object_class_install_property (gobject_class,
549
g_param_spec_enum ("selection-mode",
550
P_("Selection mode"),
551
P_("The selection mode"),
552
GTK_TYPE_SELECTION_MODE,
553
GTK_SELECTION_SINGLE,
554
GTK_PARAM_READWRITE));
557
* GtkIconView:pixbuf-column:
559
* The ::pixbuf-column property contains the number of the model column
560
* containing the pixbufs which are displayed. The pixbuf column must be
561
* of type #GDK_TYPE_PIXBUF. Setting this property to -1 turns off the
562
* display of pixbufs.
566
g_object_class_install_property (gobject_class,
568
g_param_spec_int ("pixbuf-column",
570
P_("Model column used to retrieve the icon pixbuf from"),
572
GTK_PARAM_READWRITE));
575
* GtkIconView:text-column:
577
* The ::text-column property contains the number of the model column
578
* containing the texts which are displayed. The text column must be
579
* of type #G_TYPE_STRING. If this property and the :markup-column
580
* property are both set to -1, no texts are displayed.
584
g_object_class_install_property (gobject_class,
586
g_param_spec_int ("text-column",
588
P_("Model column used to retrieve the text from"),
590
GTK_PARAM_READWRITE));
594
* GtkIconView:markup-column:
596
* The ::markup-column property contains the number of the model column
597
* containing markup information to be displayed. The markup column must be
598
* of type #G_TYPE_STRING. If this property and the :text-column property
599
* are both set to column numbers, it overrides the text column.
600
* If both are set to -1, no texts are displayed.
604
g_object_class_install_property (gobject_class,
606
g_param_spec_int ("markup-column",
608
P_("Model column used to retrieve the text if using Pango markup"),
610
GTK_PARAM_READWRITE));
612
g_object_class_install_property (gobject_class,
614
g_param_spec_object ("model",
615
P_("Icon View Model"),
616
P_("The model for the icon view"),
618
GTK_PARAM_READWRITE));
621
* GtkIconView:columns:
623
* The columns property contains the number of the columns in which the
624
* items should be displayed. If it is -1, the number of columns will
625
* be chosen automatically to fill the available area.
629
g_object_class_install_property (gobject_class,
631
g_param_spec_int ("columns",
632
P_("Number of columns"),
633
P_("Number of columns to display"),
635
GTK_PARAM_READWRITE));
639
* GtkIconView:item-width:
641
* The item-width property specifies the width to use for each item.
642
* If it is set to -1, the icon view will automatically determine a
643
* suitable item size.
647
g_object_class_install_property (gobject_class,
649
g_param_spec_int ("item-width",
650
P_("Width for each item"),
651
P_("The width used for each item"),
653
GTK_PARAM_READWRITE));
656
* GtkIconView:spacing:
658
* The spacing property specifies the space which is inserted between
659
* the cells (i.e. the icon and the text) of an item.
663
g_object_class_install_property (gobject_class,
665
g_param_spec_int ("spacing",
667
P_("Space which is inserted between cells of an item"),
669
GTK_PARAM_READWRITE));
672
* GtkIconView:row-spacing:
674
* The row-spacing property specifies the space which is inserted between
675
* the rows of the icon view.
679
g_object_class_install_property (gobject_class,
681
g_param_spec_int ("row-spacing",
683
P_("Space which is inserted between grid rows"),
685
GTK_PARAM_READWRITE));
688
* GtkIconView:column-spacing:
690
* The column-spacing property specifies the space which is inserted between
691
* the columns of the icon view.
695
g_object_class_install_property (gobject_class,
697
g_param_spec_int ("column-spacing",
698
P_("Column Spacing"),
699
P_("Space which is inserted between grid columns"),
701
GTK_PARAM_READWRITE));
704
* GtkIconView:margin:
706
* The margin property specifies the space which is inserted
707
* at the edges of the icon view.
711
g_object_class_install_property (gobject_class,
713
g_param_spec_int ("margin",
715
P_("Space which is inserted at the edges of the icon view"),
717
GTK_PARAM_READWRITE));
720
* GtkIconView:orientation:
722
* The orientation property specifies how the cells (i.e. the icon and
723
* the text) of the item are positioned relative to each other.
727
* Deprecated: 2.22: Use the #GtkIconView::item-orientation property
729
g_object_class_install_property (gobject_class,
731
g_param_spec_enum ("orientation",
733
P_("How the text and icon of each item are positioned relative to each other"),
734
GTK_TYPE_ORIENTATION,
735
GTK_ORIENTATION_VERTICAL,
736
GTK_PARAM_READWRITE | G_PARAM_DEPRECATED));
739
* GtkIconView:item-orientation:
741
* The item-orientation property specifies how the cells (i.e. the icon and
742
* the text) of the item are positioned relative to each other.
746
g_object_class_install_property (gobject_class,
747
PROP_ITEM_ORIENTATION,
748
g_param_spec_enum ("item-orientation",
749
P_("Item Orientation"),
750
P_("How the text and icon of each item are positioned relative to each other"),
751
GTK_TYPE_ORIENTATION,
752
GTK_ORIENTATION_VERTICAL,
753
GTK_PARAM_READWRITE));
756
* GtkIconView:reorderable:
758
* The reorderable property specifies if the items can be reordered
763
g_object_class_install_property (gobject_class,
765
g_param_spec_boolean ("reorderable",
767
P_("View is reorderable"),
771
g_object_class_install_property (gobject_class,
773
g_param_spec_int ("tooltip-column",
774
P_("Tooltip Column"),
775
P_("The column in the model containing the tooltip texts for the items"),
779
GTK_PARAM_READWRITE));
782
* GtkIconView:item-padding:
784
* The item-padding property specifies the padding around each
785
* of the icon view's item.
789
g_object_class_install_property (gobject_class,
791
g_param_spec_int ("item-padding",
793
P_("Padding around icon view items"),
795
GTK_PARAM_READWRITE));
799
/* Style properties */
800
gtk_widget_class_install_style_property (widget_class,
801
g_param_spec_boxed ("selection-box-color",
802
P_("Selection Box Color"),
803
P_("Color of the selection box"),
805
GTK_PARAM_READABLE));
807
gtk_widget_class_install_style_property (widget_class,
808
g_param_spec_uchar ("selection-box-alpha",
809
P_("Selection Box Alpha"),
810
P_("Opacity of the selection box"),
813
GTK_PARAM_READABLE));
817
* GtkIconView::set-scroll-adjustments
818
* @horizontal: the horizontal #GtkAdjustment
819
* @vertical: the vertical #GtkAdjustment
821
* Set the scroll adjustments for the icon view. Usually scrolled containers
822
* like #GtkScrolledWindow will emit this signal to connect two instances
823
* of #GtkScrollbar to the scroll directions of the #GtkIconView.
825
widget_class->set_scroll_adjustments_signal =
826
g_signal_new (I_("set-scroll-adjustments"),
827
G_TYPE_FROM_CLASS (gobject_class),
829
G_STRUCT_OFFSET (GtkIconViewClass, set_scroll_adjustments),
831
_gtk_marshal_VOID__OBJECT_OBJECT,
833
GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
836
* GtkIconView::item-activated:
837
* @iconview: the object on which the signal is emitted
838
* @path: the #GtkTreePath for the activated item
840
* The ::item-activated signal is emitted when the method
841
* gtk_icon_view_item_activated() is called or the user double
842
* clicks an item. It is also emitted when a non-editable item
843
* is selected and one of the keys: Space, Return or Enter is
846
icon_view_signals[ITEM_ACTIVATED] =
847
g_signal_new (I_("item-activated"),
848
G_TYPE_FROM_CLASS (gobject_class),
850
G_STRUCT_OFFSET (GtkIconViewClass, item_activated),
852
g_cclosure_marshal_VOID__BOXED,
857
* GtkIconView::selection-changed:
858
* @iconview: the object on which the signal is emitted
860
* The ::selection-changed signal is emitted when the selection
861
* (i.e. the set of selected items) changes.
863
icon_view_signals[SELECTION_CHANGED] =
864
g_signal_new (I_("selection-changed"),
865
G_TYPE_FROM_CLASS (gobject_class),
867
G_STRUCT_OFFSET (GtkIconViewClass, selection_changed),
869
g_cclosure_marshal_VOID__VOID,
873
* GtkIconView::select-all:
874
* @iconview: the object on which the signal is emitted
876
* A <link linkend="keybinding-signals">keybinding signal</link>
877
* which gets emitted when the user selects all items.
879
* Applications should not connect to it, but may emit it with
880
* g_signal_emit_by_name() if they need to control selection
883
* The default binding for this signal is Ctrl-a.
885
icon_view_signals[SELECT_ALL] =
886
g_signal_new (I_("select-all"),
887
G_TYPE_FROM_CLASS (gobject_class),
888
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
889
G_STRUCT_OFFSET (GtkIconViewClass, select_all),
891
g_cclosure_marshal_VOID__VOID,
895
* GtkIconView::unselect-all:
896
* @iconview: the object on which the signal is emitted
898
* A <link linkend="keybinding-signals">keybinding signal</link>
899
* which gets emitted when the user unselects all items.
901
* Applications should not connect to it, but may emit it with
902
* g_signal_emit_by_name() if they need to control selection
905
* The default binding for this signal is Ctrl-Shift-a.
907
icon_view_signals[UNSELECT_ALL] =
908
g_signal_new (I_("unselect-all"),
909
G_TYPE_FROM_CLASS (gobject_class),
910
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
911
G_STRUCT_OFFSET (GtkIconViewClass, unselect_all),
913
g_cclosure_marshal_VOID__VOID,
917
* GtkIconView::select-cursor-item:
918
* @iconview: the object on which the signal is emitted
920
* A <link linkend="keybinding-signals">keybinding signal</link>
921
* which gets emitted when the user selects the item that is currently
924
* Applications should not connect to it, but may emit it with
925
* g_signal_emit_by_name() if they need to control selection
928
* There is no default binding for this signal.
930
icon_view_signals[SELECT_CURSOR_ITEM] =
931
g_signal_new (I_("select-cursor-item"),
932
G_TYPE_FROM_CLASS (gobject_class),
933
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
934
G_STRUCT_OFFSET (GtkIconViewClass, select_cursor_item),
936
g_cclosure_marshal_VOID__VOID,
940
* GtkIconView::toggle-cursor-item:
941
* @iconview: the object on which the signal is emitted
943
* A <link linkend="keybinding-signals">keybinding signal</link>
944
* which gets emitted when the user toggles whether the currently
945
* focused item is selected or not. The exact effect of this
946
* depend on the selection mode.
948
* Applications should not connect to it, but may emit it with
949
* g_signal_emit_by_name() if they need to control selection
952
* There is no default binding for this signal is Ctrl-Space.
954
icon_view_signals[TOGGLE_CURSOR_ITEM] =
955
g_signal_new (I_("toggle-cursor-item"),
956
G_TYPE_FROM_CLASS (gobject_class),
957
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
958
G_STRUCT_OFFSET (GtkIconViewClass, toggle_cursor_item),
960
g_cclosure_marshal_VOID__VOID,
964
* GtkIconView::activate-cursor-item:
965
* @iconview: the object on which the signal is emitted
967
* A <link linkend="keybinding-signals">keybinding signal</link>
968
* which gets emitted when the user activates the currently
971
* Applications should not connect to it, but may emit it with
972
* g_signal_emit_by_name() if they need to control activation
975
* The default bindings for this signal are Space, Return and Enter.
977
icon_view_signals[ACTIVATE_CURSOR_ITEM] =
978
g_signal_new (I_("activate-cursor-item"),
979
G_TYPE_FROM_CLASS (gobject_class),
980
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
981
G_STRUCT_OFFSET (GtkIconViewClass, activate_cursor_item),
983
_gtk_marshal_BOOLEAN__VOID,
987
* GtkIconView::move-cursor:
988
* @iconview: the object which received the signal
989
* @step: the granularity of the move, as a #GtkMovementStep
990
* @count: the number of @step units to move
992
* The ::move-cursor signal is a
993
* <link linkend="keybinding-signals">keybinding signal</link>
994
* which gets emitted when the user initiates a cursor movement.
996
* Applications should not connect to it, but may emit it with
997
* g_signal_emit_by_name() if they need to control the cursor
1000
* The default bindings for this signal include
1002
* <listitem>Arrow keys which move by individual steps</listitem>
1003
* <listitem>Home/End keys which move to the first/last item</listitem>
1004
* <listitem>PageUp/PageDown which move by "pages"</listitem>
1007
* All of these will extend the selection when combined with
1008
* the Shift modifier.
1010
icon_view_signals[MOVE_CURSOR] =
1011
g_signal_new (I_("move-cursor"),
1012
G_TYPE_FROM_CLASS (gobject_class),
1013
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1014
G_STRUCT_OFFSET (GtkIconViewClass, move_cursor),
1016
_gtk_marshal_BOOLEAN__ENUM_INT,
1018
GTK_TYPE_MOVEMENT_STEP,
1022
gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK,
1024
gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
1026
gtk_binding_entry_add_signal (binding_set, GDK_space, GDK_CONTROL_MASK,
1027
"toggle-cursor-item", 0);
1028
gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, GDK_CONTROL_MASK,
1029
"toggle-cursor-item", 0);
1031
gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
1032
"activate-cursor-item", 0);
1033
gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
1034
"activate-cursor-item", 0);
1035
gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
1036
"activate-cursor-item", 0);
1037
gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0,
1038
"activate-cursor-item", 0);
1039
gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
1040
"activate-cursor-item", 0);
1042
gtk_icon_view_add_move_binding (binding_set, GDK_Up, 0,
1043
GTK_MOVEMENT_DISPLAY_LINES, -1);
1044
gtk_icon_view_add_move_binding (binding_set, GDK_KP_Up, 0,
1045
GTK_MOVEMENT_DISPLAY_LINES, -1);
1047
gtk_icon_view_add_move_binding (binding_set, GDK_Down, 0,
1048
GTK_MOVEMENT_DISPLAY_LINES, 1);
1049
gtk_icon_view_add_move_binding (binding_set, GDK_KP_Down, 0,
1050
GTK_MOVEMENT_DISPLAY_LINES, 1);
1052
gtk_icon_view_add_move_binding (binding_set, GDK_p, GDK_CONTROL_MASK,
1053
GTK_MOVEMENT_DISPLAY_LINES, -1);
1055
gtk_icon_view_add_move_binding (binding_set, GDK_n, GDK_CONTROL_MASK,
1056
GTK_MOVEMENT_DISPLAY_LINES, 1);
1058
gtk_icon_view_add_move_binding (binding_set, GDK_Home, 0,
1059
GTK_MOVEMENT_BUFFER_ENDS, -1);
1060
gtk_icon_view_add_move_binding (binding_set, GDK_KP_Home, 0,
1061
GTK_MOVEMENT_BUFFER_ENDS, -1);
1063
gtk_icon_view_add_move_binding (binding_set, GDK_End, 0,
1064
GTK_MOVEMENT_BUFFER_ENDS, 1);
1065
gtk_icon_view_add_move_binding (binding_set, GDK_KP_End, 0,
1066
GTK_MOVEMENT_BUFFER_ENDS, 1);
1068
gtk_icon_view_add_move_binding (binding_set, GDK_Page_Up, 0,
1069
GTK_MOVEMENT_PAGES, -1);
1070
gtk_icon_view_add_move_binding (binding_set, GDK_KP_Page_Up, 0,
1071
GTK_MOVEMENT_PAGES, -1);
1073
gtk_icon_view_add_move_binding (binding_set, GDK_Page_Down, 0,
1074
GTK_MOVEMENT_PAGES, 1);
1075
gtk_icon_view_add_move_binding (binding_set, GDK_KP_Page_Down, 0,
1076
GTK_MOVEMENT_PAGES, 1);
1078
gtk_icon_view_add_move_binding (binding_set, GDK_Right, 0,
1079
GTK_MOVEMENT_VISUAL_POSITIONS, 1);
1080
gtk_icon_view_add_move_binding (binding_set, GDK_Left, 0,
1081
GTK_MOVEMENT_VISUAL_POSITIONS, -1);
1083
gtk_icon_view_add_move_binding (binding_set, GDK_KP_Right, 0,
1084
GTK_MOVEMENT_VISUAL_POSITIONS, 1);
1085
gtk_icon_view_add_move_binding (binding_set, GDK_KP_Left, 0,
1086
GTK_MOVEMENT_VISUAL_POSITIONS, -1);
1090
gtk_icon_view_buildable_init (GtkBuildableIface *iface)
1092
parent_buildable_iface = g_type_interface_peek_parent (iface);
1093
iface->add_child = _gtk_cell_layout_buildable_add_child;
1094
iface->custom_tag_start = gtk_icon_view_buildable_custom_tag_start;
1095
iface->custom_tag_end = gtk_icon_view_buildable_custom_tag_end;
1099
gtk_icon_view_cell_layout_init (GtkCellLayoutIface *iface)
1101
iface->pack_start = gtk_icon_view_cell_layout_pack_start;
1102
iface->pack_end = gtk_icon_view_cell_layout_pack_end;
1103
iface->clear = gtk_icon_view_cell_layout_clear;
1104
iface->add_attribute = gtk_icon_view_cell_layout_add_attribute;
1105
iface->set_cell_data_func = gtk_icon_view_cell_layout_set_cell_data_func;
1106
iface->clear_attributes = gtk_icon_view_cell_layout_clear_attributes;
1107
iface->reorder = gtk_icon_view_cell_layout_reorder;
1108
iface->get_cells = gtk_icon_view_cell_layout_get_cells;
1112
gtk_icon_view_init (GtkIconView *icon_view)
1114
icon_view->priv = GTK_ICON_VIEW_GET_PRIVATE (icon_view);
1116
icon_view->priv->width = 0;
1117
icon_view->priv->height = 0;
1118
icon_view->priv->selection_mode = GTK_SELECTION_SINGLE;
1119
icon_view->priv->pressed_button = -1;
1120
icon_view->priv->press_start_x = -1;
1121
icon_view->priv->press_start_y = -1;
1122
icon_view->priv->text_column = -1;
1123
icon_view->priv->markup_column = -1;
1124
icon_view->priv->pixbuf_column = -1;
1125
icon_view->priv->text_cell = -1;
1126
icon_view->priv->pixbuf_cell = -1;
1127
icon_view->priv->tooltip_column = -1;
1129
gtk_widget_set_can_focus (GTK_WIDGET (icon_view), TRUE);
1131
gtk_icon_view_set_adjustments (icon_view, NULL, NULL);
1133
icon_view->priv->cell_list = NULL;
1134
icon_view->priv->n_cells = 0;
1135
icon_view->priv->cursor_cell = -1;
1137
icon_view->priv->item_orientation = GTK_ORIENTATION_VERTICAL;
1139
icon_view->priv->columns = -1;
1140
icon_view->priv->item_width = -1;
1141
icon_view->priv->spacing = 0;
1142
icon_view->priv->row_spacing = 6;
1143
icon_view->priv->column_spacing = 6;
1144
icon_view->priv->margin = 6;
1145
icon_view->priv->item_padding = 6;
1147
icon_view->priv->draw_focus = TRUE;
1151
gtk_icon_view_destroy (GtkObject *object)
1153
GtkIconView *icon_view;
1155
icon_view = GTK_ICON_VIEW (object);
1157
gtk_icon_view_stop_editing (icon_view, TRUE);
1159
gtk_icon_view_set_model (icon_view, NULL);
1161
if (icon_view->priv->layout_idle_id != 0)
1163
g_source_remove (icon_view->priv->layout_idle_id);
1164
icon_view->priv->layout_idle_id = 0;
1167
if (icon_view->priv->scroll_to_path != NULL)
1169
gtk_tree_row_reference_free (icon_view->priv->scroll_to_path);
1170
icon_view->priv->scroll_to_path = NULL;
1173
remove_scroll_timeout (icon_view);
1175
if (icon_view->priv->hadjustment != NULL)
1177
g_object_unref (icon_view->priv->hadjustment);
1178
icon_view->priv->hadjustment = NULL;
1181
if (icon_view->priv->vadjustment != NULL)
1183
g_object_unref (icon_view->priv->vadjustment);
1184
icon_view->priv->vadjustment = NULL;
1187
GTK_OBJECT_CLASS (gtk_icon_view_parent_class)->destroy (object);
1190
/* GObject methods */
1192
gtk_icon_view_finalize (GObject *object)
1194
gtk_icon_view_cell_layout_clear (GTK_CELL_LAYOUT (object));
1196
G_OBJECT_CLASS (gtk_icon_view_parent_class)->finalize (object);
1201
gtk_icon_view_set_property (GObject *object,
1203
const GValue *value,
1206
GtkIconView *icon_view;
1208
icon_view = GTK_ICON_VIEW (object);
1212
case PROP_SELECTION_MODE:
1213
gtk_icon_view_set_selection_mode (icon_view, g_value_get_enum (value));
1215
case PROP_PIXBUF_COLUMN:
1216
gtk_icon_view_set_pixbuf_column (icon_view, g_value_get_int (value));
1218
case PROP_TEXT_COLUMN:
1219
gtk_icon_view_set_text_column (icon_view, g_value_get_int (value));
1221
case PROP_MARKUP_COLUMN:
1222
gtk_icon_view_set_markup_column (icon_view, g_value_get_int (value));
1225
gtk_icon_view_set_model (icon_view, g_value_get_object (value));
1227
case PROP_ORIENTATION:
1228
case PROP_ITEM_ORIENTATION:
1229
gtk_icon_view_set_item_orientation (icon_view, g_value_get_enum (value));
1232
gtk_icon_view_set_columns (icon_view, g_value_get_int (value));
1234
case PROP_ITEM_WIDTH:
1235
gtk_icon_view_set_item_width (icon_view, g_value_get_int (value));
1238
gtk_icon_view_set_spacing (icon_view, g_value_get_int (value));
1240
case PROP_ROW_SPACING:
1241
gtk_icon_view_set_row_spacing (icon_view, g_value_get_int (value));
1243
case PROP_COLUMN_SPACING:
1244
gtk_icon_view_set_column_spacing (icon_view, g_value_get_int (value));
1247
gtk_icon_view_set_margin (icon_view, g_value_get_int (value));
1249
case PROP_REORDERABLE:
1250
gtk_icon_view_set_reorderable (icon_view, g_value_get_boolean (value));
1253
case PROP_TOOLTIP_COLUMN:
1254
gtk_icon_view_set_tooltip_column (icon_view, g_value_get_int (value));
1257
case PROP_ITEM_PADDING:
1258
gtk_icon_view_set_item_padding (icon_view, g_value_get_int (value));
1262
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1268
gtk_icon_view_get_property (GObject *object,
1273
GtkIconView *icon_view;
1275
icon_view = GTK_ICON_VIEW (object);
1279
case PROP_SELECTION_MODE:
1280
g_value_set_enum (value, icon_view->priv->selection_mode);
1282
case PROP_PIXBUF_COLUMN:
1283
g_value_set_int (value, icon_view->priv->pixbuf_column);
1285
case PROP_TEXT_COLUMN:
1286
g_value_set_int (value, icon_view->priv->text_column);
1288
case PROP_MARKUP_COLUMN:
1289
g_value_set_int (value, icon_view->priv->markup_column);
1292
g_value_set_object (value, icon_view->priv->model);
1294
case PROP_ORIENTATION:
1295
case PROP_ITEM_ORIENTATION:
1296
g_value_set_enum (value, icon_view->priv->item_orientation);
1299
g_value_set_int (value, icon_view->priv->columns);
1301
case PROP_ITEM_WIDTH:
1302
g_value_set_int (value, icon_view->priv->item_width);
1305
g_value_set_int (value, icon_view->priv->spacing);
1307
case PROP_ROW_SPACING:
1308
g_value_set_int (value, icon_view->priv->row_spacing);
1310
case PROP_COLUMN_SPACING:
1311
g_value_set_int (value, icon_view->priv->column_spacing);
1314
g_value_set_int (value, icon_view->priv->margin);
1316
case PROP_REORDERABLE:
1317
g_value_set_boolean (value, icon_view->priv->reorderable);
1319
case PROP_TOOLTIP_COLUMN:
1320
g_value_set_int (value, icon_view->priv->tooltip_column);
1323
case PROP_ITEM_PADDING:
1324
g_value_set_int (value, icon_view->priv->item_padding);
1328
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1333
/* GtkWidget signals */
1335
gtk_icon_view_realize (GtkWidget *widget)
1337
GtkIconView *icon_view;
1338
GdkWindowAttr attributes;
1339
gint attributes_mask;
1341
icon_view = GTK_ICON_VIEW (widget);
1343
gtk_widget_set_realized (widget, TRUE);
1345
/* Make the main, clipping window */
1346
attributes.window_type = GDK_WINDOW_CHILD;
1347
attributes.x = widget->allocation.x;
1348
attributes.y = widget->allocation.y;
1349
attributes.width = widget->allocation.width;
1350
attributes.height = widget->allocation.height;
1351
attributes.wclass = GDK_INPUT_OUTPUT;
1352
attributes.visual = gtk_widget_get_visual (widget);
1353
attributes.colormap = gtk_widget_get_colormap (widget);
1354
attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
1356
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
1358
widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
1359
&attributes, attributes_mask);
1360
gdk_window_set_back_pixmap (widget->window, NULL, FALSE);
1361
gdk_window_set_user_data (widget->window, widget);
1363
/* Make the window for the icon view */
1366
attributes.width = MAX (icon_view->priv->width, widget->allocation.width);
1367
attributes.height = MAX (icon_view->priv->height, widget->allocation.height);
1368
attributes.event_mask = (GDK_EXPOSURE_MASK |
1370
GDK_POINTER_MOTION_MASK |
1371
GDK_BUTTON_PRESS_MASK |
1372
GDK_BUTTON_RELEASE_MASK |
1373
GDK_KEY_PRESS_MASK |
1374
GDK_KEY_RELEASE_MASK) |
1375
gtk_widget_get_events (widget);
1377
icon_view->priv->bin_window = gdk_window_new (widget->window,
1378
&attributes, attributes_mask);
1379
gdk_window_set_user_data (icon_view->priv->bin_window, widget);
1381
widget->style = gtk_style_attach (widget->style, widget->window);
1382
gdk_window_set_background (icon_view->priv->bin_window, &widget->style->base[widget->state]);
1384
gdk_window_show (icon_view->priv->bin_window);
1388
gtk_icon_view_unrealize (GtkWidget *widget)
1390
GtkIconView *icon_view;
1392
icon_view = GTK_ICON_VIEW (widget);
1394
gdk_window_set_user_data (icon_view->priv->bin_window, NULL);
1395
gdk_window_destroy (icon_view->priv->bin_window);
1396
icon_view->priv->bin_window = NULL;
1398
GTK_WIDGET_CLASS (gtk_icon_view_parent_class)->unrealize (widget);
1402
gtk_icon_view_state_changed (GtkWidget *widget,
1403
GtkStateType previous_state)
1405
GtkIconView *icon_view = GTK_ICON_VIEW (widget);
1407
if (gtk_widget_get_realized (widget))
1409
gdk_window_set_background (widget->window, &widget->style->base[widget->state]);
1410
gdk_window_set_background (icon_view->priv->bin_window, &widget->style->base[widget->state]);
1413
gtk_widget_queue_draw (widget);
1417
gtk_icon_view_style_set (GtkWidget *widget,
1418
GtkStyle *previous_style)
1420
GtkIconView *icon_view = GTK_ICON_VIEW (widget);
1422
if (gtk_widget_get_realized (widget))
1424
gdk_window_set_background (widget->window, &widget->style->base[widget->state]);
1425
gdk_window_set_background (icon_view->priv->bin_window, &widget->style->base[widget->state]);
1428
gtk_widget_queue_resize (widget);
1432
gtk_icon_view_size_request (GtkWidget *widget,
1433
GtkRequisition *requisition)
1435
GtkIconView *icon_view = GTK_ICON_VIEW (widget);
1438
requisition->width = icon_view->priv->width;
1439
requisition->height = icon_view->priv->height;
1441
tmp_list = icon_view->priv->children;
1445
GtkIconViewChild *child = tmp_list->data;
1446
GtkRequisition child_requisition;
1448
tmp_list = tmp_list->next;
1450
if (gtk_widget_get_visible (child->widget))
1451
gtk_widget_size_request (child->widget, &child_requisition);
1456
gtk_icon_view_allocate_children (GtkIconView *icon_view)
1460
for (list = icon_view->priv->children; list; list = list->next)
1462
GtkIconViewChild *child = list->data;
1463
GtkAllocation allocation;
1465
/* totally ignore our child's requisition */
1466
if (child->cell < 0)
1468
allocation.x = child->item->x + icon_view->priv->item_padding;
1469
allocation.y = child->item->y + icon_view->priv->item_padding;
1470
allocation.width = child->item->width - icon_view->priv->item_padding * 2;
1471
allocation.height = child->item->height - icon_view->priv->item_padding * 2;
1475
GdkRectangle *box = &child->item->box[child->cell];
1477
allocation.x = box->x;
1478
allocation.y = box->y;
1479
allocation.width = box->width;
1480
allocation.height = box->height;
1483
gtk_widget_size_allocate (child->widget, &allocation);
1488
gtk_icon_view_size_allocate (GtkWidget *widget,
1489
GtkAllocation *allocation)
1491
GtkIconView *icon_view = GTK_ICON_VIEW (widget);
1493
GtkAdjustment *hadjustment, *vadjustment;
1495
widget->allocation = *allocation;
1497
if (gtk_widget_get_realized (widget))
1499
gdk_window_move_resize (widget->window,
1500
allocation->x, allocation->y,
1501
allocation->width, allocation->height);
1502
gdk_window_resize (icon_view->priv->bin_window,
1503
MAX (icon_view->priv->width, allocation->width),
1504
MAX (icon_view->priv->height, allocation->height));
1507
gtk_icon_view_layout (icon_view);
1509
gtk_icon_view_allocate_children (icon_view);
1511
hadjustment = icon_view->priv->hadjustment;
1512
vadjustment = icon_view->priv->vadjustment;
1514
hadjustment->page_size = allocation->width;
1515
hadjustment->page_increment = allocation->width * 0.9;
1516
hadjustment->step_increment = allocation->width * 0.1;
1517
hadjustment->lower = 0;
1518
hadjustment->upper = MAX (allocation->width, icon_view->priv->width);
1520
if (hadjustment->value > hadjustment->upper - hadjustment->page_size)
1521
gtk_adjustment_set_value (hadjustment, MAX (0, hadjustment->upper - hadjustment->page_size));
1523
vadjustment->page_size = allocation->height;
1524
vadjustment->page_increment = allocation->height * 0.9;
1525
vadjustment->step_increment = allocation->height * 0.1;
1526
vadjustment->lower = 0;
1527
vadjustment->upper = MAX (allocation->height, icon_view->priv->height);
1529
if (vadjustment->value > vadjustment->upper - vadjustment->page_size)
1530
gtk_adjustment_set_value (vadjustment, MAX (0, vadjustment->upper - vadjustment->page_size));
1532
if (gtk_widget_get_realized (widget) &&
1533
icon_view->priv->scroll_to_path)
1536
path = gtk_tree_row_reference_get_path (icon_view->priv->scroll_to_path);
1537
gtk_tree_row_reference_free (icon_view->priv->scroll_to_path);
1538
icon_view->priv->scroll_to_path = NULL;
1540
gtk_icon_view_scroll_to_path (icon_view, path,
1541
icon_view->priv->scroll_to_use_align,
1542
icon_view->priv->scroll_to_row_align,
1543
icon_view->priv->scroll_to_col_align);
1544
gtk_tree_path_free (path);
1548
gtk_adjustment_changed (hadjustment);
1549
gtk_adjustment_changed (vadjustment);
1554
gtk_icon_view_expose (GtkWidget *widget,
1555
GdkEventExpose *expose)
1557
GtkIconView *icon_view;
1562
GtkIconViewDropPosition dest_pos;
1563
GtkIconViewItem *dest_item = NULL;
1565
icon_view = GTK_ICON_VIEW (widget);
1567
if (expose->window != icon_view->priv->bin_window)
1570
/* If a layout has been scheduled, do it now so that all
1571
* cell view items have valid sizes before we proceed. */
1572
if (icon_view->priv->layout_idle_id != 0)
1573
gtk_icon_view_layout (icon_view);
1575
cr = gdk_cairo_create (icon_view->priv->bin_window);
1576
cairo_set_line_width (cr, 1.);
1578
gtk_icon_view_get_drag_dest_item (icon_view, &path, &dest_pos);
1582
dest_index = gtk_tree_path_get_indices (path)[0];
1583
gtk_tree_path_free (path);
1588
for (icons = icon_view->priv->items; icons; icons = icons->next)
1590
GtkIconViewItem *item = icons->data;
1595
area.width = item->width;
1596
area.height = item->height;
1598
if (gdk_region_rect_in (expose->region, &area) == GDK_OVERLAP_RECTANGLE_OUT)
1601
gtk_icon_view_paint_item (icon_view, cr, item, &expose->area,
1602
icon_view->priv->bin_window,
1604
icon_view->priv->draw_focus);
1606
if (dest_index == item->index)
1614
case GTK_ICON_VIEW_DROP_INTO:
1615
gtk_paint_focus (widget->style,
1616
icon_view->priv->bin_window,
1617
gtk_widget_get_state (widget),
1620
"iconview-drop-indicator",
1621
dest_item->x, dest_item->y,
1622
dest_item->width, dest_item->height);
1624
case GTK_ICON_VIEW_DROP_ABOVE:
1625
gtk_paint_focus (widget->style,
1626
icon_view->priv->bin_window,
1627
gtk_widget_get_state (widget),
1630
"iconview-drop-indicator",
1631
dest_item->x, dest_item->y - 1,
1632
dest_item->width, 2);
1634
case GTK_ICON_VIEW_DROP_LEFT:
1635
gtk_paint_focus (widget->style,
1636
icon_view->priv->bin_window,
1637
gtk_widget_get_state (widget),
1640
"iconview-drop-indicator",
1641
dest_item->x - 1, dest_item->y,
1642
2, dest_item->height);
1644
case GTK_ICON_VIEW_DROP_BELOW:
1645
gtk_paint_focus (widget->style,
1646
icon_view->priv->bin_window,
1647
gtk_widget_get_state (widget),
1650
"iconview-drop-indicator",
1651
dest_item->x, dest_item->y + dest_item->height - 1,
1652
dest_item->width, 2);
1654
case GTK_ICON_VIEW_DROP_RIGHT:
1655
gtk_paint_focus (widget->style,
1656
icon_view->priv->bin_window,
1657
gtk_widget_get_state (widget),
1660
"iconview-drop-indicator",
1661
dest_item->x + dest_item->width - 1, dest_item->y,
1662
2, dest_item->height);
1663
case GTK_ICON_VIEW_NO_DROP: ;
1668
if (icon_view->priv->doing_rubberband)
1670
GdkRectangle *rectangles;
1673
gdk_region_get_rectangles (expose->region,
1677
while (n_rectangles--)
1678
gtk_icon_view_paint_rubberband (icon_view, cr, &rectangles[n_rectangles]);
1680
g_free (rectangles);
1685
GTK_WIDGET_CLASS (gtk_icon_view_parent_class)->expose_event (widget, expose);
1691
rubberband_scroll_timeout (gpointer data)
1693
GtkIconView *icon_view;
1698
value = MIN (icon_view->priv->vadjustment->value +
1699
icon_view->priv->scroll_value_diff,
1700
icon_view->priv->vadjustment->upper -
1701
icon_view->priv->vadjustment->page_size);
1703
gtk_adjustment_set_value (icon_view->priv->vadjustment, value);
1705
gtk_icon_view_update_rubberband (icon_view);
1711
gtk_icon_view_motion (GtkWidget *widget,
1712
GdkEventMotion *event)
1714
GtkIconView *icon_view;
1717
icon_view = GTK_ICON_VIEW (widget);
1719
gtk_icon_view_maybe_begin_drag (icon_view, event);
1721
if (icon_view->priv->doing_rubberband)
1723
gtk_icon_view_update_rubberband (widget);
1725
abs_y = event->y - icon_view->priv->height *
1726
(icon_view->priv->vadjustment->value /
1727
(icon_view->priv->vadjustment->upper -
1728
icon_view->priv->vadjustment->lower));
1730
if (abs_y < 0 || abs_y > widget->allocation.height)
1733
icon_view->priv->scroll_value_diff = abs_y;
1735
icon_view->priv->scroll_value_diff = abs_y - widget->allocation.height;
1737
icon_view->priv->event_last_x = event->x;
1738
icon_view->priv->event_last_y = event->y;
1740
if (icon_view->priv->scroll_timeout_id == 0)
1741
icon_view->priv->scroll_timeout_id = gdk_threads_add_timeout (30, rubberband_scroll_timeout,
1745
remove_scroll_timeout (icon_view);
1752
gtk_icon_view_remove (GtkContainer *container,
1755
GtkIconView *icon_view;
1756
GtkIconViewChild *child = NULL;
1759
icon_view = GTK_ICON_VIEW (container);
1761
tmp_list = icon_view->priv->children;
1764
child = tmp_list->data;
1765
if (child->widget == widget)
1767
gtk_widget_unparent (widget);
1769
icon_view->priv->children = g_list_remove_link (icon_view->priv->children, tmp_list);
1770
g_list_free_1 (tmp_list);
1775
tmp_list = tmp_list->next;
1780
gtk_icon_view_forall (GtkContainer *container,
1781
gboolean include_internals,
1782
GtkCallback callback,
1783
gpointer callback_data)
1785
GtkIconView *icon_view;
1786
GtkIconViewChild *child = NULL;
1789
icon_view = GTK_ICON_VIEW (container);
1791
tmp_list = icon_view->priv->children;
1794
child = tmp_list->data;
1795
tmp_list = tmp_list->next;
1797
(* callback) (child->widget, callback_data);
1802
gtk_icon_view_item_activate_cell (GtkIconView *icon_view,
1803
GtkIconViewItem *item,
1804
GtkIconViewCellInfo *info,
1809
GdkRectangle cell_area;
1810
gboolean visible, mode;
1812
gtk_icon_view_set_cell_data (icon_view, item);
1814
g_object_get (info->cell,
1815
"visible", &visible,
1819
if (visible && mode == GTK_CELL_RENDERER_MODE_ACTIVATABLE)
1821
gtk_icon_view_get_cell_area (icon_view, item, info, &cell_area);
1823
path = gtk_tree_path_new_from_indices (item->index, -1);
1824
path_string = gtk_tree_path_to_string (path);
1825
gtk_tree_path_free (path);
1827
gtk_cell_renderer_activate (info->cell,
1829
GTK_WIDGET (icon_view),
1835
g_free (path_string);
1840
gtk_icon_view_item_selected_changed (GtkIconView *icon_view,
1841
GtkIconViewItem *item)
1844
AtkObject *item_obj;
1846
obj = gtk_widget_get_accessible (GTK_WIDGET (icon_view));
1849
item_obj = atk_object_ref_accessible_child (obj, item->index);
1850
if (item_obj != NULL)
1852
atk_object_notify_state_change (item_obj, ATK_STATE_SELECTED, item->selected);
1853
g_object_unref (item_obj);
1859
gtk_icon_view_put (GtkIconView *icon_view,
1861
GtkIconViewItem *item,
1864
GtkIconViewChild *child;
1866
child = g_new (GtkIconViewChild, 1);
1868
child->widget = widget;
1872
icon_view->priv->children = g_list_append (icon_view->priv->children, child);
1874
if (gtk_widget_get_realized (GTK_WIDGET (icon_view)))
1875
gtk_widget_set_parent_window (child->widget, icon_view->priv->bin_window);
1877
gtk_widget_set_parent (widget, GTK_WIDGET (icon_view));
1881
gtk_icon_view_remove_widget (GtkCellEditable *editable,
1882
GtkIconView *icon_view)
1885
GtkIconViewItem *item;
1887
if (icon_view->priv->edited_item == NULL)
1890
item = icon_view->priv->edited_item;
1891
icon_view->priv->edited_item = NULL;
1892
icon_view->priv->editable = NULL;
1893
for (l = icon_view->priv->cell_list; l; l = l->next)
1895
GtkIconViewCellInfo *info = l->data;
1897
info->editing = FALSE;
1900
if (gtk_widget_has_focus (GTK_WIDGET (editable)))
1901
gtk_widget_grab_focus (GTK_WIDGET (icon_view));
1903
g_signal_handlers_disconnect_by_func (editable,
1904
gtk_icon_view_remove_widget,
1907
gtk_container_remove (GTK_CONTAINER (icon_view),
1908
GTK_WIDGET (editable));
1910
gtk_icon_view_queue_draw_item (icon_view, item);
1915
gtk_icon_view_start_editing (GtkIconView *icon_view,
1916
GtkIconViewItem *item,
1917
GtkIconViewCellInfo *info,
1922
GdkRectangle cell_area;
1923
gboolean visible, mode;
1924
GtkCellEditable *editable;
1926
gtk_icon_view_set_cell_data (icon_view, item);
1928
g_object_get (info->cell,
1929
"visible", &visible,
1932
if (visible && mode == GTK_CELL_RENDERER_MODE_EDITABLE)
1934
gtk_icon_view_get_cell_area (icon_view, item, info, &cell_area);
1936
path = gtk_tree_path_new_from_indices (item->index, -1);
1937
path_string = gtk_tree_path_to_string (path);
1938
gtk_tree_path_free (path);
1940
editable = gtk_cell_renderer_start_editing (info->cell,
1942
GTK_WIDGET (icon_view),
1947
g_free (path_string);
1949
/* the rest corresponds to tree_view_real_start_editing... */
1950
icon_view->priv->edited_item = item;
1951
icon_view->priv->editable = editable;
1952
info->editing = TRUE;
1954
gtk_icon_view_put (icon_view, GTK_WIDGET (editable), item,
1956
gtk_cell_editable_start_editing (GTK_CELL_EDITABLE (editable),
1958
gtk_widget_grab_focus (GTK_WIDGET (editable));
1959
g_signal_connect (editable, "remove-widget",
1960
G_CALLBACK (gtk_icon_view_remove_widget),
1967
gtk_icon_view_stop_editing (GtkIconView *icon_view,
1968
gboolean cancel_editing)
1970
GtkCellRenderer *cell = NULL;
1971
GtkIconViewItem *item;
1974
if (icon_view->priv->edited_item == NULL)
1978
* This is very evil. We need to do this, because
1979
* gtk_cell_editable_editing_done may trigger gtk_icon_view_row_changed
1980
* later on. If gtk_icon_view_row_changed notices
1981
* icon_view->priv->edited_item != NULL, it'll call
1982
* gtk_icon_view_stop_editing again. Bad things will happen then.
1984
* Please read that again if you intend to modify anything here.
1987
item = icon_view->priv->edited_item;
1988
icon_view->priv->edited_item = NULL;
1990
for (l = icon_view->priv->cell_list; l; l = l->next)
1992
GtkIconViewCellInfo *info = l->data;
2004
gtk_cell_renderer_stop_editing (cell, cancel_editing);
2005
if (!cancel_editing)
2006
gtk_cell_editable_editing_done (icon_view->priv->editable);
2008
icon_view->priv->edited_item = item;
2010
gtk_cell_editable_remove_widget (icon_view->priv->editable);
2014
* gtk_icon_view_set_cursor:
2015
* @icon_view: A #GtkIconView
2016
* @path: A #GtkTreePath
2017
* @cell: (allow-none): One of the cell renderers of @icon_view, or %NULL
2018
* @start_editing: %TRUE if the specified cell should start being edited.
2020
* Sets the current keyboard focus to be at @path, and selects it. This is
2021
* useful when you want to focus the user's attention on a particular item.
2022
* If @cell is not %NULL, then focus is given to the cell specified by
2023
* it. Additionally, if @start_editing is %TRUE, then editing should be
2024
* started in the specified cell.
2026
* This function is often followed by <literal>gtk_widget_grab_focus
2027
* (icon_view)</literal> in order to give keyboard focus to the widget.
2028
* Please note that editing can only happen when the widget is realized.
2033
gtk_icon_view_set_cursor (GtkIconView *icon_view,
2035
GtkCellRenderer *cell,
2036
gboolean start_editing)
2038
GtkIconViewItem *item = NULL;
2039
GtkIconViewCellInfo *info = NULL;
2043
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
2044
g_return_if_fail (path != NULL);
2045
g_return_if_fail (cell == NULL || GTK_IS_CELL_RENDERER (cell));
2047
gtk_icon_view_stop_editing (icon_view, TRUE);
2049
if (gtk_tree_path_get_depth (path) == 1)
2050
item = g_list_nth_data (icon_view->priv->items,
2051
gtk_tree_path_get_indices(path)[0]);
2057
for (l = icon_view->priv->cell_list, i = 0; l; l = l->next, i++)
2061
if (info->cell == cell)
2070
g_return_if_fail (cell == NULL || info != NULL);
2072
gtk_icon_view_set_cursor_item (icon_view, item, cell_pos);
2073
gtk_icon_view_scroll_to_path (icon_view, path, FALSE, 0.0, 0.0);
2075
if (info && start_editing)
2076
gtk_icon_view_start_editing (icon_view, item, info, NULL);
2080
* gtk_icon_view_get_cursor:
2081
* @icon_view: A #GtkIconView
2082
* @path: (allow-none): Return location for the current cursor path, or %NULL
2083
* @cell: (allow-none): Return location the current focus cell, or %NULL
2085
* Fills in @path and @cell with the current cursor path and cell.
2086
* If the cursor isn't currently set, then *@path will be %NULL.
2087
* If no cell currently has focus, then *@cell will be %NULL.
2089
* The returned #GtkTreePath must be freed with gtk_tree_path_free().
2091
* Return value: %TRUE if the cursor is set.
2096
gtk_icon_view_get_cursor (GtkIconView *icon_view,
2098
GtkCellRenderer **cell)
2100
GtkIconViewItem *item;
2101
GtkIconViewCellInfo *info;
2103
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), FALSE);
2105
item = icon_view->priv->cursor_item;
2106
if (icon_view->priv->cursor_cell < 0)
2109
info = g_list_nth_data (icon_view->priv->cell_list,
2110
icon_view->priv->cursor_cell);
2115
*path = gtk_tree_path_new_from_indices (item->index, -1);
2128
return (item != NULL);
2132
gtk_icon_view_button_press (GtkWidget *widget,
2133
GdkEventButton *event)
2135
GtkIconView *icon_view;
2136
GtkIconViewItem *item;
2137
GtkIconViewCellInfo *info = NULL;
2138
gboolean dirty = FALSE;
2139
GtkCellRendererMode mode;
2140
gint cursor_cell = -1;
2142
icon_view = GTK_ICON_VIEW (widget);
2144
if (event->window != icon_view->priv->bin_window)
2147
if (!gtk_widget_has_focus (widget))
2148
gtk_widget_grab_focus (widget);
2150
if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
2152
item = gtk_icon_view_get_item_at_coords (icon_view,
2158
* We consider only the the cells' area as the item area if the
2159
* item is not selected, but if it *is* selected, the complete
2160
* selection rectangle is considered to be part of the item.
2162
if (item != NULL && (info != NULL || item->selected))
2166
g_object_get (info->cell, "mode", &mode, NULL);
2168
if (mode == GTK_CELL_RENDERER_MODE_ACTIVATABLE ||
2169
mode == GTK_CELL_RENDERER_MODE_EDITABLE)
2170
cursor_cell = g_list_index (icon_view->priv->cell_list, info);
2173
gtk_icon_view_scroll_to_item (icon_view, item);
2175
if (icon_view->priv->selection_mode == GTK_SELECTION_NONE)
2177
gtk_icon_view_set_cursor_item (icon_view, item, cursor_cell);
2179
else if (icon_view->priv->selection_mode == GTK_SELECTION_MULTIPLE &&
2180
(event->state & GTK_EXTEND_SELECTION_MOD_MASK))
2182
gtk_icon_view_unselect_all_internal (icon_view);
2184
gtk_icon_view_set_cursor_item (icon_view, item, cursor_cell);
2185
if (!icon_view->priv->anchor_item)
2186
icon_view->priv->anchor_item = item;
2188
gtk_icon_view_select_all_between (icon_view,
2189
icon_view->priv->anchor_item,
2195
if ((icon_view->priv->selection_mode == GTK_SELECTION_MULTIPLE ||
2196
((icon_view->priv->selection_mode == GTK_SELECTION_SINGLE) && item->selected)) &&
2197
(event->state & GTK_MODIFY_SELECTION_MOD_MASK))
2199
item->selected = !item->selected;
2200
gtk_icon_view_queue_draw_item (icon_view, item);
2205
gtk_icon_view_unselect_all_internal (icon_view);
2207
item->selected = TRUE;
2208
gtk_icon_view_queue_draw_item (icon_view, item);
2211
gtk_icon_view_set_cursor_item (icon_view, item, cursor_cell);
2212
icon_view->priv->anchor_item = item;
2215
/* Save press to possibly begin a drag */
2216
if (icon_view->priv->pressed_button < 0)
2218
icon_view->priv->pressed_button = event->button;
2219
icon_view->priv->press_start_x = event->x;
2220
icon_view->priv->press_start_y = event->y;
2223
if (!icon_view->priv->last_single_clicked)
2224
icon_view->priv->last_single_clicked = item;
2226
/* cancel the current editing, if it exists */
2227
gtk_icon_view_stop_editing (icon_view, TRUE);
2231
if (mode == GTK_CELL_RENDERER_MODE_ACTIVATABLE)
2232
gtk_icon_view_item_activate_cell (icon_view, item, info,
2234
else if (mode == GTK_CELL_RENDERER_MODE_EDITABLE)
2235
gtk_icon_view_start_editing (icon_view, item, info,
2241
if (icon_view->priv->selection_mode != GTK_SELECTION_BROWSE &&
2242
!(event->state & GTK_MODIFY_SELECTION_MOD_MASK))
2244
dirty = gtk_icon_view_unselect_all_internal (icon_view);
2247
if (icon_view->priv->selection_mode == GTK_SELECTION_MULTIPLE)
2248
gtk_icon_view_start_rubberbanding (icon_view, event->x, event->y);
2251
/* don't draw keyboard focus around an clicked-on item */
2252
icon_view->priv->draw_focus = FALSE;
2255
if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
2257
item = gtk_icon_view_get_item_at_coords (icon_view,
2262
if (item && item == icon_view->priv->last_single_clicked)
2266
path = gtk_tree_path_new_from_indices (item->index, -1);
2267
gtk_icon_view_item_activated (icon_view, path);
2268
gtk_tree_path_free (path);
2271
icon_view->priv->last_single_clicked = NULL;
2272
icon_view->priv->pressed_button = -1;
2276
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2278
return event->button == 1;
2282
gtk_icon_view_button_release (GtkWidget *widget,
2283
GdkEventButton *event)
2285
GtkIconView *icon_view;
2287
icon_view = GTK_ICON_VIEW (widget);
2289
if (icon_view->priv->pressed_button == event->button)
2290
icon_view->priv->pressed_button = -1;
2292
gtk_icon_view_stop_rubberbanding (icon_view);
2294
remove_scroll_timeout (icon_view);
2300
gtk_icon_view_key_press (GtkWidget *widget,
2303
GtkIconView *icon_view = GTK_ICON_VIEW (widget);
2305
if (icon_view->priv->doing_rubberband)
2307
if (event->keyval == GDK_Escape)
2308
gtk_icon_view_stop_rubberbanding (icon_view);
2313
return GTK_WIDGET_CLASS (gtk_icon_view_parent_class)->key_press_event (widget, event);
2317
gtk_icon_view_key_release (GtkWidget *widget,
2320
GtkIconView *icon_view = GTK_ICON_VIEW (widget);
2322
if (icon_view->priv->doing_rubberband)
2325
return GTK_WIDGET_CLASS (gtk_icon_view_parent_class)->key_press_event (widget, event);
2329
gtk_icon_view_update_rubberband (gpointer data)
2331
GtkIconView *icon_view;
2333
GdkRectangle old_area;
2334
GdkRectangle new_area;
2335
GdkRectangle common;
2336
GdkRegion *invalid_region;
2338
icon_view = GTK_ICON_VIEW (data);
2340
gdk_window_get_pointer (icon_view->priv->bin_window, &x, &y, NULL);
2345
old_area.x = MIN (icon_view->priv->rubberband_x1,
2346
icon_view->priv->rubberband_x2);
2347
old_area.y = MIN (icon_view->priv->rubberband_y1,
2348
icon_view->priv->rubberband_y2);
2349
old_area.width = ABS (icon_view->priv->rubberband_x2 -
2350
icon_view->priv->rubberband_x1) + 1;
2351
old_area.height = ABS (icon_view->priv->rubberband_y2 -
2352
icon_view->priv->rubberband_y1) + 1;
2354
new_area.x = MIN (icon_view->priv->rubberband_x1, x);
2355
new_area.y = MIN (icon_view->priv->rubberband_y1, y);
2356
new_area.width = ABS (x - icon_view->priv->rubberband_x1) + 1;
2357
new_area.height = ABS (y - icon_view->priv->rubberband_y1) + 1;
2359
invalid_region = gdk_region_rectangle (&old_area);
2360
gdk_region_union_with_rect (invalid_region, &new_area);
2362
gdk_rectangle_intersect (&old_area, &new_area, &common);
2363
if (common.width > 2 && common.height > 2)
2365
GdkRegion *common_region;
2367
/* make sure the border is invalidated */
2373
common_region = gdk_region_rectangle (&common);
2375
gdk_region_subtract (invalid_region, common_region);
2376
gdk_region_destroy (common_region);
2379
gdk_window_invalidate_region (icon_view->priv->bin_window, invalid_region, TRUE);
2381
gdk_region_destroy (invalid_region);
2383
icon_view->priv->rubberband_x2 = x;
2384
icon_view->priv->rubberband_y2 = y;
2386
gtk_icon_view_update_rubberband_selection (icon_view);
2390
gtk_icon_view_start_rubberbanding (GtkIconView *icon_view,
2396
g_assert (!icon_view->priv->doing_rubberband);
2398
for (items = icon_view->priv->items; items; items = items->next)
2400
GtkIconViewItem *item = items->data;
2402
item->selected_before_rubberbanding = item->selected;
2405
icon_view->priv->rubberband_x1 = x;
2406
icon_view->priv->rubberband_y1 = y;
2407
icon_view->priv->rubberband_x2 = x;
2408
icon_view->priv->rubberband_y2 = y;
2410
icon_view->priv->doing_rubberband = TRUE;
2412
gtk_grab_add (GTK_WIDGET (icon_view));
2416
gtk_icon_view_stop_rubberbanding (GtkIconView *icon_view)
2418
if (!icon_view->priv->doing_rubberband)
2421
icon_view->priv->doing_rubberband = FALSE;
2423
gtk_grab_remove (GTK_WIDGET (icon_view));
2425
gtk_widget_queue_draw (GTK_WIDGET (icon_view));
2429
gtk_icon_view_update_rubberband_selection (GtkIconView *icon_view)
2432
gint x, y, width, height;
2433
gboolean dirty = FALSE;
2435
x = MIN (icon_view->priv->rubberband_x1,
2436
icon_view->priv->rubberband_x2);
2437
y = MIN (icon_view->priv->rubberband_y1,
2438
icon_view->priv->rubberband_y2);
2439
width = ABS (icon_view->priv->rubberband_x1 -
2440
icon_view->priv->rubberband_x2);
2441
height = ABS (icon_view->priv->rubberband_y1 -
2442
icon_view->priv->rubberband_y2);
2444
for (items = icon_view->priv->items; items; items = items->next)
2446
GtkIconViewItem *item = items->data;
2450
is_in = gtk_icon_view_item_hit_test (icon_view, item,
2451
x, y, width, height);
2453
selected = is_in ^ item->selected_before_rubberbanding;
2455
if (item->selected != selected)
2457
item->selected = selected;
2459
gtk_icon_view_queue_draw_item (icon_view, item);
2464
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2468
gtk_icon_view_item_hit_test (GtkIconView *icon_view,
2469
GtkIconViewItem *item,
2478
if (MIN (x + width, item->x + item->width) - MAX (x, item->x) <= 0 ||
2479
MIN (y + height, item->y + item->height) - MAX (y, item->y) <= 0)
2482
for (l = icon_view->priv->cell_list; l; l = l->next)
2484
GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)l->data;
2486
if (!info->cell->visible)
2489
gtk_icon_view_get_cell_box (icon_view, item, info, &box);
2491
if (MIN (x + width, box.x + box.width) - MAX (x, box.x) > 0 &&
2492
MIN (y + height, box.y + box.height) - MAX (y, box.y) > 0)
2500
gtk_icon_view_unselect_all_internal (GtkIconView *icon_view)
2502
gboolean dirty = FALSE;
2505
if (icon_view->priv->selection_mode == GTK_SELECTION_NONE)
2508
for (items = icon_view->priv->items; items; items = items->next)
2510
GtkIconViewItem *item = items->data;
2514
item->selected = FALSE;
2516
gtk_icon_view_queue_draw_item (icon_view, item);
2517
gtk_icon_view_item_selected_changed (icon_view, item);
2525
/* GtkIconView signals */
2527
gtk_icon_view_set_adjustments (GtkIconView *icon_view,
2528
GtkAdjustment *hadj,
2529
GtkAdjustment *vadj)
2531
gboolean need_adjust = FALSE;
2534
g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
2536
hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2538
g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
2540
vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2542
if (icon_view->priv->hadjustment && (icon_view->priv->hadjustment != hadj))
2544
g_signal_handlers_disconnect_matched (icon_view->priv->hadjustment, G_SIGNAL_MATCH_DATA,
2545
0, 0, NULL, NULL, icon_view);
2546
g_object_unref (icon_view->priv->hadjustment);
2549
if (icon_view->priv->vadjustment && (icon_view->priv->vadjustment != vadj))
2551
g_signal_handlers_disconnect_matched (icon_view->priv->vadjustment, G_SIGNAL_MATCH_DATA,
2552
0, 0, NULL, NULL, icon_view);
2553
g_object_unref (icon_view->priv->vadjustment);
2556
if (icon_view->priv->hadjustment != hadj)
2558
icon_view->priv->hadjustment = hadj;
2559
g_object_ref_sink (icon_view->priv->hadjustment);
2561
g_signal_connect (icon_view->priv->hadjustment, "value-changed",
2562
G_CALLBACK (gtk_icon_view_adjustment_changed),
2567
if (icon_view->priv->vadjustment != vadj)
2569
icon_view->priv->vadjustment = vadj;
2570
g_object_ref_sink (icon_view->priv->vadjustment);
2572
g_signal_connect (icon_view->priv->vadjustment, "value-changed",
2573
G_CALLBACK (gtk_icon_view_adjustment_changed),
2579
gtk_icon_view_adjustment_changed (NULL, icon_view);
2583
gtk_icon_view_real_select_all (GtkIconView *icon_view)
2585
gtk_icon_view_select_all (icon_view);
2589
gtk_icon_view_real_unselect_all (GtkIconView *icon_view)
2591
gtk_icon_view_unselect_all (icon_view);
2595
gtk_icon_view_real_select_cursor_item (GtkIconView *icon_view)
2597
gtk_icon_view_unselect_all (icon_view);
2599
if (icon_view->priv->cursor_item != NULL)
2600
gtk_icon_view_select_item (icon_view, icon_view->priv->cursor_item);
2604
gtk_icon_view_real_activate_cursor_item (GtkIconView *icon_view)
2607
GtkCellRendererMode mode;
2608
GtkIconViewCellInfo *info = NULL;
2610
if (!icon_view->priv->cursor_item)
2613
info = g_list_nth_data (icon_view->priv->cell_list,
2614
icon_view->priv->cursor_cell);
2618
g_object_get (info->cell, "mode", &mode, NULL);
2620
if (mode == GTK_CELL_RENDERER_MODE_ACTIVATABLE)
2622
gtk_icon_view_item_activate_cell (icon_view,
2623
icon_view->priv->cursor_item,
2627
else if (mode == GTK_CELL_RENDERER_MODE_EDITABLE)
2629
gtk_icon_view_start_editing (icon_view,
2630
icon_view->priv->cursor_item,
2636
path = gtk_tree_path_new_from_indices (icon_view->priv->cursor_item->index, -1);
2637
gtk_icon_view_item_activated (icon_view, path);
2638
gtk_tree_path_free (path);
2644
gtk_icon_view_real_toggle_cursor_item (GtkIconView *icon_view)
2646
if (!icon_view->priv->cursor_item)
2649
switch (icon_view->priv->selection_mode)
2651
case GTK_SELECTION_NONE:
2653
case GTK_SELECTION_BROWSE:
2654
gtk_icon_view_select_item (icon_view, icon_view->priv->cursor_item);
2656
case GTK_SELECTION_SINGLE:
2657
if (icon_view->priv->cursor_item->selected)
2658
gtk_icon_view_unselect_item (icon_view, icon_view->priv->cursor_item);
2660
gtk_icon_view_select_item (icon_view, icon_view->priv->cursor_item);
2662
case GTK_SELECTION_MULTIPLE:
2663
icon_view->priv->cursor_item->selected = !icon_view->priv->cursor_item->selected;
2664
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
2666
gtk_icon_view_item_selected_changed (icon_view, icon_view->priv->cursor_item);
2667
gtk_icon_view_queue_draw_item (icon_view, icon_view->priv->cursor_item);
2672
/* Internal functions */
2674
gtk_icon_view_adjustment_changed (GtkAdjustment *adjustment,
2675
GtkIconView *icon_view)
2677
if (gtk_widget_get_realized (GTK_WIDGET (icon_view)))
2679
gdk_window_move (icon_view->priv->bin_window,
2680
- icon_view->priv->hadjustment->value,
2681
- icon_view->priv->vadjustment->value);
2683
if (icon_view->priv->doing_rubberband)
2684
gtk_icon_view_update_rubberband (GTK_WIDGET (icon_view));
2686
gdk_window_process_updates (icon_view->priv->bin_window, TRUE);
2691
gtk_icon_view_layout_single_row (GtkIconView *icon_view,
2696
gint *maximum_width)
2699
gint x, current_width;
2700
GList *items, *last_item;
2707
rtl = gtk_widget_get_direction (GTK_WIDGET (icon_view)) == GTK_TEXT_DIR_RTL;
2708
max_height = g_new0 (gint, icon_view->priv->n_cells);
2715
gtk_widget_style_get (GTK_WIDGET (icon_view),
2716
"focus-line-width", &focus_width,
2719
x += icon_view->priv->margin + focus_width;
2720
current_width += 2 * (icon_view->priv->margin + focus_width);
2725
GtkIconViewItem *item = items->data;
2727
gtk_icon_view_calculate_item_size (icon_view, item);
2728
colspan = 1 + (item->width - 1) / (item_width + icon_view->priv->column_spacing);
2730
item->width = colspan * item_width + (colspan - 1) * icon_view->priv->column_spacing;
2732
current_width += item->width;
2734
if (items != first_item)
2736
if ((icon_view->priv->columns <= 0 && current_width > GTK_WIDGET (icon_view)->allocation.width) ||
2737
(icon_view->priv->columns > 0 && col >= icon_view->priv->columns))
2741
current_width += icon_view->priv->column_spacing + 2 * focus_width;
2743
item->y = *y + focus_width;
2746
x = current_width - (icon_view->priv->margin + focus_width);
2748
for (i = 0; i < icon_view->priv->n_cells; i++)
2749
max_height[i] = MAX (max_height[i], item->box[i].height);
2751
if (current_width > *maximum_width)
2752
*maximum_width = current_width;
2758
items = items->next;
2763
/* Now go through the row again and align the icons */
2764
for (items = first_item; items != last_item; items = items->next)
2766
GtkIconViewItem *item = items->data;
2770
item->x = *maximum_width - item->width - item->x;
2771
item->col = col - 1 - item->col;
2774
gtk_icon_view_calculate_item_size2 (icon_view, item, max_height);
2776
/* We may want to readjust the new y coordinate. */
2777
if (item->y + item->height + focus_width + icon_view->priv->row_spacing > *y)
2778
*y = item->y + item->height + focus_width + icon_view->priv->row_spacing;
2781
g_free (max_height);
2787
gtk_icon_view_set_adjustment_upper (GtkAdjustment *adj,
2790
if (upper != adj->upper)
2792
gdouble min = MAX (0.0, upper - adj->page_size);
2793
gboolean value_changed = FALSE;
2797
if (adj->value > min)
2800
value_changed = TRUE;
2803
gtk_adjustment_changed (adj);
2806
gtk_adjustment_value_changed (adj);
2811
gtk_icon_view_layout (GtkIconView *icon_view)
2813
gint y = 0, maximum_width = 0;
2819
if (icon_view->priv->layout_idle_id != 0)
2821
g_source_remove (icon_view->priv->layout_idle_id);
2822
icon_view->priv->layout_idle_id = 0;
2825
if (icon_view->priv->model == NULL)
2828
widget = GTK_WIDGET (icon_view);
2830
item_width = icon_view->priv->item_width;
2834
for (icons = icon_view->priv->items; icons; icons = icons->next)
2836
GtkIconViewItem *item = icons->data;
2837
gtk_icon_view_calculate_item_size (icon_view, item);
2838
item_width = MAX (item_width, item->width);
2843
icons = icon_view->priv->items;
2844
y += icon_view->priv->margin;
2849
gtk_icon_view_set_cell_data (icon_view, icons->data);
2850
adjust_wrap_width (icon_view, icons->data);
2855
icons = gtk_icon_view_layout_single_row (icon_view, icons,
2857
&y, &maximum_width);
2860
while (icons != NULL);
2862
if (maximum_width != icon_view->priv->width)
2863
icon_view->priv->width = maximum_width;
2865
y += icon_view->priv->margin;
2867
if (y != icon_view->priv->height)
2868
icon_view->priv->height = y;
2870
gtk_icon_view_set_adjustment_upper (icon_view->priv->hadjustment,
2871
icon_view->priv->width);
2872
gtk_icon_view_set_adjustment_upper (icon_view->priv->vadjustment,
2873
icon_view->priv->height);
2875
if (icon_view->priv->width != widget->requisition.width ||
2876
icon_view->priv->height != widget->requisition.height)
2877
gtk_widget_queue_resize_no_redraw (widget);
2879
if (gtk_widget_get_realized (GTK_WIDGET (icon_view)))
2880
gdk_window_resize (icon_view->priv->bin_window,
2881
MAX (icon_view->priv->width, widget->allocation.width),
2882
MAX (icon_view->priv->height, widget->allocation.height));
2884
if (icon_view->priv->scroll_to_path)
2888
path = gtk_tree_row_reference_get_path (icon_view->priv->scroll_to_path);
2889
gtk_tree_row_reference_free (icon_view->priv->scroll_to_path);
2890
icon_view->priv->scroll_to_path = NULL;
2892
gtk_icon_view_scroll_to_path (icon_view, path,
2893
icon_view->priv->scroll_to_use_align,
2894
icon_view->priv->scroll_to_row_align,
2895
icon_view->priv->scroll_to_col_align);
2896
gtk_tree_path_free (path);
2899
gtk_widget_queue_draw (widget);
2903
gtk_icon_view_get_cell_area (GtkIconView *icon_view,
2904
GtkIconViewItem *item,
2905
GtkIconViewCellInfo *info,
2906
GdkRectangle *cell_area)
2908
g_return_if_fail (info->position < item->n_cells);
2910
if (icon_view->priv->item_orientation == GTK_ORIENTATION_HORIZONTAL)
2912
cell_area->x = item->box[info->position].x - item->before[info->position];
2913
cell_area->y = item->y + icon_view->priv->item_padding;
2914
cell_area->width = item->box[info->position].width +
2915
item->before[info->position] + item->after[info->position];
2916
cell_area->height = item->height - icon_view->priv->item_padding * 2;
2920
cell_area->x = item->x + icon_view->priv->item_padding;
2921
cell_area->y = item->box[info->position].y - item->before[info->position];
2922
cell_area->width = item->width - icon_view->priv->item_padding * 2;
2923
cell_area->height = item->box[info->position].height +
2924
item->before[info->position] + item->after[info->position];
2929
gtk_icon_view_get_cell_box (GtkIconView *icon_view,
2930
GtkIconViewItem *item,
2931
GtkIconViewCellInfo *info,
2934
g_return_if_fail (info->position < item->n_cells);
2936
*box = item->box[info->position];
2939
/* try to guess a reasonable wrap width for an implicit text cell renderer
2942
adjust_wrap_width (GtkIconView *icon_view,
2943
GtkIconViewItem *item)
2945
GtkIconViewCellInfo *text_info;
2946
GtkIconViewCellInfo *pixbuf_info;
2947
gint pixbuf_width, wrap_width;
2949
if (icon_view->priv->text_cell != -1 &&
2950
icon_view->priv->pixbuf_cell != -1)
2954
text_info = g_list_nth_data (icon_view->priv->cell_list,
2955
icon_view->priv->text_cell);
2956
pixbuf_info = g_list_nth_data (icon_view->priv->cell_list,
2957
icon_view->priv->pixbuf_cell);
2959
gtk_cell_renderer_get_size (pixbuf_info->cell,
2960
GTK_WIDGET (icon_view),
2966
if (icon_view->priv->item_width > 0)
2967
item_width = icon_view->priv->item_width;
2969
item_width = item->width;
2971
if (icon_view->priv->item_orientation == GTK_ORIENTATION_VERTICAL)
2972
wrap_width = item_width;
2974
if (item->width == -1 && item_width <= 0)
2975
wrap_width = MAX (2 * pixbuf_width, 50);
2977
wrap_width = item_width - pixbuf_width - icon_view->priv->spacing;
2980
wrap_width -= icon_view->priv->item_padding * 2;
2982
g_object_set (text_info->cell, "wrap-width", wrap_width, NULL);
2983
g_object_set (text_info->cell, "width", wrap_width, NULL);
2988
gtk_icon_view_calculate_item_size (GtkIconView *icon_view,
2989
GtkIconViewItem *item)
2994
if (item->width != -1 && item->height != -1)
2997
if (item->n_cells != icon_view->priv->n_cells)
2999
g_free (item->before);
3000
g_free (item->after);
3003
item->before = g_new0 (gint, icon_view->priv->n_cells);
3004
item->after = g_new0 (gint, icon_view->priv->n_cells);
3005
item->box = g_new0 (GdkRectangle, icon_view->priv->n_cells);
3007
item->n_cells = icon_view->priv->n_cells;
3010
gtk_icon_view_set_cell_data (icon_view, item);
3012
spacing = icon_view->priv->spacing;
3016
for (l = icon_view->priv->cell_list; l; l = l->next)
3018
GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)l->data;
3020
if (!info->cell->visible)
3023
gtk_cell_renderer_get_size (info->cell, GTK_WIDGET (icon_view),
3025
&item->box[info->position].width,
3026
&item->box[info->position].height);
3028
if (icon_view->priv->item_orientation == GTK_ORIENTATION_HORIZONTAL)
3030
item->width += item->box[info->position].width
3031
+ (info->position > 0 ? spacing : 0);
3032
item->height = MAX (item->height, item->box[info->position].height);
3036
item->width = MAX (item->width, item->box[info->position].width);
3037
item->height += item->box[info->position].height + (info->position > 0 ? spacing : 0);
3041
item->width += icon_view->priv->item_padding * 2;
3042
item->height += icon_view->priv->item_padding * 2;
3046
gtk_icon_view_calculate_item_size2 (GtkIconView *icon_view,
3047
GtkIconViewItem *item,
3050
GdkRectangle cell_area;
3056
rtl = gtk_widget_get_direction (GTK_WIDGET (icon_view)) == GTK_TEXT_DIR_RTL;
3058
gtk_icon_view_set_cell_data (icon_view, item);
3060
spacing = icon_view->priv->spacing;
3063
for (i = 0; i < icon_view->priv->n_cells; i++)
3065
if (icon_view->priv->item_orientation == GTK_ORIENTATION_HORIZONTAL)
3066
item->height = MAX (item->height, max_height[i]);
3068
item->height += max_height[i] + (i > 0 ? spacing : 0);
3071
cell_area.x = item->x + icon_view->priv->item_padding;
3072
cell_area.y = item->y + icon_view->priv->item_padding;
3074
for (k = 0; k < 2; k++)
3075
for (l = icon_view->priv->cell_list, i = 0; l; l = l->next, i++)
3077
GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)l->data;
3079
if (info->pack == (k ? GTK_PACK_START : GTK_PACK_END))
3082
if (!info->cell->visible)
3085
if (icon_view->priv->item_orientation == GTK_ORIENTATION_HORIZONTAL)
3087
/* We should not subtract icon_view->priv->item_padding from item->height,
3088
* because item->height is recalculated above using
3089
* max_height which does not contain item padding.
3091
cell_area.width = item->box[info->position].width;
3092
cell_area.height = item->height;
3096
/* item->width is not recalculated and thus needs to be
3097
* corrected for the padding.
3099
cell_area.width = item->width - 2 * icon_view->priv->item_padding;
3100
cell_area.height = max_height[i];
3103
gtk_cell_renderer_get_size (info->cell, GTK_WIDGET (icon_view),
3105
&item->box[info->position].x, &item->box[info->position].y,
3106
&item->box[info->position].width, &item->box[info->position].height);
3108
item->box[info->position].x += cell_area.x;
3109
item->box[info->position].y += cell_area.y;
3110
if (icon_view->priv->item_orientation == GTK_ORIENTATION_HORIZONTAL)
3112
item->before[info->position] = item->box[info->position].x - cell_area.x;
3113
item->after[info->position] = cell_area.width - item->box[info->position].width - item->before[info->position];
3114
cell_area.x += cell_area.width + spacing;
3118
if (item->box[info->position].width > item->width - icon_view->priv->item_padding * 2)
3120
item->width = item->box[info->position].width + icon_view->priv->item_padding * 2;
3121
cell_area.width = item->width;
3123
item->before[info->position] = item->box[info->position].y - cell_area.y;
3124
item->after[info->position] = cell_area.height - item->box[info->position].height - item->before[info->position];
3125
cell_area.y += cell_area.height + spacing;
3129
if (rtl && icon_view->priv->item_orientation == GTK_ORIENTATION_HORIZONTAL)
3131
for (i = 0; i < icon_view->priv->n_cells; i++)
3133
item->box[i].x = item->x + item->width -
3134
(item->box[i].x + item->box[i].width - item->x);
3138
item->height += icon_view->priv->item_padding * 2;
3142
gtk_icon_view_invalidate_sizes (GtkIconView *icon_view)
3144
g_list_foreach (icon_view->priv->items,
3145
(GFunc)gtk_icon_view_item_invalidate_size, NULL);
3149
gtk_icon_view_item_invalidate_size (GtkIconViewItem *item)
3156
gtk_icon_view_paint_item (GtkIconView *icon_view,
3158
GtkIconViewItem *item,
3160
GdkDrawable *drawable,
3163
gboolean draw_focus)
3167
GdkRectangle cell_area, box;
3171
GtkCellRendererState flags;
3173
if (icon_view->priv->model == NULL)
3176
gtk_icon_view_set_cell_data (icon_view, item);
3178
gtk_widget_style_get (GTK_WIDGET (icon_view),
3179
"focus-line-width", &focus_width,
3182
padding = focus_width;
3186
flags = GTK_CELL_RENDERER_SELECTED;
3187
if (gtk_widget_has_focus (GTK_WIDGET (icon_view)))
3188
state = GTK_STATE_SELECTED;
3190
state = GTK_STATE_ACTIVE;
3195
state = GTK_STATE_NORMAL;
3198
#ifdef DEBUG_ICON_VIEW
3199
gdk_draw_rectangle (drawable,
3200
GTK_WIDGET (icon_view)->style->black_gc,
3203
item->width, item->height);
3208
gtk_paint_flat_box (GTK_WIDGET (icon_view)->style,
3209
(GdkWindow *) drawable,
3213
GTK_WIDGET (icon_view),
3216
item->width, item->height);
3219
for (l = icon_view->priv->cell_list; l; l = l->next)
3221
GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)l->data;
3223
if (!info->cell->visible)
3226
gtk_icon_view_get_cell_area (icon_view, item, info, &cell_area);
3228
#ifdef DEBUG_ICON_VIEW
3229
gdk_draw_rectangle (drawable,
3230
GTK_WIDGET (icon_view)->style->black_gc,
3232
x - item->x + cell_area.x,
3233
y - item->y + cell_area.y,
3234
cell_area.width, cell_area.height);
3236
gtk_icon_view_get_cell_box (icon_view, item, info, &box);
3238
gdk_draw_rectangle (drawable,
3239
GTK_WIDGET (icon_view)->style->black_gc,
3241
x - item->x + box.x,
3242
y - item->y + box.y,
3243
box.width, box.height);
3246
cell_area.x = x - item->x + cell_area.x;
3247
cell_area.y = y - item->y + cell_area.y;
3249
gtk_cell_renderer_render (info->cell,
3251
GTK_WIDGET (icon_view),
3252
&cell_area, &cell_area, area, flags);
3256
gtk_widget_has_focus (GTK_WIDGET (icon_view)) &&
3257
item == icon_view->priv->cursor_item)
3259
for (l = icon_view->priv->cell_list, i = 0; l; l = l->next, i++)
3261
GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)l->data;
3263
if (!info->cell->visible)
3266
/* If found a editable/activatable cell, draw focus on it. */
3267
if (icon_view->priv->cursor_cell < 0 &&
3268
info->cell->mode != GTK_CELL_RENDERER_MODE_INERT)
3269
icon_view->priv->cursor_cell = i;
3271
gtk_icon_view_get_cell_box (icon_view, item, info, &box);
3273
if (i == icon_view->priv->cursor_cell)
3275
gtk_paint_focus (GTK_WIDGET (icon_view)->style,
3279
GTK_WIDGET (icon_view),
3281
x - item->x + box.x - padding,
3282
y - item->y + box.y - padding,
3283
box.width + 2 * padding,
3284
box.height + 2 * padding);
3289
/* If there are no editable/activatable cells, draw focus
3290
* around the whole item.
3292
if (icon_view->priv->cursor_cell < 0)
3293
gtk_paint_focus (GTK_WIDGET (icon_view)->style,
3297
GTK_WIDGET (icon_view),
3301
item->width + 2 * padding,
3302
item->height + 2 * padding);
3307
gtk_icon_view_paint_rubberband (GtkIconView *icon_view,
3312
GdkRectangle rubber_rect;
3313
GdkColor *fill_color_gdk;
3314
guchar fill_color_alpha;
3316
rubber_rect.x = MIN (icon_view->priv->rubberband_x1, icon_view->priv->rubberband_x2);
3317
rubber_rect.y = MIN (icon_view->priv->rubberband_y1, icon_view->priv->rubberband_y2);
3318
rubber_rect.width = ABS (icon_view->priv->rubberband_x1 - icon_view->priv->rubberband_x2) + 1;
3319
rubber_rect.height = ABS (icon_view->priv->rubberband_y1 - icon_view->priv->rubberband_y2) + 1;
3321
if (!gdk_rectangle_intersect (&rubber_rect, area, &rect))
3324
gtk_widget_style_get (GTK_WIDGET (icon_view),
3325
"selection-box-color", &fill_color_gdk,
3326
"selection-box-alpha", &fill_color_alpha,
3329
if (!fill_color_gdk)
3330
fill_color_gdk = gdk_color_copy (>K_WIDGET (icon_view)->style->base[GTK_STATE_SELECTED]);
3332
cairo_set_source_rgba (cr,
3333
fill_color_gdk->red / 65535.,
3334
fill_color_gdk->green / 65535.,
3335
fill_color_gdk->blue / 65535.,
3336
fill_color_alpha / 255.);
3339
gdk_cairo_rectangle (cr, &rect);
3343
/* Draw the border without alpha */
3344
cairo_set_source_rgb (cr,
3345
fill_color_gdk->red / 65535.,
3346
fill_color_gdk->green / 65535.,
3347
fill_color_gdk->blue / 65535.);
3348
cairo_rectangle (cr,
3349
rubber_rect.x + 0.5, rubber_rect.y + 0.5,
3350
rubber_rect.width - 1, rubber_rect.height - 1);
3354
gdk_color_free (fill_color_gdk);
3358
gtk_icon_view_queue_draw_path (GtkIconView *icon_view,
3364
index = gtk_tree_path_get_indices (path)[0];
3366
for (l = icon_view->priv->items; l; l = l->next)
3368
GtkIconViewItem *item = l->data;
3370
if (item->index == index)
3372
gtk_icon_view_queue_draw_item (icon_view, item);
3379
gtk_icon_view_queue_draw_item (GtkIconView *icon_view,
3380
GtkIconViewItem *item)
3385
gtk_widget_style_get (GTK_WIDGET (icon_view),
3386
"focus-line-width", &focus_width,
3389
rect.x = item->x - focus_width;
3390
rect.y = item->y - focus_width;
3391
rect.width = item->width + 2 * focus_width;
3392
rect.height = item->height + 2 * focus_width;
3394
if (icon_view->priv->bin_window)
3395
gdk_window_invalidate_rect (icon_view->priv->bin_window, &rect, TRUE);
3399
layout_callback (gpointer user_data)
3401
GtkIconView *icon_view;
3403
icon_view = GTK_ICON_VIEW (user_data);
3405
icon_view->priv->layout_idle_id = 0;
3407
gtk_icon_view_layout (icon_view);
3413
gtk_icon_view_queue_layout (GtkIconView *icon_view)
3415
if (icon_view->priv->layout_idle_id != 0)
3418
icon_view->priv->layout_idle_id = gdk_threads_add_idle (layout_callback, icon_view);
3422
gtk_icon_view_set_cursor_item (GtkIconView *icon_view,
3423
GtkIconViewItem *item,
3427
AtkObject *item_obj;
3428
AtkObject *cursor_item_obj;
3430
if (icon_view->priv->cursor_item == item &&
3431
(cursor_cell < 0 || cursor_cell == icon_view->priv->cursor_cell))
3434
obj = gtk_widget_get_accessible (GTK_WIDGET (icon_view));
3435
if (icon_view->priv->cursor_item != NULL)
3437
gtk_icon_view_queue_draw_item (icon_view, icon_view->priv->cursor_item);
3440
cursor_item_obj = atk_object_ref_accessible_child (obj, icon_view->priv->cursor_item->index);
3441
if (cursor_item_obj != NULL)
3442
atk_object_notify_state_change (cursor_item_obj, ATK_STATE_FOCUSED, FALSE);
3445
icon_view->priv->cursor_item = item;
3446
if (cursor_cell >= 0)
3447
icon_view->priv->cursor_cell = cursor_cell;
3449
gtk_icon_view_queue_draw_item (icon_view, item);
3451
/* Notify that accessible focus object has changed */
3452
item_obj = atk_object_ref_accessible_child (obj, item->index);
3454
if (item_obj != NULL)
3456
atk_focus_tracker_notify (item_obj);
3457
atk_object_notify_state_change (item_obj, ATK_STATE_FOCUSED, TRUE);
3458
g_object_unref (item_obj);
3463
static GtkIconViewItem *
3464
gtk_icon_view_item_new (void)
3466
GtkIconViewItem *item;
3468
item = g_new0 (GtkIconViewItem, 1);
3477
gtk_icon_view_item_free (GtkIconViewItem *item)
3479
g_return_if_fail (item != NULL);
3481
g_free (item->before);
3482
g_free (item->after);
3489
static GtkIconViewItem *
3490
gtk_icon_view_get_item_at_coords (GtkIconView *icon_view,
3493
gboolean only_in_cell,
3494
GtkIconViewCellInfo **cell_at_pos)
3500
*cell_at_pos = NULL;
3502
for (items = icon_view->priv->items; items; items = items->next)
3504
GtkIconViewItem *item = items->data;
3506
if (x >= item->x - icon_view->priv->column_spacing/2 && x <= item->x + item->width + icon_view->priv->column_spacing/2 &&
3507
y >= item->y - icon_view->priv->row_spacing/2 && y <= item->y + item->height + icon_view->priv->row_spacing/2)
3509
if (only_in_cell || cell_at_pos)
3511
gtk_icon_view_set_cell_data (icon_view, item);
3513
for (l = icon_view->priv->cell_list; l; l = l->next)
3515
GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)l->data;
3517
if (!info->cell->visible)
3520
gtk_icon_view_get_cell_box (icon_view, item, info, &box);
3522
if ((x >= box.x && x <= box.x + box.width &&
3523
y >= box.y && y <= box.y + box.height) ||
3525
x <= box.x + box.width &&
3527
y <= box.y + box.height))
3530
*cell_at_pos = info;
3548
gtk_icon_view_select_item (GtkIconView *icon_view,
3549
GtkIconViewItem *item)
3551
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3552
g_return_if_fail (item != NULL);
3557
if (icon_view->priv->selection_mode == GTK_SELECTION_NONE)
3559
else if (icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
3560
gtk_icon_view_unselect_all_internal (icon_view);
3562
item->selected = TRUE;
3564
gtk_icon_view_item_selected_changed (icon_view, item);
3565
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
3567
gtk_icon_view_queue_draw_item (icon_view, item);
3572
gtk_icon_view_unselect_item (GtkIconView *icon_view,
3573
GtkIconViewItem *item)
3575
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
3576
g_return_if_fail (item != NULL);
3578
if (!item->selected)
3581
if (icon_view->priv->selection_mode == GTK_SELECTION_NONE ||
3582
icon_view->priv->selection_mode == GTK_SELECTION_BROWSE)
3585
item->selected = FALSE;
3587
gtk_icon_view_item_selected_changed (icon_view, item);
3588
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
3590
gtk_icon_view_queue_draw_item (icon_view, item);
3594
verify_items (GtkIconView *icon_view)
3599
for (items = icon_view->priv->items; items; items = items->next)
3601
GtkIconViewItem *item = items->data;
3603
if (item->index != i)
3604
g_error ("List item does not match its index: "
3605
"item index %d and list index %d\n", item->index, i);
3612
gtk_icon_view_row_changed (GtkTreeModel *model,
3617
GtkIconViewItem *item;
3619
GtkIconView *icon_view;
3621
icon_view = GTK_ICON_VIEW (data);
3623
gtk_icon_view_stop_editing (icon_view, TRUE);
3625
index = gtk_tree_path_get_indices(path)[0];
3626
item = g_list_nth_data (icon_view->priv->items, index);
3628
gtk_icon_view_item_invalidate_size (item);
3629
gtk_icon_view_queue_layout (icon_view);
3631
verify_items (icon_view);
3635
gtk_icon_view_row_inserted (GtkTreeModel *model,
3641
GtkIconViewItem *item;
3642
gboolean iters_persist;
3643
GtkIconView *icon_view;
3646
icon_view = GTK_ICON_VIEW (data);
3648
iters_persist = gtk_tree_model_get_flags (icon_view->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST;
3650
index = gtk_tree_path_get_indices(path)[0];
3652
item = gtk_icon_view_item_new ();
3657
item->index = index;
3659
/* FIXME: We can be more efficient here,
3660
we can store a tail pointer and use that when
3661
appending (which is a rather common operation)
3663
icon_view->priv->items = g_list_insert (icon_view->priv->items,
3666
list = g_list_nth (icon_view->priv->items, index + 1);
3667
for (; list; list = list->next)
3674
verify_items (icon_view);
3676
gtk_icon_view_queue_layout (icon_view);
3680
gtk_icon_view_row_deleted (GtkTreeModel *model,
3685
GtkIconView *icon_view;
3686
GtkIconViewItem *item;
3688
gboolean emit = FALSE;
3690
icon_view = GTK_ICON_VIEW (data);
3692
index = gtk_tree_path_get_indices(path)[0];
3694
list = g_list_nth (icon_view->priv->items, index);
3697
gtk_icon_view_stop_editing (icon_view, TRUE);
3699
if (item == icon_view->priv->anchor_item)
3700
icon_view->priv->anchor_item = NULL;
3702
if (item == icon_view->priv->cursor_item)
3703
icon_view->priv->cursor_item = NULL;
3708
gtk_icon_view_item_free (item);
3710
for (next = list->next; next; next = next->next)
3717
icon_view->priv->items = g_list_delete_link (icon_view->priv->items, list);
3719
verify_items (icon_view);
3721
gtk_icon_view_queue_layout (icon_view);
3724
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
3728
gtk_icon_view_rows_reordered (GtkTreeModel *model,
3729
GtkTreePath *parent,
3736
GtkIconView *icon_view;
3737
GList *items = NULL, *list;
3738
GtkIconViewItem **item_array;
3741
icon_view = GTK_ICON_VIEW (data);
3743
gtk_icon_view_stop_editing (icon_view, TRUE);
3745
length = gtk_tree_model_iter_n_children (model, NULL);
3747
order = g_new (gint, length);
3748
for (i = 0; i < length; i++)
3749
order [new_order[i]] = i;
3751
item_array = g_new (GtkIconViewItem *, length);
3752
for (i = 0, list = icon_view->priv->items; list != NULL; list = list->next, i++)
3753
item_array[order[i]] = list->data;
3756
for (i = length - 1; i >= 0; i--)
3758
item_array[i]->index = i;
3759
items = g_list_prepend (items, item_array[i]);
3762
g_free (item_array);
3763
g_list_free (icon_view->priv->items);
3764
icon_view->priv->items = items;
3766
gtk_icon_view_queue_layout (icon_view);
3768
verify_items (icon_view);
3772
gtk_icon_view_build_items (GtkIconView *icon_view)
3776
gboolean iters_persist;
3777
GList *items = NULL;
3779
iters_persist = gtk_tree_model_get_flags (icon_view->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST;
3781
if (!gtk_tree_model_get_iter_first (icon_view->priv->model,
3789
GtkIconViewItem *item = gtk_icon_view_item_new ();
3798
items = g_list_prepend (items, item);
3800
} while (gtk_tree_model_iter_next (icon_view->priv->model, &iter));
3802
icon_view->priv->items = g_list_reverse (items);
3806
gtk_icon_view_add_move_binding (GtkBindingSet *binding_set,
3809
GtkMovementStep step,
3813
gtk_binding_entry_add_signal (binding_set, keyval, modmask,
3814
I_("move-cursor"), 2,
3818
gtk_binding_entry_add_signal (binding_set, keyval, GDK_SHIFT_MASK,
3823
if ((modmask & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
3826
gtk_binding_entry_add_signal (binding_set, keyval, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
3831
gtk_binding_entry_add_signal (binding_set, keyval, GDK_CONTROL_MASK,
3838
gtk_icon_view_real_move_cursor (GtkIconView *icon_view,
3839
GtkMovementStep step,
3842
GdkModifierType state;
3844
g_return_val_if_fail (GTK_ICON_VIEW (icon_view), FALSE);
3845
g_return_val_if_fail (step == GTK_MOVEMENT_LOGICAL_POSITIONS ||
3846
step == GTK_MOVEMENT_VISUAL_POSITIONS ||
3847
step == GTK_MOVEMENT_DISPLAY_LINES ||
3848
step == GTK_MOVEMENT_PAGES ||
3849
step == GTK_MOVEMENT_BUFFER_ENDS, FALSE);
3851
if (!gtk_widget_has_focus (GTK_WIDGET (icon_view)))
3854
gtk_icon_view_stop_editing (icon_view, FALSE);
3855
gtk_widget_grab_focus (GTK_WIDGET (icon_view));
3857
if (gtk_get_current_event_state (&state))
3859
if ((state & GTK_MODIFY_SELECTION_MOD_MASK) == GTK_MODIFY_SELECTION_MOD_MASK)
3860
icon_view->priv->modify_selection_pressed = TRUE;
3861
if ((state & GTK_EXTEND_SELECTION_MOD_MASK) == GTK_EXTEND_SELECTION_MOD_MASK)
3862
icon_view->priv->extend_selection_pressed = TRUE;
3864
/* else we assume not pressed */
3868
case GTK_MOVEMENT_LOGICAL_POSITIONS:
3869
case GTK_MOVEMENT_VISUAL_POSITIONS:
3870
gtk_icon_view_move_cursor_left_right (icon_view, count);
3872
case GTK_MOVEMENT_DISPLAY_LINES:
3873
gtk_icon_view_move_cursor_up_down (icon_view, count);
3875
case GTK_MOVEMENT_PAGES:
3876
gtk_icon_view_move_cursor_page_up_down (icon_view, count);
3878
case GTK_MOVEMENT_BUFFER_ENDS:
3879
gtk_icon_view_move_cursor_start_end (icon_view, count);
3882
g_assert_not_reached ();
3885
icon_view->priv->modify_selection_pressed = FALSE;
3886
icon_view->priv->extend_selection_pressed = FALSE;
3888
icon_view->priv->draw_focus = TRUE;
3893
static GtkIconViewItem *
3894
find_item (GtkIconView *icon_view,
3895
GtkIconViewItem *current,
3901
GtkIconViewItem *item;
3903
/* FIXME: this could be more efficient
3905
row = current->row + row_ofs;
3906
col = current->col + col_ofs;
3908
for (items = icon_view->priv->items; items; items = items->next)
3911
if (item->row == row && item->col == col)
3919
find_cell (GtkIconView *icon_view,
3920
GtkIconViewItem *item,
3922
GtkOrientation orientation,
3932
if (icon_view->priv->item_orientation != orientation)
3935
gtk_icon_view_set_cell_data (icon_view, item);
3937
focusable = g_new0 (gint, icon_view->priv->n_cells);
3941
for (k = 0; k < 2; k++)
3942
for (l = icon_view->priv->cell_list, i = 0; l; l = l->next, i++)
3944
GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)l->data;
3946
if (info->pack == (k ? GTK_PACK_START : GTK_PACK_END))
3949
if (!info->cell->visible)
3952
if (info->cell->mode != GTK_CELL_RENDERER_MODE_INERT)
3955
current = n_focusable;
3957
focusable[n_focusable] = i;
3963
if (n_focusable == 0)
3971
current = step > 0 ? 0 : n_focusable - 1;
3972
cell = focusable[current];
3975
if (current + *count < 0)
3978
*count = current + *count;
3980
else if (current + *count > n_focusable - 1)
3983
*count = current + *count - (n_focusable - 1);
3987
cell = focusable[current + *count];
3996
static GtkIconViewItem *
3997
find_item_page_up_down (GtkIconView *icon_view,
3998
GtkIconViewItem *current,
4005
y = current->y + count * icon_view->priv->vadjustment->page_size;
4007
item = g_list_find (icon_view->priv->items, current);
4012
for (next = item->next; next; next = next->next)
4014
if (((GtkIconViewItem *)next->data)->col == col)
4017
if (!next || ((GtkIconViewItem *)next->data)->y > y)
4027
for (next = item->prev; next; next = next->prev)
4029
if (((GtkIconViewItem *)next->data)->col == col)
4032
if (!next || ((GtkIconViewItem *)next->data)->y < y)
4046
gtk_icon_view_select_all_between (GtkIconView *icon_view,
4047
GtkIconViewItem *anchor,
4048
GtkIconViewItem *cursor)
4051
GtkIconViewItem *item;
4052
gint row1, row2, col1, col2;
4053
gboolean dirty = FALSE;
4055
if (anchor->row < cursor->row)
4066
if (anchor->col < cursor->col)
4077
for (items = icon_view->priv->items; items; items = items->next)
4081
if (row1 <= item->row && item->row <= row2 &&
4082
col1 <= item->col && item->col <= col2)
4084
if (!item->selected)
4087
item->selected = TRUE;
4088
gtk_icon_view_item_selected_changed (icon_view, item);
4090
gtk_icon_view_queue_draw_item (icon_view, item);
4098
gtk_icon_view_move_cursor_up_down (GtkIconView *icon_view,
4101
GtkIconViewItem *item;
4103
gboolean dirty = FALSE;
4105
GtkDirectionType direction;
4107
if (!gtk_widget_has_focus (GTK_WIDGET (icon_view)))
4110
direction = count < 0 ? GTK_DIR_UP : GTK_DIR_DOWN;
4112
if (!icon_view->priv->cursor_item)
4117
list = icon_view->priv->items;
4119
list = g_list_last (icon_view->priv->items);
4121
item = list ? list->data : NULL;
4126
item = icon_view->priv->cursor_item;
4127
cell = icon_view->priv->cursor_cell;
4128
step = count > 0 ? 1 : -1;
4131
cell = find_cell (icon_view, item, cell,
4132
GTK_ORIENTATION_VERTICAL,
4137
item = find_item (icon_view, item, step, 0);
4138
count = count - step;
4144
if (!gtk_widget_keynav_failed (GTK_WIDGET (icon_view), direction))
4146
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (icon_view));
4148
gtk_widget_child_focus (toplevel,
4149
direction == GTK_DIR_UP ?
4150
GTK_DIR_TAB_BACKWARD :
4151
GTK_DIR_TAB_FORWARD);
4157
if (icon_view->priv->modify_selection_pressed ||
4158
!icon_view->priv->extend_selection_pressed ||
4159
!icon_view->priv->anchor_item ||
4160
icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
4161
icon_view->priv->anchor_item = item;
4163
gtk_icon_view_set_cursor_item (icon_view, item, cell);
4165
if (!icon_view->priv->modify_selection_pressed &&
4166
icon_view->priv->selection_mode != GTK_SELECTION_NONE)
4168
dirty = gtk_icon_view_unselect_all_internal (icon_view);
4169
dirty = gtk_icon_view_select_all_between (icon_view,
4170
icon_view->priv->anchor_item,
4174
gtk_icon_view_scroll_to_item (icon_view, item);
4177
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
4181
gtk_icon_view_move_cursor_page_up_down (GtkIconView *icon_view,
4184
GtkIconViewItem *item;
4185
gboolean dirty = FALSE;
4187
if (!gtk_widget_has_focus (GTK_WIDGET (icon_view)))
4190
if (!icon_view->priv->cursor_item)
4195
list = icon_view->priv->items;
4197
list = g_list_last (icon_view->priv->items);
4199
item = list ? list->data : NULL;
4202
item = find_item_page_up_down (icon_view,
4203
icon_view->priv->cursor_item,
4206
if (item == icon_view->priv->cursor_item)
4207
gtk_widget_error_bell (GTK_WIDGET (icon_view));
4212
if (icon_view->priv->modify_selection_pressed ||
4213
!icon_view->priv->extend_selection_pressed ||
4214
!icon_view->priv->anchor_item ||
4215
icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
4216
icon_view->priv->anchor_item = item;
4218
gtk_icon_view_set_cursor_item (icon_view, item, -1);
4220
if (!icon_view->priv->modify_selection_pressed &&
4221
icon_view->priv->selection_mode != GTK_SELECTION_NONE)
4223
dirty = gtk_icon_view_unselect_all_internal (icon_view);
4224
dirty = gtk_icon_view_select_all_between (icon_view,
4225
icon_view->priv->anchor_item,
4229
gtk_icon_view_scroll_to_item (icon_view, item);
4232
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
4236
gtk_icon_view_move_cursor_left_right (GtkIconView *icon_view,
4239
GtkIconViewItem *item;
4241
gboolean dirty = FALSE;
4243
GtkDirectionType direction;
4245
if (!gtk_widget_has_focus (GTK_WIDGET (icon_view)))
4248
direction = count < 0 ? GTK_DIR_LEFT : GTK_DIR_RIGHT;
4250
if (!icon_view->priv->cursor_item)
4255
list = icon_view->priv->items;
4257
list = g_list_last (icon_view->priv->items);
4259
item = list ? list->data : NULL;
4263
item = icon_view->priv->cursor_item;
4264
cell = icon_view->priv->cursor_cell;
4265
step = count > 0 ? 1 : -1;
4268
cell = find_cell (icon_view, item, cell,
4269
GTK_ORIENTATION_HORIZONTAL,
4274
item = find_item (icon_view, item, 0, step);
4275
count = count - step;
4281
if (!gtk_widget_keynav_failed (GTK_WIDGET (icon_view), direction))
4283
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (icon_view));
4285
gtk_widget_child_focus (toplevel,
4286
direction == GTK_DIR_LEFT ?
4287
GTK_DIR_TAB_BACKWARD :
4288
GTK_DIR_TAB_FORWARD);
4294
if (icon_view->priv->modify_selection_pressed ||
4295
!icon_view->priv->extend_selection_pressed ||
4296
!icon_view->priv->anchor_item ||
4297
icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
4298
icon_view->priv->anchor_item = item;
4300
gtk_icon_view_set_cursor_item (icon_view, item, cell);
4302
if (!icon_view->priv->modify_selection_pressed &&
4303
icon_view->priv->selection_mode != GTK_SELECTION_NONE)
4305
dirty = gtk_icon_view_unselect_all_internal (icon_view);
4306
dirty = gtk_icon_view_select_all_between (icon_view,
4307
icon_view->priv->anchor_item,
4311
gtk_icon_view_scroll_to_item (icon_view, item);
4314
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
4318
gtk_icon_view_move_cursor_start_end (GtkIconView *icon_view,
4321
GtkIconViewItem *item;
4323
gboolean dirty = FALSE;
4325
if (!gtk_widget_has_focus (GTK_WIDGET (icon_view)))
4329
list = icon_view->priv->items;
4331
list = g_list_last (icon_view->priv->items);
4333
item = list ? list->data : NULL;
4335
if (item == icon_view->priv->cursor_item)
4336
gtk_widget_error_bell (GTK_WIDGET (icon_view));
4341
if (icon_view->priv->modify_selection_pressed ||
4342
!icon_view->priv->extend_selection_pressed ||
4343
!icon_view->priv->anchor_item ||
4344
icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
4345
icon_view->priv->anchor_item = item;
4347
gtk_icon_view_set_cursor_item (icon_view, item, -1);
4349
if (!icon_view->priv->modify_selection_pressed &&
4350
icon_view->priv->selection_mode != GTK_SELECTION_NONE)
4352
dirty = gtk_icon_view_unselect_all_internal (icon_view);
4353
dirty = gtk_icon_view_select_all_between (icon_view,
4354
icon_view->priv->anchor_item,
4358
gtk_icon_view_scroll_to_item (icon_view, item);
4361
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
4365
* gtk_icon_view_scroll_to_path:
4366
* @icon_view: A #GtkIconView.
4367
* @path: The path of the item to move to.
4368
* @use_align: whether to use alignment arguments, or %FALSE.
4369
* @row_align: The vertical alignment of the item specified by @path.
4370
* @col_align: The horizontal alignment of the item specified by @path.
4372
* Moves the alignments of @icon_view to the position specified by @path.
4373
* @row_align determines where the row is placed, and @col_align determines
4374
* where @column is placed. Both are expected to be between 0.0 and 1.0.
4375
* 0.0 means left/top alignment, 1.0 means right/bottom alignment, 0.5 means
4378
* If @use_align is %FALSE, then the alignment arguments are ignored, and the
4379
* tree does the minimum amount of work to scroll the item onto the screen.
4380
* This means that the item will be scrolled to the edge closest to its current
4381
* position. If the item is currently visible on the screen, nothing is done.
4383
* This function only works if the model is set, and @path is a valid row on
4384
* the model. If the model changes before the @icon_view is realized, the
4385
* centered path will be modified to reflect this change.
4390
gtk_icon_view_scroll_to_path (GtkIconView *icon_view,
4396
GtkIconViewItem *item = NULL;
4398
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
4399
g_return_if_fail (path != NULL);
4400
g_return_if_fail (row_align >= 0.0 && row_align <= 1.0);
4401
g_return_if_fail (col_align >= 0.0 && col_align <= 1.0);
4403
if (gtk_tree_path_get_depth (path) > 0)
4404
item = g_list_nth_data (icon_view->priv->items,
4405
gtk_tree_path_get_indices(path)[0]);
4407
if (!item || item->width < 0 ||
4408
!gtk_widget_get_realized (GTK_WIDGET (icon_view)))
4410
if (icon_view->priv->scroll_to_path)
4411
gtk_tree_row_reference_free (icon_view->priv->scroll_to_path);
4413
icon_view->priv->scroll_to_path = NULL;
4416
icon_view->priv->scroll_to_path = gtk_tree_row_reference_new_proxy (G_OBJECT (icon_view), icon_view->priv->model, path);
4418
icon_view->priv->scroll_to_use_align = use_align;
4419
icon_view->priv->scroll_to_row_align = row_align;
4420
icon_view->priv->scroll_to_col_align = col_align;
4429
gfloat offset, value;
4431
gtk_widget_style_get (GTK_WIDGET (icon_view),
4432
"focus-line-width", &focus_width,
4435
gdk_window_get_position (icon_view->priv->bin_window, &x, &y);
4437
offset = y + item->y - focus_width -
4438
row_align * (GTK_WIDGET (icon_view)->allocation.height - item->height);
4439
value = CLAMP (icon_view->priv->vadjustment->value + offset,
4440
icon_view->priv->vadjustment->lower,
4441
icon_view->priv->vadjustment->upper - icon_view->priv->vadjustment->page_size);
4442
gtk_adjustment_set_value (icon_view->priv->vadjustment, value);
4444
offset = x + item->x - focus_width -
4445
col_align * (GTK_WIDGET (icon_view)->allocation.width - item->width);
4446
value = CLAMP (icon_view->priv->hadjustment->value + offset,
4447
icon_view->priv->hadjustment->lower,
4448
icon_view->priv->hadjustment->upper - icon_view->priv->hadjustment->page_size);
4449
gtk_adjustment_set_value (icon_view->priv->hadjustment, value);
4451
gtk_adjustment_changed (icon_view->priv->hadjustment);
4452
gtk_adjustment_changed (icon_view->priv->vadjustment);
4455
gtk_icon_view_scroll_to_item (icon_view, item);
4460
gtk_icon_view_scroll_to_item (GtkIconView *icon_view,
4461
GtkIconViewItem *item)
4463
gint x, y, width, height;
4466
gtk_widget_style_get (GTK_WIDGET (icon_view),
4467
"focus-line-width", &focus_width,
4470
width = gdk_window_get_width (icon_view->priv->bin_window);
4471
height = gdk_window_get_height (icon_view->priv->bin_window);
4472
gdk_window_get_position (icon_view->priv->bin_window, &x, &y);
4474
if (y + item->y - focus_width < 0)
4475
gtk_adjustment_set_value (icon_view->priv->vadjustment,
4476
icon_view->priv->vadjustment->value + y + item->y - focus_width);
4477
else if (y + item->y + item->height + focus_width > GTK_WIDGET (icon_view)->allocation.height)
4478
gtk_adjustment_set_value (icon_view->priv->vadjustment,
4479
icon_view->priv->vadjustment->value + y + item->y + item->height
4480
+ focus_width - GTK_WIDGET (icon_view)->allocation.height);
4482
if (x + item->x - focus_width < 0)
4483
gtk_adjustment_set_value (icon_view->priv->hadjustment,
4484
icon_view->priv->hadjustment->value + x + item->x - focus_width);
4485
else if (x + item->x + item->width + focus_width > GTK_WIDGET (icon_view)->allocation.width)
4486
gtk_adjustment_set_value (icon_view->priv->hadjustment,
4487
icon_view->priv->hadjustment->value + x + item->x + item->width
4488
+ focus_width - GTK_WIDGET (icon_view)->allocation.width);
4490
gtk_adjustment_changed (icon_view->priv->hadjustment);
4491
gtk_adjustment_changed (icon_view->priv->vadjustment);
4494
/* GtkCellLayout implementation */
4495
static GtkIconViewCellInfo *
4496
gtk_icon_view_get_cell_info (GtkIconView *icon_view,
4497
GtkCellRenderer *renderer)
4501
for (i = icon_view->priv->cell_list; i; i = i->next)
4503
GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)i->data;
4505
if (info->cell == renderer)
4513
gtk_icon_view_set_cell_data (GtkIconView *icon_view,
4514
GtkIconViewItem *item)
4517
gboolean iters_persist;
4520
iters_persist = gtk_tree_model_get_flags (icon_view->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST;
4526
path = gtk_tree_path_new_from_indices (item->index, -1);
4527
if (!gtk_tree_model_get_iter (icon_view->priv->model, &iter, path))
4529
gtk_tree_path_free (path);
4534
for (i = icon_view->priv->cell_list; i; i = i->next)
4537
GtkIconViewCellInfo *info = i->data;
4539
g_object_freeze_notify (G_OBJECT (info->cell));
4541
for (j = info->attributes; j && j->next; j = j->next->next)
4543
gchar *property = j->data;
4544
gint column = GPOINTER_TO_INT (j->next->data);
4545
GValue value = {0, };
4547
gtk_tree_model_get_value (icon_view->priv->model, &iter,
4549
g_object_set_property (G_OBJECT (info->cell),
4551
g_value_unset (&value);
4555
(* info->func) (GTK_CELL_LAYOUT (icon_view),
4557
icon_view->priv->model,
4561
g_object_thaw_notify (G_OBJECT (info->cell));
4566
free_cell_attributes (GtkIconViewCellInfo *info)
4570
list = info->attributes;
4571
while (list && list->next)
4573
g_free (list->data);
4574
list = list->next->next;
4577
g_slist_free (info->attributes);
4578
info->attributes = NULL;
4582
free_cell_info (GtkIconViewCellInfo *info)
4584
free_cell_attributes (info);
4586
g_object_unref (info->cell);
4589
(* info->destroy) (info->func_data);
4595
gtk_icon_view_cell_layout_pack_start (GtkCellLayout *layout,
4596
GtkCellRenderer *renderer,
4599
GtkIconViewCellInfo *info;
4600
GtkIconView *icon_view = GTK_ICON_VIEW (layout);
4602
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
4603
g_return_if_fail (!gtk_icon_view_get_cell_info (icon_view, renderer));
4605
g_object_ref_sink (renderer);
4607
info = g_new0 (GtkIconViewCellInfo, 1);
4608
info->cell = renderer;
4609
info->expand = expand ? TRUE : FALSE;
4610
info->pack = GTK_PACK_START;
4611
info->position = icon_view->priv->n_cells;
4613
icon_view->priv->cell_list = g_list_append (icon_view->priv->cell_list, info);
4614
icon_view->priv->n_cells++;
4618
gtk_icon_view_cell_layout_pack_end (GtkCellLayout *layout,
4619
GtkCellRenderer *renderer,
4622
GtkIconViewCellInfo *info;
4623
GtkIconView *icon_view = GTK_ICON_VIEW (layout);
4625
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
4626
g_return_if_fail (!gtk_icon_view_get_cell_info (icon_view, renderer));
4628
g_object_ref_sink (renderer);
4630
info = g_new0 (GtkIconViewCellInfo, 1);
4631
info->cell = renderer;
4632
info->expand = expand ? TRUE : FALSE;
4633
info->pack = GTK_PACK_END;
4634
info->position = icon_view->priv->n_cells;
4636
icon_view->priv->cell_list = g_list_append (icon_view->priv->cell_list, info);
4637
icon_view->priv->n_cells++;
4641
gtk_icon_view_cell_layout_add_attribute (GtkCellLayout *layout,
4642
GtkCellRenderer *renderer,
4643
const gchar *attribute,
4646
GtkIconViewCellInfo *info;
4647
GtkIconView *icon_view = GTK_ICON_VIEW (layout);
4649
info = gtk_icon_view_get_cell_info (icon_view, renderer);
4650
g_return_if_fail (info != NULL);
4652
info->attributes = g_slist_prepend (info->attributes,
4653
GINT_TO_POINTER (column));
4654
info->attributes = g_slist_prepend (info->attributes,
4655
g_strdup (attribute));
4659
gtk_icon_view_cell_layout_clear (GtkCellLayout *layout)
4661
GtkIconView *icon_view = GTK_ICON_VIEW (layout);
4663
while (icon_view->priv->cell_list)
4665
GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)icon_view->priv->cell_list->data;
4666
free_cell_info (info);
4667
icon_view->priv->cell_list = g_list_delete_link (icon_view->priv->cell_list,
4668
icon_view->priv->cell_list);
4671
icon_view->priv->n_cells = 0;
4675
gtk_icon_view_cell_layout_set_cell_data_func (GtkCellLayout *layout,
4676
GtkCellRenderer *cell,
4677
GtkCellLayoutDataFunc func,
4679
GDestroyNotify destroy)
4681
GtkIconViewCellInfo *info;
4682
GtkIconView *icon_view = GTK_ICON_VIEW (layout);
4684
info = gtk_icon_view_get_cell_info (icon_view, cell);
4685
g_return_if_fail (info != NULL);
4689
GDestroyNotify d = info->destroy;
4691
info->destroy = NULL;
4692
d (info->func_data);
4696
info->func_data = func_data;
4697
info->destroy = destroy;
4701
gtk_icon_view_cell_layout_clear_attributes (GtkCellLayout *layout,
4702
GtkCellRenderer *renderer)
4704
GtkIconViewCellInfo *info;
4706
info = gtk_icon_view_get_cell_info (GTK_ICON_VIEW (layout), renderer);
4708
free_cell_attributes (info);
4712
gtk_icon_view_cell_layout_reorder (GtkCellLayout *layout,
4713
GtkCellRenderer *cell,
4716
GtkIconView *icon_view;
4718
GtkIconViewCellInfo *info;
4721
icon_view = GTK_ICON_VIEW (layout);
4723
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
4725
info = gtk_icon_view_get_cell_info (icon_view, cell);
4727
g_return_if_fail (info != NULL);
4728
g_return_if_fail (position >= 0);
4730
link = g_list_find (icon_view->priv->cell_list, info);
4732
g_return_if_fail (link != NULL);
4734
icon_view->priv->cell_list = g_list_delete_link (icon_view->priv->cell_list,
4736
icon_view->priv->cell_list = g_list_insert (icon_view->priv->cell_list,
4739
for (l = icon_view->priv->cell_list, i = 0; l; l = l->next, i++)
4746
gtk_widget_queue_draw (GTK_WIDGET (icon_view));
4750
gtk_icon_view_cell_layout_get_cells (GtkCellLayout *layout)
4752
GtkIconView *icon_view = (GtkIconView *)layout;
4753
GList *retval = NULL, *l;
4755
for (l = icon_view->priv->cell_list; l; l = l->next)
4757
GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)l->data;
4759
retval = g_list_prepend (retval, info->cell);
4762
return g_list_reverse (retval);
4769
* gtk_icon_view_new:
4771
* Creates a new #GtkIconView widget
4773
* Return value: A newly created #GtkIconView widget
4778
gtk_icon_view_new (void)
4780
return g_object_new (GTK_TYPE_ICON_VIEW, NULL);
4784
* gtk_icon_view_new_with_model:
4785
* @model: The model.
4787
* Creates a new #GtkIconView widget with the model @model.
4789
* Return value: A newly created #GtkIconView widget.
4794
gtk_icon_view_new_with_model (GtkTreeModel *model)
4796
return g_object_new (GTK_TYPE_ICON_VIEW, "model", model, NULL);
4800
* gtk_icon_view_convert_widget_to_bin_window_coords:
4801
* @icon_view: a #GtkIconView
4802
* @wx: X coordinate relative to the widget
4803
* @wy: Y coordinate relative to the widget
4804
* @bx: (out): return location for bin_window X coordinate
4805
* @by: (out): return location for bin_window Y coordinate
4807
* Converts widget coordinates to coordinates for the bin_window,
4808
* as expected by e.g. gtk_icon_view_get_path_at_pos().
4813
gtk_icon_view_convert_widget_to_bin_window_coords (GtkIconView *icon_view,
4821
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
4823
if (icon_view->priv->bin_window)
4824
gdk_window_get_position (icon_view->priv->bin_window, &x, &y);
4835
* gtk_icon_view_get_path_at_pos:
4836
* @icon_view: A #GtkIconView.
4837
* @x: The x position to be identified
4838
* @y: The y position to be identified
4840
* Finds the path at the point (@x, @y), relative to bin_window coordinates.
4841
* See gtk_icon_view_get_item_at_pos(), if you are also interested in
4842
* the cell at the specified position.
4843
* See gtk_icon_view_convert_widget_to_bin_window_coords() for converting
4844
* widget coordinates to bin_window coordinates.
4846
* Return value: The #GtkTreePath corresponding to the icon or %NULL
4847
* if no icon exists at that position.
4852
gtk_icon_view_get_path_at_pos (GtkIconView *icon_view,
4856
GtkIconViewItem *item;
4859
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), NULL);
4861
item = gtk_icon_view_get_item_at_coords (icon_view, x, y, TRUE, NULL);
4866
path = gtk_tree_path_new_from_indices (item->index, -1);
4872
* gtk_icon_view_get_item_at_pos:
4873
* @icon_view: A #GtkIconView.
4874
* @x: The x position to be identified
4875
* @y: The y position to be identified
4876
* @path: (allow-none): Return location for the path, or %NULL
4877
* @cell: Return location for the renderer responsible for the cell
4878
* at (@x, @y), or %NULL
4880
* Finds the path at the point (@x, @y), relative to bin_window coordinates.
4881
* In contrast to gtk_icon_view_get_path_at_pos(), this function also
4882
* obtains the cell at the specified position. The returned path should
4883
* be freed with gtk_tree_path_free().
4884
* See gtk_icon_view_convert_widget_to_bin_window_coords() for converting
4885
* widget coordinates to bin_window coordinates.
4887
* Return value: %TRUE if an item exists at the specified position
4892
gtk_icon_view_get_item_at_pos (GtkIconView *icon_view,
4896
GtkCellRenderer **cell)
4898
GtkIconViewItem *item;
4899
GtkIconViewCellInfo *info;
4901
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), FALSE);
4903
item = gtk_icon_view_get_item_at_coords (icon_view, x, y, TRUE, &info);
4908
*path = gtk_tree_path_new_from_indices (item->index, -1);
4921
return (item != NULL);
4925
* gtk_icon_view_set_tooltip_item:
4926
* @icon_view: a #GtkIconView
4927
* @tooltip: a #GtkTooltip
4928
* @path: a #GtkTreePath
4930
* Sets the tip area of @tooltip to be the area covered by the item at @path.
4931
* See also gtk_icon_view_set_tooltip_column() for a simpler alternative.
4932
* See also gtk_tooltip_set_tip_area().
4937
gtk_icon_view_set_tooltip_item (GtkIconView *icon_view,
4938
GtkTooltip *tooltip,
4941
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
4942
g_return_if_fail (GTK_IS_TOOLTIP (tooltip));
4944
gtk_icon_view_set_tooltip_cell (icon_view, tooltip, path, NULL);
4948
* gtk_icon_view_set_tooltip_cell:
4949
* @icon_view: a #GtkIconView
4950
* @tooltip: a #GtkTooltip
4951
* @path: a #GtkTreePath
4952
* @cell: (allow-none): a #GtkCellRenderer or %NULL
4954
* Sets the tip area of @tooltip to the area which @cell occupies in
4955
* the item pointed to by @path. See also gtk_tooltip_set_tip_area().
4957
* See also gtk_icon_view_set_tooltip_column() for a simpler alternative.
4962
gtk_icon_view_set_tooltip_cell (GtkIconView *icon_view,
4963
GtkTooltip *tooltip,
4965
GtkCellRenderer *cell)
4968
GtkIconViewItem *item = NULL;
4969
GtkIconViewCellInfo *info = NULL;
4972
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
4973
g_return_if_fail (GTK_IS_TOOLTIP (tooltip));
4974
g_return_if_fail (cell == NULL || GTK_IS_CELL_RENDERER (cell));
4976
if (gtk_tree_path_get_depth (path) > 0)
4977
item = g_list_nth_data (icon_view->priv->items,
4978
gtk_tree_path_get_indices(path)[0]);
4985
info = gtk_icon_view_get_cell_info (icon_view, cell);
4986
gtk_icon_view_get_cell_area (icon_view, item, info, &rect);
4992
rect.width = item->width;
4993
rect.height = item->height;
4996
if (icon_view->priv->bin_window)
4998
gdk_window_get_position (icon_view->priv->bin_window, &x, &y);
5003
gtk_tooltip_set_tip_area (tooltip, &rect);
5008
* gtk_icon_view_get_tooltip_context:
5009
* @icon_view: an #GtkIconView
5010
* @x: (inout): the x coordinate (relative to widget coordinates)
5011
* @y: (inout): the y coordinate (relative to widget coordinates)
5012
* @keyboard_tip: whether this is a keyboard tooltip or not
5013
* @model: (out) (allow-none): a pointer to receive a #GtkTreeModel or %NULL
5014
* @path: (out) (allow-none): a pointer to receive a #GtkTreePath or %NULL
5015
* @iter: (out) (allow-none): a pointer to receive a #GtkTreeIter or %NULL
5017
* This function is supposed to be used in a #GtkWidget::query-tooltip
5018
* signal handler for #GtkIconView. The @x, @y and @keyboard_tip values
5019
* which are received in the signal handler, should be passed to this
5020
* function without modification.
5022
* The return value indicates whether there is an icon view item at the given
5023
* coordinates (%TRUE) or not (%FALSE) for mouse tooltips. For keyboard
5024
* tooltips the item returned will be the cursor item. When %TRUE, then any of
5025
* @model, @path and @iter which have been provided will be set to point to
5026
* that row and the corresponding model. @x and @y will always be converted
5027
* to be relative to @icon_view's bin_window if @keyboard_tooltip is %FALSE.
5029
* Return value: whether or not the given tooltip context points to a item
5034
gtk_icon_view_get_tooltip_context (GtkIconView *icon_view,
5037
gboolean keyboard_tip,
5038
GtkTreeModel **model,
5042
GtkTreePath *tmppath = NULL;
5044
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), FALSE);
5045
g_return_val_if_fail (x != NULL, FALSE);
5046
g_return_val_if_fail (y != NULL, FALSE);
5050
gtk_icon_view_get_cursor (icon_view, &tmppath, NULL);
5057
gtk_icon_view_convert_widget_to_bin_window_coords (icon_view, *x, *y,
5060
if (!gtk_icon_view_get_item_at_pos (icon_view, *x, *y, &tmppath, NULL))
5065
*model = gtk_icon_view_get_model (icon_view);
5068
gtk_tree_model_get_iter (gtk_icon_view_get_model (icon_view),
5074
gtk_tree_path_free (tmppath);
5080
gtk_icon_view_set_tooltip_query_cb (GtkWidget *widget,
5083
gboolean keyboard_tip,
5084
GtkTooltip *tooltip,
5090
GtkTreeModel *model;
5091
GtkIconView *icon_view = GTK_ICON_VIEW (widget);
5093
if (!gtk_icon_view_get_tooltip_context (GTK_ICON_VIEW (widget),
5096
&model, &path, &iter))
5099
gtk_tree_model_get (model, &iter, icon_view->priv->tooltip_column, &str, -1);
5103
gtk_tree_path_free (path);
5107
gtk_tooltip_set_markup (tooltip, str);
5108
gtk_icon_view_set_tooltip_item (icon_view, tooltip, path);
5110
gtk_tree_path_free (path);
5118
* gtk_icon_view_set_tooltip_column:
5119
* @icon_view: a #GtkIconView
5120
* @column: an integer, which is a valid column number for @icon_view's model
5122
* If you only plan to have simple (text-only) tooltips on full items, you
5123
* can use this function to have #GtkIconView handle these automatically
5124
* for you. @column should be set to the column in @icon_view's model
5125
* containing the tooltip texts, or -1 to disable this feature.
5127
* When enabled, #GtkWidget::has-tooltip will be set to %TRUE and
5128
* @icon_view will connect a #GtkWidget::query-tooltip signal handler.
5133
gtk_icon_view_set_tooltip_column (GtkIconView *icon_view,
5136
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
5138
if (column == icon_view->priv->tooltip_column)
5143
g_signal_handlers_disconnect_by_func (icon_view,
5144
gtk_icon_view_set_tooltip_query_cb,
5146
gtk_widget_set_has_tooltip (GTK_WIDGET (icon_view), FALSE);
5150
if (icon_view->priv->tooltip_column == -1)
5152
g_signal_connect (icon_view, "query-tooltip",
5153
G_CALLBACK (gtk_icon_view_set_tooltip_query_cb), NULL);
5154
gtk_widget_set_has_tooltip (GTK_WIDGET (icon_view), TRUE);
5158
icon_view->priv->tooltip_column = column;
5159
g_object_notify (G_OBJECT (icon_view), "tooltip-column");
5163
* gtk_icon_view_get_tooltip_column:
5164
* @icon_view: a #GtkIconView
5166
* Returns the column of @icon_view's model which is being used for
5167
* displaying tooltips on @icon_view's rows.
5169
* Return value: the index of the tooltip column that is currently being
5170
* used, or -1 if this is disabled.
5175
gtk_icon_view_get_tooltip_column (GtkIconView *icon_view)
5177
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), 0);
5179
return icon_view->priv->tooltip_column;
5183
* gtk_icon_view_get_visible_range:
5184
* @icon_view: A #GtkIconView
5185
* @start_path: (allow-none): Return location for start of region, or %NULL
5186
* @end_path: (allow-none): Return location for end of region, or %NULL
5188
* Sets @start_path and @end_path to be the first and last visible path.
5189
* Note that there may be invisible paths in between.
5191
* Both paths should be freed with gtk_tree_path_free() after use.
5193
* Return value: %TRUE, if valid paths were placed in @start_path and @end_path
5198
gtk_icon_view_get_visible_range (GtkIconView *icon_view,
5199
GtkTreePath **start_path,
5200
GtkTreePath **end_path)
5202
gint start_index = -1;
5203
gint end_index = -1;
5206
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), FALSE);
5208
if (icon_view->priv->hadjustment == NULL ||
5209
icon_view->priv->vadjustment == NULL)
5212
if (start_path == NULL && end_path == NULL)
5215
for (icons = icon_view->priv->items; icons; icons = icons->next)
5217
GtkIconViewItem *item = icons->data;
5219
if ((item->x + item->width >= (int)icon_view->priv->hadjustment->value) &&
5220
(item->y + item->height >= (int)icon_view->priv->vadjustment->value) &&
5221
(item->x <= (int) (icon_view->priv->hadjustment->value + icon_view->priv->hadjustment->page_size)) &&
5222
(item->y <= (int) (icon_view->priv->vadjustment->value + icon_view->priv->vadjustment->page_size)))
5224
if (start_index == -1)
5225
start_index = item->index;
5226
end_index = item->index;
5230
if (start_path && start_index != -1)
5231
*start_path = gtk_tree_path_new_from_indices (start_index, -1);
5232
if (end_path && end_index != -1)
5233
*end_path = gtk_tree_path_new_from_indices (end_index, -1);
5235
return start_index != -1;
5239
* gtk_icon_view_selected_foreach:
5240
* @icon_view: A #GtkIconView.
5241
* @func: (scope call): The function to call for each selected icon.
5242
* @data: User data to pass to the function.
5244
* Calls a function for each selected icon. Note that the model or
5245
* selection cannot be modified from within this function.
5250
gtk_icon_view_selected_foreach (GtkIconView *icon_view,
5251
GtkIconViewForeachFunc func,
5256
for (list = icon_view->priv->items; list; list = list->next)
5258
GtkIconViewItem *item = list->data;
5259
GtkTreePath *path = gtk_tree_path_new_from_indices (item->index, -1);
5262
(* func) (icon_view, path, data);
5264
gtk_tree_path_free (path);
5269
* gtk_icon_view_set_selection_mode:
5270
* @icon_view: A #GtkIconView.
5271
* @mode: The selection mode
5273
* Sets the selection mode of the @icon_view.
5278
gtk_icon_view_set_selection_mode (GtkIconView *icon_view,
5279
GtkSelectionMode mode)
5281
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
5283
if (mode == icon_view->priv->selection_mode)
5286
if (mode == GTK_SELECTION_NONE ||
5287
icon_view->priv->selection_mode == GTK_SELECTION_MULTIPLE)
5288
gtk_icon_view_unselect_all (icon_view);
5290
icon_view->priv->selection_mode = mode;
5292
g_object_notify (G_OBJECT (icon_view), "selection-mode");
5296
* gtk_icon_view_get_selection_mode:
5297
* @icon_view: A #GtkIconView.
5299
* Gets the selection mode of the @icon_view.
5301
* Return value: the current selection mode
5306
gtk_icon_view_get_selection_mode (GtkIconView *icon_view)
5308
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), GTK_SELECTION_SINGLE);
5310
return icon_view->priv->selection_mode;
5314
* gtk_icon_view_set_model:
5315
* @icon_view: A #GtkIconView.
5316
* @model: (allow-none): The model.
5318
* Sets the model for a #GtkIconView.
5319
* If the @icon_view already has a model set, it will remove
5320
* it before setting the new model. If @model is %NULL, then
5321
* it will unset the old model.
5326
gtk_icon_view_set_model (GtkIconView *icon_view,
5327
GtkTreeModel *model)
5329
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
5330
g_return_if_fail (model == NULL || GTK_IS_TREE_MODEL (model));
5332
if (icon_view->priv->model == model)
5335
if (icon_view->priv->scroll_to_path)
5337
gtk_tree_row_reference_free (icon_view->priv->scroll_to_path);
5338
icon_view->priv->scroll_to_path = NULL;
5341
gtk_icon_view_stop_editing (icon_view, TRUE);
5347
g_return_if_fail (gtk_tree_model_get_flags (model) & GTK_TREE_MODEL_LIST_ONLY);
5349
if (icon_view->priv->pixbuf_column != -1)
5351
column_type = gtk_tree_model_get_column_type (model,
5352
icon_view->priv->pixbuf_column);
5354
g_return_if_fail (column_type == GDK_TYPE_PIXBUF);
5357
if (icon_view->priv->text_column != -1)
5359
column_type = gtk_tree_model_get_column_type (model,
5360
icon_view->priv->text_column);
5362
g_return_if_fail (column_type == G_TYPE_STRING);
5365
if (icon_view->priv->markup_column != -1)
5367
column_type = gtk_tree_model_get_column_type (model,
5368
icon_view->priv->markup_column);
5370
g_return_if_fail (column_type == G_TYPE_STRING);
5375
if (icon_view->priv->model)
5377
g_signal_handlers_disconnect_by_func (icon_view->priv->model,
5378
gtk_icon_view_row_changed,
5380
g_signal_handlers_disconnect_by_func (icon_view->priv->model,
5381
gtk_icon_view_row_inserted,
5383
g_signal_handlers_disconnect_by_func (icon_view->priv->model,
5384
gtk_icon_view_row_deleted,
5386
g_signal_handlers_disconnect_by_func (icon_view->priv->model,
5387
gtk_icon_view_rows_reordered,
5390
g_object_unref (icon_view->priv->model);
5392
g_list_foreach (icon_view->priv->items, (GFunc)gtk_icon_view_item_free, NULL);
5393
g_list_free (icon_view->priv->items);
5394
icon_view->priv->items = NULL;
5395
icon_view->priv->anchor_item = NULL;
5396
icon_view->priv->cursor_item = NULL;
5397
icon_view->priv->last_single_clicked = NULL;
5398
icon_view->priv->width = 0;
5399
icon_view->priv->height = 0;
5402
icon_view->priv->model = model;
5404
if (icon_view->priv->model)
5406
g_object_ref (icon_view->priv->model);
5407
g_signal_connect (icon_view->priv->model,
5409
G_CALLBACK (gtk_icon_view_row_changed),
5411
g_signal_connect (icon_view->priv->model,
5413
G_CALLBACK (gtk_icon_view_row_inserted),
5415
g_signal_connect (icon_view->priv->model,
5417
G_CALLBACK (gtk_icon_view_row_deleted),
5419
g_signal_connect (icon_view->priv->model,
5421
G_CALLBACK (gtk_icon_view_rows_reordered),
5424
gtk_icon_view_build_items (icon_view);
5426
gtk_icon_view_layout (icon_view);
5429
g_object_notify (G_OBJECT (icon_view), "model");
5431
if (gtk_widget_get_realized (GTK_WIDGET (icon_view)))
5432
gtk_widget_queue_resize (GTK_WIDGET (icon_view));
5436
* gtk_icon_view_get_model:
5437
* @icon_view: a #GtkIconView
5439
* Returns the model the #GtkIconView is based on. Returns %NULL if the
5442
* Return value: (transfer none): A #GtkTreeModel, or %NULL if none is
5443
* currently being used.
5448
gtk_icon_view_get_model (GtkIconView *icon_view)
5450
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), NULL);
5452
return icon_view->priv->model;
5456
update_text_cell (GtkIconView *icon_view)
5458
GtkIconViewCellInfo *info;
5462
if (icon_view->priv->text_column == -1 &&
5463
icon_view->priv->markup_column == -1)
5465
if (icon_view->priv->text_cell != -1)
5467
if (icon_view->priv->pixbuf_cell > icon_view->priv->text_cell)
5468
icon_view->priv->pixbuf_cell--;
5470
info = g_list_nth_data (icon_view->priv->cell_list,
5471
icon_view->priv->text_cell);
5473
icon_view->priv->cell_list = g_list_remove (icon_view->priv->cell_list, info);
5475
free_cell_info (info);
5477
icon_view->priv->n_cells--;
5478
icon_view->priv->text_cell = -1;
5483
if (icon_view->priv->text_cell == -1)
5485
GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
5486
gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (icon_view), cell, FALSE);
5487
for (l = icon_view->priv->cell_list, i = 0; l; l = l->next, i++)
5490
if (info->cell == cell)
5492
icon_view->priv->text_cell = i;
5498
info = g_list_nth_data (icon_view->priv->cell_list,
5499
icon_view->priv->text_cell);
5501
if (icon_view->priv->markup_column != -1)
5502
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (icon_view),
5504
"markup", icon_view->priv->markup_column,
5507
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (icon_view),
5509
"text", icon_view->priv->text_column,
5512
if (icon_view->priv->item_orientation == GTK_ORIENTATION_VERTICAL)
5513
g_object_set (info->cell,
5514
"alignment", PANGO_ALIGN_CENTER,
5515
"wrap-mode", PANGO_WRAP_WORD_CHAR,
5520
g_object_set (info->cell,
5521
"alignment", PANGO_ALIGN_LEFT,
5522
"wrap-mode", PANGO_WRAP_WORD_CHAR,
5530
update_pixbuf_cell (GtkIconView *icon_view)
5532
GtkIconViewCellInfo *info;
5536
if (icon_view->priv->pixbuf_column == -1)
5538
if (icon_view->priv->pixbuf_cell != -1)
5540
if (icon_view->priv->text_cell > icon_view->priv->pixbuf_cell)
5541
icon_view->priv->text_cell--;
5543
info = g_list_nth_data (icon_view->priv->cell_list,
5544
icon_view->priv->pixbuf_cell);
5546
icon_view->priv->cell_list = g_list_remove (icon_view->priv->cell_list, info);
5548
free_cell_info (info);
5550
icon_view->priv->n_cells--;
5551
icon_view->priv->pixbuf_cell = -1;
5556
if (icon_view->priv->pixbuf_cell == -1)
5558
GtkCellRenderer *cell = gtk_cell_renderer_pixbuf_new ();
5560
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (icon_view), cell, FALSE);
5561
for (l = icon_view->priv->cell_list, i = 0; l; l = l->next, i++)
5564
if (info->cell == cell)
5566
icon_view->priv->pixbuf_cell = i;
5572
info = g_list_nth_data (icon_view->priv->cell_list,
5573
icon_view->priv->pixbuf_cell);
5575
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (icon_view),
5577
"pixbuf", icon_view->priv->pixbuf_column,
5580
if (icon_view->priv->item_orientation == GTK_ORIENTATION_VERTICAL)
5581
g_object_set (info->cell,
5586
g_object_set (info->cell,
5594
* gtk_icon_view_set_text_column:
5595
* @icon_view: A #GtkIconView.
5596
* @column: A column in the currently used model, or -1 to display no text
5598
* Sets the column with text for @icon_view to be @column. The text
5599
* column must be of type #G_TYPE_STRING.
5604
gtk_icon_view_set_text_column (GtkIconView *icon_view,
5607
if (column == icon_view->priv->text_column)
5611
icon_view->priv->text_column = -1;
5614
if (icon_view->priv->model != NULL)
5618
column_type = gtk_tree_model_get_column_type (icon_view->priv->model, column);
5620
g_return_if_fail (column_type == G_TYPE_STRING);
5623
icon_view->priv->text_column = column;
5626
gtk_icon_view_stop_editing (icon_view, TRUE);
5628
update_text_cell (icon_view);
5630
gtk_icon_view_invalidate_sizes (icon_view);
5631
gtk_icon_view_queue_layout (icon_view);
5633
g_object_notify (G_OBJECT (icon_view), "text-column");
5637
* gtk_icon_view_get_text_column:
5638
* @icon_view: A #GtkIconView.
5640
* Returns the column with text for @icon_view.
5642
* Returns: the text column, or -1 if it's unset.
5647
gtk_icon_view_get_text_column (GtkIconView *icon_view)
5649
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
5651
return icon_view->priv->text_column;
5655
* gtk_icon_view_set_markup_column:
5656
* @icon_view: A #GtkIconView.
5657
* @column: A column in the currently used model, or -1 to display no text
5659
* Sets the column with markup information for @icon_view to be
5660
* @column. The markup column must be of type #G_TYPE_STRING.
5661
* If the markup column is set to something, it overrides
5662
* the text column set by gtk_icon_view_set_text_column().
5667
gtk_icon_view_set_markup_column (GtkIconView *icon_view,
5670
if (column == icon_view->priv->markup_column)
5674
icon_view->priv->markup_column = -1;
5677
if (icon_view->priv->model != NULL)
5681
column_type = gtk_tree_model_get_column_type (icon_view->priv->model, column);
5683
g_return_if_fail (column_type == G_TYPE_STRING);
5686
icon_view->priv->markup_column = column;
5689
gtk_icon_view_stop_editing (icon_view, TRUE);
5691
update_text_cell (icon_view);
5693
gtk_icon_view_invalidate_sizes (icon_view);
5694
gtk_icon_view_queue_layout (icon_view);
5696
g_object_notify (G_OBJECT (icon_view), "markup-column");
5700
* gtk_icon_view_get_markup_column:
5701
* @icon_view: A #GtkIconView.
5703
* Returns the column with markup text for @icon_view.
5705
* Returns: the markup column, or -1 if it's unset.
5710
gtk_icon_view_get_markup_column (GtkIconView *icon_view)
5712
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
5714
return icon_view->priv->markup_column;
5718
* gtk_icon_view_set_pixbuf_column:
5719
* @icon_view: A #GtkIconView.
5720
* @column: A column in the currently used model, or -1 to disable
5722
* Sets the column with pixbufs for @icon_view to be @column. The pixbuf
5723
* column must be of type #GDK_TYPE_PIXBUF
5728
gtk_icon_view_set_pixbuf_column (GtkIconView *icon_view,
5731
if (column == icon_view->priv->pixbuf_column)
5735
icon_view->priv->pixbuf_column = -1;
5738
if (icon_view->priv->model != NULL)
5742
column_type = gtk_tree_model_get_column_type (icon_view->priv->model, column);
5744
g_return_if_fail (column_type == GDK_TYPE_PIXBUF);
5747
icon_view->priv->pixbuf_column = column;
5750
gtk_icon_view_stop_editing (icon_view, TRUE);
5752
update_pixbuf_cell (icon_view);
5754
gtk_icon_view_invalidate_sizes (icon_view);
5755
gtk_icon_view_queue_layout (icon_view);
5757
g_object_notify (G_OBJECT (icon_view), "pixbuf-column");
5762
* gtk_icon_view_get_pixbuf_column:
5763
* @icon_view: A #GtkIconView.
5765
* Returns the column with pixbufs for @icon_view.
5767
* Returns: the pixbuf column, or -1 if it's unset.
5772
gtk_icon_view_get_pixbuf_column (GtkIconView *icon_view)
5774
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
5776
return icon_view->priv->pixbuf_column;
5780
* gtk_icon_view_select_path:
5781
* @icon_view: A #GtkIconView.
5782
* @path: The #GtkTreePath to be selected.
5784
* Selects the row at @path.
5789
gtk_icon_view_select_path (GtkIconView *icon_view,
5792
GtkIconViewItem *item = NULL;
5794
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
5795
g_return_if_fail (icon_view->priv->model != NULL);
5796
g_return_if_fail (path != NULL);
5798
if (gtk_tree_path_get_depth (path) > 0)
5799
item = g_list_nth_data (icon_view->priv->items,
5800
gtk_tree_path_get_indices(path)[0]);
5803
gtk_icon_view_select_item (icon_view, item);
5807
* gtk_icon_view_unselect_path:
5808
* @icon_view: A #GtkIconView.
5809
* @path: The #GtkTreePath to be unselected.
5811
* Unselects the row at @path.
5816
gtk_icon_view_unselect_path (GtkIconView *icon_view,
5819
GtkIconViewItem *item;
5821
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
5822
g_return_if_fail (icon_view->priv->model != NULL);
5823
g_return_if_fail (path != NULL);
5825
item = g_list_nth_data (icon_view->priv->items,
5826
gtk_tree_path_get_indices(path)[0]);
5831
gtk_icon_view_unselect_item (icon_view, item);
5835
* gtk_icon_view_get_selected_items:
5836
* @icon_view: A #GtkIconView.
5838
* Creates a list of paths of all selected items. Additionally, if you are
5839
* planning on modifying the model after calling this function, you may
5840
* want to convert the returned list into a list of #GtkTreeRowReference<!-- -->s.
5841
* To do this, you can use gtk_tree_row_reference_new().
5843
* To free the return value, use:
5845
* g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
5846
* g_list_free (list);
5849
* Return value: (element-type GtkTreePath) (transfer full): A #GList containing a #GtkTreePath for each selected row.
5854
gtk_icon_view_get_selected_items (GtkIconView *icon_view)
5857
GList *selected = NULL;
5859
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), NULL);
5861
for (list = icon_view->priv->items; list != NULL; list = list->next)
5863
GtkIconViewItem *item = list->data;
5867
GtkTreePath *path = gtk_tree_path_new_from_indices (item->index, -1);
5869
selected = g_list_prepend (selected, path);
5877
* gtk_icon_view_select_all:
5878
* @icon_view: A #GtkIconView.
5880
* Selects all the icons. @icon_view must has its selection mode set
5881
* to #GTK_SELECTION_MULTIPLE.
5886
gtk_icon_view_select_all (GtkIconView *icon_view)
5889
gboolean dirty = FALSE;
5891
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
5893
if (icon_view->priv->selection_mode != GTK_SELECTION_MULTIPLE)
5896
for (items = icon_view->priv->items; items; items = items->next)
5898
GtkIconViewItem *item = items->data;
5900
if (!item->selected)
5903
item->selected = TRUE;
5904
gtk_icon_view_queue_draw_item (icon_view, item);
5909
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
5913
* gtk_icon_view_unselect_all:
5914
* @icon_view: A #GtkIconView.
5916
* Unselects all the icons.
5921
gtk_icon_view_unselect_all (GtkIconView *icon_view)
5923
gboolean dirty = FALSE;
5925
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
5927
if (icon_view->priv->selection_mode == GTK_SELECTION_BROWSE)
5930
dirty = gtk_icon_view_unselect_all_internal (icon_view);
5933
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
5937
* gtk_icon_view_path_is_selected:
5938
* @icon_view: A #GtkIconView.
5939
* @path: A #GtkTreePath to check selection on.
5941
* Returns %TRUE if the icon pointed to by @path is currently
5942
* selected. If @path does not point to a valid location, %FALSE is returned.
5944
* Return value: %TRUE if @path is selected.
5949
gtk_icon_view_path_is_selected (GtkIconView *icon_view,
5952
GtkIconViewItem *item;
5954
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), FALSE);
5955
g_return_val_if_fail (icon_view->priv->model != NULL, FALSE);
5956
g_return_val_if_fail (path != NULL, FALSE);
5958
item = g_list_nth_data (icon_view->priv->items,
5959
gtk_tree_path_get_indices(path)[0]);
5964
return item->selected;
5968
* gtk_icon_view_get_item_row:
5969
* @icon_view: a #GtkIconView
5970
* @path: the #GtkTreePath of the item
5972
* Gets the row in which the item @path is currently
5973
* displayed. Row numbers start at 0.
5975
* Returns: The row in which the item is displayed
5980
gtk_icon_view_get_item_row (GtkIconView *icon_view,
5983
GtkIconViewItem *item;
5985
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), FALSE);
5986
g_return_val_if_fail (icon_view->priv->model != NULL, FALSE);
5987
g_return_val_if_fail (path != NULL, FALSE);
5989
item = g_list_nth_data (icon_view->priv->items,
5990
gtk_tree_path_get_indices(path)[0]);
5999
* gtk_icon_view_get_item_column:
6000
* @icon_view: a #GtkIconView
6001
* @path: the #GtkTreePath of the item
6003
* Gets the column in which the item @path is currently
6004
* displayed. Column numbers start at 0.
6006
* Returns: The column in which the item is displayed
6011
gtk_icon_view_get_item_column (GtkIconView *icon_view,
6014
GtkIconViewItem *item;
6016
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), FALSE);
6017
g_return_val_if_fail (icon_view->priv->model != NULL, FALSE);
6018
g_return_val_if_fail (path != NULL, FALSE);
6020
item = g_list_nth_data (icon_view->priv->items,
6021
gtk_tree_path_get_indices(path)[0]);
6030
* gtk_icon_view_item_activated:
6031
* @icon_view: A #GtkIconView
6032
* @path: The #GtkTreePath to be activated
6034
* Activates the item determined by @path.
6039
gtk_icon_view_item_activated (GtkIconView *icon_view,
6042
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
6043
g_return_if_fail (path != NULL);
6045
g_signal_emit (icon_view, icon_view_signals[ITEM_ACTIVATED], 0, path);
6049
* gtk_icon_view_set_item_orientation:
6050
* @icon_view: a #GtkIconView
6051
* @orientation: the relative position of texts and icons
6053
* Sets the ::item-orientation property which determines whether
6054
* the labels are drawn beside the icons instead of below.
6059
gtk_icon_view_set_item_orientation (GtkIconView *icon_view,
6060
GtkOrientation orientation)
6062
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
6064
if (icon_view->priv->item_orientation != orientation)
6066
icon_view->priv->item_orientation = orientation;
6068
gtk_icon_view_stop_editing (icon_view, TRUE);
6069
gtk_icon_view_invalidate_sizes (icon_view);
6070
gtk_icon_view_queue_layout (icon_view);
6072
update_text_cell (icon_view);
6073
update_pixbuf_cell (icon_view);
6075
g_object_notify (G_OBJECT (icon_view), "item-orientation");
6076
g_object_notify (G_OBJECT (icon_view), "orientation");
6081
* gtk_icon_view_set_orientation:
6082
* @icon_view: a #GtkIconView
6083
* @orientation: the relative position of texts and icons
6085
* Sets the ::orientation property which determines whether the labels
6086
* are drawn beside the icons instead of below.
6090
* Deprecated: 2.22: Use gtk_icon_view_set_item_orientation()
6093
gtk_icon_view_set_orientation (GtkIconView *icon_view,
6094
GtkOrientation orientation)
6096
gtk_icon_view_set_item_orientation (icon_view, orientation);
6100
* gtk_icon_view_get_item_orientation:
6101
* @icon_view: a #GtkIconView
6103
* Returns the value of the ::item-orientation property which determines
6104
* whether the labels are drawn beside the icons instead of below.
6106
* Return value: the relative position of texts and icons
6111
gtk_icon_view_get_item_orientation (GtkIconView *icon_view)
6113
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view),
6114
GTK_ORIENTATION_VERTICAL);
6116
return icon_view->priv->item_orientation;
6120
* gtk_icon_view_get_orientation:
6121
* @icon_view: a #GtkIconView
6123
* Returns the value of the ::orientation property which determines
6124
* whether the labels are drawn beside the icons instead of below.
6126
* Return value: the relative position of texts and icons
6130
* Deprecated: 2.22: Use gtk_icon_view_get_item_orientation()
6133
gtk_icon_view_get_orientation (GtkIconView *icon_view)
6135
return gtk_icon_view_get_item_orientation (icon_view);
6139
* gtk_icon_view_set_columns:
6140
* @icon_view: a #GtkIconView
6141
* @columns: the number of columns
6143
* Sets the ::columns property which determines in how
6144
* many columns the icons are arranged. If @columns is
6145
* -1, the number of columns will be chosen automatically
6146
* to fill the available area.
6151
gtk_icon_view_set_columns (GtkIconView *icon_view,
6154
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
6156
if (icon_view->priv->columns != columns)
6158
icon_view->priv->columns = columns;
6160
gtk_icon_view_stop_editing (icon_view, TRUE);
6161
gtk_icon_view_queue_layout (icon_view);
6163
g_object_notify (G_OBJECT (icon_view), "columns");
6168
* gtk_icon_view_get_columns:
6169
* @icon_view: a #GtkIconView
6171
* Returns the value of the ::columns property.
6173
* Return value: the number of columns, or -1
6178
gtk_icon_view_get_columns (GtkIconView *icon_view)
6180
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
6182
return icon_view->priv->columns;
6186
* gtk_icon_view_set_item_width:
6187
* @icon_view: a #GtkIconView
6188
* @item_width: the width for each item
6190
* Sets the ::item-width property which specifies the width
6191
* to use for each item. If it is set to -1, the icon view will
6192
* automatically determine a suitable item size.
6197
gtk_icon_view_set_item_width (GtkIconView *icon_view,
6200
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
6202
if (icon_view->priv->item_width != item_width)
6204
icon_view->priv->item_width = item_width;
6206
gtk_icon_view_stop_editing (icon_view, TRUE);
6207
gtk_icon_view_invalidate_sizes (icon_view);
6208
gtk_icon_view_queue_layout (icon_view);
6210
update_text_cell (icon_view);
6212
g_object_notify (G_OBJECT (icon_view), "item-width");
6217
* gtk_icon_view_get_item_width:
6218
* @icon_view: a #GtkIconView
6220
* Returns the value of the ::item-width property.
6222
* Return value: the width of a single item, or -1
6227
gtk_icon_view_get_item_width (GtkIconView *icon_view)
6229
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
6231
return icon_view->priv->item_width;
6236
* gtk_icon_view_set_spacing:
6237
* @icon_view: a #GtkIconView
6238
* @spacing: the spacing
6240
* Sets the ::spacing property which specifies the space
6241
* which is inserted between the cells (i.e. the icon and
6242
* the text) of an item.
6247
gtk_icon_view_set_spacing (GtkIconView *icon_view,
6250
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
6252
if (icon_view->priv->spacing != spacing)
6254
icon_view->priv->spacing = spacing;
6256
gtk_icon_view_stop_editing (icon_view, TRUE);
6257
gtk_icon_view_invalidate_sizes (icon_view);
6258
gtk_icon_view_queue_layout (icon_view);
6260
g_object_notify (G_OBJECT (icon_view), "spacing");
6265
* gtk_icon_view_get_spacing:
6266
* @icon_view: a #GtkIconView
6268
* Returns the value of the ::spacing property.
6270
* Return value: the space between cells
6275
gtk_icon_view_get_spacing (GtkIconView *icon_view)
6277
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
6279
return icon_view->priv->spacing;
6283
* gtk_icon_view_set_row_spacing:
6284
* @icon_view: a #GtkIconView
6285
* @row_spacing: the row spacing
6287
* Sets the ::row-spacing property which specifies the space
6288
* which is inserted between the rows of the icon view.
6293
gtk_icon_view_set_row_spacing (GtkIconView *icon_view,
6296
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
6298
if (icon_view->priv->row_spacing != row_spacing)
6300
icon_view->priv->row_spacing = row_spacing;
6302
gtk_icon_view_stop_editing (icon_view, TRUE);
6303
gtk_icon_view_invalidate_sizes (icon_view);
6304
gtk_icon_view_queue_layout (icon_view);
6306
g_object_notify (G_OBJECT (icon_view), "row-spacing");
6311
* gtk_icon_view_get_row_spacing:
6312
* @icon_view: a #GtkIconView
6314
* Returns the value of the ::row-spacing property.
6316
* Return value: the space between rows
6321
gtk_icon_view_get_row_spacing (GtkIconView *icon_view)
6323
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
6325
return icon_view->priv->row_spacing;
6329
* gtk_icon_view_set_column_spacing:
6330
* @icon_view: a #GtkIconView
6331
* @column_spacing: the column spacing
6333
* Sets the ::column-spacing property which specifies the space
6334
* which is inserted between the columns of the icon view.
6339
gtk_icon_view_set_column_spacing (GtkIconView *icon_view,
6340
gint column_spacing)
6342
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
6344
if (icon_view->priv->column_spacing != column_spacing)
6346
icon_view->priv->column_spacing = column_spacing;
6348
gtk_icon_view_stop_editing (icon_view, TRUE);
6349
gtk_icon_view_invalidate_sizes (icon_view);
6350
gtk_icon_view_queue_layout (icon_view);
6352
g_object_notify (G_OBJECT (icon_view), "column-spacing");
6357
* gtk_icon_view_get_column_spacing:
6358
* @icon_view: a #GtkIconView
6360
* Returns the value of the ::column-spacing property.
6362
* Return value: the space between columns
6367
gtk_icon_view_get_column_spacing (GtkIconView *icon_view)
6369
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
6371
return icon_view->priv->column_spacing;
6375
* gtk_icon_view_set_margin:
6376
* @icon_view: a #GtkIconView
6377
* @margin: the margin
6379
* Sets the ::margin property which specifies the space
6380
* which is inserted at the top, bottom, left and right
6386
gtk_icon_view_set_margin (GtkIconView *icon_view,
6389
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
6391
if (icon_view->priv->margin != margin)
6393
icon_view->priv->margin = margin;
6395
gtk_icon_view_stop_editing (icon_view, TRUE);
6396
gtk_icon_view_invalidate_sizes (icon_view);
6397
gtk_icon_view_queue_layout (icon_view);
6399
g_object_notify (G_OBJECT (icon_view), "margin");
6404
* gtk_icon_view_get_margin:
6405
* @icon_view: a #GtkIconView
6407
* Returns the value of the ::margin property.
6409
* Return value: the space at the borders
6414
gtk_icon_view_get_margin (GtkIconView *icon_view)
6416
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
6418
return icon_view->priv->margin;
6422
* gtk_icon_view_set_item_padding:
6423
* @icon_view: a #GtkIconView
6424
* @item_padding: the item padding
6426
* Sets the #GtkIconView:item-padding property which specifies the padding
6427
* around each of the icon view's items.
6432
gtk_icon_view_set_item_padding (GtkIconView *icon_view,
6435
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
6437
if (icon_view->priv->item_padding != item_padding)
6439
icon_view->priv->item_padding = item_padding;
6441
gtk_icon_view_stop_editing (icon_view, TRUE);
6442
gtk_icon_view_invalidate_sizes (icon_view);
6443
gtk_icon_view_queue_layout (icon_view);
6445
g_object_notify (G_OBJECT (icon_view), "item-padding");
6450
* gtk_icon_view_get_item_padding:
6451
* @icon_view: a #GtkIconView
6453
* Returns the value of the ::item-padding property.
6455
* Return value: the padding around items
6460
gtk_icon_view_get_item_padding (GtkIconView *icon_view)
6462
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
6464
return icon_view->priv->item_padding;
6467
/* Get/set whether drag_motion requested the drag data and
6468
* drag_data_received should thus not actually insert the data,
6469
* since the data doesn't result from a drop.
6472
set_status_pending (GdkDragContext *context,
6473
GdkDragAction suggested_action)
6475
g_object_set_data (G_OBJECT (context),
6476
I_("gtk-icon-view-status-pending"),
6477
GINT_TO_POINTER (suggested_action));
6480
static GdkDragAction
6481
get_status_pending (GdkDragContext *context)
6483
return GPOINTER_TO_INT (g_object_get_data (G_OBJECT (context),
6484
"gtk-icon-view-status-pending"));
6488
unset_reorderable (GtkIconView *icon_view)
6490
if (icon_view->priv->reorderable)
6492
icon_view->priv->reorderable = FALSE;
6493
g_object_notify (G_OBJECT (icon_view), "reorderable");
6498
set_source_row (GdkDragContext *context,
6499
GtkTreeModel *model,
6500
GtkTreePath *source_row)
6503
g_object_set_data_full (G_OBJECT (context),
6504
I_("gtk-icon-view-source-row"),
6505
gtk_tree_row_reference_new (model, source_row),
6506
(GDestroyNotify) gtk_tree_row_reference_free);
6508
g_object_set_data_full (G_OBJECT (context),
6509
I_("gtk-icon-view-source-row"),
6514
get_source_row (GdkDragContext *context)
6516
GtkTreeRowReference *ref;
6518
ref = g_object_get_data (G_OBJECT (context), "gtk-icon-view-source-row");
6521
return gtk_tree_row_reference_get_path (ref);
6528
GtkTreeRowReference *dest_row;
6529
gboolean empty_view_drop;
6530
gboolean drop_append_mode;
6534
dest_row_free (gpointer data)
6536
DestRow *dr = (DestRow *)data;
6538
gtk_tree_row_reference_free (dr->dest_row);
6543
set_dest_row (GdkDragContext *context,
6544
GtkTreeModel *model,
6545
GtkTreePath *dest_row,
6546
gboolean empty_view_drop,
6547
gboolean drop_append_mode)
6553
g_object_set_data_full (G_OBJECT (context),
6554
I_("gtk-icon-view-dest-row"),
6559
dr = g_new0 (DestRow, 1);
6561
dr->dest_row = gtk_tree_row_reference_new (model, dest_row);
6562
dr->empty_view_drop = empty_view_drop;
6563
dr->drop_append_mode = drop_append_mode;
6564
g_object_set_data_full (G_OBJECT (context),
6565
I_("gtk-icon-view-dest-row"),
6566
dr, (GDestroyNotify) dest_row_free);
6570
get_dest_row (GdkDragContext *context)
6574
dr = g_object_get_data (G_OBJECT (context), "gtk-icon-view-dest-row");
6578
GtkTreePath *path = NULL;
6581
path = gtk_tree_row_reference_get_path (dr->dest_row);
6582
else if (dr->empty_view_drop)
6583
path = gtk_tree_path_new_from_indices (0, -1);
6587
if (path && dr->drop_append_mode)
6588
gtk_tree_path_next (path);
6597
check_model_dnd (GtkTreeModel *model,
6598
GType required_iface,
6599
const gchar *signal)
6601
if (model == NULL || !G_TYPE_CHECK_INSTANCE_TYPE ((model), required_iface))
6603
g_warning ("You must override the default '%s' handler "
6604
"on GtkIconView when using models that don't support "
6605
"the %s interface and enabling drag-and-drop. The simplest way to do this "
6606
"is to connect to '%s' and call "
6607
"g_signal_stop_emission_by_name() in your signal handler to prevent "
6608
"the default handler from running. Look at the source code "
6609
"for the default handler in gtkiconview.c to get an idea what "
6610
"your handler should do. (gtkiconview.c is in the GTK+ source "
6611
"code.) If you're using GTK+ from a language other than C, "
6612
"there may be a more natural way to override default handlers, e.g. via derivation.",
6613
signal, g_type_name (required_iface), signal);
6621
remove_scroll_timeout (GtkIconView *icon_view)
6623
if (icon_view->priv->scroll_timeout_id != 0)
6625
g_source_remove (icon_view->priv->scroll_timeout_id);
6627
icon_view->priv->scroll_timeout_id = 0;
6632
gtk_icon_view_autoscroll (GtkIconView *icon_view)
6634
gint px, py, x, y, width, height;
6635
gint hoffset, voffset;
6638
gdk_window_get_pointer (GTK_WIDGET (icon_view)->window, &px, &py, NULL);
6639
gdk_window_get_geometry (GTK_WIDGET (icon_view)->window, &x, &y, &width, &height, NULL);
6641
/* see if we are near the edge. */
6642
voffset = py - (y + 2 * SCROLL_EDGE_SIZE);
6644
voffset = MAX (py - (y + height - 2 * SCROLL_EDGE_SIZE), 0);
6646
hoffset = px - (x + 2 * SCROLL_EDGE_SIZE);
6648
hoffset = MAX (px - (x + width - 2 * SCROLL_EDGE_SIZE), 0);
6652
value = CLAMP (icon_view->priv->vadjustment->value + voffset,
6653
icon_view->priv->vadjustment->lower,
6654
icon_view->priv->vadjustment->upper - icon_view->priv->vadjustment->page_size);
6655
gtk_adjustment_set_value (icon_view->priv->vadjustment, value);
6659
value = CLAMP (icon_view->priv->hadjustment->value + hoffset,
6660
icon_view->priv->hadjustment->lower,
6661
icon_view->priv->hadjustment->upper - icon_view->priv->hadjustment->page_size);
6662
gtk_adjustment_set_value (icon_view->priv->hadjustment, value);
6668
drag_scroll_timeout (gpointer data)
6670
GtkIconView *icon_view = GTK_ICON_VIEW (data);
6672
gtk_icon_view_autoscroll (icon_view);
6679
set_destination (GtkIconView *icon_view,
6680
GdkDragContext *context,
6683
GdkDragAction *suggested_action,
6687
GtkTreePath *path = NULL;
6688
GtkIconViewDropPosition pos;
6689
GtkIconViewDropPosition old_pos;
6690
GtkTreePath *old_dest_path = NULL;
6691
gboolean can_drop = FALSE;
6693
widget = GTK_WIDGET (icon_view);
6695
*suggested_action = 0;
6698
if (!icon_view->priv->dest_set)
6700
/* someone unset us as a drag dest, note that if
6701
* we return FALSE drag_leave isn't called
6704
gtk_icon_view_set_drag_dest_item (icon_view,
6706
GTK_ICON_VIEW_DROP_LEFT);
6708
remove_scroll_timeout (GTK_ICON_VIEW (widget));
6710
return FALSE; /* no longer a drop site */
6713
*target = gtk_drag_dest_find_target (widget, context,
6714
gtk_drag_dest_get_target_list (widget));
6715
if (*target == GDK_NONE)
6718
if (!gtk_icon_view_get_dest_item_at_pos (icon_view, x, y, &path, &pos))
6721
GtkTreeModel *model;
6723
/* the row got dropped on empty space, let's setup a special case
6727
gtk_tree_path_free (path);
6729
model = gtk_icon_view_get_model (icon_view);
6731
n_children = gtk_tree_model_iter_n_children (model, NULL);
6734
pos = GTK_ICON_VIEW_DROP_BELOW;
6735
path = gtk_tree_path_new_from_indices (n_children - 1, -1);
6739
pos = GTK_ICON_VIEW_DROP_ABOVE;
6740
path = gtk_tree_path_new_from_indices (0, -1);
6750
gtk_icon_view_get_drag_dest_item (icon_view,
6755
gtk_tree_path_free (old_dest_path);
6757
if (TRUE /* FIXME if the location droppable predicate */)
6765
GtkWidget *source_widget;
6767
*suggested_action = gdk_drag_context_get_suggested_action (context);
6768
source_widget = gtk_drag_get_source_widget (context);
6770
if (source_widget == widget)
6772
/* Default to MOVE, unless the user has
6773
* pressed ctrl or shift to affect available actions
6775
if ((gdk_drag_context_get_actions (context) & GDK_ACTION_MOVE) != 0)
6776
*suggested_action = GDK_ACTION_MOVE;
6779
gtk_icon_view_set_drag_dest_item (GTK_ICON_VIEW (widget),
6784
/* can't drop here */
6785
gtk_icon_view_set_drag_dest_item (GTK_ICON_VIEW (widget),
6787
GTK_ICON_VIEW_DROP_LEFT);
6791
gtk_tree_path_free (path);
6797
get_logical_destination (GtkIconView *icon_view,
6798
gboolean *drop_append_mode)
6800
/* adjust path to point to the row the drop goes in front of */
6801
GtkTreePath *path = NULL;
6802
GtkIconViewDropPosition pos;
6804
*drop_append_mode = FALSE;
6806
gtk_icon_view_get_drag_dest_item (icon_view, &path, &pos);
6811
if (pos == GTK_ICON_VIEW_DROP_RIGHT ||
6812
pos == GTK_ICON_VIEW_DROP_BELOW)
6815
GtkTreeModel *model = icon_view->priv->model;
6817
if (!gtk_tree_model_get_iter (model, &iter, path) ||
6818
!gtk_tree_model_iter_next (model, &iter))
6819
*drop_append_mode = TRUE;
6822
*drop_append_mode = FALSE;
6823
gtk_tree_path_next (path);
6831
gtk_icon_view_maybe_begin_drag (GtkIconView *icon_view,
6832
GdkEventMotion *event)
6834
GtkWidget *widget = GTK_WIDGET (icon_view);
6835
GdkDragContext *context;
6836
GtkTreePath *path = NULL;
6838
GtkTreeModel *model;
6839
gboolean retval = FALSE;
6841
if (!icon_view->priv->source_set)
6844
if (icon_view->priv->pressed_button < 0)
6847
if (!gtk_drag_check_threshold (GTK_WIDGET (icon_view),
6848
icon_view->priv->press_start_x,
6849
icon_view->priv->press_start_y,
6850
event->x, event->y))
6853
model = gtk_icon_view_get_model (icon_view);
6858
button = icon_view->priv->pressed_button;
6859
icon_view->priv->pressed_button = -1;
6861
path = gtk_icon_view_get_path_at_pos (icon_view,
6862
icon_view->priv->press_start_x,
6863
icon_view->priv->press_start_y);
6868
if (!GTK_IS_TREE_DRAG_SOURCE (model) ||
6869
!gtk_tree_drag_source_row_draggable (GTK_TREE_DRAG_SOURCE (model),
6873
/* FIXME Check whether we're a start button, if not return FALSE and
6877
/* Now we can begin the drag */
6881
context = gtk_drag_begin (widget,
6882
gtk_drag_source_get_target_list (widget),
6883
icon_view->priv->source_actions,
6887
set_source_row (context, model, path);
6891
gtk_tree_path_free (path);
6896
/* Source side drag signals */
6898
gtk_icon_view_drag_begin (GtkWidget *widget,
6899
GdkDragContext *context)
6901
GtkIconView *icon_view;
6902
GtkIconViewItem *item;
6907
icon_view = GTK_ICON_VIEW (widget);
6909
/* if the user uses a custom DnD impl, we don't set the icon here */
6910
if (!icon_view->priv->dest_set && !icon_view->priv->source_set)
6913
item = gtk_icon_view_get_item_at_coords (icon_view,
6914
icon_view->priv->press_start_x,
6915
icon_view->priv->press_start_y,
6919
g_return_if_fail (item != NULL);
6921
x = icon_view->priv->press_start_x - item->x + 1;
6922
y = icon_view->priv->press_start_y - item->y + 1;
6924
path = gtk_tree_path_new_from_indices (item->index, -1);
6925
icon = gtk_icon_view_create_drag_icon (icon_view, path);
6926
gtk_tree_path_free (path);
6928
gtk_drag_set_icon_pixmap (context,
6929
gdk_drawable_get_colormap (icon),
6934
g_object_unref (icon);
6938
gtk_icon_view_drag_end (GtkWidget *widget,
6939
GdkDragContext *context)
6945
gtk_icon_view_drag_data_get (GtkWidget *widget,
6946
GdkDragContext *context,
6947
GtkSelectionData *selection_data,
6951
GtkIconView *icon_view;
6952
GtkTreeModel *model;
6953
GtkTreePath *source_row;
6955
icon_view = GTK_ICON_VIEW (widget);
6956
model = gtk_icon_view_get_model (icon_view);
6961
if (!icon_view->priv->source_set)
6964
source_row = get_source_row (context);
6966
if (source_row == NULL)
6969
/* We can implement the GTK_TREE_MODEL_ROW target generically for
6970
* any model; for DragSource models there are some other targets
6974
if (GTK_IS_TREE_DRAG_SOURCE (model) &&
6975
gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (model),
6980
/* If drag_data_get does nothing, try providing row data. */
6981
if (selection_data->target == gdk_atom_intern_static_string ("GTK_TREE_MODEL_ROW"))
6982
gtk_tree_set_row_drag_data (selection_data,
6987
gtk_tree_path_free (source_row);
6991
gtk_icon_view_drag_data_delete (GtkWidget *widget,
6992
GdkDragContext *context)
6994
GtkTreeModel *model;
6995
GtkIconView *icon_view;
6996
GtkTreePath *source_row;
6998
icon_view = GTK_ICON_VIEW (widget);
6999
model = gtk_icon_view_get_model (icon_view);
7001
if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_SOURCE, "drag-data-delete"))
7004
if (!icon_view->priv->source_set)
7007
source_row = get_source_row (context);
7009
if (source_row == NULL)
7012
gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (model),
7015
gtk_tree_path_free (source_row);
7017
set_source_row (context, NULL, NULL);
7020
/* Target side drag signals */
7022
gtk_icon_view_drag_leave (GtkWidget *widget,
7023
GdkDragContext *context,
7026
GtkIconView *icon_view;
7028
icon_view = GTK_ICON_VIEW (widget);
7030
/* unset any highlight row */
7031
gtk_icon_view_set_drag_dest_item (icon_view,
7033
GTK_ICON_VIEW_DROP_LEFT);
7035
remove_scroll_timeout (icon_view);
7039
gtk_icon_view_drag_motion (GtkWidget *widget,
7040
GdkDragContext *context,
7045
GtkTreePath *path = NULL;
7046
GtkIconViewDropPosition pos;
7047
GtkIconView *icon_view;
7048
GdkDragAction suggested_action = 0;
7052
icon_view = GTK_ICON_VIEW (widget);
7054
if (!set_destination (icon_view, context, x, y, &suggested_action, &target))
7057
gtk_icon_view_get_drag_dest_item (icon_view, &path, &pos);
7059
/* we only know this *after* set_desination_row */
7060
empty = icon_view->priv->empty_view_drop;
7062
if (path == NULL && !empty)
7064
/* Can't drop here. */
7065
gdk_drag_status (context, 0, time);
7069
if (icon_view->priv->scroll_timeout_id == 0)
7071
icon_view->priv->scroll_timeout_id =
7072
gdk_threads_add_timeout (50, drag_scroll_timeout, icon_view);
7075
if (target == gdk_atom_intern_static_string ("GTK_TREE_MODEL_ROW"))
7077
/* Request data so we can use the source row when
7078
* determining whether to accept the drop
7080
set_status_pending (context, suggested_action);
7081
gtk_drag_get_data (widget, context, target, time);
7085
set_status_pending (context, 0);
7086
gdk_drag_status (context, suggested_action, time);
7091
gtk_tree_path_free (path);
7097
gtk_icon_view_drag_drop (GtkWidget *widget,
7098
GdkDragContext *context,
7103
GtkIconView *icon_view;
7105
GdkDragAction suggested_action = 0;
7106
GdkAtom target = GDK_NONE;
7107
GtkTreeModel *model;
7108
gboolean drop_append_mode;
7110
icon_view = GTK_ICON_VIEW (widget);
7111
model = gtk_icon_view_get_model (icon_view);
7113
remove_scroll_timeout (GTK_ICON_VIEW (widget));
7115
if (!icon_view->priv->dest_set)
7118
if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_DEST, "drag-drop"))
7121
if (!set_destination (icon_view, context, x, y, &suggested_action, &target))
7124
path = get_logical_destination (icon_view, &drop_append_mode);
7126
if (target != GDK_NONE && path != NULL)
7128
/* in case a motion had requested drag data, change things so we
7129
* treat drag data receives as a drop.
7131
set_status_pending (context, 0);
7132
set_dest_row (context, model, path,
7133
icon_view->priv->empty_view_drop, drop_append_mode);
7137
gtk_tree_path_free (path);
7139
/* Unset this thing */
7140
gtk_icon_view_set_drag_dest_item (icon_view, NULL, GTK_ICON_VIEW_DROP_LEFT);
7142
if (target != GDK_NONE)
7144
gtk_drag_get_data (widget, context, target, time);
7152
gtk_icon_view_drag_data_received (GtkWidget *widget,
7153
GdkDragContext *context,
7156
GtkSelectionData *selection_data,
7161
gboolean accepted = FALSE;
7162
GtkTreeModel *model;
7163
GtkIconView *icon_view;
7164
GtkTreePath *dest_row;
7165
GdkDragAction suggested_action;
7166
gboolean drop_append_mode;
7168
icon_view = GTK_ICON_VIEW (widget);
7169
model = gtk_icon_view_get_model (icon_view);
7171
if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_DEST, "drag-data-received"))
7174
if (!icon_view->priv->dest_set)
7177
suggested_action = get_status_pending (context);
7179
if (suggested_action)
7181
/* We are getting this data due to a request in drag_motion,
7182
* rather than due to a request in drag_drop, so we are just
7183
* supposed to call drag_status, not actually paste in the
7186
path = get_logical_destination (icon_view, &drop_append_mode);
7189
suggested_action = 0;
7191
if (suggested_action)
7193
if (!gtk_tree_drag_dest_row_drop_possible (GTK_TREE_DRAG_DEST (model),
7196
suggested_action = 0;
7199
gdk_drag_status (context, suggested_action, time);
7202
gtk_tree_path_free (path);
7204
/* If you can't drop, remove user drop indicator until the next motion */
7205
if (suggested_action == 0)
7206
gtk_icon_view_set_drag_dest_item (icon_view,
7208
GTK_ICON_VIEW_DROP_LEFT);
7213
dest_row = get_dest_row (context);
7215
if (dest_row == NULL)
7218
if (selection_data->length >= 0)
7220
if (gtk_tree_drag_dest_drag_data_received (GTK_TREE_DRAG_DEST (model),
7226
gtk_drag_finish (context,
7228
(gdk_drag_context_get_selected_action (context) == GDK_ACTION_MOVE),
7231
gtk_tree_path_free (dest_row);
7234
set_dest_row (context, NULL, NULL, FALSE, FALSE);
7237
/* Drag-and-Drop support */
7239
* gtk_icon_view_enable_model_drag_source:
7240
* @icon_view: a #GtkIconTreeView
7241
* @start_button_mask: Mask of allowed buttons to start drag
7242
* @targets: the table of targets that the drag will support
7243
* @n_targets: the number of items in @targets
7244
* @actions: the bitmask of possible actions for a drag from this
7247
* Turns @icon_view into a drag source for automatic DND. Calling this
7248
* method sets #GtkIconView:reorderable to %FALSE.
7253
gtk_icon_view_enable_model_drag_source (GtkIconView *icon_view,
7254
GdkModifierType start_button_mask,
7255
const GtkTargetEntry *targets,
7257
GdkDragAction actions)
7259
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
7261
gtk_drag_source_set (GTK_WIDGET (icon_view), 0, targets, n_targets, actions);
7263
icon_view->priv->start_button_mask = start_button_mask;
7264
icon_view->priv->source_actions = actions;
7266
icon_view->priv->source_set = TRUE;
7268
unset_reorderable (icon_view);
7272
* gtk_icon_view_enable_model_drag_dest:
7273
* @icon_view: a #GtkIconView
7274
* @targets: the table of targets that the drag will support
7275
* @n_targets: the number of items in @targets
7276
* @actions: the bitmask of possible actions for a drag to this
7279
* Turns @icon_view into a drop destination for automatic DND. Calling this
7280
* method sets #GtkIconView:reorderable to %FALSE.
7285
gtk_icon_view_enable_model_drag_dest (GtkIconView *icon_view,
7286
const GtkTargetEntry *targets,
7288
GdkDragAction actions)
7290
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
7292
gtk_drag_dest_set (GTK_WIDGET (icon_view), 0, targets, n_targets, actions);
7294
icon_view->priv->dest_actions = actions;
7296
icon_view->priv->dest_set = TRUE;
7298
unset_reorderable (icon_view);
7302
* gtk_icon_view_unset_model_drag_source:
7303
* @icon_view: a #GtkIconView
7305
* Undoes the effect of gtk_icon_view_enable_model_drag_source(). Calling this
7306
* method sets #GtkIconView:reorderable to %FALSE.
7311
gtk_icon_view_unset_model_drag_source (GtkIconView *icon_view)
7313
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
7315
if (icon_view->priv->source_set)
7317
gtk_drag_source_unset (GTK_WIDGET (icon_view));
7318
icon_view->priv->source_set = FALSE;
7321
unset_reorderable (icon_view);
7325
* gtk_icon_view_unset_model_drag_dest:
7326
* @icon_view: a #GtkIconView
7328
* Undoes the effect of gtk_icon_view_enable_model_drag_dest(). Calling this
7329
* method sets #GtkIconView:reorderable to %FALSE.
7334
gtk_icon_view_unset_model_drag_dest (GtkIconView *icon_view)
7336
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
7338
if (icon_view->priv->dest_set)
7340
gtk_drag_dest_unset (GTK_WIDGET (icon_view));
7341
icon_view->priv->dest_set = FALSE;
7344
unset_reorderable (icon_view);
7347
/* These are useful to implement your own custom stuff. */
7349
* gtk_icon_view_set_drag_dest_item:
7350
* @icon_view: a #GtkIconView
7351
* @path: (allow-none): The path of the item to highlight, or %NULL.
7352
* @pos: Specifies where to drop, relative to the item
7354
* Sets the item that is highlighted for feedback.
7359
gtk_icon_view_set_drag_dest_item (GtkIconView *icon_view,
7361
GtkIconViewDropPosition pos)
7363
/* Note; this function is exported to allow a custom DND
7364
* implementation, so it can't touch TreeViewDragInfo
7367
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
7369
if (icon_view->priv->dest_item)
7371
GtkTreePath *current_path;
7372
current_path = gtk_tree_row_reference_get_path (icon_view->priv->dest_item);
7373
gtk_tree_row_reference_free (icon_view->priv->dest_item);
7374
icon_view->priv->dest_item = NULL;
7376
gtk_icon_view_queue_draw_path (icon_view, current_path);
7377
gtk_tree_path_free (current_path);
7380
/* special case a drop on an empty model */
7381
icon_view->priv->empty_view_drop = FALSE;
7382
if (pos == GTK_ICON_VIEW_DROP_ABOVE && path
7383
&& gtk_tree_path_get_depth (path) == 1
7384
&& gtk_tree_path_get_indices (path)[0] == 0)
7388
n_children = gtk_tree_model_iter_n_children (icon_view->priv->model,
7391
if (n_children == 0)
7392
icon_view->priv->empty_view_drop = TRUE;
7395
icon_view->priv->dest_pos = pos;
7399
icon_view->priv->dest_item =
7400
gtk_tree_row_reference_new_proxy (G_OBJECT (icon_view),
7401
icon_view->priv->model, path);
7403
gtk_icon_view_queue_draw_path (icon_view, path);
7408
* gtk_icon_view_get_drag_dest_item:
7409
* @icon_view: a #GtkIconView
7410
* @path: (allow-none): Return location for the path of the highlighted item, or %NULL.
7411
* @pos: (allow-none): Return location for the drop position, or %NULL
7413
* Gets information about the item that is highlighted for feedback.
7418
gtk_icon_view_get_drag_dest_item (GtkIconView *icon_view,
7420
GtkIconViewDropPosition *pos)
7422
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
7426
if (icon_view->priv->dest_item)
7427
*path = gtk_tree_row_reference_get_path (icon_view->priv->dest_item);
7433
*pos = icon_view->priv->dest_pos;
7437
* gtk_icon_view_get_dest_item_at_pos:
7438
* @icon_view: a #GtkIconView
7439
* @drag_x: the position to determine the destination item for
7440
* @drag_y: the position to determine the destination item for
7441
* @path: (allow-none): Return location for the path of the item, or %NULL.
7442
* @pos: (allow-none): Return location for the drop position, or %NULL
7444
* Determines the destination item for a given position.
7446
* Return value: whether there is an item at the given position.
7451
gtk_icon_view_get_dest_item_at_pos (GtkIconView *icon_view,
7455
GtkIconViewDropPosition *pos)
7457
GtkIconViewItem *item;
7459
/* Note; this function is exported to allow a custom DND
7460
* implementation, so it can't touch TreeViewDragInfo
7463
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), FALSE);
7464
g_return_val_if_fail (drag_x >= 0, FALSE);
7465
g_return_val_if_fail (drag_y >= 0, FALSE);
7466
g_return_val_if_fail (icon_view->priv->bin_window != NULL, FALSE);
7472
item = gtk_icon_view_get_item_at_coords (icon_view,
7473
drag_x + icon_view->priv->hadjustment->value,
7474
drag_y + icon_view->priv->vadjustment->value,
7481
*path = gtk_tree_path_new_from_indices (item->index, -1);
7485
if (drag_x < item->x + item->width / 4)
7486
*pos = GTK_ICON_VIEW_DROP_LEFT;
7487
else if (drag_x > item->x + item->width * 3 / 4)
7488
*pos = GTK_ICON_VIEW_DROP_RIGHT;
7489
else if (drag_y < item->y + item->height / 4)
7490
*pos = GTK_ICON_VIEW_DROP_ABOVE;
7491
else if (drag_y > item->y + item->height * 3 / 4)
7492
*pos = GTK_ICON_VIEW_DROP_BELOW;
7494
*pos = GTK_ICON_VIEW_DROP_INTO;
7501
* gtk_icon_view_create_drag_icon:
7502
* @icon_view: a #GtkIconView
7503
* @path: a #GtkTreePath in @icon_view
7505
* Creates a #GdkPixmap representation of the item at @path.
7506
* This image is used for a drag icon.
7508
* Return value: (transfer full): a newly-allocated pixmap of the drag icon.
7513
gtk_icon_view_create_drag_icon (GtkIconView *icon_view,
7518
GdkPixmap *drawable;
7523
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), NULL);
7524
g_return_val_if_fail (path != NULL, NULL);
7526
widget = GTK_WIDGET (icon_view);
7528
if (!gtk_widget_get_realized (widget))
7531
index = gtk_tree_path_get_indices (path)[0];
7533
for (l = icon_view->priv->items; l; l = l->next)
7535
GtkIconViewItem *item = l->data;
7537
if (index == item->index)
7539
drawable = gdk_pixmap_new (icon_view->priv->bin_window,
7544
cr = gdk_cairo_create (drawable);
7545
cairo_set_line_width (cr, 1.);
7547
gdk_cairo_set_source_color
7548
(cr, &widget->style->base[gtk_widget_get_state (widget)]);
7549
cairo_rectangle (cr, 0, 0, item->width + 2, item->height + 2);
7554
area.width = item->width;
7555
area.height = item->height;
7557
gtk_icon_view_paint_item (icon_view, cr, item, &area,
7558
drawable, 1, 1, FALSE);
7560
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
7561
cairo_rectangle (cr, 0.5, 0.5, item->width + 1, item->height + 1);
7574
* gtk_icon_view_get_reorderable:
7575
* @icon_view: a #GtkIconView
7577
* Retrieves whether the user can reorder the list via drag-and-drop.
7578
* See gtk_icon_view_set_reorderable().
7580
* Return value: %TRUE if the list can be reordered.
7585
gtk_icon_view_get_reorderable (GtkIconView *icon_view)
7587
g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), FALSE);
7589
return icon_view->priv->reorderable;
7592
static const GtkTargetEntry item_targets[] = {
7593
{ "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, 0 }
7598
* gtk_icon_view_set_reorderable:
7599
* @icon_view: A #GtkIconView.
7600
* @reorderable: %TRUE, if the list of items can be reordered.
7602
* This function is a convenience function to allow you to reorder models that
7603
* support the #GtkTreeDragSourceIface and the #GtkTreeDragDestIface. Both
7604
* #GtkTreeStore and #GtkListStore support these. If @reorderable is %TRUE, then
7605
* the user can reorder the model by dragging and dropping rows. The
7606
* developer can listen to these changes by connecting to the model's
7607
* row_inserted and row_deleted signals. The reordering is implemented by setting up
7608
* the icon view as a drag source and destination. Therefore, drag and
7609
* drop can not be used in a reorderable view for any other purpose.
7611
* This function does not give you any degree of control over the order -- any
7612
* reordering is allowed. If more control is needed, you should probably
7613
* handle drag and drop manually.
7618
gtk_icon_view_set_reorderable (GtkIconView *icon_view,
7619
gboolean reorderable)
7621
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
7623
reorderable = reorderable != FALSE;
7625
if (icon_view->priv->reorderable == reorderable)
7630
gtk_icon_view_enable_model_drag_source (icon_view,
7633
G_N_ELEMENTS (item_targets),
7635
gtk_icon_view_enable_model_drag_dest (icon_view,
7637
G_N_ELEMENTS (item_targets),
7642
gtk_icon_view_unset_model_drag_source (icon_view);
7643
gtk_icon_view_unset_model_drag_dest (icon_view);
7646
icon_view->priv->reorderable = reorderable;
7648
g_object_notify (G_OBJECT (icon_view), "reorderable");
7652
/* Accessibility Support */
7654
static gpointer accessible_parent_class;
7655
static gpointer accessible_item_parent_class;
7656
static GQuark accessible_private_data_quark = 0;
7658
#define GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE (gtk_icon_view_item_accessible_get_type ())
7659
#define GTK_ICON_VIEW_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE, GtkIconViewItemAccessible))
7660
#define GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ICON_VIEW_ITEM_ACCESSIBLE))
7662
static GType gtk_icon_view_item_accessible_get_type (void);
7673
GtkIconViewItem *item;
7677
AtkStateSet *state_set;
7681
GtkTextBuffer *text_buffer;
7683
gchar *action_descriptions[LAST_ACTION];
7684
gchar *image_description;
7685
guint action_idle_handler;
7686
} GtkIconViewItemAccessible;
7688
static const gchar *const gtk_icon_view_item_accessible_action_names[] =
7694
static const gchar *const gtk_icon_view_item_accessible_action_descriptions[] =
7699
typedef struct _GtkIconViewItemAccessibleClass
7701
AtkObjectClass parent_class;
7703
} GtkIconViewItemAccessibleClass;
7705
static gboolean gtk_icon_view_item_accessible_is_showing (GtkIconViewItemAccessible *item);
7708
gtk_icon_view_item_accessible_idle_do_action (gpointer data)
7710
GtkIconViewItemAccessible *item;
7711
GtkIconView *icon_view;
7714
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (data);
7715
item->action_idle_handler = 0;
7717
if (item->widget != NULL)
7719
icon_view = GTK_ICON_VIEW (item->widget);
7720
path = gtk_tree_path_new_from_indices (item->item->index, -1);
7721
gtk_icon_view_item_activated (icon_view, path);
7722
gtk_tree_path_free (path);
7729
gtk_icon_view_item_accessible_action_do_action (AtkAction *action,
7732
GtkIconViewItemAccessible *item;
7734
if (i < 0 || i >= LAST_ACTION)
7737
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
7739
if (!GTK_IS_ICON_VIEW (item->widget))
7742
if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
7747
case ACTION_ACTIVATE:
7748
if (!item->action_idle_handler)
7749
item->action_idle_handler = gdk_threads_add_idle (gtk_icon_view_item_accessible_idle_do_action, item);
7752
g_assert_not_reached ();
7760
gtk_icon_view_item_accessible_action_get_n_actions (AtkAction *action)
7765
static const gchar *
7766
gtk_icon_view_item_accessible_action_get_description (AtkAction *action,
7769
GtkIconViewItemAccessible *item;
7771
if (i < 0 || i >= LAST_ACTION)
7774
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
7776
if (item->action_descriptions[i])
7777
return item->action_descriptions[i];
7779
return gtk_icon_view_item_accessible_action_descriptions[i];
7782
static const gchar *
7783
gtk_icon_view_item_accessible_action_get_name (AtkAction *action,
7786
if (i < 0 || i >= LAST_ACTION)
7789
return gtk_icon_view_item_accessible_action_names[i];
7793
gtk_icon_view_item_accessible_action_set_description (AtkAction *action,
7795
const gchar *description)
7797
GtkIconViewItemAccessible *item;
7799
if (i < 0 || i >= LAST_ACTION)
7802
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (action);
7804
g_free (item->action_descriptions[i]);
7806
item->action_descriptions[i] = g_strdup (description);
7812
atk_action_item_interface_init (AtkActionIface *iface)
7814
iface->do_action = gtk_icon_view_item_accessible_action_do_action;
7815
iface->get_n_actions = gtk_icon_view_item_accessible_action_get_n_actions;
7816
iface->get_description = gtk_icon_view_item_accessible_action_get_description;
7817
iface->get_name = gtk_icon_view_item_accessible_action_get_name;
7818
iface->set_description = gtk_icon_view_item_accessible_action_set_description;
7821
static const gchar *
7822
gtk_icon_view_item_accessible_image_get_image_description (AtkImage *image)
7824
GtkIconViewItemAccessible *item;
7826
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
7828
return item->image_description;
7832
gtk_icon_view_item_accessible_image_set_image_description (AtkImage *image,
7833
const gchar *description)
7835
GtkIconViewItemAccessible *item;
7837
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
7839
g_free (item->image_description);
7840
item->image_description = g_strdup (description);
7846
get_pixbuf_box (GtkIconView *icon_view,
7847
GtkIconViewItem *item,
7852
for (l = icon_view->priv->cell_list; l; l = l->next)
7854
GtkIconViewCellInfo *info = l->data;
7856
if (GTK_IS_CELL_RENDERER_PIXBUF (info->cell))
7858
gtk_icon_view_get_cell_box (icon_view, item, info, box);
7868
get_text (GtkIconView *icon_view,
7869
GtkIconViewItem *item)
7874
for (l = icon_view->priv->cell_list; l; l = l->next)
7876
GtkIconViewCellInfo *info = l->data;
7878
if (GTK_IS_CELL_RENDERER_TEXT (info->cell))
7880
g_object_get (info->cell, "text", &text, NULL);
7890
gtk_icon_view_item_accessible_image_get_image_size (AtkImage *image,
7894
GtkIconViewItemAccessible *item;
7897
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
7899
if (!GTK_IS_ICON_VIEW (item->widget))
7902
if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
7905
if (get_pixbuf_box (GTK_ICON_VIEW (item->widget), item->item, &box))
7908
*height = box.height;
7913
gtk_icon_view_item_accessible_image_get_image_position (AtkImage *image,
7916
AtkCoordType coord_type)
7918
GtkIconViewItemAccessible *item;
7921
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (image);
7923
if (!GTK_IS_ICON_VIEW (item->widget))
7926
if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
7929
atk_component_get_position (ATK_COMPONENT (image), x, y, coord_type);
7931
if (get_pixbuf_box (GTK_ICON_VIEW (item->widget), item->item, &box))
7933
*x+= box.x - item->item->x;
7934
*y+= box.y - item->item->y;
7940
atk_image_item_interface_init (AtkImageIface *iface)
7942
iface->get_image_description = gtk_icon_view_item_accessible_image_get_image_description;
7943
iface->set_image_description = gtk_icon_view_item_accessible_image_set_image_description;
7944
iface->get_image_size = gtk_icon_view_item_accessible_image_get_image_size;
7945
iface->get_image_position = gtk_icon_view_item_accessible_image_get_image_position;
7949
gtk_icon_view_item_accessible_text_get_text (AtkText *text,
7953
GtkIconViewItemAccessible *item;
7954
GtkTextIter start, end;
7955
GtkTextBuffer *buffer;
7957
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
7959
if (!GTK_IS_ICON_VIEW (item->widget))
7962
if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
7965
buffer = item->text_buffer;
7966
gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
7968
gtk_text_buffer_get_end_iter (buffer, &end);
7970
gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
7972
return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
7976
gtk_icon_view_item_accessible_text_get_character_at_offset (AtkText *text,
7979
GtkIconViewItemAccessible *item;
7980
GtkTextIter start, end;
7981
GtkTextBuffer *buffer;
7985
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
7987
if (!GTK_IS_ICON_VIEW (item->widget))
7990
if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
7993
buffer = item->text_buffer;
7994
if (offset >= gtk_text_buffer_get_char_count (buffer))
7997
gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
7999
gtk_text_iter_forward_char (&end);
8000
string = gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
8001
unichar = g_utf8_get_char (string);
8009
get_pango_text_offsets (PangoLayout *layout,
8010
GtkTextBuffer *buffer,
8012
AtkTextBoundary boundary_type,
8016
GtkTextIter *start_iter,
8017
GtkTextIter *end_iter)
8019
PangoLayoutIter *iter;
8020
PangoLayoutLine *line, *prev_line = NULL, *prev_prev_line = NULL;
8021
gint index, start_index, end_index;
8023
gboolean found = FALSE;
8025
text = pango_layout_get_text (layout);
8026
index = g_utf8_offset_to_pointer (text, offset) - text;
8027
iter = pango_layout_get_iter (layout);
8030
line = pango_layout_iter_get_line_readonly (iter);
8031
start_index = line->start_index;
8032
end_index = start_index + line->length;
8034
if (index >= start_index && index <= end_index)
8037
* Found line for offset
8043
* We want the previous line
8047
switch (boundary_type)
8049
case ATK_TEXT_BOUNDARY_LINE_START:
8050
end_index = start_index;
8051
start_index = prev_line->start_index;
8053
case ATK_TEXT_BOUNDARY_LINE_END:
8055
start_index = prev_prev_line->start_index +
8056
prev_prev_line->length;
8057
end_index = prev_line->start_index + prev_line->length;
8060
g_assert_not_reached();
8064
start_index = end_index = 0;
8067
switch (boundary_type)
8069
case ATK_TEXT_BOUNDARY_LINE_START:
8070
if (pango_layout_iter_next_line (iter))
8071
end_index = pango_layout_iter_get_line_readonly (iter)->start_index;
8073
case ATK_TEXT_BOUNDARY_LINE_END:
8075
start_index = prev_line->start_index +
8079
g_assert_not_reached();
8084
* We want the next line
8086
if (pango_layout_iter_next_line (iter))
8088
line = pango_layout_iter_get_line_readonly (iter);
8089
switch (boundary_type)
8091
case ATK_TEXT_BOUNDARY_LINE_START:
8092
start_index = line->start_index;
8093
if (pango_layout_iter_next_line (iter))
8094
end_index = pango_layout_iter_get_line_readonly (iter)->start_index;
8096
end_index = start_index + line->length;
8098
case ATK_TEXT_BOUNDARY_LINE_END:
8099
start_index = end_index;
8100
end_index = line->start_index + line->length;
8103
g_assert_not_reached();
8107
start_index = end_index;
8113
prev_prev_line = prev_line;
8116
while (pango_layout_iter_next_line (iter));
8120
start_index = prev_line->start_index + prev_line->length;
8121
end_index = start_index;
8123
pango_layout_iter_free (iter);
8124
*start_offset = g_utf8_pointer_to_offset (text, text + start_index);
8125
*end_offset = g_utf8_pointer_to_offset (text, text + end_index);
8127
gtk_text_buffer_get_iter_at_offset (buffer, start_iter, *start_offset);
8128
gtk_text_buffer_get_iter_at_offset (buffer, end_iter, *end_offset);
8133
gtk_icon_view_item_accessible_text_get_text_before_offset (AtkText *text,
8135
AtkTextBoundary boundary_type,
8139
GtkIconViewItemAccessible *item;
8140
GtkTextIter start, end;
8141
GtkTextBuffer *buffer;
8143
GtkIconView *icon_view;
8146
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
8148
if (!GTK_IS_ICON_VIEW (item->widget))
8151
if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
8154
buffer = item->text_buffer;
8156
if (!gtk_text_buffer_get_char_count (buffer))
8160
return g_strdup ("");
8162
gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
8166
switch (boundary_type)
8168
case ATK_TEXT_BOUNDARY_CHAR:
8169
gtk_text_iter_backward_char(&start);
8171
case ATK_TEXT_BOUNDARY_WORD_START:
8172
if (!gtk_text_iter_starts_word (&start))
8173
gtk_text_iter_backward_word_start (&start);
8175
gtk_text_iter_backward_word_start(&start);
8177
case ATK_TEXT_BOUNDARY_WORD_END:
8178
if (gtk_text_iter_inside_word (&start) &&
8179
!gtk_text_iter_starts_word (&start))
8180
gtk_text_iter_backward_word_start (&start);
8181
while (!gtk_text_iter_ends_word (&start))
8183
if (!gtk_text_iter_backward_char (&start))
8187
gtk_text_iter_backward_word_start(&start);
8188
while (!gtk_text_iter_ends_word (&start))
8190
if (!gtk_text_iter_backward_char (&start))
8194
case ATK_TEXT_BOUNDARY_SENTENCE_START:
8195
if (!gtk_text_iter_starts_sentence (&start))
8196
gtk_text_iter_backward_sentence_start (&start);
8198
gtk_text_iter_backward_sentence_start (&start);
8200
case ATK_TEXT_BOUNDARY_SENTENCE_END:
8201
if (gtk_text_iter_inside_sentence (&start) &&
8202
!gtk_text_iter_starts_sentence (&start))
8203
gtk_text_iter_backward_sentence_start (&start);
8204
while (!gtk_text_iter_ends_sentence (&start))
8206
if (!gtk_text_iter_backward_char (&start))
8210
gtk_text_iter_backward_sentence_start (&start);
8211
while (!gtk_text_iter_ends_sentence (&start))
8213
if (!gtk_text_iter_backward_char (&start))
8217
case ATK_TEXT_BOUNDARY_LINE_START:
8218
case ATK_TEXT_BOUNDARY_LINE_END:
8220
icon_view = GTK_ICON_VIEW (item->widget);
8221
/* FIXME we probably have to use GailTextCell to salvage this */
8222
gtk_icon_view_update_item_text (icon_view, item->item);
8223
get_pango_text_offsets (icon_view->priv->layout,
8236
*start_offset = gtk_text_iter_get_offset (&start);
8237
*end_offset = gtk_text_iter_get_offset (&end);
8239
return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
8243
gtk_icon_view_item_accessible_text_get_text_at_offset (AtkText *text,
8245
AtkTextBoundary boundary_type,
8249
GtkIconViewItemAccessible *item;
8250
GtkTextIter start, end;
8251
GtkTextBuffer *buffer;
8253
GtkIconView *icon_view;
8256
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
8258
if (!GTK_IS_ICON_VIEW (item->widget))
8261
if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
8264
buffer = item->text_buffer;
8266
if (!gtk_text_buffer_get_char_count (buffer))
8270
return g_strdup ("");
8272
gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
8276
switch (boundary_type)
8278
case ATK_TEXT_BOUNDARY_CHAR:
8279
gtk_text_iter_forward_char (&end);
8281
case ATK_TEXT_BOUNDARY_WORD_START:
8282
if (!gtk_text_iter_starts_word (&start))
8283
gtk_text_iter_backward_word_start (&start);
8284
if (gtk_text_iter_inside_word (&end))
8285
gtk_text_iter_forward_word_end (&end);
8286
while (!gtk_text_iter_starts_word (&end))
8288
if (!gtk_text_iter_forward_char (&end))
8292
case ATK_TEXT_BOUNDARY_WORD_END:
8293
if (gtk_text_iter_inside_word (&start) &&
8294
!gtk_text_iter_starts_word (&start))
8295
gtk_text_iter_backward_word_start (&start);
8296
while (!gtk_text_iter_ends_word (&start))
8298
if (!gtk_text_iter_backward_char (&start))
8301
gtk_text_iter_forward_word_end (&end);
8303
case ATK_TEXT_BOUNDARY_SENTENCE_START:
8304
if (!gtk_text_iter_starts_sentence (&start))
8305
gtk_text_iter_backward_sentence_start (&start);
8306
if (gtk_text_iter_inside_sentence (&end))
8307
gtk_text_iter_forward_sentence_end (&end);
8308
while (!gtk_text_iter_starts_sentence (&end))
8310
if (!gtk_text_iter_forward_char (&end))
8314
case ATK_TEXT_BOUNDARY_SENTENCE_END:
8315
if (gtk_text_iter_inside_sentence (&start) &&
8316
!gtk_text_iter_starts_sentence (&start))
8317
gtk_text_iter_backward_sentence_start (&start);
8318
while (!gtk_text_iter_ends_sentence (&start))
8320
if (!gtk_text_iter_backward_char (&start))
8323
gtk_text_iter_forward_sentence_end (&end);
8325
case ATK_TEXT_BOUNDARY_LINE_START:
8326
case ATK_TEXT_BOUNDARY_LINE_END:
8328
icon_view = GTK_ICON_VIEW (item->widget);
8329
/* FIXME we probably have to use GailTextCell to salvage this */
8330
gtk_icon_view_update_item_text (icon_view, item->item);
8331
get_pango_text_offsets (icon_view->priv->layout,
8345
*start_offset = gtk_text_iter_get_offset (&start);
8346
*end_offset = gtk_text_iter_get_offset (&end);
8348
return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
8352
gtk_icon_view_item_accessible_text_get_text_after_offset (AtkText *text,
8354
AtkTextBoundary boundary_type,
8358
GtkIconViewItemAccessible *item;
8359
GtkTextIter start, end;
8360
GtkTextBuffer *buffer;
8362
GtkIconView *icon_view;
8365
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
8367
if (!GTK_IS_ICON_VIEW (item->widget))
8370
if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
8373
buffer = item->text_buffer;
8375
if (!gtk_text_buffer_get_char_count (buffer))
8379
return g_strdup ("");
8381
gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
8385
switch (boundary_type)
8387
case ATK_TEXT_BOUNDARY_CHAR:
8388
gtk_text_iter_forward_char(&start);
8389
gtk_text_iter_forward_chars(&end, 2);
8391
case ATK_TEXT_BOUNDARY_WORD_START:
8392
if (gtk_text_iter_inside_word (&end))
8393
gtk_text_iter_forward_word_end (&end);
8394
while (!gtk_text_iter_starts_word (&end))
8396
if (!gtk_text_iter_forward_char (&end))
8400
if (!gtk_text_iter_is_end (&end))
8402
gtk_text_iter_forward_word_end (&end);
8403
while (!gtk_text_iter_starts_word (&end))
8405
if (!gtk_text_iter_forward_char (&end))
8410
case ATK_TEXT_BOUNDARY_WORD_END:
8411
gtk_text_iter_forward_word_end (&end);
8413
if (!gtk_text_iter_is_end (&end))
8414
gtk_text_iter_forward_word_end (&end);
8416
case ATK_TEXT_BOUNDARY_SENTENCE_START:
8417
if (gtk_text_iter_inside_sentence (&end))
8418
gtk_text_iter_forward_sentence_end (&end);
8419
while (!gtk_text_iter_starts_sentence (&end))
8421
if (!gtk_text_iter_forward_char (&end))
8425
if (!gtk_text_iter_is_end (&end))
8427
gtk_text_iter_forward_sentence_end (&end);
8428
while (!gtk_text_iter_starts_sentence (&end))
8430
if (!gtk_text_iter_forward_char (&end))
8435
case ATK_TEXT_BOUNDARY_SENTENCE_END:
8436
gtk_text_iter_forward_sentence_end (&end);
8438
if (!gtk_text_iter_is_end (&end))
8439
gtk_text_iter_forward_sentence_end (&end);
8441
case ATK_TEXT_BOUNDARY_LINE_START:
8442
case ATK_TEXT_BOUNDARY_LINE_END:
8444
icon_view = GTK_ICON_VIEW (item->widget);
8445
/* FIXME we probably have to use GailTextCell to salvage this */
8446
gtk_icon_view_update_item_text (icon_view, item->item);
8447
get_pango_text_offsets (icon_view->priv->layout,
8459
*start_offset = gtk_text_iter_get_offset (&start);
8460
*end_offset = gtk_text_iter_get_offset (&end);
8462
return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
8466
gtk_icon_view_item_accessible_text_get_character_count (AtkText *text)
8468
GtkIconViewItemAccessible *item;
8470
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
8472
if (!GTK_IS_ICON_VIEW (item->widget))
8475
if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
8478
return gtk_text_buffer_get_char_count (item->text_buffer);
8482
gtk_icon_view_item_accessible_text_get_character_extents (AtkText *text,
8488
AtkCoordType coord_type)
8490
GtkIconViewItemAccessible *item;
8492
GtkIconView *icon_view;
8493
PangoRectangle char_rect;
8494
const gchar *item_text;
8498
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
8500
if (!GTK_IS_ICON_VIEW (item->widget))
8503
if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
8507
icon_view = GTK_ICON_VIEW (item->widget);
8508
/* FIXME we probably have to use GailTextCell to salvage this */
8509
gtk_icon_view_update_item_text (icon_view, item->item);
8510
item_text = pango_layout_get_text (icon_view->priv->layout);
8511
index = g_utf8_offset_to_pointer (item_text, offset) - item_text;
8512
pango_layout_index_to_pos (icon_view->priv->layout, index, &char_rect);
8514
atk_component_get_position (ATK_COMPONENT (text), x, y, coord_type);
8515
*x += item->item->layout_x - item->item->x + char_rect.x / PANGO_SCALE;
8516
/* Look at gtk_icon_view_paint_item() to see where the text is. */
8517
*x -= ((item->item->width - item->item->layout_width) / 2) + (MAX (item->item->pixbuf_width, icon_view->priv->item_width) - item->item->width) / 2,
8518
*y += item->item->layout_y - item->item->y + char_rect.y / PANGO_SCALE;
8519
*width = char_rect.width / PANGO_SCALE;
8520
*height = char_rect.height / PANGO_SCALE;
8525
gtk_icon_view_item_accessible_text_get_offset_at_point (AtkText *text,
8528
AtkCoordType coord_type)
8530
GtkIconViewItemAccessible *item;
8533
GtkIconView *icon_view;
8534
const gchar *item_text;
8539
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
8541
if (!GTK_IS_ICON_VIEW (item->widget))
8544
if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
8548
icon_view = GTK_ICON_VIEW (item->widget);
8549
/* FIXME we probably have to use GailTextCell to salvage this */
8550
gtk_icon_view_update_item_text (icon_view, item->item);
8551
atk_component_get_position (ATK_COMPONENT (text), &l_x, &l_y, coord_type);
8552
x -= l_x + item->item->layout_x - item->item->x;
8553
x += ((item->item->width - item->item->layout_width) / 2) + (MAX (item->item->pixbuf_width, icon_view->priv->item_width) - item->item->width) / 2,
8554
y -= l_y + item->item->layout_y - item->item->y;
8555
item_text = pango_layout_get_text (icon_view->priv->layout);
8556
if (!pango_layout_xy_to_index (icon_view->priv->layout,
8567
offset = g_utf8_strlen (item_text, -1);
8569
offset = g_utf8_pointer_to_offset (item_text, item_text + index);
8575
atk_text_item_interface_init (AtkTextIface *iface)
8577
iface->get_text = gtk_icon_view_item_accessible_text_get_text;
8578
iface->get_character_at_offset = gtk_icon_view_item_accessible_text_get_character_at_offset;
8579
iface->get_text_before_offset = gtk_icon_view_item_accessible_text_get_text_before_offset;
8580
iface->get_text_at_offset = gtk_icon_view_item_accessible_text_get_text_at_offset;
8581
iface->get_text_after_offset = gtk_icon_view_item_accessible_text_get_text_after_offset;
8582
iface->get_character_count = gtk_icon_view_item_accessible_text_get_character_count;
8583
iface->get_character_extents = gtk_icon_view_item_accessible_text_get_character_extents;
8584
iface->get_offset_at_point = gtk_icon_view_item_accessible_text_get_offset_at_point;
8588
gtk_icon_view_item_accessible_get_extents (AtkComponent *component,
8593
AtkCoordType coord_type)
8595
GtkIconViewItemAccessible *item;
8596
AtkObject *parent_obj;
8599
g_return_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component));
8601
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (component);
8602
if (!GTK_IS_WIDGET (item->widget))
8605
if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
8608
*width = item->item->width;
8609
*height = item->item->height;
8610
if (gtk_icon_view_item_accessible_is_showing (item))
8612
parent_obj = gtk_widget_get_accessible (item->widget);
8613
atk_component_get_position (ATK_COMPONENT (parent_obj), &l_x, &l_y, coord_type);
8614
*x = l_x + item->item->x;
8615
*y = l_y + item->item->y;
8625
gtk_icon_view_item_accessible_grab_focus (AtkComponent *component)
8627
GtkIconViewItemAccessible *item;
8628
GtkWidget *toplevel;
8630
g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (component), FALSE);
8632
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (component);
8633
if (!GTK_IS_WIDGET (item->widget))
8636
gtk_widget_grab_focus (item->widget);
8637
gtk_icon_view_set_cursor_item (GTK_ICON_VIEW (item->widget), item->item, -1);
8638
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item->widget));
8639
if (gtk_widget_is_toplevel (toplevel))
8640
gtk_window_present (GTK_WINDOW (toplevel));
8646
atk_component_item_interface_init (AtkComponentIface *iface)
8648
iface->get_extents = gtk_icon_view_item_accessible_get_extents;
8649
iface->grab_focus = gtk_icon_view_item_accessible_grab_focus;
8653
gtk_icon_view_item_accessible_add_state (GtkIconViewItemAccessible *item,
8654
AtkStateType state_type,
8655
gboolean emit_signal)
8659
rc = atk_state_set_add_state (item->state_set, state_type);
8661
* The signal should only be generated if the value changed,
8662
* not when the item is set up. So states that are set
8663
* initially should pass FALSE as the emit_signal argument.
8668
atk_object_notify_state_change (ATK_OBJECT (item), state_type, TRUE);
8669
/* If state_type is ATK_STATE_VISIBLE, additional notification */
8670
if (state_type == ATK_STATE_VISIBLE)
8671
g_signal_emit_by_name (item, "visible-data-changed");
8678
gtk_icon_view_item_accessible_remove_state (GtkIconViewItemAccessible *item,
8679
AtkStateType state_type,
8680
gboolean emit_signal)
8682
if (atk_state_set_contains_state (item->state_set, state_type))
8686
rc = atk_state_set_remove_state (item->state_set, state_type);
8688
* The signal should only be generated if the value changed,
8689
* not when the item is set up. So states that are set
8690
* initially should pass FALSE as the emit_signal argument.
8695
atk_object_notify_state_change (ATK_OBJECT (item), state_type, FALSE);
8696
/* If state_type is ATK_STATE_VISIBLE, additional notification */
8697
if (state_type == ATK_STATE_VISIBLE)
8698
g_signal_emit_by_name (item, "visible-data-changed");
8708
gtk_icon_view_item_accessible_is_showing (GtkIconViewItemAccessible *item)
8710
GtkIconView *icon_view;
8711
GdkRectangle visible_rect;
8712
gboolean is_showing;
8715
* An item is considered "SHOWING" if any part of the item is in the
8716
* visible rectangle.
8719
if (!GTK_IS_ICON_VIEW (item->widget))
8722
if (item->item == NULL)
8725
icon_view = GTK_ICON_VIEW (item->widget);
8727
if (icon_view->priv->hadjustment)
8728
visible_rect.x += icon_view->priv->hadjustment->value;
8730
if (icon_view->priv->hadjustment)
8731
visible_rect.y += icon_view->priv->vadjustment->value;
8732
visible_rect.width = item->widget->allocation.width;
8733
visible_rect.height = item->widget->allocation.height;
8735
if (((item->item->x + item->item->width) < visible_rect.x) ||
8736
((item->item->y + item->item->height) < (visible_rect.y)) ||
8737
(item->item->x > (visible_rect.x + visible_rect.width)) ||
8738
(item->item->y > (visible_rect.y + visible_rect.height)))
8747
gtk_icon_view_item_accessible_set_visibility (GtkIconViewItemAccessible *item,
8748
gboolean emit_signal)
8750
if (gtk_icon_view_item_accessible_is_showing (item))
8751
return gtk_icon_view_item_accessible_add_state (item, ATK_STATE_SHOWING,
8754
return gtk_icon_view_item_accessible_remove_state (item, ATK_STATE_SHOWING,
8759
gtk_icon_view_item_accessible_object_init (GtkIconViewItemAccessible *item)
8763
item->state_set = atk_state_set_new ();
8765
atk_state_set_add_state (item->state_set, ATK_STATE_ENABLED);
8766
atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSABLE);
8767
atk_state_set_add_state (item->state_set, ATK_STATE_SENSITIVE);
8768
atk_state_set_add_state (item->state_set, ATK_STATE_SELECTABLE);
8769
atk_state_set_add_state (item->state_set, ATK_STATE_VISIBLE);
8771
for (i = 0; i < LAST_ACTION; i++)
8772
item->action_descriptions[i] = NULL;
8774
item->image_description = NULL;
8776
item->action_idle_handler = 0;
8780
gtk_icon_view_item_accessible_finalize (GObject *object)
8782
GtkIconViewItemAccessible *item;
8785
g_return_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (object));
8787
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (object);
8790
g_object_remove_weak_pointer (G_OBJECT (item->widget), (gpointer) &item->widget);
8792
if (item->state_set)
8793
g_object_unref (item->state_set);
8795
if (item->text_buffer)
8796
g_object_unref (item->text_buffer);
8798
for (i = 0; i < LAST_ACTION; i++)
8799
g_free (item->action_descriptions[i]);
8801
g_free (item->image_description);
8803
if (item->action_idle_handler)
8805
g_source_remove (item->action_idle_handler);
8806
item->action_idle_handler = 0;
8809
G_OBJECT_CLASS (accessible_item_parent_class)->finalize (object);
8813
gtk_icon_view_item_accessible_get_parent (AtkObject *obj)
8815
GtkIconViewItemAccessible *item;
8817
g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (obj), NULL);
8818
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
8821
return gtk_widget_get_accessible (item->widget);
8827
gtk_icon_view_item_accessible_get_index_in_parent (AtkObject *obj)
8829
GtkIconViewItemAccessible *item;
8831
g_return_val_if_fail (GTK_IS_ICON_VIEW_ITEM_ACCESSIBLE (obj), 0);
8832
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
8834
return item->item->index;
8837
static AtkStateSet *
8838
gtk_icon_view_item_accessible_ref_state_set (AtkObject *obj)
8840
GtkIconViewItemAccessible *item;
8841
GtkIconView *icon_view;
8843
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
8844
g_return_val_if_fail (item->state_set, NULL);
8849
icon_view = GTK_ICON_VIEW (item->widget);
8850
if (icon_view->priv->cursor_item == item->item)
8851
atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSED);
8853
atk_state_set_remove_state (item->state_set, ATK_STATE_FOCUSED);
8854
if (item->item->selected)
8855
atk_state_set_add_state (item->state_set, ATK_STATE_SELECTED);
8857
atk_state_set_remove_state (item->state_set, ATK_STATE_SELECTED);
8859
return g_object_ref (item->state_set);
8863
gtk_icon_view_item_accessible_class_init (AtkObjectClass *klass)
8865
GObjectClass *gobject_class;
8867
accessible_item_parent_class = g_type_class_peek_parent (klass);
8869
gobject_class = (GObjectClass *)klass;
8871
gobject_class->finalize = gtk_icon_view_item_accessible_finalize;
8873
klass->get_index_in_parent = gtk_icon_view_item_accessible_get_index_in_parent;
8874
klass->get_parent = gtk_icon_view_item_accessible_get_parent;
8875
klass->ref_state_set = gtk_icon_view_item_accessible_ref_state_set;
8879
gtk_icon_view_item_accessible_get_type (void)
8881
static GType type = 0;
8885
const GTypeInfo tinfo =
8887
sizeof (GtkIconViewItemAccessibleClass),
8888
(GBaseInitFunc) NULL, /* base init */
8889
(GBaseFinalizeFunc) NULL, /* base finalize */
8890
(GClassInitFunc) gtk_icon_view_item_accessible_class_init, /* class init */
8891
(GClassFinalizeFunc) NULL, /* class finalize */
8892
NULL, /* class data */
8893
sizeof (GtkIconViewItemAccessible), /* instance size */
8894
0, /* nb preallocs */
8895
(GInstanceInitFunc) gtk_icon_view_item_accessible_object_init, /* instance init */
8896
NULL /* value table */
8899
const GInterfaceInfo atk_component_info =
8901
(GInterfaceInitFunc) atk_component_item_interface_init,
8902
(GInterfaceFinalizeFunc) NULL,
8905
const GInterfaceInfo atk_action_info =
8907
(GInterfaceInitFunc) atk_action_item_interface_init,
8908
(GInterfaceFinalizeFunc) NULL,
8911
const GInterfaceInfo atk_image_info =
8913
(GInterfaceInitFunc) atk_image_item_interface_init,
8914
(GInterfaceFinalizeFunc) NULL,
8917
const GInterfaceInfo atk_text_info =
8919
(GInterfaceInitFunc) atk_text_item_interface_init,
8920
(GInterfaceFinalizeFunc) NULL,
8924
type = g_type_register_static (ATK_TYPE_OBJECT,
8925
I_("GtkIconViewItemAccessible"), &tinfo, 0);
8926
g_type_add_interface_static (type, ATK_TYPE_COMPONENT,
8927
&atk_component_info);
8928
g_type_add_interface_static (type, ATK_TYPE_ACTION,
8930
g_type_add_interface_static (type, ATK_TYPE_IMAGE,
8932
g_type_add_interface_static (type, ATK_TYPE_TEXT,
8939
#define GTK_TYPE_ICON_VIEW_ACCESSIBLE (gtk_icon_view_accessible_get_type ())
8940
#define GTK_ICON_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ICON_VIEW_ACCESSIBLE, GtkIconViewAccessible))
8941
#define GTK_IS_ICON_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ICON_VIEW_ACCESSIBLE))
8943
static GType gtk_icon_view_accessible_get_type (void);
8948
} GtkIconViewAccessible;
8954
} GtkIconViewItemAccessibleInfo;
8960
GtkAdjustment *old_hadj;
8961
GtkAdjustment *old_vadj;
8963
GtkTreeModel *model;
8965
} GtkIconViewAccessiblePrivate;
8967
static GtkIconViewAccessiblePrivate *
8968
gtk_icon_view_accessible_get_priv (AtkObject *accessible)
8970
return g_object_get_qdata (G_OBJECT (accessible),
8971
accessible_private_data_quark);
8975
gtk_icon_view_item_accessible_info_new (AtkObject *accessible,
8979
GtkIconViewItemAccessibleInfo *info;
8980
GtkIconViewItemAccessibleInfo *tmp_info;
8981
GtkIconViewAccessiblePrivate *priv;
8984
info = g_new (GtkIconViewItemAccessibleInfo, 1);
8986
info->index = index;
8988
priv = gtk_icon_view_accessible_get_priv (accessible);
8989
items = priv->items;
8992
tmp_info = items->data;
8993
if (tmp_info->index > index)
8995
items = items->next;
8997
priv->items = g_list_insert_before (priv->items, items, info);
8998
priv->old_hadj = NULL;
8999
priv->old_vadj = NULL;
9003
gtk_icon_view_accessible_get_n_children (AtkObject *accessible)
9005
GtkIconView *icon_view;
9008
widget = GTK_ACCESSIBLE (accessible)->widget;
9012
icon_view = GTK_ICON_VIEW (widget);
9014
return g_list_length (icon_view->priv->items);
9018
gtk_icon_view_accessible_find_child (AtkObject *accessible,
9021
GtkIconViewAccessiblePrivate *priv;
9022
GtkIconViewItemAccessibleInfo *info;
9025
priv = gtk_icon_view_accessible_get_priv (accessible);
9026
items = priv->items;
9031
if (info->index == index)
9033
items = items->next;
9039
gtk_icon_view_accessible_ref_child (AtkObject *accessible,
9042
GtkIconView *icon_view;
9046
GtkIconViewItemAccessible *a11y_item;
9048
widget = GTK_ACCESSIBLE (accessible)->widget;
9052
icon_view = GTK_ICON_VIEW (widget);
9053
icons = g_list_nth (icon_view->priv->items, index);
9057
GtkIconViewItem *item = icons->data;
9059
g_return_val_if_fail (item->index == index, NULL);
9060
obj = gtk_icon_view_accessible_find_child (accessible, index);
9065
obj = g_object_new (gtk_icon_view_item_accessible_get_type (), NULL);
9066
gtk_icon_view_item_accessible_info_new (accessible,
9069
obj->role = ATK_ROLE_ICON;
9070
a11y_item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (obj);
9071
a11y_item->item = item;
9072
a11y_item->widget = widget;
9073
a11y_item->text_buffer = gtk_text_buffer_new (NULL);
9075
gtk_icon_view_set_cell_data (icon_view, item);
9076
text = get_text (icon_view, item);
9079
gtk_text_buffer_set_text (a11y_item->text_buffer, text, -1);
9083
gtk_icon_view_item_accessible_set_visibility (a11y_item, FALSE);
9084
g_object_add_weak_pointer (G_OBJECT (widget), (gpointer) &(a11y_item->widget));
9092
gtk_icon_view_accessible_traverse_items (GtkIconViewAccessible *view,
9095
GtkIconViewAccessiblePrivate *priv;
9096
GtkIconViewItemAccessibleInfo *info;
9097
GtkIconViewItemAccessible *item;
9100
priv = gtk_icon_view_accessible_get_priv (ATK_OBJECT (view));
9104
gboolean act_on_item;
9106
widget = GTK_ACCESSIBLE (view)->widget;
9110
items = priv->items;
9112
act_on_item = (list == NULL);
9117
info = (GtkIconViewItemAccessibleInfo *)items->data;
9118
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
9120
if (act_on_item == FALSE && list == items)
9124
gtk_icon_view_item_accessible_set_visibility (item, TRUE);
9126
items = items->next;
9132
gtk_icon_view_accessible_adjustment_changed (GtkAdjustment *adjustment,
9133
GtkIconView *icon_view)
9136
GtkIconViewAccessible *view;
9139
* The scrollbars have changed
9141
obj = gtk_widget_get_accessible (GTK_WIDGET (icon_view));
9142
view = GTK_ICON_VIEW_ACCESSIBLE (obj);
9144
gtk_icon_view_accessible_traverse_items (view, NULL);
9148
gtk_icon_view_accessible_set_scroll_adjustments (GtkWidget *widget,
9149
GtkAdjustment *hadj,
9150
GtkAdjustment *vadj)
9153
GtkIconViewAccessiblePrivate *priv;
9155
atk_obj = gtk_widget_get_accessible (widget);
9156
priv = gtk_icon_view_accessible_get_priv (atk_obj);
9158
if (priv->old_hadj != hadj)
9162
g_object_remove_weak_pointer (G_OBJECT (priv->old_hadj),
9163
(gpointer *)&priv->old_hadj);
9165
g_signal_handlers_disconnect_by_func (priv->old_hadj,
9166
(gpointer) gtk_icon_view_accessible_adjustment_changed,
9169
priv->old_hadj = hadj;
9172
g_object_add_weak_pointer (G_OBJECT (priv->old_hadj),
9173
(gpointer *)&priv->old_hadj);
9174
g_signal_connect (hadj,
9176
G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
9180
if (priv->old_vadj != vadj)
9184
g_object_remove_weak_pointer (G_OBJECT (priv->old_vadj),
9185
(gpointer *)&priv->old_vadj);
9187
g_signal_handlers_disconnect_by_func (priv->old_vadj,
9188
(gpointer) gtk_icon_view_accessible_adjustment_changed,
9191
priv->old_vadj = vadj;
9194
g_object_add_weak_pointer (G_OBJECT (priv->old_vadj),
9195
(gpointer *)&priv->old_vadj);
9196
g_signal_connect (vadj,
9198
G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
9205
gtk_icon_view_accessible_model_row_changed (GtkTreeModel *tree_model,
9213
GtkIconView *icon_view;
9214
GtkIconViewItem *item;
9215
GtkIconViewAccessible *a11y_view;
9216
GtkIconViewItemAccessible *a11y_item;
9220
atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
9221
a11y_view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
9222
index = gtk_tree_path_get_indices(path)[0];
9223
a11y_item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (
9224
gtk_icon_view_accessible_find_child (atk_obj, index));
9228
widget = GTK_ACCESSIBLE (atk_obj)->widget;
9229
icon_view = GTK_ICON_VIEW (widget);
9230
item = a11y_item->item;
9232
name = atk_object_get_name (ATK_OBJECT (a11y_item));
9234
if (!name || strcmp (name, "") == 0)
9236
gtk_icon_view_set_cell_data (icon_view, item);
9237
text = get_text (icon_view, item);
9240
gtk_text_buffer_set_text (a11y_item->text_buffer, text, -1);
9246
g_signal_emit_by_name (atk_obj, "visible-data-changed");
9252
gtk_icon_view_accessible_model_row_inserted (GtkTreeModel *tree_model,
9257
GtkIconViewAccessiblePrivate *priv;
9258
GtkIconViewItemAccessibleInfo *info;
9259
GtkIconViewAccessible *view;
9260
GtkIconViewItemAccessible *item;
9266
index = gtk_tree_path_get_indices(path)[0];
9267
atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
9268
view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
9269
priv = gtk_icon_view_accessible_get_priv (atk_obj);
9271
items = priv->items;
9276
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
9277
if (info->index != item->item->index)
9279
if (info->index < index)
9280
g_warning ("Unexpected index value on insertion %d %d", index, info->index);
9282
if (tmp_list == NULL)
9285
info->index = item->item->index;
9288
items = items->next;
9290
gtk_icon_view_accessible_traverse_items (view, tmp_list);
9291
g_signal_emit_by_name (atk_obj, "children-changed::add",
9297
gtk_icon_view_accessible_model_row_deleted (GtkTreeModel *tree_model,
9301
GtkIconViewAccessiblePrivate *priv;
9302
GtkIconViewItemAccessibleInfo *info;
9303
GtkIconViewAccessible *view;
9304
GtkIconViewItemAccessible *item;
9307
GList *deleted_item;
9311
index = gtk_tree_path_get_indices(path)[0];
9312
atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
9313
view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
9314
priv = gtk_icon_view_accessible_get_priv (atk_obj);
9316
items = priv->items;
9318
deleted_item = NULL;
9323
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
9324
if (info->index == index)
9326
deleted_item = items;
9328
if (info->index != item->item->index)
9330
if (tmp_list == NULL)
9333
info->index = item->item->index;
9336
items = items->next;
9338
gtk_icon_view_accessible_traverse_items (view, tmp_list);
9341
info = deleted_item->data;
9342
gtk_icon_view_item_accessible_add_state (GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item), ATK_STATE_DEFUNCT, TRUE);
9343
g_signal_emit_by_name (atk_obj, "children-changed::remove",
9345
priv->items = g_list_remove_link (priv->items, deleted_item);
9353
gtk_icon_view_accessible_item_compare (GtkIconViewItemAccessibleInfo *i1,
9354
GtkIconViewItemAccessibleInfo *i2)
9356
return i1->index - i2->index;
9360
gtk_icon_view_accessible_model_rows_reordered (GtkTreeModel *tree_model,
9366
GtkIconViewAccessiblePrivate *priv;
9367
GtkIconViewItemAccessibleInfo *info;
9368
GtkIconView *icon_view;
9369
GtkIconViewItemAccessible *item;
9375
atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
9376
icon_view = GTK_ICON_VIEW (user_data);
9377
priv = gtk_icon_view_accessible_get_priv (atk_obj);
9379
length = gtk_tree_model_iter_n_children (tree_model, NULL);
9381
order = g_new (gint, length);
9382
for (i = 0; i < length; i++)
9383
order [new_order[i]] = i;
9385
items = priv->items;
9389
item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (info->item);
9390
info->index = order[info->index];
9391
item->item = g_list_nth_data (icon_view->priv->items, info->index);
9392
items = items->next;
9395
priv->items = g_list_sort (priv->items,
9396
(GCompareFunc)gtk_icon_view_accessible_item_compare);
9402
gtk_icon_view_accessible_disconnect_model_signals (GtkTreeModel *model,
9407
obj = G_OBJECT (model);
9408
g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_changed, widget);
9409
g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_inserted, widget);
9410
g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_row_deleted, widget);
9411
g_signal_handlers_disconnect_by_func (obj, (gpointer) gtk_icon_view_accessible_model_rows_reordered, widget);
9415
gtk_icon_view_accessible_connect_model_signals (GtkIconView *icon_view)
9419
obj = G_OBJECT (icon_view->priv->model);
9420
g_signal_connect_data (obj, "row-changed",
9421
(GCallback) gtk_icon_view_accessible_model_row_changed,
9422
icon_view, NULL, 0);
9423
g_signal_connect_data (obj, "row-inserted",
9424
(GCallback) gtk_icon_view_accessible_model_row_inserted,
9425
icon_view, NULL, G_CONNECT_AFTER);
9426
g_signal_connect_data (obj, "row-deleted",
9427
(GCallback) gtk_icon_view_accessible_model_row_deleted,
9428
icon_view, NULL, G_CONNECT_AFTER);
9429
g_signal_connect_data (obj, "rows-reordered",
9430
(GCallback) gtk_icon_view_accessible_model_rows_reordered,
9431
icon_view, NULL, G_CONNECT_AFTER);
9435
gtk_icon_view_accessible_clear_cache (GtkIconViewAccessiblePrivate *priv)
9437
GtkIconViewItemAccessibleInfo *info;
9440
items = priv->items;
9443
info = (GtkIconViewItemAccessibleInfo *) items->data;
9444
g_object_unref (info->item);
9445
g_free (items->data);
9446
items = items->next;
9448
g_list_free (priv->items);
9453
gtk_icon_view_accessible_notify_gtk (GObject *obj,
9456
GtkIconView *icon_view;
9459
GtkIconViewAccessiblePrivate *priv;
9461
if (strcmp (pspec->name, "model") == 0)
9463
widget = GTK_WIDGET (obj);
9464
atk_obj = gtk_widget_get_accessible (widget);
9465
priv = gtk_icon_view_accessible_get_priv (atk_obj);
9468
g_object_remove_weak_pointer (G_OBJECT (priv->model),
9469
(gpointer *)&priv->model);
9470
gtk_icon_view_accessible_disconnect_model_signals (priv->model, widget);
9472
gtk_icon_view_accessible_clear_cache (priv);
9474
icon_view = GTK_ICON_VIEW (obj);
9475
priv->model = icon_view->priv->model;
9476
/* If there is no model the GtkIconView is probably being destroyed */
9479
g_object_add_weak_pointer (G_OBJECT (priv->model), (gpointer *)&priv->model);
9480
gtk_icon_view_accessible_connect_model_signals (icon_view);
9488
gtk_icon_view_accessible_initialize (AtkObject *accessible,
9491
GtkIconViewAccessiblePrivate *priv;
9492
GtkIconView *icon_view;
9494
if (ATK_OBJECT_CLASS (accessible_parent_class)->initialize)
9495
ATK_OBJECT_CLASS (accessible_parent_class)->initialize (accessible, data);
9497
priv = g_new0 (GtkIconViewAccessiblePrivate, 1);
9498
g_object_set_qdata (G_OBJECT (accessible),
9499
accessible_private_data_quark,
9502
icon_view = GTK_ICON_VIEW (data);
9503
if (icon_view->priv->hadjustment)
9505
priv->old_hadj = icon_view->priv->hadjustment;
9506
g_object_add_weak_pointer (G_OBJECT (priv->old_hadj), (gpointer *)&priv->old_hadj);
9507
g_signal_connect (icon_view->priv->hadjustment,
9509
G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
9512
if (icon_view->priv->vadjustment)
9514
priv->old_vadj = icon_view->priv->vadjustment;
9515
g_object_add_weak_pointer (G_OBJECT (priv->old_vadj), (gpointer *)&priv->old_vadj);
9516
g_signal_connect (icon_view->priv->vadjustment,
9518
G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
9521
g_signal_connect_after (data,
9522
"set-scroll-adjustments",
9523
G_CALLBACK (gtk_icon_view_accessible_set_scroll_adjustments),
9525
g_signal_connect (data,
9527
G_CALLBACK (gtk_icon_view_accessible_notify_gtk),
9530
priv->model = icon_view->priv->model;
9533
g_object_add_weak_pointer (G_OBJECT (priv->model), (gpointer *)&priv->model);
9534
gtk_icon_view_accessible_connect_model_signals (icon_view);
9537
accessible->role = ATK_ROLE_LAYERED_PANE;
9541
gtk_icon_view_accessible_finalize (GObject *object)
9543
GtkIconViewAccessiblePrivate *priv;
9545
priv = gtk_icon_view_accessible_get_priv (ATK_OBJECT (object));
9546
gtk_icon_view_accessible_clear_cache (priv);
9550
G_OBJECT_CLASS (accessible_parent_class)->finalize (object);
9554
gtk_icon_view_accessible_destroyed (GtkWidget *widget,
9555
GtkAccessible *accessible)
9558
GtkIconViewAccessiblePrivate *priv;
9560
atk_obj = ATK_OBJECT (accessible);
9561
priv = gtk_icon_view_accessible_get_priv (atk_obj);
9564
g_object_remove_weak_pointer (G_OBJECT (priv->old_hadj),
9565
(gpointer *)&priv->old_hadj);
9567
g_signal_handlers_disconnect_by_func (priv->old_hadj,
9568
(gpointer) gtk_icon_view_accessible_adjustment_changed,
9570
priv->old_hadj = NULL;
9574
g_object_remove_weak_pointer (G_OBJECT (priv->old_vadj),
9575
(gpointer *)&priv->old_vadj);
9577
g_signal_handlers_disconnect_by_func (priv->old_vadj,
9578
(gpointer) gtk_icon_view_accessible_adjustment_changed,
9580
priv->old_vadj = NULL;
9585
gtk_icon_view_accessible_connect_widget_destroyed (GtkAccessible *accessible)
9587
if (accessible->widget)
9589
g_signal_connect_after (accessible->widget,
9591
G_CALLBACK (gtk_icon_view_accessible_destroyed),
9594
GTK_ACCESSIBLE_CLASS (accessible_parent_class)->connect_widget_destroyed (accessible);
9598
gtk_icon_view_accessible_class_init (AtkObjectClass *klass)
9600
GObjectClass *gobject_class;
9601
GtkAccessibleClass *accessible_class;
9603
accessible_parent_class = g_type_class_peek_parent (klass);
9605
gobject_class = (GObjectClass *)klass;
9606
accessible_class = (GtkAccessibleClass *)klass;
9608
gobject_class->finalize = gtk_icon_view_accessible_finalize;
9610
klass->get_n_children = gtk_icon_view_accessible_get_n_children;
9611
klass->ref_child = gtk_icon_view_accessible_ref_child;
9612
klass->initialize = gtk_icon_view_accessible_initialize;
9614
accessible_class->connect_widget_destroyed = gtk_icon_view_accessible_connect_widget_destroyed;
9616
accessible_private_data_quark = g_quark_from_static_string ("icon_view-accessible-private-data");
9620
gtk_icon_view_accessible_ref_accessible_at_point (AtkComponent *component,
9623
AtkCoordType coord_type)
9626
GtkIconView *icon_view;
9627
GtkIconViewItem *item;
9630
widget = GTK_ACCESSIBLE (component)->widget;
9632
/* State is defunct */
9635
icon_view = GTK_ICON_VIEW (widget);
9636
atk_component_get_extents (component, &x_pos, &y_pos, NULL, NULL, coord_type);
9637
item = gtk_icon_view_get_item_at_coords (icon_view, x - x_pos, y - y_pos, TRUE, NULL);
9639
return gtk_icon_view_accessible_ref_child (ATK_OBJECT (component), item->index);
9645
atk_component_interface_init (AtkComponentIface *iface)
9647
iface->ref_accessible_at_point = gtk_icon_view_accessible_ref_accessible_at_point;
9651
gtk_icon_view_accessible_add_selection (AtkSelection *selection,
9655
GtkIconView *icon_view;
9656
GtkIconViewItem *item;
9658
widget = GTK_ACCESSIBLE (selection)->widget;
9662
icon_view = GTK_ICON_VIEW (widget);
9664
item = g_list_nth_data (icon_view->priv->items, i);
9669
gtk_icon_view_select_item (icon_view, item);
9675
gtk_icon_view_accessible_clear_selection (AtkSelection *selection)
9678
GtkIconView *icon_view;
9680
widget = GTK_ACCESSIBLE (selection)->widget;
9684
icon_view = GTK_ICON_VIEW (widget);
9685
gtk_icon_view_unselect_all (icon_view);
9691
gtk_icon_view_accessible_ref_selection (AtkSelection *selection,
9696
GtkIconView *icon_view;
9697
GtkIconViewItem *item;
9699
widget = GTK_ACCESSIBLE (selection)->widget;
9703
icon_view = GTK_ICON_VIEW (widget);
9705
l = icon_view->priv->items;
9712
return atk_object_ref_accessible_child (gtk_widget_get_accessible (widget), item->index);
9723
gtk_icon_view_accessible_get_selection_count (AtkSelection *selection)
9726
GtkIconView *icon_view;
9727
GtkIconViewItem *item;
9731
widget = GTK_ACCESSIBLE (selection)->widget;
9735
icon_view = GTK_ICON_VIEW (widget);
9737
l = icon_view->priv->items;
9753
gtk_icon_view_accessible_is_child_selected (AtkSelection *selection,
9757
GtkIconView *icon_view;
9758
GtkIconViewItem *item;
9760
widget = GTK_ACCESSIBLE (selection)->widget;
9764
icon_view = GTK_ICON_VIEW (widget);
9766
item = g_list_nth_data (icon_view->priv->items, i);
9770
return item->selected;
9774
gtk_icon_view_accessible_remove_selection (AtkSelection *selection,
9778
GtkIconView *icon_view;
9779
GtkIconViewItem *item;
9783
widget = GTK_ACCESSIBLE (selection)->widget;
9787
icon_view = GTK_ICON_VIEW (widget);
9788
l = icon_view->priv->items;
9797
gtk_icon_view_unselect_item (icon_view, item);
9809
gtk_icon_view_accessible_select_all_selection (AtkSelection *selection)
9812
GtkIconView *icon_view;
9814
widget = GTK_ACCESSIBLE (selection)->widget;
9818
icon_view = GTK_ICON_VIEW (widget);
9819
gtk_icon_view_select_all (icon_view);
9824
gtk_icon_view_accessible_selection_interface_init (AtkSelectionIface *iface)
9826
iface->add_selection = gtk_icon_view_accessible_add_selection;
9827
iface->clear_selection = gtk_icon_view_accessible_clear_selection;
9828
iface->ref_selection = gtk_icon_view_accessible_ref_selection;
9829
iface->get_selection_count = gtk_icon_view_accessible_get_selection_count;
9830
iface->is_child_selected = gtk_icon_view_accessible_is_child_selected;
9831
iface->remove_selection = gtk_icon_view_accessible_remove_selection;
9832
iface->select_all_selection = gtk_icon_view_accessible_select_all_selection;
9836
gtk_icon_view_accessible_get_type (void)
9838
static GType type = 0;
9845
(GBaseInitFunc) NULL, /* base init */
9846
(GBaseFinalizeFunc) NULL, /* base finalize */
9847
(GClassInitFunc) gtk_icon_view_accessible_class_init,
9848
(GClassFinalizeFunc) NULL, /* class finalize */
9849
NULL, /* class data */
9850
0, /* instance size */
9851
0, /* nb preallocs */
9852
(GInstanceInitFunc) NULL, /* instance init */
9853
NULL /* value table */
9855
const GInterfaceInfo atk_component_info =
9857
(GInterfaceInitFunc) atk_component_interface_init,
9858
(GInterfaceFinalizeFunc) NULL,
9861
const GInterfaceInfo atk_selection_info =
9863
(GInterfaceInitFunc) gtk_icon_view_accessible_selection_interface_init,
9864
(GInterfaceFinalizeFunc) NULL,
9869
* Figure out the size of the class and instance
9870
* we are deriving from
9872
AtkObjectFactory *factory;
9875
GType derived_atk_type;
9877
derived_type = g_type_parent (GTK_TYPE_ICON_VIEW);
9878
factory = atk_registry_get_factory (atk_get_default_registry (),
9880
derived_atk_type = atk_object_factory_get_accessible_type (factory);
9881
g_type_query (derived_atk_type, &query);
9882
tinfo.class_size = query.class_size;
9883
tinfo.instance_size = query.instance_size;
9885
type = g_type_register_static (derived_atk_type,
9886
I_("GtkIconViewAccessible"),
9888
g_type_add_interface_static (type, ATK_TYPE_COMPONENT,
9889
&atk_component_info);
9890
g_type_add_interface_static (type, ATK_TYPE_SELECTION,
9891
&atk_selection_info);
9897
gtk_icon_view_accessible_new (GObject *obj)
9899
AtkObject *accessible;
9901
g_return_val_if_fail (GTK_IS_WIDGET (obj), NULL);
9903
accessible = g_object_new (gtk_icon_view_accessible_get_type (), NULL);
9904
atk_object_initialize (accessible, obj);
9910
gtk_icon_view_accessible_factory_get_accessible_type (void)
9912
return gtk_icon_view_accessible_get_type ();
9916
gtk_icon_view_accessible_factory_create_accessible (GObject *obj)
9918
return gtk_icon_view_accessible_new (obj);
9922
gtk_icon_view_accessible_factory_class_init (AtkObjectFactoryClass *klass)
9924
klass->create_accessible = gtk_icon_view_accessible_factory_create_accessible;
9925
klass->get_accessible_type = gtk_icon_view_accessible_factory_get_accessible_type;
9929
gtk_icon_view_accessible_factory_get_type (void)
9931
static GType type = 0;
9935
const GTypeInfo tinfo =
9937
sizeof (AtkObjectFactoryClass),
9938
NULL, /* base_init */
9939
NULL, /* base_finalize */
9940
(GClassInitFunc) gtk_icon_view_accessible_factory_class_init,
9941
NULL, /* class_finalize */
9942
NULL, /* class_data */
9943
sizeof (AtkObjectFactory),
9944
0, /* n_preallocs */
9948
type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY,
9949
I_("GtkIconViewAccessibleFactory"),
9957
gtk_icon_view_get_accessible (GtkWidget *widget)
9959
static gboolean first_time = TRUE;
9963
AtkObjectFactory *factory;
9964
AtkRegistry *registry;
9966
GType derived_atk_type;
9969
* Figure out whether accessibility is enabled by looking at the
9970
* type of the accessible object which would be created for
9971
* the parent type of GtkIconView.
9973
derived_type = g_type_parent (GTK_TYPE_ICON_VIEW);
9975
registry = atk_get_default_registry ();
9976
factory = atk_registry_get_factory (registry,
9978
derived_atk_type = atk_object_factory_get_accessible_type (factory);
9979
if (g_type_is_a (derived_atk_type, GTK_TYPE_ACCESSIBLE))
9980
atk_registry_set_factory_type (registry,
9982
gtk_icon_view_accessible_factory_get_type ());
9985
return GTK_WIDGET_CLASS (gtk_icon_view_parent_class)->get_accessible (widget);
9989
gtk_icon_view_buildable_custom_tag_start (GtkBuildable *buildable,
9990
GtkBuilder *builder,
9992
const gchar *tagname,
9993
GMarkupParser *parser,
9996
if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
9997
tagname, parser, data))
10000
return _gtk_cell_layout_buildable_custom_tag_start (buildable, builder, child,
10001
tagname, parser, data);
10005
gtk_icon_view_buildable_custom_tag_end (GtkBuildable *buildable,
10006
GtkBuilder *builder,
10008
const gchar *tagname,
10011
if (strcmp (tagname, "attributes") == 0)
10012
_gtk_cell_layout_buildable_custom_tag_end (buildable, builder, child, tagname,
10015
parent_buildable_iface->custom_tag_end (buildable, builder, child, tagname,
10021
#define __GTK_ICON_VIEW_C__
10022
#include "gtkaliasdef.c"