~ubuntu-branches/ubuntu/hoary/gimp/hoary

« back to all changes in this revision

Viewing changes to app/widgets/gimpcontainergridview.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-04-04 14:51:23 UTC
  • Revision ID: james.westby@ubuntu.com-20050404145123-9py049eeelfymur8
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* The GIMP -- an image manipulation program
 
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 
3
 *
 
4
 * gimpcontainergridview.c
 
5
 * Copyright (C) 2001-2004 Michael Natterer <mitch@gimp.org>
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include <gtk/gtk.h>
 
25
#include <gdk/gdkkeysyms.h>
 
26
 
 
27
#include "libgimpcolor/gimpcolor.h"
 
28
#include "libgimpwidgets/gimpwidgets.h"
 
29
 
 
30
#include "widgets-types.h"
 
31
 
 
32
#include "core/gimpcontainer.h"
 
33
#include "core/gimpcontext.h"
 
34
#include "core/gimpmarshal.h"
 
35
#include "core/gimpviewable.h"
 
36
 
 
37
#include "gimpcontainergridview.h"
 
38
#include "gimpcontainerview.h"
 
39
#include "gimpview.h"
 
40
#include "gimpviewrenderer.h"
 
41
#include "gimpwidgets-utils.h"
 
42
#include "gtkhwrapbox.h"
 
43
 
 
44
#include "gimp-intl.h"
 
45
 
 
46
 
 
47
enum
 
48
{
 
49
  MOVE_CURSOR,
 
50
  LAST_SIGNAL
 
51
};
 
52
 
 
53
 
 
54
static void     gimp_container_grid_view_class_init   (GimpContainerGridViewClass *klass);
 
55
static void     gimp_container_grid_view_init         (GimpContainerGridView      *view);
 
56
 
 
57
static void     gimp_container_grid_view_view_iface_init (GimpContainerViewInterface *view_iface);
 
58
 
 
59
static gboolean gimp_container_grid_view_move_cursor  (GimpContainerGridView  *view,
 
60
                                                       GtkMovementStep         step,
 
61
                                                       gint                    count);
 
62
static gboolean gimp_container_grid_view_focus        (GtkWidget              *widget,
 
63
                                                       GtkDirectionType        direction);
 
64
static gboolean  gimp_container_grid_view_popup_menu  (GtkWidget              *widget);
 
65
 
 
66
static gpointer gimp_container_grid_view_insert_item  (GimpContainerView      *view,
 
67
                                                       GimpViewable           *viewable,
 
68
                                                       gint                    index);
 
69
static void     gimp_container_grid_view_remove_item  (GimpContainerView      *view,
 
70
                                                       GimpViewable           *viewable,
 
71
                                                       gpointer                insert_data);
 
72
static void     gimp_container_grid_view_reorder_item (GimpContainerView      *view,
 
73
                                                       GimpViewable           *viewable,
 
74
                                                       gint                    new_index,
 
75
                                                       gpointer                insert_data);
 
76
static void     gimp_container_grid_view_rename_item  (GimpContainerView      *view,
 
77
                                                       GimpViewable           *viewable,
 
78
                                                       gpointer                insert_data);
 
79
static gboolean  gimp_container_grid_view_select_item (GimpContainerView      *view,
 
80
                                                       GimpViewable           *viewable,
 
81
                                                       gpointer                insert_data);
 
82
static void     gimp_container_grid_view_clear_items  (GimpContainerView      *view);
 
83
static void gimp_container_grid_view_set_preview_size (GimpContainerView      *view);
 
84
static gboolean gimp_container_grid_view_item_selected(GtkWidget              *widget,
 
85
                                                       GdkEventButton         *bevent,
 
86
                                                       gpointer                data);
 
87
static void   gimp_container_grid_view_item_activated (GtkWidget              *widget,
 
88
                                                       gpointer                data);
 
89
static void   gimp_container_grid_view_item_context   (GtkWidget              *widget,
 
90
                                                       gpointer                data);
 
