gtkiconview.c 214 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 48 49
#include "gtkcssnodeprivate.h"
#include "gtkwidgetprivate.h"
#include "gtkstylecontextprivate.h"
50
#include "a11y/gtkiconviewaccessibleprivate.h"
Anders Carlsson's avatar
Anders Carlsson committed
51

52 53 54 55 56
/**
 * SECTION:gtkiconview
 * @title: GtkIconView
 * @short_description: A widget which displays a list of icons in a grid
 *
57
 * #GtkIconView provides an alternative view on a #GtkTreeModel.
58 59 60 61 62
 * 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.
63 64 65 66
 *
 * 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
67
 * ignore the tree’s branches.
68 69 70
 *
 * # CSS nodes
 *
71 72 73 74
 * |[<!-- language="plain" -->
 * iconview.view
 * ╰── [rubberband]
 * ]|
75
 *
76
 * GtkIconView has a single CSS node with name iconview and style class .view.
77
 * For rubberband selection, a subnode with name rubberband is used.
78 79
 */

Matthias Clasen's avatar
Matthias Clasen committed
80 81
#define SCROLL_EDGE_SIZE 15

Matthias Clasen's avatar
Matthias Clasen committed
82 83 84
typedef struct _GtkIconViewChild GtkIconViewChild;
struct _GtkIconViewChild
{
85 86
  GtkWidget    *widget;
  GdkRectangle  area;
Matthias Clasen's avatar
Matthias Clasen committed
87
};
Anders Carlsson's avatar
Anders Carlsson committed
88 89 90 91 92 93 94 95 96 97 98

/* Signals */
enum
{
  ITEM_ACTIVATED,
  SELECTION_CHANGED,
  SELECT_ALL,
  UNSELECT_ALL,
  SELECT_CURSOR_ITEM,
  TOGGLE_CURSOR_ITEM,
  MOVE_CURSOR,
99
  ACTIVATE_CURSOR_ITEM,
Anders Carlsson's avatar
Anders Carlsson committed
100 101 102 103 104 105 106
  LAST_SIGNAL
};

/* Properties */
enum
{
  PROP_0,
107 108
  PROP_PIXBUF_COLUMN,
  PROP_TEXT_COLUMN,
109
  PROP_MARKUP_COLUMN,
Anders Carlsson's avatar
Anders Carlsson committed
110
  PROP_SELECTION_MODE,
111
  PROP_ITEM_ORIENTATION,
112
  PROP_MODEL,
Matthias Clasen's avatar
Matthias Clasen committed
113 114 115 116 117
  PROP_COLUMNS,
  PROP_ITEM_WIDTH,
  PROP_SPACING,
  PROP_ROW_SPACING,
  PROP_COLUMN_SPACING,
Matthias Clasen's avatar
Matthias Clasen committed
118
  PROP_MARGIN,
119
  PROP_REORDERABLE,
120
  PROP_TOOLTIP_COLUMN,
121
  PROP_ITEM_PADDING,
122
  PROP_CELL_AREA,
123
  PROP_HADJUSTMENT,
124 125
  PROP_VADJUSTMENT,
  PROP_HSCROLL_POLICY,
126 127
  PROP_VSCROLL_POLICY,
  PROP_ACTIVATE_ON_SINGLE_CLICK
Anders Carlsson's avatar
Anders Carlsson committed
128 129
};

Matthias Clasen's avatar
Matthias Clasen committed
130 131
/* GObject vfuncs */
static void             gtk_icon_view_cell_layout_init          (GtkCellLayoutIface *iface);
132
static void             gtk_icon_view_dispose                   (GObject            *object);
133
static void             gtk_icon_view_constructed               (GObject            *object);
Matthias Clasen's avatar
Matthias Clasen committed
134 135 136 137 138 139 140 141 142
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 */
143
static void             gtk_icon_view_destroy                   (GtkWidget          *widget);
Matthias Clasen's avatar
Matthias Clasen committed
144 145
static void             gtk_icon_view_realize                   (GtkWidget          *widget);
static void             gtk_icon_view_unrealize                 (GtkWidget          *widget);
146
static GtkSizeRequestMode gtk_icon_view_get_request_mode        (GtkWidget          *widget);
147 148 149
static void             gtk_icon_view_get_preferred_width       (GtkWidget          *widget,
								 gint               *minimum,
								 gint               *natural);
150 151 152 153 154
static void             gtk_icon_view_get_preferred_width_for_height
                                                                (GtkWidget          *widget,
                                                                 gint                height,
								 gint               *minimum,
								 gint               *natural);
155 156 157
static void             gtk_icon_view_get_preferred_height      (GtkWidget          *widget,
								 gint               *minimum,
								 gint               *natural);
158 159 160 161 162
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
163 164
static void             gtk_icon_view_size_allocate             (GtkWidget          *widget,
								 GtkAllocation      *allocation);
165 166
static gboolean         gtk_icon_view_draw                      (GtkWidget          *widget,
                                                                 cairo_t            *cr);
