gtkiconview.c 213 KB
Newer Older
1
/* gtkiconview.c
2
 * Copyright (C) 2002, 2004  Anders Carlsson <andersca@gnu.org>
Anders Carlsson's avatar
Anders Carlsson committed
3 4 5 6 7 8 9 10 11 12 13 14
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
Javier Jardón's avatar
Javier Jardón committed
15
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
Anders Carlsson's avatar
Anders Carlsson committed
16 17
 */

18
#include "config.h"
19

Anders Carlsson's avatar
Anders Carlsson committed
20 21
#include <string.h>

22
#include "gtkiconview.h"
23 24
#include "gtkiconviewprivate.h"

25
#include "gtkadjustmentprivate.h"
Matthias Clasen's avatar
Matthias Clasen committed
26 27
#include "gtkcelllayout.h"
#include "gtkcellrenderer.h"
28
#include "gtkcellareabox.h"
29
#include "gtkcellareacontext.h"
Matthias Clasen's avatar
Matthias Clasen committed
30 31
#include "gtkcellrenderertext.h"
#include "gtkcellrendererpixbuf.h"
32
#include "gtkorientable.h"
33 34 35 36 37
#include "gtkmarshalers.h"
#include "gtkbindings.h"
#include "gtkdnd.h"
#include "gtkmain.h"
#include "gtkintl.h"
38 39
#include "gtkaccessible.h"
#include "gtkwindow.h"
Matthias Clasen's avatar
Matthias Clasen committed
40 41
#include "gtkentry.h"
#include "gtkcombobox.h"
42
#include "gtkscrollable.h"
43
#include "gtksizerequest.h"
Matthias Clasen's avatar
Matthias Clasen committed
44
#include "gtktreednd.h"
45
#include "gtktypebuiltins.h"
46
#include "gtkprivate.h"
47
#include "a11y/gtkiconviewaccessibleprivate.h"
Anders Carlsson's avatar
Anders Carlsson committed
48

49 50 51 52 53
/**
 * SECTION:gtkiconview
 * @title: GtkIconView
 * @short_description: A widget which displays a list of icons in a grid
 *
54
 * #GtkIconView provides an alternative view on a #GtkTreeModel.
55 56 57 58 59
 * It displays the model as a grid of icons with labels. Like
 * #GtkTreeView, it allows to select one or multiple items
 * (depending on the selection mode, see gtk_icon_view_set_selection_mode()).
 * In addition to selection with the arrow keys, #GtkIconView supports
 * rubberband selection, which is controlled by dragging the pointer.
60 61 62 63
 *
 * Note that if the tree model is backed by an actual tree store (as
 * opposed to a flat list where the mapping to icons is obvious),
 * #GtkIconView will only display the first level of the tree and
64
 * ignore the tree’s branches.
65 66
 */

Matthias Clasen's avatar
Matthias Clasen committed
67 68
#define SCROLL_EDGE_SIZE 15

Matthias Clasen's avatar
Matthias Clasen committed
69 70 71
typedef struct _GtkIconViewChild GtkIconViewChild;
struct _GtkIconViewChild
{
72 73
  GtkWidget    *widget;
  GdkRectangle  area;
Matthias Clasen's avatar
Matthias Clasen committed
74
};
Anders Carlsson's avatar
Anders Carlsson committed
75 76 77 78 79 80 81 82 83 84 85

/* Signals */
enum
{
  ITEM_ACTIVATED,
  SELECTION_CHANGED,
  SELECT_ALL,
  UNSELECT_ALL,
  SELECT_CURSOR_ITEM,
  TOGGLE_CURSOR_ITEM,
  MOVE_CURSOR,
86
  ACTIVATE_CURSOR_ITEM,
Anders Carlsson's avatar
Anders Carlsson committed
87 88 89 90 91 92 93
  LAST_SIGNAL
};

/* Properties */
enum
{
  PROP_0,
94 95
  PROP_PIXBUF_COLUMN,
  PROP_TEXT_COLUMN,
96
  PROP_MARKUP_COLUMN,
Anders Carlsson's avatar
Anders Carlsson committed
97
  PROP_SELECTION_MODE,
98
  PROP_ITEM_ORIENTATION,
99
  PROP_MODEL,
Matthias Clasen's avatar
Matthias Clasen committed
100 101 102 103 104
  PROP_COLUMNS,
  PROP_ITEM_WIDTH,
  PROP_SPACING,
  PROP_ROW_SPACING,
  PROP_COLUMN_SPACING,
Matthias Clasen's avatar
Matthias Clasen committed
105
  PROP_MARGIN,
106
  PROP_REORDERABLE,
107
  PROP_TOOLTIP_COLUMN,
108
  PROP_ITEM_PADDING,
109
  PROP_CELL_AREA,
110
  PROP_HADJUSTMENT,
111 112
  PROP_VADJUSTMENT,
  PROP_HSCROLL_POLICY,
113 114
  PROP_VSCROLL_POLICY,
  PROP_ACTIVATE_ON_SINGLE_CLICK
Anders Carlsson's avatar
Anders Carlsson committed
115 116
};

Matthias Clasen's avatar
Matthias Clasen committed
117 118
/* GObject vfuncs */
static void             gtk_icon_view_cell_layout_init          (GtkCellLayoutIface *iface);
119
static void             gtk_icon_view_dispose                   (GObject            *object);
120
static void             gtk_icon_view_constructed               (GObject            *object);
Matthias Clasen's avatar
Matthias Clasen committed
121 122 123 124 125 126 127 128 129
static void             gtk_icon_view_set_property              (GObject            *object,
								 guint               prop_id,
								 const GValue       *value,
								 GParamSpec         *pspec);
static void             gtk_icon_view_get_property              (GObject            *object,
								 guint               prop_id,
								 GValue             *value,
								 GParamSpec         *pspec);
/* GtkWidget vfuncs */
130
static void             gtk_icon_view_destroy                   (GtkWidget          *widget);
Matthias Clasen's avatar
Matthias Clasen committed
131 132
static void             gtk_icon_view_realize                   (GtkWidget          *widget);
static void             gtk_icon_view_unrealize                 (GtkWidget          *widget);
133
static GtkSizeRequestMode gtk_icon_view_get_request_mode        (GtkWidget          *widget);
134 135 136
static void             gtk_icon_view_get_preferred_width       (GtkWidget          *widget,
								 gint               *minimum,
								 gint               *natural);
137 138 139 140 141
static void             gtk_icon_view_get_preferred_width_for_height
                                                                (GtkWidget          *widget,
                                                                 gint                height,
								 gint               *minimum,
								 gint               *natural);
142 143 144
static void             gtk_icon_view_get_preferred_height      (GtkWidget          *widget,
								 gint               *minimum,
								 gint               *natural);
145 146 147 148 149
static void             gtk_icon_view_get_preferred_height_for_width
                                                                (GtkWidget          *widget,
                                                                 gint                width,
								 gint               *minimum,
								 gint               *natural);
Matthias Clasen's avatar
Matthias Clasen committed
150 151
static void             gtk_icon_view_size_allocate             (GtkWidget          *widget,
								 GtkAllocation      *allocation);
152 153
static gboolean         gtk_icon_view_draw                      (GtkWidget          *widget,
                                                                 cairo_t            *cr);
Matthias Clasen's avatar
Matthias Clasen committed
154 155
static gboolean         gtk_icon_view_motion                    (GtkWidget          *widget,
								 GdkEventMotion     *event);
156 157
static gboolean         gtk_icon_view_leave                     (GtkWidget          *widget,
								 GdkEventCrossing   *event);
Matthias Clasen's avatar
Matthias Clasen committed
158 159 160 161
static gboolean         gtk_icon_view_button_press              (GtkWidget          *widget,
								 GdkEventButton     *event);
static gboolean         gtk_icon_view_button_release            (GtkWidget          *widget,
								 GdkEventButton     *event);
162 163 164 165
static gboolean         gtk_icon_view_key_press                 (GtkWidget          *widget,
								 GdkEventKey        *event);