91
static void   gimp_container_grid_view_highlight_item (GimpContainerView      *view,
 
92
                                                       GimpViewable           *viewable,
 
93
                                                       gpointer                insert_data);
 
94
 
 
95
static void gimp_container_grid_view_viewport_resized (GtkWidget              *widget,
 
96
                                                       GtkAllocation          *allocation,
 
97
                                                       GimpContainerGridView  *view);
 
98
 
 
99
 
 
100
static GimpContainerBoxClass      *parent_class      = NULL;
 
101
static GimpContainerViewInterface *parent_view_iface = NULL;
 
102
 
 
103
static guint grid_view_signals[LAST_SIGNAL] = { 0 };
 
104
 
 
105
static GimpRGB  white_color;
 
106
static GimpRGB  black_color;
 
107
 
 
108
 
 
109
GType
 
110
gimp_container_grid_view_get_type (void)
 
111
{
 
112
  static GType view_type = 0;
 
113
 
 
114
  if (! view_type)
 
115
    {
 
116
      static const GTypeInfo view_info =
 
117
      {
 
118
        sizeof (GimpContainerGridViewClass),
 
119
        NULL,           /* base_init */
 
120
        NULL,           /* base_finalize */
 
121
        (GClassInitFunc) gimp_container_grid_view_class_init,
 
122
        NULL,           /* class_finalize */
 
123
        NULL,           /* class_data */
 
124
        sizeof (GimpContainerGridView),
 
125
        0,              /* n_preallocs */
 
126
        (GInstanceInitFunc) gimp_container_grid_view_init,
 
127
      };
 
128
 
 
129
      static const GInterfaceInfo view_iface_info =
 
130
      {
 
131
        (GInterfaceInitFunc) gimp_container_grid_view_view_iface_init,
 
132
        NULL,           /* iface_finalize */
 
133
        NULL            /* iface_data     */
 
134
      };
 
135
 
 
136
      view_type = g_type_register_static (GIMP_TYPE_CONTAINER_BOX,
 
137
                                          "GimpContainerGridView",
 
138
                                          &view_info, 0);
 
139
 
 
140
      g_type_add_interface_static (view_type, GIMP_TYPE_CONTAINER_VIEW,
 
141
                                   &view_iface_info);
 
142
    }
 
143
 
 
144
  return view_type;
 
145
}
 
146
 
 
147
static void
 
148
gimp_container_grid_view_class_init (GimpContainerGridViewClass *klass)
 
149
{
 
150
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
151
  GtkBindingSet  *binding_set;
 
152
 
 
153
  parent_class = g_type_class_peek_parent (klass);
 
154
  binding_set  = gtk_binding_set_by_class (klass);
 
155
 
 
156
  widget_class->focus      = gimp_container_grid_view_focus;
 
157
  widget_class->popup_menu = gimp_container_grid_view_popup_menu;
 
158
 
 
159
  klass->move_cursor       = gimp_container_grid_view_move_cursor;
 
160
 
 
161
  grid_view_signals[MOVE_CURSOR] =
 
162
    g_signal_new ("move_cursor",
 
163
                  G_TYPE_FROM_CLASS (klass),
 
164
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
 
165
                  G_STRUCT_OFFSET (GimpContainerGridViewClass, move_cursor),
 
166
                  NULL, NULL,
 
167
                  gimp_marshal_BOOLEAN__ENUM_INT,
 
168
                  G_TYPE_BOOLEAN, 2,
 
169
                  GTK_TYPE_MOVEMENT_STEP,
 
170
                  G_TYPE_INT);
 
171
 
 
172
  gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
 
173
                                "move_cursor", 2,
 
174
                                G_TYPE_ENUM, GTK_MOVEMENT_BUFFER_ENDS,
 
175
                                G_TYPE_INT, -1);
 
176
  gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
 
177
                                "move_cursor", 2,
 