Matthias Clasen's avatar
Matthias Clasen committed
167 168
static gboolean         gtk_icon_view_motion                    (GtkWidget          *widget,
								 GdkEventMotion     *event);
169 170
static gboolean         gtk_icon_view_leave                     (GtkWidget          *widget,
								 GdkEventCrossing   *event);
Matthias Clasen's avatar
Matthias Clasen committed
171 172 173 174
static gboolean         gtk_icon_view_button_press              (GtkWidget          *widget,
								 GdkEventButton     *event);
static gboolean         gtk_icon_view_button_release            (GtkWidget          *widget,
								 GdkEventButton     *event);
175 176 177 178
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
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196


/* 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 */
197 198 199 200 201 202
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
203 204 205 206
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,
207
									  cairo_t                *cr,
Matthias Clasen's avatar
Matthias Clasen committed
208
									  GtkIconViewItem        *item,
209 210 211
									  gint                    x,
									  gint                    y,
									  gboolean                draw_focus);
Matthias Clasen's avatar
Matthias Clasen committed
212
static void                 gtk_icon_view_paint_rubberband               (GtkIconView            *icon_view,
213
								          cairo_t                *cr);
Matthias Clasen's avatar
Matthias Clasen committed
214 215
static void                 gtk_icon_view_queue_draw_path                (GtkIconView *icon_view,
									  GtkTreePath *path);
Matthias Clasen's avatar
Matthias Clasen committed
216 217 218
static void                 gtk_icon_view_queue_draw_item                (GtkIconView            *icon_view,
									  GtkIconViewItem        *item);
static void                 gtk_icon_view_start_rubberbanding            (GtkIconView            *icon_view,
219
                                                                          GdkDevice              *device,
Matthias Clasen's avatar
Matthias Clasen committed
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
									  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);
255

256 257 258
static void                 gtk_icon_view_ensure_cell_area               (GtkIconView            *icon_view,
                                                                          GtkCellArea            *cell_area);

259 260
static GtkCellArea         *gtk_icon_view_cell_layout_get_area           (GtkCellLayout          *layout);

261 262
static void                 gtk_icon_view_item_selected_changed          (GtkIconView            *icon_view,
		                                                          GtkIconViewItem        *item);
263 264 265 266 267 268 269 270 271 272 273

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);
274 275
static void                 update_text_cell                             (GtkIconView            *icon_view);
static void                 update_pixbuf_cell                           (GtkIconView            *icon_view);
276

Matthias Clasen's avatar
Matthias Clasen committed
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 303 304 305 306 307 308 309 310 311 312 313 314 315
/* 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);

316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
/* 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);

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

Matthias Clasen's avatar
Matthias Clasen committed
333
G_DEFINE_TYPE_WITH_CODE (GtkIconView, gtk_icon_view, GTK_TYPE_CONTAINER,
334
                         G_ADD_PRIVATE (GtkIconView)
Matthias Clasen's avatar
Matthias Clasen committed
335
			 G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
336 337
						gtk_icon_view_cell_layout_init)
			 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
338 339
						gtk_icon_view_buildable_init)
			 G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
Anders Carlsson's avatar
Anders Carlsson committed
340 341

static void
342
gtk_icon_view_class_init (GtkIconViewClass *klass)
Anders Carlsson's avatar
Anders Carlsson committed
343 344 345
{
  GObjectClass *gobject_class;
  GtkWidgetClass *widget_class;
Matthias Clasen's avatar
Matthias Clasen committed
346
  GtkContainerClass *container_class;
Anders Carlsson's avatar
Anders Carlsson committed
347 348 349
  GtkBindingSet *binding_set;
  
  binding_set = gtk_binding_set_by_class (klass);
350

Anders Carlsson's avatar
Anders Carlsson committed
351 352
  gobject_class = (GObjectClass *) klass;
  widget_class = (GtkWidgetClass *) klass;
Matthias Clasen's avatar
Matthias Clasen committed
353
  container_class = (GtkContainerClass *) klass;
Anders Carlsson's avatar
Anders Carlsson committed
354

355
  gobject_class->constructed = gtk_icon_view_constructed;
356
  gobject_class->dispose = gtk_icon_view_dispose;
357 358 359
  gobject_class->set_property = gtk_icon_view_set_property;
  gobject_class->get_property = gtk_icon_view_get_property;

360
  widget_class->destroy = gtk_icon_view_destroy;
361 362
  widget_class->realize = gtk_icon_view_realize;
  widget_class->unrealize = gtk_icon_view_unrealize;
363
  widget_class->get_request_mode = gtk_icon_view_get_request_mode;
364 365
  widget_class->get_preferred_width = gtk_icon_view_get_preferred_width;
  widget_class->get_preferred_height = gtk_icon_view_get_preferred_height;
366 367
  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;
368
  widget_class->size_allocate = gtk_icon_view_size_allocate;
369
  widget_class->draw = gtk_icon_view_draw;
370
  widget_class->motion_notify_event = gtk_icon_view_motion;
371
  widget_class->leave_notify_event = gtk_icon_view_leave;
372 373
  widget_class->button_press_event = gtk_icon_view_button_press;
  widget_class->button_release_event = gtk_icon_view_button_release;
374 375
  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
376 377 378 379 380 381 382 383
  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;
384

Matthias Clasen's avatar
Matthias Clasen committed
385 386 387
  container_class->remove = gtk_icon_view_remove;
  container_class->forall = gtk_icon_view_forall;

388 389 390 391
  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;
392
  klass->activate_cursor_item = gtk_icon_view_real_activate_cursor_item;  
393
  klass->move_cursor = gtk_icon_view_real_move_cursor;
Anders Carlsson's avatar
Anders Carlsson committed
394 395
  
  /* Properties */