static gboolean         gtk_icon_view_key_release               (GtkWidget          *widget,
								 GdkEventKey        *event);
Matthias Clasen's avatar
Matthias Clasen committed
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183


/* GtkContainer vfuncs */
static void             gtk_icon_view_remove                    (GtkContainer       *container,
								 GtkWidget          *widget);
static void             gtk_icon_view_forall                    (GtkContainer       *container,
								 gboolean            include_internals,
								 GtkCallback         callback,
								 gpointer            callback_data);

/* GtkIconView vfuncs */
static void             gtk_icon_view_real_select_all           (GtkIconView        *icon_view);
static void             gtk_icon_view_real_unselect_all         (GtkIconView        *icon_view);
static void             gtk_icon_view_real_select_cursor_item   (GtkIconView        *icon_view);
static void             gtk_icon_view_real_toggle_cursor_item   (GtkIconView        *icon_view);
static gboolean         gtk_icon_view_real_activate_cursor_item (GtkIconView        *icon_view);

 /* Internal functions */
184 185 186 187 188 189
static void                 gtk_icon_view_set_hadjustment_values         (GtkIconView            *icon_view);
static void                 gtk_icon_view_set_vadjustment_values         (GtkIconView            *icon_view);
static void                 gtk_icon_view_set_hadjustment                (GtkIconView            *icon_view,
                                                                          GtkAdjustment          *adjustment);
static void                 gtk_icon_view_set_vadjustment                (GtkIconView            *icon_view,
                                                                          GtkAdjustment          *adjustment);
Matthias Clasen's avatar
Matthias Clasen committed
190 191 192 193
static void                 gtk_icon_view_adjustment_changed             (GtkAdjustment          *adjustment,
									  GtkIconView            *icon_view);
static void                 gtk_icon_view_layout                         (GtkIconView            *icon_view);
static void                 gtk_icon_view_paint_item                     (GtkIconView            *icon_view,
194
									  cairo_t                *cr,
Matthias Clasen's avatar
Matthias Clasen committed
195
									  GtkIconViewItem        *item,
196 197 198
									  gint                    x,
									  gint                    y,
									  gboolean                draw_focus);
Matthias Clasen's avatar
Matthias Clasen committed
199
static void                 gtk_icon_view_paint_rubberband               (GtkIconView            *icon_view,
200
								          cairo_t                *cr);
Matthias Clasen's avatar
Matthias Clasen committed
201 202
static void                 gtk_icon_view_queue_draw_path                (GtkIconView *icon_view,
									  GtkTreePath *path);
Matthias Clasen's avatar
Matthias Clasen committed
203 204 205
static void                 gtk_icon_view_queue_draw_item                (GtkIconView            *icon_view,
									  GtkIconViewItem        *item);
static void                 gtk_icon_view_start_rubberbanding            (GtkIconView            *icon_view,
206
                                                                          GdkDevice              *device,
Matthias Clasen's avatar
Matthias Clasen committed
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
									  gint                    x,
									  gint                    y);
static void                 gtk_icon_view_stop_rubberbanding             (GtkIconView            *icon_view);
static void                 gtk_icon_view_update_rubberband_selection    (GtkIconView            *icon_view);
static gboolean             gtk_icon_view_item_hit_test                  (GtkIconView            *icon_view,
									  GtkIconViewItem        *item,
									  gint                    x,
									  gint                    y,
									  gint                    width,
									  gint                    height);
static gboolean             gtk_icon_view_unselect_all_internal          (GtkIconView            *icon_view);
static void                 gtk_icon_view_update_rubberband              (gpointer                data);
static void                 gtk_icon_view_item_invalidate_size           (GtkIconViewItem        *item);
static void                 gtk_icon_view_invalidate_sizes               (GtkIconView            *icon_view);
static void                 gtk_icon_view_add_move_binding               (GtkBindingSet          *binding_set,
									  guint                   keyval,
									  guint                   modmask,
									  GtkMovementStep         step,
									  gint                    count);
static gboolean             gtk_icon_view_real_move_cursor               (GtkIconView            *icon_view,
									  GtkMovementStep         step,
									  gint                    count);
static void                 gtk_icon_view_move_cursor_up_down            (GtkIconView            *icon_view,
									  gint                    count);
static void                 gtk_icon_view_move_cursor_page_up_down       (GtkIconView            *icon_view,
									  gint                    count);
static void                 gtk_icon_view_move_cursor_left_right         (GtkIconView            *icon_view,
									  gint                    count);
static void                 gtk_icon_view_move_cursor_start_end          (GtkIconView            *icon_view,
									  gint                    count);
static void                 gtk_icon_view_scroll_to_item                 (GtkIconView            *icon_view,
									  GtkIconViewItem        *item);
static gboolean             gtk_icon_view_select_all_between             (GtkIconView            *icon_view,
									  GtkIconViewItem        *anchor,
									  GtkIconViewItem        *cursor);
242

243 244 245
static void                 gtk_icon_view_ensure_cell_area               (GtkIconView            *icon_view,
                                                                          GtkCellArea            *cell_area);

246 247
static GtkCellArea         *gtk_icon_view_cell_layout_get_area           (GtkCellLayout          *layout);

248 249
static void                 gtk_icon_view_item_selected_changed          (GtkIconView            *icon_view,
		                                                          GtkIconViewItem        *item);
250 251 252 253 254 255 256 257 258 259 260

static void                 gtk_icon_view_add_editable                   (GtkCellArea            *area,
									  GtkCellRenderer        *renderer,
									  GtkCellEditable        *editable,
									  GdkRectangle           *cell_area,
									  const gchar            *path,
									  GtkIconView            *icon_view);
static void                 gtk_icon_view_remove_editable                (GtkCellArea            *area,
									  GtkCellRenderer        *renderer,
									  GtkCellEditable        *editable,
									  GtkIconView            *icon_view);
261 262
static void                 update_text_cell                             (GtkIconView            *icon_view);
static void                 update_pixbuf_cell                           (GtkIconView            *icon_view);
263

Matthias Clasen's avatar
Matthias Clasen committed
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
/* Source side drag signals */
static void gtk_icon_view_drag_begin       (GtkWidget        *widget,
                                            GdkDragContext   *context);
static void gtk_icon_view_drag_end         (GtkWidget        *widget,
                                            GdkDragContext   *context);
static void gtk_icon_view_drag_data_get    (GtkWidget        *widget,
                                            GdkDragContext   *context,
                                            GtkSelectionData *selection_data,
                                            guint             info,
                                            guint             time);
static void gtk_icon_view_drag_data_delete (GtkWidget        *widget,
                                            GdkDragContext   *context);

/* Target side drag signals */
static void     gtk_icon_view_drag_leave         (GtkWidget        *widget,
                                                  GdkDragContext   *context,
                                                  guint             time);
static gboolean gtk_icon_view_drag_motion        (GtkWidget        *widget,
                                                  GdkDragContext   *context,
                                                  gint              x,
                                                  gint              y,
                                                  guint             time);
static gboolean gtk_icon_view_drag_drop          (GtkWidget        *widget,
                                                  GdkDragContext   *context,
                                                  gint              x,
                                                  gint              y,
                                                  guint             time);
static void     gtk_icon_view_drag_data_received (GtkWidget        *widget,
                                                  GdkDragContext   *context,
                                                  gint              x,
                                                  gint              y,
                                                  GtkSelectionData *selection_data,
                                                  guint             info,
                                                  guint             time);
static gboolean gtk_icon_view_maybe_begin_drag   (GtkIconView             *icon_view,
					   	  GdkEventMotion          *event);

static void     remove_scroll_timeout            (GtkIconView *icon_view);

303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
/* GtkBuildable */
static GtkBuildableIface *parent_buildable_iface;
static void     gtk_icon_view_buildable_init             (GtkBuildableIface *iface);
static gboolean gtk_icon_view_buildable_custom_tag_start (GtkBuildable  *buildable,
							  GtkBuilder    *builder,
							  GObject       *child,
							  const gchar   *tagname,
							  GMarkupParser *parser,
							  gpointer      *data);