178
                                G_TYPE_ENUM, GTK_MOVEMENT_BUFFER_ENDS,
 
179
                                G_TYPE_INT, 1);
 
180
  gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, 0,
 
181
                                "move_cursor", 2,
 
182
                                G_TYPE_ENUM, GTK_MOVEMENT_PAGES,
 
183
                                G_TYPE_INT, -1);
 
184
  gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, 0,
 
185
                                "move_cursor", 2,
 
186
                                G_TYPE_ENUM, GTK_MOVEMENT_PAGES,
 
187
                                G_TYPE_INT, 1);
 
188
 
 
189
  gimp_rgba_set (&white_color, 1.0, 1.0, 1.0, 1.0);
 
190
  gimp_rgba_set (&black_color, 0.0, 0.0, 0.0, 1.0);
 
191
}
 
192
 
 
193
static void
 
194
gimp_container_grid_view_init (GimpContainerGridView *grid_view)
 
195
{
 
196
  GimpContainerBox *box = GIMP_CONTAINER_BOX (grid_view);
 
197
 
 
198
  grid_view->rows          = 1;
 
199
  grid_view->columns       = 1;
 
200
  grid_view->visible_rows  = 0;
 
201
  grid_view->selected_item = NULL;
 
202
 
 
203
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (box->scrolled_win),
 
204
                                  GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
 
205
 
 
206
  grid_view->name_label = gtk_label_new (_("(None)"));
 
207
  gtk_misc_set_alignment (GTK_MISC (grid_view->name_label), 0.0, 0.5);
 
208
  gimp_label_set_attributes (GTK_LABEL (grid_view->name_label),
 
209
                             PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
 
210
                             -1);
 
211
  gtk_box_pack_start (GTK_BOX (grid_view), grid_view->name_label,
 
212
                      FALSE, FALSE, 0);
 
213
  gtk_box_reorder_child (GTK_BOX (grid_view), grid_view->name_label, 0);
 
214
  gtk_widget_show (grid_view->name_label);
 
215
 
 
216
  grid_view->wrap_box = gtk_hwrap_box_new (FALSE);
 
217
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (box->scrolled_win),
 
218
                                         grid_view->wrap_box);
 
219
  gtk_widget_show (grid_view->wrap_box);
 
220
 
 
221
  g_signal_connect (grid_view->wrap_box->parent, "size_allocate",
 
222
                    G_CALLBACK (gimp_container_grid_view_viewport_resized),
 
223
                    grid_view);
 
224
 
 
225
  GTK_WIDGET_SET_FLAGS (grid_view, GTK_CAN_FOCUS);
 
226
}
 
227
 
 
228
static void
 
229
gimp_container_grid_view_view_iface_init (GimpContainerViewInterface *view_iface)
 
230
{
 
231
  parent_view_iface = g_type_interface_peek_parent (view_iface);
 
232
 
 
233
  view_iface->insert_item      = gimp_container_grid_view_insert_item;
 
234
  view_iface->remove_item      = gimp_container_grid_view_remove_item;
 
235
  view_iface->reorder_item     = gimp_container_grid_view_reorder_item;
 
236
  view_iface->rename_item      = gimp_container_grid_view_rename_item;
 
237
  view_iface->select_item      = gimp_container_grid_view_select_item;
 
238
  view_iface->clear_items      = gimp_container_grid_view_clear_items;
 
239
  view_iface->set_preview_size = gimp_container_grid_view_set_preview_size;
 
240
}
 
241
 
 
242
GtkWidget *
 
243
gimp_container_grid_view_new (GimpContainer *container,
 
244
                              GimpContext   *context,
 
245
                              gint           view_size,
 
246
                              gint           view_border_width)
 
247
{
 
248
  GimpContainerGridView *grid_view;
 
249
  GimpContainerView     *view;
 
250
 
 
251
  g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
 
252
                        NULL);
 
253
  g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);
 