396 397 398 399 400 401 402 403 404
  /**
   * 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
405 406
  g_object_class_install_property (gobject_class,
				   PROP_SELECTION_MODE,
407
				   g_param_spec_enum ("selection-mode",
408 409
						      P_("Selection mode"),
						      P_("The selection mode"),
Anders Carlsson's avatar
Anders Carlsson committed
410 411
						      GTK_TYPE_SELECTION_MODE,
						      GTK_SELECTION_SINGLE,
412
						      GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Anders Carlsson's avatar
Anders Carlsson committed
413

414 415 416 417 418 419 420 421 422 423
  /**
   * 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
424
  g_object_class_install_property (gobject_class,
425
				   PROP_PIXBUF_COLUMN,
426
				   g_param_spec_int ("pixbuf-column",
427 428
						     P_("Pixbuf column"),
						     P_("Model column used to retrieve the icon pixbuf from"),
429
						     -1, G_MAXINT, -1,
430
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
431

432 433 434 435 436 437 438 439 440 441
  /**
   * 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
442
  g_object_class_install_property (gobject_class,
443
				   PROP_TEXT_COLUMN,
444
				   g_param_spec_int ("text-column",
445 446
						     P_("Text column"),
						     P_("Model column used to retrieve the text from"),
447
						     -1, G_MAXINT, -1,
448
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Anders Carlsson's avatar
Anders Carlsson committed
449

450 451 452 453 454 455 456 457 458 459 460 461
  
  /**
   * 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
   */