static void     gtk_icon_view_buildable_custom_tag_end   (GtkBuildable  *buildable,
							  GtkBuilder    *builder,
							  GObject       *child,
							  const gchar   *tagname,
							  gpointer      *data);

318
static guint icon_view_signals[LAST_SIGNAL] = { 0 };
Anders Carlsson's avatar
Anders Carlsson committed
319

Matthias Clasen's avatar
Matthias Clasen committed
320
G_DEFINE_TYPE_WITH_CODE (GtkIconView, gtk_icon_view, GTK_TYPE_CONTAINER,
321
                         G_ADD_PRIVATE (GtkIconView)
Matthias Clasen's avatar
Matthias Clasen committed
322
			 G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
323 324
						gtk_icon_view_cell_layout_init)
			 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
325 326
						gtk_icon_view_buildable_init)
			 G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
Anders Carlsson's avatar
Anders Carlsson committed
327 328

static void
329
gtk_icon_view_class_init (GtkIconViewClass *klass)
Anders Carlsson's avatar
Anders Carlsson committed
330 331 332
{
  GObjectClass *gobject_class;
  GtkWidgetClass *widget_class;
Matthias Clasen's avatar
Matthias Clasen committed
333
  GtkContainerClass *container_class;
Anders Carlsson's avatar
Anders Carlsson committed
334 335 336
  GtkBindingSet *binding_set;
  
  binding_set = gtk_binding_set_by_class (klass);
337

Anders Carlsson's avatar
Anders Carlsson committed
338 339
  gobject_class = (GObjectClass *) klass;
  widget_class = (GtkWidgetClass *) klass;
Matthias Clasen's avatar
Matthias Clasen committed
340
  container_class = (GtkContainerClass *) klass;
Anders Carlsson's avatar
Anders Carlsson committed
341

342
  gobject_class->constructed = gtk_icon_view_constructed;
343
  gobject_class->dispose = gtk_icon_view_dispose;
344 345 346
  gobject_class->set_property = gtk_icon_view_set_property;
  gobject_class->get_property = gtk_icon_view_get_property;

347
  widget_class->destroy = gtk_icon_view_destroy;
348 349
  widget_class->realize = gtk_icon_view_realize;
  widget_class->unrealize = gtk_icon_view_unrealize;
350
  widget_class->get_request_mode = gtk_icon_view_get_request_mode;
351 352
  widget_class->get_preferred_width = gtk_icon_view_get_preferred_width;
  widget_class->get_preferred_height = gtk_icon_view_get_preferred_height;
353 354
  widget_class->get_preferred_width_for_height = gtk_icon_view_get_preferred_width_for_height;
  widget_class->get_preferred_height_for_width = gtk_icon_view_get_preferred_height_for_width;
355
  widget_class->size_allocate = gtk_icon_view_size_allocate;
356
  widget_class->draw = gtk_icon_view_draw;
357
  widget_class->motion_notify_event = gtk_icon_view_motion;
358
  widget_class->leave_notify_event = gtk_icon_view_leave;
359 360
  widget_class->button_press_event = gtk_icon_view_button_press;
  widget_class->button_release_event = gtk_icon_view_button_release;
361 362
  widget_class->key_press_event = gtk_icon_view_key_press;
  widget_class->key_release_event = gtk_icon_view_key_release;
Matthias Clasen's avatar
Matthias Clasen committed
363 364 365 366 367 368 369 370
  widget_class->drag_begin = gtk_icon_view_drag_begin;
  widget_class->drag_end = gtk_icon_view_drag_end;
  widget_class->drag_data_get = gtk_icon_view_drag_data_get;
  widget_class->drag_data_delete = gtk_icon_view_drag_data_delete;
  widget_class->drag_leave = gtk_icon_view_drag_leave;
  widget_class->drag_motion = gtk_icon_view_drag_motion;
  widget_class->drag_drop = gtk_icon_view_drag_drop;
  widget_class->drag_data_received = gtk_icon_view_drag_data_received;
371

Matthias Clasen's avatar
Matthias Clasen committed
372 373 374
  container_class->remove = gtk_icon_view_remove;
  container_class->forall = gtk_icon_view_forall;

375 376 377 378
  klass->select_all = gtk_icon_view_real_select_all;
  klass->unselect_all = gtk_icon_view_real_unselect_all;
  klass->select_cursor_item = gtk_icon_view_real_select_cursor_item;
  klass->toggle_cursor_item = gtk_icon_view_real_toggle_cursor_item;
379
  klass->activate_cursor_item = gtk_icon_view_real_activate_cursor_item;  
380
  klass->move_cursor = gtk_icon_view_real_move_cursor;
Anders Carlsson's avatar
Anders Carlsson committed
381 382
  
  /* Properties */
383 384 385 386 387 388 389 390 391
  /**
   * GtkIconView:selection-mode:
   * 
   * The ::selection-mode property specifies the selection mode of
   * icon view. If the mode is #GTK_SELECTION_MULTIPLE, rubberband selection
   * is enabled, for the other modes, only keyboard selection is possible.
   *
   * Since: 2.6
   */
Anders Carlsson's avatar
Anders Carlsson committed
392 393
  g_object_class_install_property (gobject_class,
				   PROP_SELECTION_MODE,
394
				   g_param_spec_enum ("selection-mode",
395 396
						      P_("Selection mode"),
						      P_("The selection mode"),
Anders Carlsson's avatar
Anders Carlsson committed
397 398
						      GTK_TYPE_SELECTION_MODE,
						      GTK_SELECTION_SINGLE,
399
						      GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Anders Carlsson's avatar
Anders Carlsson committed
400

401 402 403 404 405 406 407 408 409 410
  /**
   * GtkIconView:pixbuf-column:
   *
   * The ::pixbuf-column property contains the number of the model column
   * containing the pixbufs which are displayed. The pixbuf column must be 
   * of type #GDK_TYPE_PIXBUF. Setting this property to -1 turns off the
   * display of pixbufs.
   *
   * Since: 2.6
   */
Anders Carlsson's avatar
Anders Carlsson committed
411
  g_object_class_install_property (gobject_class,
412
				   PROP_PIXBUF_COLUMN,
413
				   g_param_spec_int ("pixbuf-column",
414 415
						     P_("Pixbuf column"),
						     P_("Model column used to retrieve the icon pixbuf from"),
416
						     -1, G_MAXINT, -1,
417
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
418

419 420 421 422 423 424 425 426 427 428
  /**
   * GtkIconView:text-column:
   *
   * The ::text-column property contains the number of the model column
   * containing the texts which are displayed. The text column must be 
   * of type #G_TYPE_STRING. If this property and the :markup-column 
   * property are both set to -1, no texts are displayed.   
   *
   * Since: 2.6
   */
Anders Carlsson's avatar
Anders Carlsson committed
429
  g_object_class_install_property (gobject_class,
430
				   PROP_TEXT_COLUMN,
431
				   g_param_spec_int ("text-column",
432 433
						     P_("Text column"),
						     P_("Model column used to retrieve the text from"),
434
						     -1, G_MAXINT, -1,
435
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Anders Carlsson's avatar
Anders Carlsson committed
436

437 438 439 440 441 442 443 444 445 446 447 448
  
  /**
   * GtkIconView:markup-column:
   *
   * The ::markup-column property contains the number of the model column
   * containing markup information to be displayed. The markup column must be 
   * of type #G_TYPE_STRING. If this property and the :text-column property 
   * are both set to column numbers, it overrides the text column.
   * If both are set to -1, no texts are displayed.   
   *
   * Since: 2.6
   */
449 450
  g_object_class_install_property (gobject_class,
				   PROP_MARKUP_COLUMN,
451
				   g_param_spec_int ("markup-column",
452
						     P_("Markup column"),
453
						     P_("Model column used to retrieve the text if using Pango markup"),
454
						     -1, G_MAXINT, -1,
455
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
456
  
457 458 459
  g_object_class_install_property (gobject_class,
                                   PROP_MODEL,
                                   g_param_spec_object ("model",
460 461
							P_("Icon View Model"),
							P_("The model for the icon view"),
462
							GTK_TYPE_TREE_MODEL,
463
							GTK_PARAM_READWRITE));
464
  
Matthias Clasen's avatar
Matthias Clasen committed
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479
  /**
   * GtkIconView:columns:
   *
   * The columns property contains the number of the columns in which the
   * items should be displayed. If it is -1, the number of columns will
   * be chosen automatically to fill the available area.
   *
   * Since: 2.6
   */
  g_object_class_install_property (gobject_class,
				   PROP_COLUMNS,
				   g_param_spec_int ("columns",
						     P_("Number of columns"),
						     P_("Number of columns to display"),
						     -1, G_MAXINT, -1,
480
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
481 482 483
  

  /**
484
   * GtkIconView:item-width:
Matthias Clasen's avatar
Matthias Clasen committed
485 486 487 488 489 490 491 492 493
   *
   * The item-width property specifies the width to use for each item. 
   * If it is set to -1, the icon view will automatically determine a 
   * suitable item size.
   *
   * Since: 2.6
   */
  g_object_class_install_property (gobject_class,
				   PROP_ITEM_WIDTH,
494
				   g_param_spec_int ("item-width",
Matthias Clasen's avatar
Matthias Clasen committed
495 496 497
						     P_("Width for each item"),
						     P_("The width used for each item"),
						     -1, G_MAXINT, -1,
498
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
499 500

  /**
501
   * GtkIconView:spacing:
Matthias Clasen's avatar
Matthias Clasen committed
502 503 504 505 506 507 508 509 510 511 512 513
   *
   * The spacing property specifies the space which is inserted between
   * the cells (i.e. the icon and the text) of an item.
   *
   * Since: 2.6
   */
  g_object_class_install_property (gobject_class,
                                   PROP_SPACING,
                                   g_param_spec_int ("spacing",
						     P_("Spacing"),
						     P_("Space which is inserted between cells of an item"),
						     0, G_MAXINT, 0,
514
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
515 516

  /**
517
   * GtkIconView:row-spacing:
Matthias Clasen's avatar
Matthias Clasen committed
518 519 520 521 522 523 524 525
   *
   * The row-spacing property specifies the space which is inserted between
   * the rows of the icon view.
   *
   * Since: 2.6
   */
  g_object_class_install_property (gobject_class,
                                   PROP_ROW_SPACING,
526
                                   g_param_spec_int ("row-spacing",
Matthias Clasen's avatar
Matthias Clasen committed
527 528 529
						     P_("Row Spacing"),
						     P_("Space which is inserted between grid rows"),
						     0, G_MAXINT, 6,
530
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
531 532

  /**
533
   * GtkIconView:column-spacing:
Matthias Clasen's avatar
Matthias Clasen committed
534 535 536 537 538 539 540 541
   *
   * The column-spacing property specifies the space which is inserted between
   * the columns of the icon view.
   *
   * Since: 2.6
   */
  g_object_class_install_property (gobject_class,
                                   PROP_COLUMN_SPACING,
542
                                   g_param_spec_int ("column-spacing",
Matthias Clasen's avatar
Matthias Clasen committed
543
						     P_("Column Spacing"),
544
						     P_("Space which is inserted between grid columns"),
Matthias Clasen's avatar
Matthias Clasen committed
545
						     0, G_MAXINT, 6,
546
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
547 548

  /**
549
   * GtkIconView:margin:
Matthias Clasen's avatar
Matthias Clasen committed
550 551 552 553 554 555 556 557 558 559 560 561
   *
   * The margin property specifies the space which is inserted 
   * at the edges of the icon view.
   *
   * Since: 2.6
   */
  g_object_class_install_property (gobject_class,
                                   PROP_MARGIN,
                                   g_param_spec_int ("margin",
						     P_("Margin"),
						     P_("Space which is inserted at the edges of the icon view"),
						     0, G_MAXINT, 6,
562
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
563 564

  /**
565
   * GtkIconView:item-orientation:
Matthias Clasen's avatar
Matthias Clasen committed
566
   *
567
   * The item-orientation property specifies how the cells (i.e. the icon and
Matthias Clasen's avatar
Matthias Clasen committed
568 569 570 571
   * the text) of the item are positioned relative to each other.
   *
   * Since: 2.6
   */
572
  g_object_class_install_property (gobject_class,
573 574 575
				   PROP_ITEM_ORIENTATION,
				   g_param_spec_enum ("item-orientation",
						      P_("Item Orientation"),
576 577 578
						      P_("How the text and icon of each item are positioned relative to each other"),
						      GTK_TYPE_ORIENTATION,
						      GTK_ORIENTATION_VERTICAL,
579
						      GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Anders Carlsson's avatar
Anders Carlsson committed
580

Matthias Clasen's avatar
Matthias Clasen committed
581
  /**
582
   * GtkIconView:reorderable:
Matthias Clasen's avatar
Matthias Clasen committed
583 584 585 586 587 588 589 590 591 592 593 594
   *
   * The reorderable property specifies if the items can be reordered
   * by DND.
   *
   * Since: 2.8
   */
  g_object_class_install_property (gobject_class,
                                   PROP_REORDERABLE,
                                   g_param_spec_boolean ("reorderable",
							 P_("Reorderable"),
							 P_("View is reorderable"),
							 FALSE,
595
							 G_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
596

597 598 599 600 601 602 603 604
    g_object_class_install_property (gobject_class,
                                     PROP_TOOLTIP_COLUMN,
                                     g_param_spec_int ("tooltip-column",
                                                       P_("Tooltip Column"),
                                                       P_("The column in the model containing the tooltip texts for the items"),
                                                       -1,
                                                       G_MAXINT,
                                                       -1,
605
                                                       GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
606

607 608 609 610 611 612 613 614 615 616 617 618 619 620
  /**
   * GtkIconView:item-padding:
   *
   * The item-padding property specifies the padding around each
   * of the icon view's item.
   *
   * Since: 2.18
   */
  g_object_class_install_property (gobject_class,
                                   PROP_ITEM_PADDING,
                                   g_param_spec_int ("item-padding",
						     P_("Item Padding"),
						     P_("Padding around icon view items"),
						     0, G_MAXINT, 6,
621
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
622

623 624 625 626 627
  /**
   * GtkIconView:cell-area:
   *
   * The #GtkCellArea used to layout cell renderers for this view.
   *
628 629 630
   * If no area is specified when creating the icon view with gtk_icon_view_new_with_area() 
   * a #GtkCellAreaBox will be used.
   *
631 632 633 634 635 636 637 638 639 640
   * Since: 3.0
   */
  g_object_class_install_property (gobject_class,
				   PROP_CELL_AREA,
				   g_param_spec_object ("cell-area",
							P_("Cell Area"),
							P_("The GtkCellArea used to layout cells"),
							GTK_TYPE_CELL_AREA,
							GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));

641 642 643 644 645 646 647 648 649 650 651 652 653 654
  /**
   * GtkIconView:activate-on-single-click:
   *
   * The activate-on-single-click property specifies whether the "item-activated" signal
   * will be emitted after a single click.
   *
   * Since: 3.8
   */
  g_object_class_install_property (gobject_class,
                                   PROP_ACTIVATE_ON_SINGLE_CLICK,
                                   g_param_spec_boolean ("activate-on-single-click",
							 P_("Activate on Single Click"),
							 P_("Activate row on a single click"),
							 FALSE,
655
							 GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
656

657
  /* Scrollable interface properties */
658 659 660 661
  g_object_class_override_property (gobject_class, PROP_HADJUSTMENT,    "hadjustment");
  g_object_class_override_property (gobject_class, PROP_VADJUSTMENT,    "vadjustment");
  g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
  g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
662

663
  /* Style properties */
664
  gtk_widget_class_install_style_property (widget_class,
665
                                           g_param_spec_boxed ("selection-box-color",
666 667
                                                               P_("Selection Box Color"),
                                                               P_("Color of the selection box"),
Matthias Clasen's avatar
Matthias Clasen committed
668
                                                               g_type_from_name ("GdkColor"),
669
                                                               GTK_PARAM_READABLE));
670 671

  gtk_widget_class_install_style_property (widget_class,
672
                                           g_param_spec_uchar ("selection-box-alpha",
673 674
                                                               P_("Selection Box Alpha"),
                                                               P_("Opacity of the selection box"),
675 676
                                                               0, 0xff,
                                                               0x40,
677
                                                               GTK_PARAM_READABLE));
678

Anders Carlsson's avatar
Anders Carlsson committed
679
  /* Signals */
Matthias Clasen's avatar
Matthias Clasen committed
680 681 682 683 684 685
  /**
   * GtkIconView::item-activated:
   * @iconview: the object on which the signal is emitted
   * @path: the #GtkTreePath for the activated item
   *
   * The ::item-activated signal is emitted when the method
686 687 688 689 690 691
   * gtk_icon_view_item_activated() is called, when the user double
   * clicks an item with the "activate-on-single-click" property set
   * to %FALSE, or when the user single clicks an item when the
   * "activate-on-single-click" property set to %TRUE. It is also
   * emitted when a non-editable item is selected and one of the keys:
   * Space, Return or Enter is pressed.
Matthias Clasen's avatar
Matthias Clasen committed
692
   */
693
  icon_view_signals[ITEM_ACTIVATED] =
694
    g_signal_new (I_("item-activated"),
Anders Carlsson's avatar
Anders Carlsson committed
695 696
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST,
697
		  G_STRUCT_OFFSET (GtkIconViewClass, item_activated),
Anders Carlsson's avatar
Anders Carlsson committed
698
		  NULL, NULL,
699
		  g_cclosure_marshal_VOID__BOXED,
Anders Carlsson's avatar
Anders Carlsson committed
700
		  G_TYPE_NONE, 1,
701
		  GTK_TYPE_TREE_PATH);
Anders Carlsson's avatar
Anders Carlsson committed
702

Matthias Clasen's avatar
Matthias Clasen committed
703 704 705 706 707 708 709
  /**
   * GtkIconView::selection-changed:
   * @iconview: the object on which the signal is emitted
   *
   * The ::selection-changed signal is emitted when the selection
   * (i.e. the set of selected items) changes.
   */
710
  icon_view_signals[SELECTION_CHANGED] =
711
    g_signal_new (I_("selection-changed"),
Anders Carlsson's avatar
Anders Carlsson committed
712 713
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_FIRST,
714
		  G_STRUCT_OFFSET (GtkIconViewClass, selection_changed),
Anders Carlsson's avatar
Anders Carlsson committed
715 716 717 718
		  NULL, NULL,
		  g_cclosure_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);
  
Matthias Clasen's avatar
Matthias Clasen committed
719 720 721 722
  /**
   * GtkIconView::select-all:
   * @iconview: the object on which the signal is emitted
   *
723
   * A [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
724 725 726 727 728 729 730 731
   * which gets emitted when the user selects all items.
   *
   * Applications should not connect to it, but may emit it with
   * g_signal_emit_by_name() if they need to control selection
   * programmatically.
   * 
   * The default binding for this signal is Ctrl-a.
   */
732
  icon_view_signals[SELECT_ALL] =
733
    g_signal_new (I_("select-all"),
Anders Carlsson's avatar
Anders Carlsson committed
734 735
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
736
		  G_STRUCT_OFFSET (GtkIconViewClass, select_all),
Anders Carlsson's avatar
Anders Carlsson committed
737 738 739 740
		  NULL, NULL,
		  g_cclosure_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);
  
Matthias Clasen's avatar
Matthias Clasen committed
741 742 743 744
  /**
   * GtkIconView::unselect-all:
   * @iconview: the object on which the signal is emitted
   *
745
   * A [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
746 747 748 749 750 751 752 753
   * which gets emitted when the user unselects all items.
   *
   * Applications should not connect to it, but may emit it with
   * g_signal_emit_by_name() if they need to control selection
   * programmatically.
   * 
   * The default binding for this signal is Ctrl-Shift-a. 
   */
754
  icon_view_signals[UNSELECT_ALL] =
755
    g_signal_new (I_("unselect-all"),
Anders Carlsson's avatar
Anders Carlsson committed
756 757
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
758
		  G_STRUCT_OFFSET (GtkIconViewClass, unselect_all),
Anders Carlsson's avatar
Anders Carlsson committed
759 760 761 762
		  NULL, NULL,
		  g_cclosure_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);

Matthias Clasen's avatar
Matthias Clasen committed
763 764 765 766
  /**
   * GtkIconView::select-cursor-item:
   * @iconview: the object on which the signal is emitted
   *
767
   * A [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
768 769 770 771 772 773 774 775 776
   * which gets emitted when the user selects the item that is currently
   * focused.
   *
   * Applications should not connect to it, but may emit it with
   * g_signal_emit_by_name() if they need to control selection
   * programmatically.
   * 
   * There is no default binding for this signal.
   */
777
  icon_view_signals[SELECT_CURSOR_ITEM] =
778
    g_signal_new (I_("select-cursor-item"),
Anders Carlsson's avatar
Anders Carlsson committed
779 780
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
781
		  G_STRUCT_OFFSET (GtkIconViewClass, select_cursor_item),
Anders Carlsson's avatar
Anders Carlsson committed
782 783 784 785
		  NULL, NULL,
		  g_cclosure_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);

Matthias Clasen's avatar
Matthias Clasen committed
786 787 788 789
  /**
   * GtkIconView::toggle-cursor-item:
   * @iconview: the object on which the signal is emitted
   *
790
   * A [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
791 792 793 794 795 796 797 798 799 800
   * which gets emitted when the user toggles whether the currently
   * focused item is selected or not. The exact effect of this 
   * depend on the selection mode.
   *
   * Applications should not connect to it, but may emit it with
   * g_signal_emit_by_name() if they need to control selection
   * programmatically.
   * 
   * There is no default binding for this signal is Ctrl-Space.
   */
801
  icon_view_signals[TOGGLE_CURSOR_ITEM] =
802
    g_signal_new (I_("toggle-cursor-item"),
Anders Carlsson's avatar
Anders Carlsson committed
803 804
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
805
		  G_STRUCT_OFFSET (GtkIconViewClass, toggle_cursor_item),
Anders Carlsson's avatar
Anders Carlsson committed
806 807 808 809
		  NULL, NULL,
		  g_cclosure_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);

Matthias Clasen's avatar
Matthias Clasen committed
810 811 812 813
  /**
   * GtkIconView::activate-cursor-item:
   * @iconview: the object on which the signal is emitted
   *
814
   * A [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
815 816 817 818 819 820 821 822 823
   * which gets emitted when the user activates the currently 
   * focused item. 
   *
   * Applications should not connect to it, but may emit it with
   * g_signal_emit_by_name() if they need to control activation
   * programmatically.
   * 
   * The default bindings for this signal are Space, Return and Enter.
   */
824
  icon_view_signals[ACTIVATE_CURSOR_ITEM] =
825
    g_signal_new (I_("activate-cursor-item"),
826 827 828 829 830 831 832
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkIconViewClass, activate_cursor_item),
		  NULL, NULL,
		  _gtk_marshal_BOOLEAN__VOID,
		  G_TYPE_BOOLEAN, 0);
  
Matthias Clasen's avatar
Matthias Clasen committed
833 834 835 836 837 838 839
  /**
   * GtkIconView::move-cursor:
   * @iconview: the object which received the signal
   * @step: the granularity of the move, as a #GtkMovementStep
   * @count: the number of @step units to move
   *
   * The ::move-cursor signal is a
840
   * [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
841 842 843 844 845 846 847
   * which gets emitted when the user initiates a cursor movement.
   *
   * Applications should not connect to it, but may emit it with
   * g_signal_emit_by_name() if they need to control the cursor
   * programmatically.
   *
   * The default bindings for this signal include
848 849 850
   * - Arrow keys which move by individual steps
   * - Home/End keys which move to the first/last item
   * - PageUp/PageDown which move by "pages"
Matthias Clasen's avatar
Matthias Clasen committed
851 852 853
   * All of these will extend the selection when combined with
   * the Shift modifier.
   */
854
  icon_view_signals[MOVE_CURSOR] =
855
    g_signal_new (I_("move-cursor"),
Matthias Clasen's avatar
Matthias Clasen committed
856 857
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
858
		  G_STRUCT_OFFSET (GtkIconViewClass, move_cursor),
Matthias Clasen's avatar
Matthias Clasen committed
859
		  NULL, NULL,
860
		  _gtk_marshal_BOOLEAN__ENUM_INT,
Matthias Clasen's avatar
Matthias Clasen committed
861 862 863 864
		  G_TYPE_BOOLEAN, 2,
		  GTK_TYPE_MOVEMENT_STEP,
		  G_TYPE_INT);

Anders Carlsson's avatar
Anders Carlsson committed
865
  /* Key bindings */
866
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_a, GDK_CONTROL_MASK, 
867
				"select-all", 0);
868
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_a, GDK_CONTROL_MASK | GDK_SHIFT_MASK, 
869
				"unselect-all", 0);
870
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, GDK_CONTROL_MASK, 
871
				"toggle-cursor-item", 0);
872
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Space, GDK_CONTROL_MASK,
873
				"toggle-cursor-item", 0);
874

875
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, 0, 
876
				"activate-cursor-item", 0);
877
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Space, 0,
878
				"activate-cursor-item", 0);
879
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0, 
880
				"activate-cursor-item", 0);
881
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_ISO_Enter, 0, 
882
				"activate-cursor-item", 0);
883
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0, 
884
				"activate-cursor-item", 0);
885

886
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Up, 0,
Matthias Clasen's avatar
Matthias Clasen committed
887
				  GTK_MOVEMENT_DISPLAY_LINES, -1);
888
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Up, 0,
Matthias Clasen's avatar
Matthias Clasen committed
889 890
				  GTK_MOVEMENT_DISPLAY_LINES, -1);

891
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Down, 0,
Matthias Clasen's avatar
Matthias Clasen committed
892
				  GTK_MOVEMENT_DISPLAY_LINES, 1);
893
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Down, 0,
Matthias Clasen's avatar
Matthias Clasen committed
894 895
				  GTK_MOVEMENT_DISPLAY_LINES, 1);

896
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_p, GDK_CONTROL_MASK,
Matthias Clasen's avatar
Matthias Clasen committed
897 898
				  GTK_MOVEMENT_DISPLAY_LINES, -1);

899
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_n, GDK_CONTROL_MASK,
Matthias Clasen's avatar
Matthias Clasen committed
900 901
				  GTK_MOVEMENT_DISPLAY_LINES, 1);

902
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Home, 0,
Matthias Clasen's avatar
Matthias Clasen committed
903
				  GTK_MOVEMENT_BUFFER_ENDS, -1);
904
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Home, 0,
Matthias Clasen's avatar
Matthias Clasen committed
905 906
				  GTK_MOVEMENT_BUFFER_ENDS, -1);

907
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_End, 0,
Matthias Clasen's avatar
Matthias Clasen committed
908
				  GTK_MOVEMENT_BUFFER_ENDS, 1);
909
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_End, 0,
Matthias Clasen's avatar
Matthias Clasen committed
910 911
				  GTK_MOVEMENT_BUFFER_ENDS, 1);

912
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Page_Up, 0,
Matthias Clasen's avatar
Matthias Clasen committed
913
				  GTK_MOVEMENT_PAGES, -1);
914
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Page_Up, 0,
Matthias Clasen's avatar
Matthias Clasen committed
915 916
				  GTK_MOVEMENT_PAGES, -1);

917
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Page_Down, 0,
Matthias Clasen's avatar
Matthias Clasen committed
918
				  GTK_MOVEMENT_PAGES, 1);
919
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Page_Down, 0,
Matthias Clasen's avatar
Matthias Clasen committed
920 921
				  GTK_MOVEMENT_PAGES, 1);

922
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Right, 0, 
Matthias Clasen's avatar
Matthias Clasen committed
923
				  GTK_MOVEMENT_VISUAL_POSITIONS, 1);
924
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Left, 0, 
Matthias Clasen's avatar
Matthias Clasen committed
925 926
				  GTK_MOVEMENT_VISUAL_POSITIONS, -1);

927
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Right, 0, 
Matthias Clasen's avatar
Matthias Clasen committed
928
				  GTK_MOVEMENT_VISUAL_POSITIONS, 1);
929
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Left, 0, 
Matthias Clasen's avatar
Matthias Clasen committed
930
				  GTK_MOVEMENT_VISUAL_POSITIONS, -1);
931

932
  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_ICON_VIEW_ACCESSIBLE);
Matthias Clasen's avatar
Matthias Clasen committed
933
}
Anders Carlsson's avatar
Anders Carlsson committed
934

935 936 937 938
static void
gtk_icon_view_buildable_init (GtkBuildableIface *iface)
{
  parent_buildable_iface = g_type_interface_peek_parent (iface);
939
  iface->add_child = _gtk_cell_layout_buildable_add_child;
940 941 942 943
  iface->custom_tag_start = gtk_icon_view_buildable_custom_tag_start;
  iface->custom_tag_end = gtk_icon_view_buildable_custom_tag_end;
}

Matthias Clasen's avatar
Matthias Clasen committed
944 945 946
static void
gtk_icon_view_cell_layout_init (GtkCellLayoutIface *iface)
{
947
  iface->get_area = gtk_icon_view_cell_layout_get_area;
Matthias Clasen's avatar
Matthias Clasen committed
948 949
}

Anders Carlsson's avatar
Anders Carlsson committed
950
static void
951
gtk_icon_view_init (GtkIconView *icon_view)
Anders Carlsson's avatar
Anders Carlsson committed
952
{
953
  icon_view->priv = gtk_icon_view_get_instance_private (icon_view);
954

955 956 957 958 959 960 961 962 963
  icon_view->priv->width = 0;
  icon_view->priv->height = 0;
  icon_view->priv->selection_mode = GTK_SELECTION_SINGLE;
  icon_view->priv->pressed_button = -1;
  icon_view->priv->press_start_x = -1;
  icon_view->priv->press_start_y = -1;
  icon_view->priv->text_column = -1;
  icon_view->priv->markup_column = -1;  
  icon_view->priv->pixbuf_column = -1;
964 965
  icon_view->priv->text_cell = NULL;
  icon_view->priv->pixbuf_cell = NULL;  
966
  icon_view->priv->tooltip_column = -1;  
967

968
  gtk_widget_set_can_focus (GTK_WIDGET (icon_view), TRUE);
Matthias Clasen's avatar
Matthias Clasen committed
969

970
  icon_view->priv->item_orientation = GTK_ORIENTATION_VERTICAL;
Matthias Clasen's avatar
Matthias Clasen committed
971 972 973 974 975 976 977

  icon_view->priv->columns = -1;
  icon_view->priv->item_width = -1;
  icon_view->priv->spacing = 0;
  icon_view->priv->row_spacing = 6;
  icon_view->priv->column_spacing = 6;
  icon_view->priv->margin = 6;
978
  icon_view->priv->item_padding = 6;
979
  icon_view->priv->activate_on_single_click = FALSE;
980 981

  icon_view->priv->draw_focus = TRUE;
982 983 984

  icon_view->priv->row_contexts = 
    g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
985 986 987

  gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (icon_view)),
                               GTK_STYLE_CLASS_VIEW);