254
  g_return_val_if_fail (view_size  > 0 &&
 
255
                        view_size <= GIMP_VIEWABLE_MAX_PREVIEW_SIZE, NULL);
 
256
  g_return_val_if_fail (view_border_width >= 0 &&
 
257
                        view_border_width <= GIMP_VIEW_MAX_BORDER_WIDTH,
 
258
                        NULL);
 
259
 
 
260
  grid_view = g_object_new (GIMP_TYPE_CONTAINER_GRID_VIEW, NULL);
 
261
 
 
262
  view = GIMP_CONTAINER_VIEW (grid_view);
 
263
 
 
264
  gimp_container_view_set_preview_size (view, view_size,
 
265
                                        view_border_width);
 
266
 
 
267
  if (container)
 
268
    gimp_container_view_set_container (view, container);
 
269
 
 
270
  if (context)
 
271
    gimp_container_view_set_context (view, context);
 
272
 
 
273
  return GTK_WIDGET (grid_view);
 
274
}
 
275
 
 
276
static gboolean
 
277
gimp_container_grid_view_move_by (GimpContainerGridView *grid_view,
 
278
                                  gint                   x,
 
279
                                  gint                   y)
 
280
{
 
281
  GimpContainerView *view = GIMP_CONTAINER_VIEW (grid_view);
 
282
  GimpContainer     *container;
 
283
  GimpViewable      *item;
 
284
  gint               index;
 
285
 
 
286
  if (! grid_view->selected_item)
 
287
    return FALSE;
 
288
 
 
289
  container = gimp_container_view_get_container (view);
 
290
 
 
291
  item = grid_view->selected_item->viewable;
 
292
 
 
293
  index = gimp_container_get_child_index (container, GIMP_OBJECT (item));
 
294
 
 
295
  index += x;
 
296
  index = CLAMP (index, 0, container->num_children - 1);
 
297
 
 
298
  index += y * grid_view->columns;
 
299
  while (index < 0)
 
300
    index += grid_view->columns;
 
301
  while (index >= container->num_children)
 
302
    index -= grid_view->columns;
 
303
 
 
304
  item = (GimpViewable *) gimp_container_get_child_by_index (container, index);
 
305
  if (item)
 
306
    gimp_container_view_item_selected (GIMP_CONTAINER_VIEW (view), item);
 
307
 
 
308
  return TRUE;
 
309
}
 
310
 
 
311
static gboolean
 
312
gimp_container_grid_view_move_cursor (GimpContainerGridView *grid_view,
 
313
                                      GtkMovementStep        step,
 
314
                                      gint                   count)
 
315
{
 
316
  GimpContainerView *view = GIMP_CONTAINER_VIEW (grid_view);
 
317
  GimpContainer     *container;
 
318
  GimpViewable      *item;
 
319
 
 
320
  if (! GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (grid_view)) || count == 0)
 
321
    return FALSE;
 
322
 
 
323
  container = gimp_container_view_get_container (view);
 
324
 
 
325
  switch (step)
 
326
    {
 
327
    case GTK_MOVEMENT_PAGES:
 
328
      return gimp_container_grid_view_move_by (grid_view, 0,
 
329
                                               count * grid_view->visible_rows);
 
330
 
 
331
    case GTK_MOVEMENT_BUFFER_ENDS:
 
332
      count = count < 0 ? 0 : container->num_children - 1;
 
333
 
 
334
      item = (GimpViewable *) gimp_container_get_child_by_index (container,
 
335
                                                                 count);
 
336
      if (item)
 
337
        gimp_container_view_item_selected (view, item);
 
338
 
 
339
      return TRUE;
 
340
 
 
341
    default:
 
342
      break;
 
343
    }
 
344
 
 
345
  return FALSE;
 
346
}
 
347
 
 
348
static gboolean
 
349
gimp_container_grid_view_focus (GtkWidget        *widget,
 
350
                                GtkDirectionType  direction)
 