462 463
  g_object_class_install_property (gobject_class,
				   PROP_MARKUP_COLUMN,
464
				   g_param_spec_int ("markup-column",
465
						     P_("Markup column"),
466
						     P_("Model column used to retrieve the text if using Pango markup"),
467
						     -1, G_MAXINT, -1,
468
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
469
  
470 471 472
  g_object_class_install_property (gobject_class,
                                   PROP_MODEL,
                                   g_param_spec_object ("model",
473 474
							P_("Icon View Model"),
							P_("The model for the icon view"),
475
							GTK_TYPE_TREE_MODEL,
476
							GTK_PARAM_READWRITE));
477
  
Matthias Clasen's avatar
Matthias Clasen committed
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
  /**
   * 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,
493
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
494 495 496
  

  /**
497
   * GtkIconView:item-width:
Matthias Clasen's avatar
Matthias Clasen committed
498 499 500 501 502 503 504 505 506
   *
   * 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,
507
				   g_param_spec_int ("item-width",
Matthias Clasen's avatar
Matthias Clasen committed
508 509 510
						     P_("Width for each item"),
						     P_("The width used for each item"),
						     -1, G_MAXINT, -1,
511
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
512 513

  /**
514
   * GtkIconView:spacing:
Matthias Clasen's avatar
Matthias Clasen committed
515 516 517 518 519 520 521 522 523 524 525 526
   *
   * 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,
527
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
528 529

  /**
530
   * GtkIconView:row-spacing:
Matthias Clasen's avatar
Matthias Clasen committed
531 532 533 534 535 536 537 538
   *
   * 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,
539
                                   g_param_spec_int ("row-spacing",
Matthias Clasen's avatar
Matthias Clasen committed
540 541 542
						     P_("Row Spacing"),
						     P_("Space which is inserted between grid rows"),
						     0, G_MAXINT, 6,
543
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
544 545

  /**
546
   * GtkIconView:column-spacing:
Matthias Clasen's avatar
Matthias Clasen committed
547 548 549 550 551 552 553 554
   *
   * 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,
555
                                   g_param_spec_int ("column-spacing",
Matthias Clasen's avatar
Matthias Clasen committed
556
						     P_("Column Spacing"),
557
						     P_("Space which is inserted between grid columns"),
Matthias Clasen's avatar
Matthias Clasen committed
558
						     0, G_MAXINT, 6,
559
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
560 561

  /**
562
   * GtkIconView:margin:
Matthias Clasen's avatar
Matthias Clasen committed
563 564 565 566 567 568 569 570 571 572 573 574
   *
   * 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,
575
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
576 577

  /**
578
   * GtkIconView:item-orientation:
Matthias Clasen's avatar
Matthias Clasen committed
579
   *
580
   * The item-orientation property specifies how the cells (i.e. the icon and
Matthias Clasen's avatar
Matthias Clasen committed
581 582 583 584
   * the text) of the item are positioned relative to each other.
   *
   * Since: 2.6
   */
585
  g_object_class_install_property (gobject_class,
586 587 588
				   PROP_ITEM_ORIENTATION,
				   g_param_spec_enum ("item-orientation",
						      P_("Item Orientation"),
589 590 591
						      P_("How the text and icon of each item are positioned relative to each other"),
						      GTK_TYPE_ORIENTATION,
						      GTK_ORIENTATION_VERTICAL,
592
						      GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Anders Carlsson's avatar
Anders Carlsson committed
593

Matthias Clasen's avatar
Matthias Clasen committed
594
  /**
595
   * GtkIconView:reorderable:
Matthias Clasen's avatar
Matthias Clasen committed
596 597 598 599 600 601 602 603 604 605 606 607
   *
   * 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,
608
							 G_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
Matthias Clasen's avatar
Matthias Clasen committed
609

610 611 612 613 614 615 616 617
    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,
618
                                                       GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
619

620 621 622 623 624 625 626 627 628 629 630 631 632 633
  /**
   * 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,
634
						     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
635

636 637 638 639 640
  /**
   * GtkIconView:cell-area:
   *
   * The #GtkCellArea used to layout cell renderers for this view.
   *
641 642 643
   * If no area is specified when creating the icon view with gtk_icon_view_new_with_area() 
   * a #GtkCellAreaBox will be used.
   *
644 645 646 647 648 649 650 651 652 653
   * 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));

654 655 656 657 658 659 660 661 662 663 664 665 666 667
  /**
   * 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,
668
							 GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
669

670
  /* Scrollable interface properties */
671 672 673 674
  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");
675

676
  /* Style properties */
677 678 679 680 681 682 683 684
  /**
   * GtkIconView:selection-box-color:
   *
   * The color of the selection box.
   *
   * Deprecated: 3.20: The color of the selection box is determined by CSS;
   *     the value of this style property is ignored.
   */
685
  gtk_widget_class_install_style_property (widget_class,
686
                                           g_param_spec_boxed ("selection-box-color",
687 688
                                                               P_("Selection Box Color"),
                                                               P_("Color of the selection box"),
Matthias Clasen's avatar
Matthias Clasen committed
689
                                                               g_type_from_name ("GdkColor"),
690
                                                               GTK_PARAM_READABLE|G_PARAM_DEPRECATED));
691

692 693 694 695 696 697 698 699 700

  /**
   * GtkIconView:selection-box-alpha:
   *
   * The opacity of the selection box.
   *
   * Deprecated: 3.20: The opacity of the selection box is determined by CSS;
   *     the value of this style property is ignored.
   */
701
  gtk_widget_class_install_style_property (widget_class,
702
                                           g_param_spec_uchar ("selection-box-alpha",
703 704
                                                               P_("Selection Box Alpha"),
                                                               P_("Opacity of the selection box"),
705 706
                                                               0, 0xff,
                                                               0x40,
707
                                                               GTK_PARAM_READABLE|G_PARAM_DEPRECATED));
708

Anders Carlsson's avatar
Anders Carlsson committed
709
  /* Signals */
Matthias Clasen's avatar
Matthias Clasen committed
710 711 712 713 714 715
  /**
   * 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
716 717 718 719 720 721
   * 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
722
   */
723
  icon_view_signals[ITEM_ACTIVATED] =
724
    g_signal_new (I_("item-activated"),
Anders Carlsson's avatar
Anders Carlsson committed
725 726
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST,
727
		  G_STRUCT_OFFSET (GtkIconViewClass, item_activated),
Anders Carlsson's avatar
Anders Carlsson committed
728
		  NULL, NULL,
729
		  g_cclosure_marshal_VOID__BOXED,
Anders Carlsson's avatar
Anders Carlsson committed
730
		  G_TYPE_NONE, 1,
731
		  GTK_TYPE_TREE_PATH);
Anders Carlsson's avatar
Anders Carlsson committed
732

Matthias Clasen's avatar
Matthias Clasen committed
733 734 735 736 737 738 739
  /**
   * 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.
   */
740
  icon_view_signals[SELECTION_CHANGED] =
741
    g_signal_new (I_("selection-changed"),
Anders Carlsson's avatar
Anders Carlsson committed
742 743
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_FIRST,
744
		  G_STRUCT_OFFSET (GtkIconViewClass, selection_changed),
Anders Carlsson's avatar
Anders Carlsson committed
745 746 747 748
		  NULL, NULL,
		  g_cclosure_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);
  
Matthias Clasen's avatar
Matthias Clasen committed
749 750 751 752
  /**
   * GtkIconView::select-all:
   * @iconview: the object on which the signal is emitted
   *
753
   * A [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
754 755 756 757 758 759 760 761
   * 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.
   */
762
  icon_view_signals[SELECT_ALL] =
763
    g_signal_new (I_("select-all"),
Anders Carlsson's avatar
Anders Carlsson committed
764 765
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
766
		  G_STRUCT_OFFSET (GtkIconViewClass, select_all),
Anders Carlsson's avatar
Anders Carlsson committed
767 768 769 770
		  NULL, NULL,
		  g_cclosure_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);
  
Matthias Clasen's avatar
Matthias Clasen committed
771 772 773 774
  /**
   * GtkIconView::unselect-all:
   * @iconview: the object on which the signal is emitted
   *
775
   * A [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
776 777 778 779 780 781 782 783
   * 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. 
   */
784
  icon_view_signals[UNSELECT_ALL] =
785
    g_signal_new (I_("unselect-all"),
Anders Carlsson's avatar
Anders Carlsson committed
786 787
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
788
		  G_STRUCT_OFFSET (GtkIconViewClass, unselect_all),
Anders Carlsson's avatar
Anders Carlsson committed
789 790 791 792
		  NULL, NULL,
		  g_cclosure_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);

Matthias Clasen's avatar
Matthias Clasen committed
793 794 795 796
  /**
   * GtkIconView::select-cursor-item:
   * @iconview: the object on which the signal is emitted
   *
797
   * A [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
798 799 800 801 802 803 804 805 806
   * 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.
   */
807
  icon_view_signals[SELECT_CURSOR_ITEM] =
808
    g_signal_new (I_("select-cursor-item"),
Anders Carlsson's avatar
Anders Carlsson committed
809 810
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
811
		  G_STRUCT_OFFSET (GtkIconViewClass, select_cursor_item),
Anders Carlsson's avatar
Anders Carlsson committed
812 813 814 815
		  NULL, NULL,
		  g_cclosure_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);

Matthias Clasen's avatar
Matthias Clasen committed
816 817 818 819
  /**
   * GtkIconView::toggle-cursor-item:
   * @iconview: the object on which the signal is emitted
   *
820
   * A [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
821 822 823 824 825 826 827 828 829 830
   * 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.
   */
831
  icon_view_signals[TOGGLE_CURSOR_ITEM] =
832
    g_signal_new (I_("toggle-cursor-item"),
Anders Carlsson's avatar
Anders Carlsson committed
833 834
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
835
		  G_STRUCT_OFFSET (GtkIconViewClass, toggle_cursor_item),
Anders Carlsson's avatar
Anders Carlsson committed
836 837 838 839
		  NULL, NULL,
		  g_cclosure_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);

Matthias Clasen's avatar
Matthias Clasen committed
840 841 842 843
  /**
   * GtkIconView::activate-cursor-item:
   * @iconview: the object on which the signal is emitted
   *
844
   * A [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
845 846 847 848 849 850 851 852 853
   * 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.
   */
854
  icon_view_signals[ACTIVATE_CURSOR_ITEM] =
855
    g_signal_new (I_("activate-cursor-item"),
856 857 858 859 860 861 862
		  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
863 864 865 866 867 868 869
  /**
   * 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
870
   * [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
871 872 873 874 875 876 877
   * 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
878 879 880
   * - 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
881 882 883
   * All of these will extend the selection when combined with
   * the Shift modifier.
   */
884
  icon_view_signals[MOVE_CURSOR] =
885
    g_signal_new (I_("move-cursor"),
Matthias Clasen's avatar
Matthias Clasen committed
886 887
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
888
		  G_STRUCT_OFFSET (GtkIconViewClass, move_cursor),
Matthias Clasen's avatar
Matthias Clasen committed
889
		  NULL, NULL,
890
		  _gtk_marshal_BOOLEAN__ENUM_INT,
Matthias Clasen's avatar
Matthias Clasen committed
891 892 893 894
		  G_TYPE_BOOLEAN, 2,
		  GTK_TYPE_MOVEMENT_STEP,
		  G_TYPE_INT);

Anders Carlsson's avatar
Anders Carlsson committed
895
  /* Key bindings */
896
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_a, GDK_CONTROL_MASK, 
897
				"select-all", 0);
898
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_a, GDK_CONTROL_MASK | GDK_SHIFT_MASK, 
899
				"unselect-all", 0);
900
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, GDK_CONTROL_MASK, 
901
				"toggle-cursor-item", 0);
902
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Space, GDK_CONTROL_MASK,
903
				"toggle-cursor-item", 0);
904

905
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, 0, 
906
				"activate-cursor-item", 0);