Anders Carlsson's avatar
Anders Carlsson committed
988 989
}

990
/* GObject methods */
991

992 993 994 995
static void
gtk_icon_view_constructed (GObject *object)
{
  GtkIconView *icon_view = GTK_ICON_VIEW (object);
996

997
  G_OBJECT_CLASS (gtk_icon_view_parent_class)->constructed (object);
998

999
  gtk_icon_view_ensure_cell_area (icon_view, NULL);
1000 1001
}

1002
static void
1003
gtk_icon_view_dispose (GObject *object)
1004
{
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016
  GtkIconView *icon_view;
  GtkIconViewPrivate *priv;

  icon_view = GTK_ICON_VIEW (object);
  priv      = icon_view->priv;

  if (priv->cell_area_context)
    {
      g_object_unref (priv->cell_area_context);
      priv->cell_area_context = NULL;
    }

1017 1018 1019 1020 1021 1022
  if (priv->row_contexts)
    {
      g_ptr_array_free (priv->row_contexts, TRUE);
      priv->row_contexts = NULL;
    }

1023 1024
  if (priv->cell_area)
    {
1025 1026
      gtk_cell_area_stop_editing (icon_view->priv->cell_area, TRUE);

1027 1028 1029 1030 1031
      g_signal_handler_disconnect (priv->cell_area, priv->add_editable_id);
      g_signal_handler_disconnect (priv->cell_area, priv->remove_editable_id);
      priv->add_editable_id = 0;
      priv->remove_editable_id = 0;

1032 1033 1034 1035 1036
      g_object_unref (priv->cell_area);
      priv->cell_area = NULL;
    }

  G_OBJECT_CLASS (gtk_icon_view_parent_class)->dispose (object);
Anders Carlsson's avatar
Anders Carlsson committed
1037 1038 1039
}