351
{
 
352
  GimpContainerGridView *view = GIMP_CONTAINER_GRID_VIEW (widget);
 
353
 
 
354
  if (GTK_WIDGET_CAN_FOCUS (widget) && ! GTK_WIDGET_HAS_FOCUS (widget))
 
355
    {
 
356
      gtk_widget_grab_focus (GTK_WIDGET (widget));
 
357
      return TRUE;
 
358
    }
 
359
 
 
360
  switch (direction)
 
361
    {
 
362
    case GTK_DIR_UP:
 
363
      return gimp_container_grid_view_move_by (view,  0, -1);
 
364
    case GTK_DIR_DOWN:
 
365
      return gimp_container_grid_view_move_by (view,  0,  1);
 
366
    case GTK_DIR_LEFT:
 
367
      return gimp_container_grid_view_move_by (view, -1,  0);
 
368
    case GTK_DIR_RIGHT:
 
369
      return gimp_container_grid_view_move_by (view,  1,  0);
 
370
 
 
371
    case GTK_DIR_TAB_FORWARD:
 
372
    case GTK_DIR_TAB_BACKWARD:
 
373
      break;
 
374
    }
 
375
 
 
376
  return FALSE;
 
377
}
 
378
 
 
379
static void
 
380
gimp_container_grid_view_menu_position (GtkMenu  *menu,
 
381
                                        gint     *x,
 
382
                                        gint     *y,
 
383
                                        gpointer  data)
 
384
{
 
385
  GtkWidget *widget = GTK_WIDGET (data);
 
386
 
 
387
  gdk_window_get_origin (widget->window, x, y);
 
388
 
 
389
  if (GTK_WIDGET_NO_WINDOW (widget))
 
390
    {
 
391
      *x += widget->allocation.x;
 
392
      *y += widget->allocation.y;
 
393
    }
 
394
 
 
395
  *x += widget->allocation.width  / 2;
 
396
  *y += widget->allocation.height / 2;
 
397
 
 
398
  gimp_menu_position (menu, x, y);
 
399
}
 
400
 
 
401
static gboolean
 
402
gimp_container_grid_view_popup_menu (GtkWidget *widget)
 
403
{
 
404
  GimpContainerGridView *grid_view = GIMP_CONTAINER_GRID_VIEW (widget);
 
405
 
 
406
  if (grid_view->selected_item)
 
407
    {
 
408
      return gimp_editor_popup_menu (GIMP_EDITOR (grid_view),
 
409
                                     gimp_container_grid_view_menu_position,
 
410
                                     grid_view->selected_item);
 
411
    }
 
412
 
 
413
  return FALSE;
 
414
}
 
415
 
 
416
static gpointer
 
417
gimp_container_grid_view_insert_item (GimpContainerView *view,
 
418
                                      GimpViewable      *viewable,
 
419
                                      gint               index)
 
420
{
 
421
  GimpContainerGridView *grid_view = GIMP_CONTAINER_GRID_VIEW (view);
 
422
  GtkWidget             *preview;
 
423
  gint                   preview_size;
 
424
 
 
425
  preview_size = gimp_container_view_get_preview_size (view, NULL);
 
426
 
 
427
  preview = gimp_view_new_full (viewable,
 
428
                                preview_size,
 
429
                                preview_size,
 
430
                                1,
 
431
                                FALSE, TRUE, TRUE);
 
432
  gimp_view_renderer_set_border_type (GIMP_VIEW (preview)->renderer,
 
433
                                      GIMP_VIEW_BORDER_WHITE);
 
434
  gimp_view_renderer_remove_idle (GIMP_VIEW (preview)->renderer);
 
435
 
 
436
  gtk_wrap_box_pack (GTK_WRAP_BOX (grid_view->wrap_box), preview,
 
437
                     FALSE, FALSE, FALSE, FALSE);
 
438
 
 
439
  if (index != -1)
 
440
    gtk_wrap_box_reorder_child (GTK_WRAP_BOX (grid_view->wrap_box),
 
441
                                preview, index);
 
442
 
 
443
  gtk_widget_show (preview);
 
444
 
 
445
  g_signal_connect (preview, "button_press_event",
 
446
                    G_CALLBACK (gimp_container_grid_view_item_selected),
 
447
                    view);
 
448
  g_signal_connect (preview, "double_clicked",
 
449
                    G_CALLBACK (gimp_container_grid_view_item_activated),
 
450
                    view);
 
451
  g_signal_connect (preview, "context",
 
452
                    G_CALLBACK (gimp_container_grid_view_item_context),
 
453
                    view);
 
454
 
 
455
  return (gpointer) preview;
 
456
}
 