907
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Space, 0,
908
				"activate-cursor-item", 0);
909
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0, 
910
				"activate-cursor-item", 0);
911
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_ISO_Enter, 0, 
912
				"activate-cursor-item", 0);
913
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0, 
914
				"activate-cursor-item", 0);
915

916
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Up, 0,
Matthias Clasen's avatar
Matthias Clasen committed
917
				  GTK_MOVEMENT_DISPLAY_LINES, -1);
918
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Up, 0,
Matthias Clasen's avatar
Matthias Clasen committed
919 920
				  GTK_MOVEMENT_DISPLAY_LINES, -1);

921
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Down, 0,
Matthias Clasen's avatar
Matthias Clasen committed
922
				  GTK_MOVEMENT_DISPLAY_LINES, 1);
923
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Down, 0,
Matthias Clasen's avatar
Matthias Clasen committed
924 925
				  GTK_MOVEMENT_DISPLAY_LINES, 1);

926
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_p, GDK_CONTROL_MASK,
Matthias Clasen's avatar
Matthias Clasen committed
927 928
				  GTK_MOVEMENT_DISPLAY_LINES, -1);

929
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_n, GDK_CONTROL_MASK,
Matthias Clasen's avatar
Matthias Clasen committed
930 931
				  GTK_MOVEMENT_DISPLAY_LINES, 1);