static void
1040
gtk_icon_view_set_property (GObject      *object,
Anders Carlsson's avatar
Anders Carlsson committed
1041 1042 1043 1044
			    guint         prop_id,
			    const GValue *value,
			    GParamSpec   *pspec)
{
1045
  GtkIconView *icon_view;
1046
  GtkCellArea *area;
Anders Carlsson's avatar
Anders Carlsson committed
1047

1048
  icon_view = GTK_ICON_VIEW (object);
Anders Carlsson's avatar
Anders Carlsson committed
1049 1050 1051 1052

  switch (prop_id)
    {
    case PROP_SELECTION_MODE:
1053
      gtk_icon_view_set_selection_mode (icon_view, g_value_get_enum (value));
Anders Carlsson's avatar
Anders Carlsson committed
1054
      break;
1055
    case PROP_PIXBUF_COLUMN:
1056
      gtk_icon_view_set_pixbuf_column (icon_view, g_value_get_int (value));
1057 1058
      break;
    case PROP_TEXT_COLUMN:
1059
      gtk_icon_view_set_text_column (icon_view, g_value_get_int (value));
Anders Carlsson's avatar
Anders Carlsson committed
1060
      break;
1061
    case PROP_MARKUP_COLUMN:
1062
      gtk_icon_view_set_markup_column (icon_view, g_value_get_int (value));
1063
      break;
1064
    case PROP_MODEL:
1065
      gtk_icon_view_set_model (icon_view, g_value_get_object (value));
Anders Carlsson's avatar
Anders Carlsson committed
1066
      break;
1067 1068
    case PROP_ITEM_ORIENTATION:
      gtk_icon_view_set_item_orientation (icon_view, g_value_get_enum (value));
1069
      break;
Matthias Clasen's avatar
Matthias Clasen committed
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087
    case PROP_COLUMNS:
      gtk_icon_view_set_columns (icon_view, g_value_get_int (value));
      break;
    case PROP_ITEM_WIDTH:
      gtk_icon_view_set_item_width (icon_view, g_value_get_int (value));
      break;
    case PROP_SPACING:
      gtk_icon_view_set_spacing (icon_view, g_value_get_int (value));
      break;
    case PROP_ROW_SPACING:
      gtk_icon_view_set_row_spacing (icon_view, g_value_get_int (value));
      break;
    case PROP_COLUMN_SPACING:
      gtk_icon_view_set_column_spacing (icon_view, g_value_get_int (value));
      break;
    case PROP_MARGIN:
      gtk_icon_view_set_margin (icon_view, g_value_get_int (value));
      break;
Matthias Clasen's avatar
Matthias Clasen committed
1088 1089 1090
    case PROP_REORDERABLE:
      gtk_icon_view_set_reorderable (icon_view, g_value_get_boolean (value));
      break;
1091
      
1092 1093 1094 1095
    case PROP_TOOLTIP_COLUMN:
      gtk_icon_view_set_tooltip_column (icon_view, g_value_get_int (value));
      break;

Matthias Clasen's avatar
Matthias Clasen committed
1096 1097 1098 1099
    case PROP_ITEM_PADDING:
      gtk_icon_view_set_item_padding (icon_view, g_value_get_int (value));
      break;

1100 1101 1102 1103
    case PROP_ACTIVATE_ON_SINGLE_CLICK:
      gtk_icon_view_set_activate_on_single_click (icon_view, g_value_get_boolean (value));
      break;

1104 1105 1106 1107
    case PROP_CELL_AREA:
      /* Construct-only, can only be assigned once */
      area = g_value_get_object (value);
      if (area)
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117
        {
          if (icon_view->priv->cell_area != NULL)
            {
              g_warning ("cell-area has already been set, ignoring construct property");
              g_object_ref_sink (area);
              g_object_unref (area);
            }
          else
            gtk_icon_view_ensure_cell_area (icon_view, area);
        }
1118 1119
      break;

1120 1121 1122 1123 1124 1125
    case PROP_HADJUSTMENT:
      gtk_icon_view_set_hadjustment (icon_view, g_value_get_object (value));
      break;
    case PROP_VADJUSTMENT:
      gtk_icon_view_set_vadjustment (icon_view, g_value_get_object (value));
      break;
1126
    case PROP_HSCROLL_POLICY:
1127 1128 1129 1130 1131 1132
      if (icon_view->priv->hscroll_policy != g_value_get_enum (value))
        {
          icon_view->priv->hscroll_policy = g_value_get_enum (value);
          gtk_widget_queue_resize (GTK_WIDGET (icon_view));
          g_object_notify_by_pspec (object, pspec);
        }
1133 1134
      break;
    case PROP_VSCROLL_POLICY:
1135 1136 1137 1138 1139 1140
      if (icon_view->priv->vscroll_policy != g_value_get_enum (value))
        {
          icon_view->priv->vscroll_policy = g_value_get_enum (value);
          gtk_widget_queue_resize (GTK_WIDGET (icon_view));
          g_object_notify_by_pspec (object, pspec);
        }
1141
      break;
1142

Anders Carlsson's avatar
Anders Carlsson committed
1143 1144 1145 1146 1147 1148 1149
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
1150
gtk_icon_view_get_property (GObject      *object,
Anders Carlsson's avatar
Anders Carlsson committed
1151 1152 1153 1154
			    guint         prop_id,
			    GValue       *value,
			    GParamSpec   *pspec)
{
1155
  GtkIconView *icon_view;
Anders Carlsson's avatar
Anders Carlsson committed
1156

1157
  icon_view = GTK_ICON_VIEW (object);
Anders Carlsson's avatar
Anders Carlsson committed
1158 1159 1160 1161

  switch (prop_id)
    {
    case PROP_SELECTION_MODE:
1162
      g_value_set_enum (value, icon_view->priv->selection_mode);
Anders Carlsson's avatar
Anders Carlsson committed
1163
      break;
1164
    case PROP_PIXBUF_COLUMN:
1165
      g_value_set_int (value, icon_view->priv->pixbuf_column);
1166 1167
      break;
    case PROP_TEXT_COLUMN:
1168
      g_value_set_int (value, icon_view->priv->text_column);
Anders Carlsson's avatar
Anders Carlsson committed
1169
      break;
1170
    case PROP_MARKUP_COLUMN:
1171
      g_value_set_int (value, icon_view->priv->markup_column);
1172
      break;
1173
    case PROP_MODEL:
1174
      g_value_set_object (value, icon_view->priv->model);
Anders Carlsson's avatar
Anders Carlsson committed
1175
      break;
1176 1177
    case PROP_ITEM_ORIENTATION:
      g_value_set_enum (value, icon_view->priv->item_orientation);
1178
      break;
Matthias Clasen's avatar
Matthias Clasen committed
1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196
    case PROP_COLUMNS:
      g_value_set_int (value, icon_view->priv->columns);
      break;
    case PROP_ITEM_WIDTH:
      g_value_set_int (value, icon_view->priv->item_width);
      break;
    case PROP_SPACING:
      g_value_set_int (value, icon_view->priv->spacing);
      break;
    case PROP_ROW_SPACING:
      g_value_set_int (value, icon_view->priv->row_spacing);
      break;
    case PROP_COLUMN_SPACING:
      g_value_set_int (value, icon_view->priv->column_spacing);
      break;
    case PROP_MARGIN:
      g_value_set_int (value, icon_view->priv->margin);
      break;
Matthias Clasen's avatar
Matthias Clasen committed
1197 1198 1199
    case PROP_REORDERABLE:
      g_value_set_boolean (value, icon_view->priv->reorderable);
      break;
1200 1201 1202
    case PROP_TOOLTIP_COLUMN:
      g_value_set_int (value, icon_view->priv->tooltip_column);
      break;
Matthias Clasen's avatar
Matthias Clasen committed
1203

Matthias Clasen's avatar
Matthias Clasen committed
1204 1205 1206 1207
    case PROP_ITEM_PADDING:
      g_value_set_int (value, icon_view->priv->item_padding);
      break;

1208 1209 1210 1211
    case PROP_ACTIVATE_ON_SINGLE_CLICK:
      g_value_set_boolean (value, icon_view->priv->activate_on_single_click);
      break;

1212 1213 1214 1215
    case PROP_CELL_AREA:
      g_value_set_object (value, icon_view->priv->cell_area);
      break;

1216 1217 1218 1219 1220 1221
    case PROP_HADJUSTMENT:
      g_value_set_object (value, icon_view->priv->hadjustment);
      break;
    case PROP_VADJUSTMENT:
      g_value_set_object (value, icon_view->priv->vadjustment);
      break;
1222 1223 1224 1225 1226 1227
    case PROP_HSCROLL_POLICY:
      g_value_set_enum (value, icon_view->priv->hscroll_policy);
      break;
    case PROP_VSCROLL_POLICY:
      g_value_set_enum (value, icon_view->priv->vscroll_policy);
      break;
1228

Anders Carlsson's avatar
Anders Carlsson committed
1229 1230 1231 1232 1233 1234
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265
/* GtkWidget methods */
static void
gtk_icon_view_destroy (GtkWidget *widget)
{
  GtkIconView *icon_view = GTK_ICON_VIEW (widget);

  gtk_icon_view_set_model (icon_view, NULL);

  if (icon_view->priv->scroll_to_path != NULL)
    {
      gtk_tree_row_reference_free (icon_view->priv->scroll_to_path);
      icon_view->priv->scroll_to_path = NULL;
    }

  remove_scroll_timeout (icon_view);

  if (icon_view->priv->hadjustment != NULL)
    {
      g_object_unref (icon_view->priv->hadjustment);
      icon_view->priv->hadjustment = NULL;
    }

  if (icon_view->priv->vadjustment != NULL)
    {
      g_object_unref (icon_view->priv->vadjustment);
      icon_view->priv->vadjustment = NULL;
    }

  GTK_WIDGET_CLASS (gtk_icon_view_parent_class)->destroy (widget);
}

Anders Carlsson's avatar
Anders Carlsson committed
1266
static void
1267
gtk_icon_view_realize (GtkWidget *widget)
Anders Carlsson's avatar
Anders Carlsson committed
1268
{
1269 1270 1271
  GtkIconView *icon_view = GTK_ICON_VIEW (widget);
  GtkAllocation allocation;
  GdkWindow *window;
Anders Carlsson's avatar
Anders Carlsson committed
1272 1273 1274
  GdkWindowAttr attributes;
  gint attributes_mask;

1275
  gtk_widget_set_realized (widget, TRUE);
Anders Carlsson's avatar
Anders Carlsson committed
1276

1277 1278
  gtk_widget_get_allocation (widget, &allocation);

Anders Carlsson's avatar
Anders Carlsson committed
1279 1280
  /* Make the main, clipping window */
  attributes.window_type = GDK_WINDOW_CHILD;
1281 1282 1283 1284
  attributes.x = allocation.x;
  attributes.y = allocation.y;
  attributes.width = allocation.width;
  attributes.height = allocation.height;
Anders Carlsson's avatar
Anders Carlsson committed
1285 1286 1287 1288
  attributes.wclass = GDK_INPUT_OUTPUT;
  attributes.visual = gtk_widget_get_visual (widget);
  attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;

1289
  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
Anders Carlsson's avatar
Anders Carlsson committed
1290

1291 1292 1293
  window = gdk_window_new (gtk_widget_get_parent_window (widget),
                           &attributes, attributes_mask);
  gtk_widget_set_window (widget, window);
1294
  gtk_widget_register_window (widget, window);
1295 1296

  gtk_widget_get_allocation (widget, &allocation);
Anders Carlsson's avatar
Anders Carlsson committed
1297

1298
  /* Make the window for the icon view */
Anders Carlsson's avatar
Anders Carlsson committed
1299 1300
  attributes.x = 0;
  attributes.y = 0;
1301 1302
  attributes.width = MAX (icon_view->priv->width, allocation.width);
  attributes.height = MAX (icon_view->priv->height, allocation.height);
Anders Carlsson's avatar
Anders Carlsson committed
1303
  attributes.event_mask = (GDK_EXPOSURE_MASK |
1304 1305 1306
                           GDK_SCROLL_MASK |
                           GDK_SMOOTH_SCROLL_MASK |
                           GDK_POINTER_MOTION_MASK |
1307
                           GDK_LEAVE_NOTIFY_MASK |
1308 1309 1310 1311
                           GDK_BUTTON_PRESS_MASK |
                           GDK_BUTTON_RELEASE_MASK |
                           GDK_KEY_PRESS_MASK |
                           GDK_KEY_RELEASE_MASK) |
Anders Carlsson's avatar
Anders Carlsson committed
1312 1313
    gtk_widget_get_events (widget);
  
1314
  icon_view->priv->bin_window = gdk_window_new (window,
1315
						&attributes, attributes_mask);
1316
  gtk_widget_register_window (widget, icon_view->priv->bin_window);
1317
  gdk_window_show (icon_view->priv->bin_window);
Anders Carlsson's avatar
Anders Carlsson committed
1318 1319 1320
}

static void
1321
gtk_icon_view_unrealize (GtkWidget *widget)
Anders Carlsson's avatar
Anders Carlsson committed
1322
{
1323
  GtkIconView *icon_view;
Anders Carlsson's avatar
Anders Carlsson committed
1324

1325
  icon_view = GTK_ICON_VIEW (widget);
Anders Carlsson's avatar
Anders Carlsson committed
1326

1327
  gtk_widget_unregister_window (widget, icon_view->priv->bin_window);
1328 1329
  gdk_window_destroy (icon_view->priv->bin_window);
  icon_view->priv->bin_window = NULL;
Anders Carlsson's avatar
Anders Carlsson committed
1330

1331
  GTK_WIDGET_CLASS (gtk_icon_view_parent_class)->unrealize (widget);
Anders Carlsson's avatar
Anders Carlsson committed
1332 1333
}

1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344
static gint
gtk_icon_view_get_n_items (GtkIconView *icon_view)
{
  GtkIconViewPrivate *priv = icon_view->priv;

  if (priv->model == NULL)
    return 0;

  return gtk_tree_model_iter_n_children (priv->model, NULL);
}

1345 1346 1347 1348 1349
static void
adjust_wrap_width (GtkIconView *icon_view)
{
  if (icon_view->priv->text_cell)
    {
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379
      gint pixbuf_width, wrap_width;

      if (icon_view->priv->items && icon_view->priv->pixbuf_cell)
        {
          gtk_cell_renderer_get_preferred_width (icon_view->priv->pixbuf_cell,
                                                 GTK_WIDGET (icon_view),
                                                 &pixbuf_width, NULL);
        }
      else
        {
          pixbuf_width = 0;
        }

      if (icon_view->priv->item_width >=