457
 
 
458
static void
 
459
gimp_container_grid_view_remove_item (GimpContainerView *view,
 
460
                                      GimpViewable      *viewable,
 
461
                                      gpointer           insert_data)
 
462
{
 
463
  GimpContainerGridView *grid_view = GIMP_CONTAINER_GRID_VIEW (view);
 
464
  GtkWidget             *preview   = GTK_WIDGET (insert_data);
 
465
 
 
466
  if (preview == (GtkWidget *) grid_view->selected_item)
 
467
    grid_view->selected_item = NULL;
 
468
 
 
469
  gtk_container_remove (GTK_CONTAINER (grid_view->wrap_box), preview);
 
470
}
 
471
 
 
472
static void
 
473
gimp_container_grid_view_reorder_item (GimpContainerView *view,
 
474
                                       GimpViewable      *viewable,
 
475
                                       gint               new_index,
 
476
                                       gpointer           insert_data)
 
477
{
 
478
  GimpContainerGridView *grid_view = GIMP_CONTAINER_GRID_VIEW (view);
 
479
  GtkWidget             *preview   = GTK_WIDGET (insert_data);
 
480
 
 
481
  gtk_wrap_box_reorder_child (GTK_WRAP_BOX (grid_view->wrap_box),
 
482
                              preview, new_index);
 
483
}
 
484
 
 
485
static void
 
486
gimp_container_grid_view_rename_item (GimpContainerView *view,
 
487
                                      GimpViewable      *viewable,
 
488
                                      gpointer           insert_data)
 
489
{
 
490
  GimpContainerGridView *grid_view = GIMP_CONTAINER_GRID_VIEW (view);
 
491
  GtkWidget             *preview   = GTK_WIDGET (insert_data);
 
492
 
 
493
  if (preview == (GtkWidget *) grid_view->selected_item)
 
494
    {
 
495
      gchar *name = gimp_viewable_get_description (viewable, NULL);
 
496
 
 
497
      gtk_label_set_text (GTK_LABEL (grid_view->name_label), name);
 
498
 
 
499
      g_free (name);
 
500
    }
 
501
}
 
502
 
 
503
static gboolean
 
504
gimp_container_grid_view_select_item (GimpContainerView *view,
 
505
                                      GimpViewable      *viewable,
 
506
                                      gpointer           insert_data)
 
507
{
 
508
  gimp_container_grid_view_highlight_item (view, viewable, insert_data);
 
509
 
 
510
  return TRUE;
 
511
}
 
512
 
 
513
static void
 
514
gimp_container_grid_view_clear_items (GimpContainerView *view)
 
515
{
 
516
  GimpContainerGridView *grid_view = GIMP_CONTAINER_GRID_VIEW (view);
 
517
 
 
518
  grid_view->selected_item = NULL;
 
519
 
 
520
  while (GTK_WRAP_BOX (grid_view->wrap_box)->children)
 
521
    gtk_container_remove (GTK_CONTAINER (grid_view->wrap_box),
 
522
                          GTK_WRAP_BOX (grid_view->wrap_box)->children->widget);
 
523
 
 
524
  parent_view_iface->clear_items (view);
 
525
}
 
526
 
 
527
static void
 
528
gimp_container_grid_view_set_preview_size (GimpContainerView *view)
 