932
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Home, 0,
Matthias Clasen's avatar
Matthias Clasen committed
933
				  GTK_MOVEMENT_BUFFER_ENDS, -1);
934
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Home, 0,
Matthias Clasen's avatar
Matthias Clasen committed
935 936
				  GTK_MOVEMENT_BUFFER_ENDS, -1);

937
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_End, 0,
Matthias Clasen's avatar
Matthias Clasen committed
938
				  GTK_MOVEMENT_BUFFER_ENDS, 1);
939
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_End, 0,
Matthias Clasen's avatar
Matthias Clasen committed
940 941
				  GTK_MOVEMENT_BUFFER_ENDS, 1);

942
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Page_Up, 0,
Matthias Clasen's avatar
Matthias Clasen committed
943
				  GTK_MOVEMENT_PAGES, -1);
944
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Page_Up, 0,
Matthias Clasen's avatar
Matthias Clasen committed
945 946
				  GTK_MOVEMENT_PAGES, -1);

947
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Page_Down, 0,
Matthias Clasen's avatar
Matthias Clasen committed
948
				  GTK_MOVEMENT_PAGES, 1);
949
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Page_Down, 0,
Matthias Clasen's avatar
Matthias Clasen committed
950 951
				  GTK_MOVEMENT_PAGES, 1);

952
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Right, 0, 
Matthias Clasen's avatar
Matthias Clasen committed
953
				  GTK_MOVEMENT_VISUAL_POSITIONS, 1);
954
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_Left, 0, 
Matthias Clasen's avatar
Matthias Clasen committed
955 956
				  GTK_MOVEMENT_VISUAL_POSITIONS, -1);

957
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Right, 0, 
Matthias Clasen's avatar
Matthias Clasen committed
958
				  GTK_MOVEMENT_VISUAL_POSITIONS, 1);
959
  gtk_icon_view_add_move_binding (binding_set, GDK_KEY_KP_Left, 0, 
Matthias Clasen's avatar
Matthias Clasen committed
960
				  GTK_MOVEMENT_VISUAL_POSITIONS, -1);
961

962
  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_ICON_VIEW_ACCESSIBLE);
963
  gtk_widget_class_set_css_name (widget_class, "iconview");
Matthias Clasen's avatar
Matthias Clasen committed
964
}
Anders Carlsson's avatar
Anders Carlsson committed
965