529
{
 
530
  GimpContainerGridView *grid_view = GIMP_CONTAINER_GRID_VIEW (view);
 
531
  GtkWrapBoxChild       *child;
 
532
  gint                   preview_size;
 
533
 
 
534
  preview_size = gimp_container_view_get_preview_size (view, NULL);
 
535
 
 
536
  for (child = GTK_WRAP_BOX (grid_view->wrap_box)->children;
 
537
       child;
 
538
       child = child->next)
 
539
    {
 
540
      GimpView *view = GIMP_VIEW (child->widget);
 
541
 
 
542
      gimp_view_renderer_set_size (view->renderer,
 
543
                                   preview_size,
 
544
                                   view->renderer->border_width);
 
545
    }
 
546
 
 
547
  gtk_widget_queue_resize (grid_view->wrap_box);
 
548
}
 
549
 
 
550
static gboolean
 
551
gimp_container_grid_view_item_selected (GtkWidget      *widget,
 
552
                                        GdkEventButton *bevent,
 
553
                                        gpointer        data)
 
554
{
 
555
  if (bevent->type == GDK_BUTTON_PRESS && bevent->button == 1)
 
556
    {
 
557
      if (GTK_WIDGET_CAN_FOCUS (data) && ! GTK_WIDGET_HAS_FOCUS (data))
 
558
        gtk_widget_grab_focus (GTK_WIDGET (data));
 
559
 
 
560
      gimp_container_view_item_selected (GIMP_CONTAINER_VIEW (data),
 
561
                                         GIMP_VIEW (widget)->viewable);
 
562
    }
 
563
 
 
564
  return FALSE;
 
565
}
 
566
 
 
567
static void
 
568
gimp_container_grid_view_item_activated (GtkWidget *widget,
 
569
                                         gpointer   data)
 
570
{
 
571
  gimp_container_view_item_activated (GIMP_CONTAINER_VIEW (data),
 
572
                                      GIMP_VIEW (widget)->viewable);
 
573
}
 
574
 
 
575
static void
 
576
gimp_container_grid_view_item_context (GtkWidget *widget,
 
577
                                       gpointer   data)
 
578
{
 
579
  /*  ref the view because calling gimp_container_view_item_selected()
 
580
   *  may destroy the widget
 
581
   */
 
582
  g_object_ref (data);
 
583
 
 
584
  if (gimp_container_view_item_selected (GIMP_CONTAINER_VIEW (data),
 
585
                                         GIMP_VIEW (widget)->viewable))
 
586
    {
 
587
      gimp_container_view_item_context (GIMP_CONTAINER_VIEW (data),
 
588
                                        GIMP_VIEW (widget)->viewable);
 
589
    }
 
590
 
 
591
  g_object_unref (data);
 
592
}
 
593
 
 
594
static void
 
595
gimp_container_grid_view_highlight_item (GimpContainerView *view,
 
596
                                         GimpViewable      *viewable,
 
597
                                         gpointer           insert_data)
 
598
{
 
599
  GimpContainerGridView *grid_view = GIMP_CONTAINER_GRID_VIEW (view);
 
600
  GimpContainerBox      *box       = GIMP_CONTAINER_BOX (view);
 
601
  GimpContainer         *container;
 
602
  GimpView              *preview   = NULL;
 
603
 
 
604
  container = gimp_container_view_get_container (view);
 
605
 
 
606
  if (insert_data)
 
607
    preview = GIMP_VIEW (insert_data);
 
608
 
 
609
  if (grid_view->selected_item && grid_view->selected_item != preview)
 
610
    {
 
611
      gimp_view_renderer_set_border_type (grid_view->selected_item->renderer,
 
612
                                          GIMP_VIEW_BORDER_WHITE);
 
613
      gimp_view_renderer_update (grid_view->selected_item->renderer);
 
614
    }
 
615
 
 
616
  if (preview)
 
617
    {
 
618
      GtkRequisition  preview_requisition;
 
619
      GtkAdjustment  *adj;
 
620
      gint            item_height;
 
621
      gint            index;
 
622
      gint            row;
 
623
      gchar          *name;
 
624
 
 
625
      adj = gtk_scrolled_window_get_vadjustment
 
626
        (GTK_SCROLLED_WINDOW (box->scrolled_win));
 
627
 
 
628
      gtk_widget_size_request (GTK_WIDGET (preview), &preview_requisition);
 
629
 
 
630
      item_height = preview_requisition.height;
 
631
 
 
632
      index = gimp_container_get_child_index (container,
 
633
                                              GIMP_OBJECT (viewable));
 
634
 
 
635
      row = index / grid_view->columns;
 
636
 
 
637
      if (row * item_height < adj->value)
 
638
        {
 
639
          gtk_adjustment_set_value (adj, row * item_height);
 
640
        }
 
641
      else if ((row + 1) * item_height > adj->value + adj->page_size)
 
642
        {
 
643
          gtk_adjustment_set_value (adj,
 
644
                                    (row + 1) * item_height - adj->page_size);
 
645
        }
 
646
 
 
647
      gimp_view_renderer_set_border_type (preview->renderer,
 
648
                                          GIMP_VIEW_BORDER_BLACK);
 
649
      gimp_view_renderer_update (preview->renderer);
 
650
 
 
651
      name = gimp_viewable_get_description (preview->renderer->viewable, NULL);
 
652
      gtk_label_set_text (GTK_LABEL (grid_view->name_label), name);
 
653
      g_free (name);
 
654
    }
 
655
  else
 
656
    {
 
657
      gtk_label_set_text (GTK_LABEL (grid_view->name_label), _("(None)"));
 
658
    }
 
659
 
 
660
  grid_view->selected_item = preview;
 
661
}
 
662
 
 
663
static void
 
664
gimp_container_grid_view_viewport_resized (GtkWidget             *widget,
 
665
                                           GtkAllocation         *allocation,
 
666
                                           GimpContainerGridView *grid_view)
 
667
{
 
668
  GimpContainerView *view = GIMP_CONTAINER_VIEW (grid_view);
 
669
 
 
670
  if (gimp_container_view_get_container (view))
 
671
    {
 
672
      GList *children;
 
673
      gint   n_children;
 
674
 
 
675
      children = gtk_container_get_children (GTK_CONTAINER (grid_view->wrap_box));
 
676
      n_children = g_list_length (children);
 
677
 
 
678
      if (children)
 
679
        {
 
680
          GtkRequisition preview_requisition;
 
681
          gint           columns;
 
682
          gint           rows;
 
683
 
 
684
          gtk_widget_size_request (GTK_WIDGET (children->data),
 
685
                                   &preview_requisition);
 
686
 
 
687
          g_list_free (children);
 
688
 
 
689
          columns = MAX (1, allocation->width / preview_requisition.width);
 
690
 
 
691
          rows = n_children / columns;
 
692
 
 
693
          if (n_children % columns)
 
694
            rows++;
 
695
 
 
696
          if ((rows != grid_view->rows) || (columns != grid_view->columns))
 
697
            {
 
698
              grid_view->rows    = rows;
 
699
              grid_view->columns = columns;
 
700
 
 
701
              gtk_widget_set_size_request (grid_view->wrap_box,
 
702
                                           columns * preview_requisition.width,
 
703
                                           rows    * preview_requisition.height);
 
704
 
 
705
            }
 
706
 
 
707
          grid_view->visible_rows = (allocation->height /
 
708
                                     preview_requisition.height);
 
709
        }
 
710
 
 
711
      if (grid_view->selected_item)
 
712
        {
 
713
          GimpView *preview = grid_view->selected_item;
 
714
 
 
715
          gimp_container_grid_view_highlight_item (view,
 
716
                                                   preview->viewable,
 
717
                                                   preview);
 
718
        }
 
719
    }
 
720
}