966 967 968 969
static void
gtk_icon_view_buildable_init (GtkBuildableIface *iface)
{
  parent_buildable_iface = g_type_interface_peek_parent (iface);
970
  iface->add_child = _gtk_cell_layout_buildable_add_child;
971 972 973 974
  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
975 976 977
static void
gtk_icon_view_cell_layout_init (GtkCellLayoutIface *iface)
{
978
  iface->get_area = gtk_icon_view_cell_layout_get_area;
Matthias Clasen's avatar
Matthias Clasen committed
979 980
}

Anders Carlsson's avatar
Anders Carlsson committed
981
static void
982
gtk_icon_view_init (GtkIconView *icon_view)
Anders Carlsson's avatar
Anders Carlsson committed
983
{
984
  icon_view->priv = gtk_icon_view_get_instance_private (icon_view);
985

986 987 988 989 990 991 992 993 994
  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;
995 996
  icon_view->priv->text_cell = NULL;
  icon_view->priv->pixbuf_cell = NULL;  
997
  icon_view->priv->tooltip_column = -1;  
998

999
  gtk_widget_set_can_focus (GTK_WIDGET (icon_view), TRUE);
Matthias Clasen's avatar
Matthias Clasen committed
1000

1001
  icon_view->priv->item_orientation = GTK_ORIENTATION_VERTICAL;
Matthias Clasen's avatar
Matthias Clasen committed
1002 1003 1004 1005 1006 1007 1008

  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;
1009
  icon_view->priv->item_padding = 6;
1010
  icon_view->priv->activate_on_single_click = FALSE;
1011 1012

  icon_view->priv->draw_focus = TRUE;
1013 1014 1015

  icon_view->priv->row_contexts = 
    g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
1016 1017 1018

  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
1019 1020
}

1021
/* GObject methods */
1022

1023 1024 1025 1026
static void
gtk_icon_view_constructed (GObject *object)
{
  GtkIconView *icon_view = GTK_ICON_VIEW (object);
1027

1028
  G_OBJECT_CLASS (gtk_icon_view_parent_class)->constructed (object);
1029

1030
  gtk_icon_view_ensure_cell_area (icon_view, NULL);
1031 1032
}

1033
static void
1034
gtk_icon_view_dispose (GObject *object)
1035
{
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
  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;
    }

1048 1049 1050 1051 1052 1053
  if (priv->row_contexts)
    {
      g_ptr_array_free (priv->row_contexts, TRUE);
      priv->row_contexts = NULL;
    }

1054 1055
  if (priv->cell_area)
    {
1056 1057
      gtk_cell_area_stop_editing (icon_view->priv->cell_area, TRUE);

1058 1059 1060 1061 1062
      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;

1063 1064 1065 1066 1067
      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
1068 1069 1070
}

static void
1071
gtk_icon_view_set_property (GObject      *object,
Anders Carlsson's avatar
Anders Carlsson committed
1072 1073 1074 1075
			    guint         prop_id,
			    const GValue *value,
			    GParamSpec   *pspec)
{
1076
  GtkIconView *icon_view;
1077
  GtkCellArea *area;
Anders Carlsson's avatar
Anders Carlsson committed
1078

1079
  icon_view = GTK_ICON_VIEW (object);
Anders Carlsson's avatar
Anders Carlsson committed
1080 1081 1082 1083

  switch (prop_id)
    {
    case PROP_SELECTION_MODE:
1084
      gtk_icon_view_set_selection_mode (icon_view, g_value_get_enum (value));
Anders Carlsson's avatar
Anders Carlsson committed
1085
      break;
1086
    case PROP_PIXBUF_COLUMN:
1087
      gtk_icon_view_set_pixbuf_column (icon_view, g_value_get_int (value));
1088 1089
      break;
    case PROP_TEXT_COLUMN:
1090
      gtk_icon_view_set_text_column (icon_view, g_value_get_int (value));
Anders Carlsson's avatar
Anders Carlsson committed
1091
      break;
1092
    case PROP_MARKUP_COLUMN:
1093
      gtk_icon_view_set_markup_column (icon_view, g_value_get_int (value));
1094
      break;
1095
    case PROP_MODEL:
1096
      gtk_icon_view_set_model (icon_view, g_value_get_object (value));
Anders Carlsson's avatar
Anders Carlsson committed
1097
      break;
1098 1099
    case PROP_ITEM_ORIENTATION:
      gtk_icon_view_set_item_orientation (icon_view, g_value_get_enum (value));
1100
      break;
Matthias Clasen's avatar
Matthias Clasen committed
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
    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
1119 1120 1121
    case PROP_REORDERABLE:
      gtk_icon_view_set_reorderable (icon_view, g_value_get_boolean (value));
      break;
1122
      
1123 1124 1125 1126
    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
1127 1128 1129 1130
    case PROP_ITEM_PADDING:
      gtk_icon_view_set_item_padding (icon_view, g_value_get_int (value));
      break;

1131 1132 1133 1134
    case PROP_ACTIVATE_ON_SINGLE_CLICK:
      gtk_icon_view_set_activate_on_single_click (icon_view, g_value_get_boolean (value));
      break;

1135 1136 1137 1138
    case PROP_CELL_AREA:
      /* Construct-only, can only be assigned once */
      area = g_value_get_object (value);
      if (area)
1139 1140 1141 1142 1143 1144 1145 1146 1147 1148
        {
          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);
        }
1149 1150
      break;

1151 1152 1153 1154 1155 1156
    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;
1157
    case PROP_HSCROLL_POLICY:
1158 1159 1160 1161 1162 1163
      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);
        }
1164 1165
      break;
    case PROP_VSCROLL_POLICY:
1166 1167 1168 1169 1170 1171
      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);
        }
1172
      break;
1173

Anders Carlsson's avatar
Anders Carlsson committed
1174 1175 1176 1177 1178 1179 1180
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
1181
gtk_icon_view_get_property (GObject      *object,
Anders Carlsson's avatar
Anders Carlsson committed
1182 1183 1184 1185
			    guint         prop_id,
			    GValue       *value,
			    GParamSpec   *pspec)
{
1186
  GtkIconView *icon_view;
Anders Carlsson's avatar
Anders Carlsson committed
1187

1188
  icon_view = GTK_ICON_VIEW (object);
Anders Carlsson's avatar
Anders Carlsson committed
1189 1190 1191 1192

  switch (prop_id)
    {
    case PROP_SELECTION_MODE:
1193
      g_value_set_enum (value, icon_view->priv->selection_mode);
Anders Carlsson's avatar
Anders Carlsson committed
1194
      break;
1195
    case PROP_PIXBUF_COLUMN:
1196
      g_value_set_int (value, icon_view->priv->pixbuf_column);
1197 1198
      break;
    case PROP_TEXT_COLUMN:
1199
      g_value_set_int (value, icon_view->priv->text_column);
Anders Carlsson's avatar
Anders Carlsson committed
1200
      break;
1201
    case PROP_MARKUP_COLUMN:
1202
      g_value_set_int (value, icon_view->priv->markup_column);
1203
      break;
1204
    case PROP_MODEL:
1205
      g_value_set_object (value, icon_view->priv->model);
Anders Carlsson's avatar
Anders Carlsson committed
1206
      break;
1207 1208
    case PROP_ITEM_ORIENTATION:
      g_value_set_enum (value, icon_view->priv->item_orientation);
1209
      break;
Matthias Clasen's avatar
Matthias Clasen committed
1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227
    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
1228 1229 1230
    case PROP_REORDERABLE:
      g_value_set_boolean (value, icon_view->priv->reorderable);
      break;
1231 1232 1233
    case PROP_TOOLTIP_COLUMN:
      g_value_set_int (value, icon_view->priv->tooltip_column);
      break;
Matthias Clasen's avatar
Matthias Clasen committed
1234

Matthias Clasen's avatar
Matthias Clasen committed
1235 1236 1237 1238
    case PROP_ITEM_PADDING:
      g_value_set_int (value, icon_view->priv->item_padding);
      break;

1239 1240 1241 1242
    case PROP_ACTIVATE_ON_SINGLE_CLICK:
      g_value_set_boolean (value, icon_view->priv->activate_on_single_click);
      break;

1243 1244 1245 1246
    case PROP_CELL_AREA:
      g_value_set_object (value, icon_view->priv->cell_area);
      break;

1247 1248 1249 1250 1251 1252
    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;
1253 1254 1255 1256 1257 1258
    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;
1259

Anders Carlsson's avatar
Anders Carlsson committed
1260 1261 1262 1263 1264 1265
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296
/* 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
1297
static void
1298
gtk_icon_view_realize (GtkWidget *widget)
Anders Carlsson's avatar
Anders Carlsson committed
1299
{
1300 1301 1302
  GtkIconView *icon_view = GTK_ICON_VIEW (widget);
  GtkAllocation allocation;
  GdkWindow *window;
Anders Carlsson's avatar
Anders Carlsson committed
1303 1304 1305
  GdkWindowAttr attributes;
  gint attributes_mask;

1306
  gtk_widget_set_realized (widget, TRUE);
Anders Carlsson's avatar
Anders Carlsson committed
1307

1308 1309
  gtk_widget_get_allocation (widget, &allocation);

Anders Carlsson's avatar
Anders Carlsson committed
1310 1311
  /* Make the main, clipping window */
  attributes.window_type = GDK_WINDOW_CHILD;
1312 1313 1314 1315
  attributes.x = allocation.x;
  attributes.y = allocation.y;
  attributes.width = allocation.width;
  attributes.height = allocation.height;
Anders Carlsson's avatar
Anders Carlsson committed
1316 1317 1318 1319
  attributes.wclass = GDK_INPUT_OUTPUT;
  attributes.visual = gtk_widget_get_visual (widget);
  attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;

1320
  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
Anders Carlsson's avatar
Anders Carlsson committed
1321

1322 1323 1324
  window = gdk_window_new (gtk_widget_get_parent_window (widget),
                           &attributes, attributes_mask);
  gtk_widget_set_window (widget, window);
1325
  gtk_widget_register_window (widget, window);
1326 1327

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

1329
  /* Make the window for the icon view */
Anders Carlsson's avatar
Anders Carlsson committed
1330 1331
  attributes.x = 0;
  attributes.y = 0;
1332 1333
  attributes.width = MAX (icon_view->priv->width, allocation.width);
  attributes.height = MAX (icon_view->priv->height, allocation.height);
1334
  attributes.event_mask = (GDK_SCROLL_MASK |
1335 1336
                           GDK_SMOOTH_SCROLL_MASK |
                           GDK_POINTER_MOTION_MASK |
1337
                           GDK_LEAVE_NOTIFY_MASK |
1338 1339 1340 1341
                           GDK_BUTTON_PRESS_MASK |
                           GDK_BUTTON_RELEASE_MASK |
                           GDK_KEY_PRESS_MASK |
                           GDK_KEY_RELEASE_MASK) |
Anders Carlsson's avatar
Anders Carlsson committed
1342 1343
    gtk_widget_get_events (widget);
  
1344
  icon_view->priv->bin_window = gdk_window_new (window,
1345
						&attributes, attributes_mask);
1346
  gtk_widget_register_window (widget, icon_view->priv->bin_window);
1347
  gdk_window_show (icon_view->priv->bin_window);
Anders Carlsson's avatar
Anders Carlsson committed
1348 1349 1350
}

static void
1351
gtk_icon_view_unrealize (GtkWidget *widget)
Anders Carlsson's avatar
Anders Carlsson committed
1352
{
1353
  GtkIconView *icon_view;
Anders Carlsson's avatar
Anders Carlsson committed
1354

1355
  icon_view = GTK_ICON_VIEW (widget);
Anders Carlsson's avatar
Anders Carlsson committed
1356

1357
  gtk_widget_unregister_window (widget, icon_view->priv->bin_window);
1358