~ubuntu-branches/ubuntu/quantal/glom/quantal

« back to all changes in this revision

Viewing changes to glom/utility_widgets/egg/toolpalette/testtoolpalette.c

  • Committer: Bazaar Package Importer
  • Author(s): Iain Lane
  • Date: 2009-01-11 17:12:01 UTC
  • mfrom: (1.1.39 upstream)
  • Revision ID: james.westby@ubuntu.com-20090111171201-0ov9zh1fxfueshxc
Tags: 1.8.5-0ubuntu1
* New upstream release (LP: #256701), fixes LP bugs: 
  + Clear the text in property dialogs for text items (LP: #309147)
  + Don't crash when showing and then hiding the grid (LP: #303453)
  + Temporarily remember the sort order so it is the same when navigating 
    away and back (LP: #303422)
  + Use the list's sort order for the top-level records in the report 
    (LP: #303425)
  + Users/Groups: Disable drag-and-drop for the treeview, because it is
    useless and confusing (LP: #299573)
  + Import: Sort the fields list alphabetically (LP: #306593)
  + delete primary key make unusuable the database (LP: #299549)
  + Spanish translate incomplete (LP: #299556)
  + import date format error (LP: #299591)
  + can't delete data from table list view (LP: #299853)
  + Field definition: default value not saved (LP: #299896)
  + reports crashing (LP: #300054)
  + Year error with date fields (LP: #300057)
  + list view: 2 records added instead of 1 (LP: #300819)
* debian/control: Refreshed dependencies for libglom-dev.
* debian/control: Updated build-deps to match configure checks. goocavnasmm
  build-dep bumped to version without .la files.
* debian/rules: Don't delete the directory containing the templates.
* debian/control, debian/rules, debian/glom-doc.*: Split out
  arch-independent manual and examples into separate package glom-doc, which
  is now recommended by glom (glom will still work if they're not available)
* debian/copyright: Rewritten to new machine-readable format. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "eggtoolpalette.h"
 
2
#include "eggtoolitemgroup.h"
 
3
#include "eggenumaction.h"
 
4
 
 
5
#include <gtk/gtk.h>
 
6
#include <glib/gi18n.h>
 
7
#include <string.h>
 
8
 
 
9
typedef struct _CanvasItem CanvasItem;
 
10
 
 
11
struct _CanvasItem
 
12
{
 
13
  GdkPixbuf *pixbuf;
 
14
  gdouble x, y;
 
15
};
 
16
 
 
17
static CanvasItem *drop_item = NULL;
 
18
static GList *canvas_items = NULL;
 
19
 
 
20
/********************************/
 
21
/* ====== Canvas drawing ====== */
 
22
/********************************/
 
23
 
 
24
static CanvasItem*
 
25
canvas_item_new (GtkWidget     *widget,
 
26
                 GtkToolButton *button,
 
27
                 gdouble        x,
 
28
                 gdouble        y)
 
29
{
 
30
  CanvasItem *item = NULL;
 
31
  const gchar *stock_id;
 
32
  GdkPixbuf *pixbuf;
 
33
 
 
34
  stock_id = gtk_tool_button_get_stock_id (button);
 
35
  pixbuf = gtk_widget_render_icon (widget, stock_id, GTK_ICON_SIZE_DIALOG, NULL);
 
36
 
 
37
  if (pixbuf)
 
38
    {
 
39
      item = g_slice_new0 (CanvasItem);
 
40
      item->pixbuf = pixbuf;
 
41
      item->x = x;
 
42
      item->y = y;
 
43
    }
 
44
 
 
45
  return item;
 
46
}
 
47
 
 
48
static void
 
49
canvas_item_free (CanvasItem *item)
 
50
{
 
51
  g_object_unref (item->pixbuf);
 
52
  g_slice_free (CanvasItem, item);
 
53
}
 
54
 
 
55
static void
 
56
canvas_item_draw (const CanvasItem *item,
 
57
                  cairo_t          *cr,
 
58
                  gboolean          preview)
 
59
{
 
60
  gdouble cx = gdk_pixbuf_get_width (item->pixbuf);
 
61
  gdouble cy = gdk_pixbuf_get_height (item->pixbuf);
 
62
 
 
63
  gdk_cairo_set_source_pixbuf (cr,
 
64
                               item->pixbuf,
 
65
                               item->x - cx * 0.5,
 
66
                               item->y - cy * 0.5);
 
67
 
 
68
  if (preview)
 
69
    cairo_paint_with_alpha (cr, 0.6);
 
70
  else
 
71
    cairo_paint (cr);
 
72
}
 
73
 
 
74
static gboolean
 
75
canvas_expose_event (GtkWidget      *widget,
 
76
                     GdkEventExpose *event)
 
77
{
 
78
  cairo_t *cr;
 
79
  GList *iter;
 
80
 
 
81
  cr = gdk_cairo_create (widget->window);
 
82
  gdk_cairo_region (cr, event->region);
 
83
  cairo_clip (cr);
 
84
 
 
85
  cairo_set_source_rgb (cr, 1, 1, 1);
 
86
  cairo_rectangle (cr, 0, 0, widget->allocation.width, widget->allocation.height);
 
87
  cairo_fill (cr);
 
88
 
 
89
  for (iter = canvas_items; iter; iter = iter->next)
 
90
    canvas_item_draw (iter->data, cr, FALSE);
 
91
 
 
92
  if (drop_item)
 
93
    canvas_item_draw (drop_item, cr, TRUE);
 
94
 
 
95
  cairo_destroy (cr);
 
96
 
 
97
  return TRUE;
 
98
}
 
99
 
 
100
/*****************************/
 
101
/* ====== Palette DnD ====== */
 
102
/*****************************/
 
103
 
 
104
static void
 
105
palette_drop_item (GtkToolItem      *drag_item,
 
106
                   EggToolItemGroup *drop_group,
 
107
                   gint              x,
 
108
                   gint              y)
 
109
{
 
110
  GtkWidget *drag_group = gtk_widget_get_parent (GTK_WIDGET (drag_item));
 
111
  GtkToolItem *drop_item = egg_tool_item_group_get_drop_item (drop_group, x, y);
 
112
  gint drop_position = -1;
 
113
 
 
114
  if (drop_item)
 
115
    drop_position = egg_tool_item_group_get_item_position (EGG_TOOL_ITEM_GROUP (drop_group), drop_item);
 
116
 
 
117
  if (EGG_TOOL_ITEM_GROUP (drag_group) != drop_group)
 
118
    {
 
119
      gboolean homogeneous, expand, fill, new_row;
 
120
 
 
121
      g_object_ref (drag_item);
 
122
      gtk_container_child_get (GTK_CONTAINER (drag_group), GTK_WIDGET (drag_item),
 
123
                               "homogeneous", &homogeneous,
 
124
                               "expand", &expand,
 
125
                               "fill", &fill,
 
126
                               "new-row", &new_row,
 
127
                               NULL);
 
128
      gtk_container_remove (GTK_CONTAINER (drag_group), GTK_WIDGET (drag_item));
 
129
      egg_tool_item_group_insert (EGG_TOOL_ITEM_GROUP (drop_group),
 
130
                                  drag_item, drop_position);
 
131
      gtk_container_child_set (GTK_CONTAINER (drop_group), GTK_WIDGET (drag_item),
 
132
                               "homogeneous", homogeneous,
 
133
                               "expand", expand,
 
134
                               "fill", fill,
 
135
                               "new-row", new_row,
 
136
                               NULL);
 
137
      g_object_unref (drag_item);
 
138
    }
 
139
  else
 
140
    egg_tool_item_group_set_item_position (EGG_TOOL_ITEM_GROUP (drop_group),
 
141
                                           drag_item, drop_position);
 
142
}
 
143
 
 
144
static void
 
145
palette_drop_group (EggToolPalette *palette,
 
146
                    GtkWidget      *drag_group,
 
147
                    GtkWidget      *drop_group)
 
148
{
 
149
  gint drop_position = -1;
 
150
 
 
151
  if (drop_group)
 
152
    drop_position = egg_tool_palette_get_group_position (palette, drop_group);
 
153
 
 
154
  egg_tool_palette_set_group_position (palette, drag_group, drop_position);
 
155
}
 
156
 
 
157
static void
 
158
palette_drag_data_received (GtkWidget        *widget,
 
159
                            GdkDragContext   *context,
 
160
                            gint              x,
 
161
                            gint              y,
 
162
                            GtkSelectionData *selection,
 
163
                            guint             info G_GNUC_UNUSED,
 
164
                            guint             time G_GNUC_UNUSED,
 
165
                            gpointer          data G_GNUC_UNUSED)
 
166
{
 
167
  GtkWidget *drag_palette = gtk_drag_get_source_widget (context);
 
168
  GtkWidget *drag_item = NULL, *drop_group = NULL;
 
169
 
 
170
  while (drag_palette && !EGG_IS_TOOL_PALETTE (drag_palette))
 
171
    drag_palette = gtk_widget_get_parent (drag_palette);
 
172
 
 
173
  if (drag_palette)
 
174
    {
 
175
      drag_item = egg_tool_palette_get_drag_item (EGG_TOOL_PALETTE (drag_palette), selection);
 
176
      drop_group = egg_tool_palette_get_drop_group (EGG_TOOL_PALETTE (widget), x, y);
 
177
    }
 
178
 
 
179
  if (EGG_IS_TOOL_ITEM_GROUP (drag_item))
 
180
    palette_drop_group (EGG_TOOL_PALETTE (drag_palette), drag_item, drop_group);
 
181
  else if (GTK_IS_TOOL_ITEM (drag_item) && drop_group)
 
182
    palette_drop_item (GTK_TOOL_ITEM (drag_item),
 
183
                       EGG_TOOL_ITEM_GROUP (drop_group),
 
184
                       x - GTK_WIDGET (drop_group)->allocation.x,
 
185
                       y - GTK_WIDGET (drop_group)->allocation.y);
 
186
}
 
187
 
 
188
/********************************/
 
189
/* ====== Passive Canvas ====== */
 
190
/********************************/
 
191
 
 
192
static void
 
193
passive_canvas_drag_data_received (GtkWidget        *widget,
 
194
                                   GdkDragContext   *context,
 
195
                                   gint              x,
 
196
                                   gint              y,
 
197
                                   GtkSelectionData *selection,
 
198
                                   guint             info G_GNUC_UNUSED,
 
199
                                   guint             time G_GNUC_UNUSED,
 
200
                                   gpointer          data G_GNUC_UNUSED)
 
201
{
 
202
  /* find the tool button, which is the source of this DnD operation */
 
203
 
 
204
  GtkWidget *palette = gtk_drag_get_source_widget (context);
 
205
  CanvasItem *canvas_item = NULL;
 
206
  GtkWidget *tool_item = NULL;
 
207
 
 
208
  while (palette && !EGG_IS_TOOL_PALETTE (palette))
 
209
    palette = gtk_widget_get_parent (palette);
 
210
 
 
211
  if (palette)
 
212
    tool_item = egg_tool_palette_get_drag_item (EGG_TOOL_PALETTE (palette), selection);
 
213
 
 
214
  g_assert (NULL == drop_item);
 
215
 
 
216
  /* append a new canvas item when a tool button was found */
 
217
 
 
218
  if (GTK_IS_TOOL_ITEM (tool_item))
 
219
    canvas_item = canvas_item_new (widget, GTK_TOOL_BUTTON (tool_item), x, y);
 
220
 
 
221
  if (canvas_item)
 
222
    {
 
223
      canvas_items = g_list_append (canvas_items, canvas_item);
 
224
      gtk_widget_queue_draw (widget);
 
225
    }
 
226
}
 
227
 
 
228
/************************************/
 
229
/* ====== Interactive Canvas ====== */
 
230
/************************************/
 
231
 
 
232
static gboolean
 
233
interactive_canvas_drag_motion (GtkWidget        *widget,
 
234
                                GdkDragContext   *context,
 
235
                                gint              x,
 
236
                                gint              y,
 
237
                                guint             time,
 
238
                                gpointer          data G_GNUC_UNUSED)
 
239
{
 
240
  if (drop_item)
 
241
    {
 
242
      /* already have a drop indicator - just update position */
 
243
 
 
244
      drop_item->x = x;
 
245
      drop_item->y = y;
 
246
 
 
247
      gtk_widget_queue_draw (widget);
 
248
      gdk_drag_status (context, GDK_ACTION_COPY, time);
 
249
    }
 
250
  else
 
251
    {
 
252
      /* request DnD data for creating a drop indicator */
 
253
 
 
254
      GdkAtom target = gtk_drag_dest_find_target (widget, context, NULL);
 
255
 
 
256
      if (!target)
 
257
        return FALSE;
 
258
 
 
259
      gtk_drag_get_data (widget, context, target, time);
 
260
    }
 
261
 
 
262
  return TRUE;
 
263
}
 
264
 
 
265
static void
 
266
interactive_canvas_drag_data_received (GtkWidget        *widget,
 
267
                                       GdkDragContext   *context,
 
268
                                       gint              x,
 
269
                                       gint              y,
 
270
                                       GtkSelectionData *selection,
 
271
                                       guint             info G_GNUC_UNUSED,
 
272
                                       guint             time G_GNUC_UNUSED,
 
273
                                       gpointer          data G_GNUC_UNUSED)
 
274
 
 
275
{
 
276
  /* find the tool button, which is the source of this DnD operation */
 
277
 
 
278
  GtkWidget *palette = gtk_drag_get_source_widget (context);
 
279
  GtkWidget *tool_item = NULL;
 
280
 
 
281
  while (palette && !EGG_IS_TOOL_PALETTE (palette))
 
282
    palette = gtk_widget_get_parent (palette);
 
283
 
 
284
  if (palette)
 
285
    tool_item = egg_tool_palette_get_drag_item (EGG_TOOL_PALETTE (palette), selection);
 
286
 
 
287
  /* create a drop indicator when a tool button was found */
 
288
 
 
289
  g_assert (NULL == drop_item);
 
290
 
 
291
  if (GTK_IS_TOOL_ITEM (tool_item))
 
292
    {
 
293
      drop_item = canvas_item_new (widget, GTK_TOOL_BUTTON (tool_item), x, y);
 
294
      gdk_drag_status (context, GDK_ACTION_COPY, time);
 
295
      gtk_widget_queue_draw (widget);
 
296
    }
 
297
}
 
298
 
 
299
static gboolean
 
300
interactive_canvas_drag_drop (GtkWidget        *widget,
 
301
                              GdkDragContext   *context G_GNUC_UNUSED,
 
302
                              gint              x,
 
303
                              gint              y,
 
304
                              guint             time,
 
305
                              gpointer          data    G_GNUC_UNUSED)
 
306
{
 
307
  if (drop_item)
 
308
    {
 
309
      /* turn the drop indicator into a real canvas item */
 
310
 
 
311
      drop_item->x = x;
 
312
      drop_item->y = y;
 
313
 
 
314
      canvas_items = g_list_append (canvas_items, drop_item);
 
315
      drop_item = NULL;
 
316
 
 
317
      /* signal the item was accepted and redraw */
 
318
 
 
319
      gtk_drag_finish (context, TRUE, FALSE, time);
 
320
      gtk_widget_queue_draw (widget);
 
321
 
 
322
      return TRUE;
 
323
    }
 
324
 
 
325
  return FALSE;
 
326
}
 
327
 
 
328
static gboolean
 
329
interactive_canvas_real_drag_leave (gpointer data)
 
330
{
 
331
  if (drop_item)
 
332
    {
 
333
      GtkWidget *widget = GTK_WIDGET (data);
 
334
 
 
335
      canvas_item_free (drop_item);
 
336
      drop_item = NULL;
 
337
 
 
338
      gtk_widget_queue_draw (widget);
 
339
    }
 
340
 
 
341
  return FALSE;
 
342
}
 
343
 
 
344
static void
 
345
interactive_canvas_drag_leave (GtkWidget        *widget,
 
346
                               GdkDragContext   *context G_GNUC_UNUSED,
 
347
                               guint             time    G_GNUC_UNUSED,
 
348
                               gpointer          data    G_GNUC_UNUSED)
 
349
{
 
350
  /* defer cleanup until a potential "drag-drop" signal was received */
 
351
  g_idle_add (interactive_canvas_real_drag_leave, widget);
 
352
}
 
353
 
 
354
/*******************************/
 
355
/* ====== Setup Test UI ====== */
 
356
/*******************************/
 
357
 
 
358
static void
 
359
not_implemented (GtkAction *action,
 
360
                 GtkWindow *parent)
 
361
{
 
362
  GtkWidget *dialog = gtk_message_dialog_new (parent,
 
363
                                              GTK_DIALOG_MODAL |
 
364
                                              GTK_DIALOG_DESTROY_WITH_PARENT,
 
365
                                              GTK_MESSAGE_INFO,
 
366
                                              GTK_BUTTONS_CLOSE,
 
367
                                              _("Not implemented yet."));
 
368
  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
 
369
                                            _("Sorry, the '%s' action is not implemented."),
 
370
                                            gtk_action_get_name (action));
 
371
 
 
372
  gtk_dialog_run (GTK_DIALOG (dialog));
 
373
  gtk_widget_destroy (dialog);
 
374
}
 
375
 
 
376
static void
 
377
load_stock_items (EggToolPalette *palette)
 
378
{
 
379
  GtkWidget *group_af = egg_tool_item_group_new (_("Stock Icons (A-F)"));
 
380
  GtkWidget *group_gn = egg_tool_item_group_new (_("Stock Icons (G-N)"));
 
381
  GtkWidget *group_or = egg_tool_item_group_new (_("Stock Icons (O-R)"));
 
382
  GtkWidget *group_sz = egg_tool_item_group_new (_("Stock Icons (S-Z)"));
 
383
  GtkWidget *group = NULL;
 
384
 
 
385
  GtkToolItem *item;
 
386
  GSList *stock_ids;
 
387
  GSList *iter;
 
388
 
 
389
  stock_ids = gtk_stock_list_ids ();
 
390
  stock_ids = g_slist_sort (stock_ids, (GCompareFunc) strcmp);
 
391
 
 
392
  gtk_container_add (GTK_CONTAINER (palette), group_af);
 
393
  gtk_container_add (GTK_CONTAINER (palette), group_gn);
 
394
  gtk_container_add (GTK_CONTAINER (palette), group_or);
 
395
  gtk_container_add (GTK_CONTAINER (palette), group_sz);
 
396
 
 
397
  for (iter = stock_ids; iter; iter = g_slist_next (iter))
 
398
    {
 
399
      GtkStockItem stock_item;
 
400
      gchar *id = iter->data;
 
401
 
 
402
      switch (id[4])
 
403
        {
 
404
          case 'a':
 
405
            group = group_af;
 
406
            break;
 
407
 
 
408
          case 'g':
 
409
            group = group_gn;
 
410
            break;
 
411
 
 
412
          case 'o':
 
413
            group = group_or;
 
414
            break;
 
415
 
 
416
          case 's':
 
417
            group = group_sz;
 
418
            break;
 
419
        }
 
420
 
 
421
      item = gtk_tool_button_new_from_stock (id);
 
422
      gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (item), id);
 
423
      gtk_tool_item_set_is_important (GTK_TOOL_ITEM (item), TRUE);
 
424
      egg_tool_item_group_insert (EGG_TOOL_ITEM_GROUP (group), item, -1);
 
425
 
 
426
      if (!gtk_stock_lookup (id, &stock_item) || !stock_item.label)
 
427
        gtk_tool_button_set_label (GTK_TOOL_BUTTON (item), id);
 
428
 
 
429
      g_free (id);
 
430
    }
 
431
 
 
432
  g_slist_free (stock_ids);
 
433
}
 
434
 
 
435
static void
 
436
load_toggle_items (EggToolPalette *palette)
 
437
{
 
438
  GSList *toggle_group = NULL;
 
439
  GtkToolItem *item;
 
440
  GtkWidget *group;
 
441
  char *label;
 
442
  int i;
 
443
 
 
444
  group = egg_tool_item_group_new (_("Radio Item"));
 
445
  gtk_container_add (GTK_CONTAINER (palette), group);
 
446
 
 
447
  for (i = 1; i <= 10; ++i)
 
448
    {
 
449
      label = g_strdup_printf ("#%d", i);
 
450
      item = gtk_radio_tool_button_new (toggle_group);
 
451
      gtk_tool_button_set_label (GTK_TOOL_BUTTON (item), label);
 
452
      g_free (label);
 
453
 
 
454
      egg_tool_item_group_insert (EGG_TOOL_ITEM_GROUP (group), item, -1);
 
455
      toggle_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (item));
 
456
    }
 
457
}
 
458
 
 
459
static void
 
460
load_special_items (EggToolPalette *palette)
 
461
{
 
462
  GtkToolItem *item;
 
463
  GtkWidget *group;
 
464
 
 
465
  group = egg_tool_item_group_new (_("Advanced Features"));
 
466
  gtk_container_add (GTK_CONTAINER (palette), group);
 
467
 
 
468
  item = gtk_tool_item_new ();
 
469
  gtk_container_add (GTK_CONTAINER (item), gtk_entry_new ());
 
470
  gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (item))), "homogeneous=FALSE");
 
471
  egg_tool_item_group_insert (EGG_TOOL_ITEM_GROUP (group), item, -1);
 
472
  gtk_container_child_set (GTK_CONTAINER (group), GTK_WIDGET (item),
 
473
                           "homogeneous", FALSE,
 
474
                           NULL);
 
475
 
 
476
  item = gtk_tool_item_new ();
 
477
  gtk_container_add (GTK_CONTAINER (item), gtk_entry_new ());
 
478
  gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (item))), "homogeneous=FALSE, expand=TRUE");
 
479
  egg_tool_item_group_insert (EGG_TOOL_ITEM_GROUP (group), item, -1);
 
480
  gtk_container_child_set (GTK_CONTAINER (group), GTK_WIDGET (item),
 
481
                           "homogeneous", FALSE,
 
482
                           "expand", TRUE,
 
483
                           NULL);
 
484
 
 
485
  item = gtk_tool_item_new ();
 
486
  gtk_container_add (GTK_CONTAINER (item), gtk_entry_new ());
 
487
  gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (item))), "homogeneous=FALSE, expand=TRUE, fill=FALSE");
 
488
  egg_tool_item_group_insert (EGG_TOOL_ITEM_GROUP (group), item, -1);
 
489
  gtk_container_child_set (GTK_CONTAINER (group), GTK_WIDGET (item),
 
490
                           "homogeneous", FALSE,
 
491
                           "expand", TRUE,
 
492
                           "fill", FALSE,
 
493
                           NULL);
 
494
 
 
495
  item = gtk_tool_item_new ();
 
496
  gtk_container_add (GTK_CONTAINER (item), gtk_entry_new ());
 
497
  gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (item))), "homogeneous=FALSE, expand=TRUE, new-row=TRUE");
 
498
  egg_tool_item_group_insert (EGG_TOOL_ITEM_GROUP (group), item, -1);
 
499
  gtk_container_child_set (GTK_CONTAINER (group), GTK_WIDGET (item),
 
500
                           "homogeneous", FALSE,
 
501
                           "expand", TRUE,
 
502
                           "new-row", TRUE,
 
503
                           NULL);
 
504
 
 
505
  item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_UP);
 
506
  gtk_tool_item_set_tooltip_text (item, "Show on vertical palettes only");
 
507
  egg_tool_item_group_insert (EGG_TOOL_ITEM_GROUP (group), item, -1);
 
508
  gtk_tool_item_set_visible_horizontal (item, FALSE);
 
509
 
 
510
  item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD);
 
511
  gtk_tool_item_set_tooltip_text (item, "Show on horizontal palettes only");
 
512
  egg_tool_item_group_insert (EGG_TOOL_ITEM_GROUP (group), item, -1);
 
513
  gtk_tool_item_set_visible_vertical (item, FALSE);
 
514
 
 
515
  item = gtk_tool_button_new_from_stock (GTK_STOCK_DELETE);
 
516
  gtk_tool_item_set_tooltip_text (item, "Do not show at all");
 
517
  egg_tool_item_group_insert (EGG_TOOL_ITEM_GROUP (group), item, -1);
 
518
  gtk_widget_set_no_show_all (GTK_WIDGET (item), TRUE);
 
519
 
 
520
  item = gtk_tool_button_new_from_stock (GTK_STOCK_FULLSCREEN);
 
521
  gtk_tool_item_set_tooltip_text (item, "Expanded this item");
 
522
  egg_tool_item_group_insert (EGG_TOOL_ITEM_GROUP (group), item, -1);
 
523
  gtk_container_child_set (GTK_CONTAINER (group), GTK_WIDGET (item),
 
524
                           "homogeneous", FALSE,
 
525
                           "expand", TRUE,
 
526
                           NULL);
 
527
 
 
528
  item = gtk_tool_button_new_from_stock (GTK_STOCK_HELP);
 
529
  gtk_tool_item_set_tooltip_text (item, "A regular item");
 
530
  egg_tool_item_group_insert (EGG_TOOL_ITEM_GROUP (group), item, -1);
 
531
}
 
532
 
 
533
static gboolean
 
534
drop_invalid_icon_size (GEnumValue *enum_value,
 
535
                        gpointer    user_data G_GNUC_UNUSED)
 
536
{
 
537
  return (enum_value->value != GTK_ICON_SIZE_INVALID);
 
538
}
 
539
 
 
540
static void
 
541
palette_notify_orientation (GObject    *object,
 
542
                            GParamSpec *pspec G_GNUC_UNUSED,
 
543
                            gpointer    data  G_GNUC_UNUSED)
 
544
{
 
545
  GtkWidget *scroller = gtk_widget_get_parent (GTK_WIDGET (object));
 
546
  GtkWidget *parent = gtk_widget_get_parent (scroller);
 
547
 
 
548
  GtkWidget *hpaned = g_object_get_data (object, "hpaned");
 
549
  GtkWidget *vpaned = g_object_get_data (object, "vpaned");
 
550
 
 
551
  g_object_ref (scroller);
 
552
 
 
553
  if (parent)
 
554
    gtk_container_remove (GTK_CONTAINER (parent), scroller);
 
555
 
 
556
  switch (egg_tool_palette_get_orientation (EGG_TOOL_PALETTE (object)))
 
557
    {
 
558
      case GTK_ORIENTATION_VERTICAL:
 
559
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroller),
 
560
                                        GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
 
561
        gtk_paned_pack1 (GTK_PANED (hpaned), scroller, FALSE, FALSE);
 
562
        break;
 
563
 
 
564
      case GTK_ORIENTATION_HORIZONTAL:
 
565
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroller),
 
566
                                        GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
 
567
        gtk_paned_pack1 (GTK_PANED (vpaned), scroller, FALSE, FALSE);
 
568
        break;
 
569
    }
 
570
 
 
571
  g_object_unref (scroller);
 
572
}
 
573
 
 
574
static void
 
575
view_ellipsize_changed_cb (GtkWidget *widget,
 
576
                      gpointer   data)
 
577
{
 
578
  GEnumValue *ellipsize = data;
 
579
 
 
580
  egg_tool_item_group_set_ellipsize (EGG_TOOL_ITEM_GROUP (widget),
 
581
                                     ellipsize->value);
 
582
}
 
583
 
 
584
static void
 
585
view_ellipsize_changed (GEnumValue *value,
 
586
                        gpointer    data)
 
587
{
 
588
  gtk_container_foreach (data, view_ellipsize_changed_cb, value);
 
589
}
 
590
 
 
591
static void
 
592
view_exclusive_toggled_cb (GtkWidget *widget,
 
593
                           gpointer   data)
 
594
{
 
595
  gboolean value = gtk_toggle_action_get_active (data);
 
596
  GtkWidget *palette = gtk_widget_get_parent (widget);
 
597
 
 
598
  egg_tool_palette_set_exclusive (EGG_TOOL_PALETTE (palette), widget, value);
 
599
}
 
600
 
 
601
static void
 
602
view_exclusive_toggled (GtkToggleAction *action,
 
603
                        gpointer         data)
 
604
{
 
605
  gtk_container_foreach (data, view_exclusive_toggled_cb, action);
 
606
}
 
607
 
 
608
static void
 
609
view_expand_toggled_cb (GtkWidget *widget,
 
610
                        gpointer   data)
 
611
{
 
612
  gboolean value = gtk_toggle_action_get_active (data);
 
613
  GtkWidget *palette = gtk_widget_get_parent (widget);
 
614
 
 
615
  egg_tool_palette_set_expand (EGG_TOOL_PALETTE (palette), widget, value);
 
616
}
 
617
 
 
618
static void
 
619
view_expand_toggled (GtkToggleAction *action,
 
620
                     gpointer         data)
 
621
{
 
622
  gtk_container_foreach (data, view_expand_toggled_cb, action);
 
623
}
 
624
 
 
625
static GtkWidget*
 
626
create_ui (void)
 
627
{
 
628
  static const gchar ui_spec[] = "              \
 
629
    <ui>                                        \
 
630
      <menubar>                                 \
 
631
        <menu action='FileMenu'>                \
 
632
          <menuitem action='FileNew' />         \
 
633
          <menuitem action='FileOpen' />        \
 
634
          <separator />                         \
 
635
          <menuitem action='FileSave' />        \
 
636
          <menuitem action='FileSaveAs' />      \
 
637
          <separator />                         \
 
638
          <menuitem action='FileClose' />       \
 
639
          <menuitem action='FileQuit' />        \
 
640
        </menu>                                 \
 
641
                                                \
 
642
        <menu action='ViewMenu'>                \
 
643
          <menuitem action='ViewIconSize' />    \
 
644
          <menuitem action='ViewOrientation' /> \
 
645
          <menuitem action='ViewStyle' />       \
 
646
          <separator />                         \
 
647
          <menuitem action='ViewEllipsize' />   \
 
648
          <menuitem action='ViewExclusive' />   \
 
649
          <menuitem action='ViewExpand' />      \
 
650
        </menu>                                 \
 
651
                                                \
 
652
        <menu action='HelpMenu'>                \
 
653
          <menuitem action='HelpAbout' />       \
 
654
        </menu>                                 \
 
655
      </menubar>                                \
 
656
                                                \
 
657
      <toolbar>                                 \
 
658
        <toolitem action='FileNew' />           \
 
659
        <toolitem action='FileOpen' />          \
 
660
        <toolitem action='FileSave' />          \
 
661
        <separator />                           \
 
662
        <toolitem action='ViewIconSize' />      \
 
663
        <toolitem action='ViewOrientation' />   \
 
664
        <toolitem action='ViewStyle' />         \
 
665
        <separator />                           \
 
666
        <toolitem action='ViewEllipsize' />     \
 
667
        <toolitem action='ViewExclusive' />     \
 
668
        <toolitem action='ViewExpand' />        \
 
669
        <separator />                           \
 
670
        <toolitem action='HelpAbout' />         \
 
671
      </toolbar>                                \
 
672
    </ui>";
 
673
 
 
674
  static GtkActionEntry actions[] = {
 
675
    { "FileMenu",   NULL, N_("_File"),       NULL, NULL, NULL },
 
676
    { "FileNew",    GTK_STOCK_NEW, NULL,     NULL, NULL, G_CALLBACK (not_implemented) },
 
677
    { "FileOpen",   GTK_STOCK_OPEN, NULL,    NULL, NULL, G_CALLBACK (not_implemented) },
 
678
    { "FileSave",   GTK_STOCK_SAVE, NULL,    NULL, NULL, G_CALLBACK (not_implemented) },
 
679
    { "FileSaveAs", GTK_STOCK_SAVE_AS, NULL, NULL, NULL, G_CALLBACK (not_implemented) },
 
680
    { "FileClose",  GTK_STOCK_CLOSE, NULL,   NULL, NULL, G_CALLBACK (not_implemented) },
 
681
    { "FileQuit",   GTK_STOCK_QUIT, NULL,    NULL, NULL, G_CALLBACK (gtk_main_quit) },
 
682
    { "ViewMenu",   NULL, N_("_View"),       NULL, NULL, NULL },
 
683
    { "HelpMenu",   NULL, N_("_Help"),       NULL, NULL, NULL },
 
684
    { "HelpAbout",  GTK_STOCK_ABOUT, NULL,   NULL, NULL, G_CALLBACK (not_implemented) },
 
685
  };
 
686
 
 
687
  GtkActionGroup *group;
 
688
  GError *error = NULL;
 
689
  GtkUIManager *ui;
 
690
 
 
691
  GtkWidget *window, *vbox, *hpaned, *vpaned;
 
692
  GtkWidget *menubar, *toolbar, *notebook;
 
693
  GtkWidget *palette, *palette_scroller;
 
694
  GtkWidget *contents, *contents_scroller;
 
695
  GtkAction *action;
 
696
 
 
697
  /* ===== menubar/toolbar ===== */
 
698
 
 
699
  palette = egg_tool_palette_new ();
 
700
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
701
  group = gtk_action_group_new ("");
 
702
  ui = gtk_ui_manager_new ();
 
703
 
 
704
  gtk_action_group_add_actions (group, actions, G_N_ELEMENTS (actions), window);
 
705
 
 
706
  action = egg_enum_action_new ("ViewIconSize", _("Icon Size"), NULL, GTK_TYPE_ICON_SIZE);
 
707
  egg_enum_action_set_filter (EGG_ENUM_ACTION (action), drop_invalid_icon_size, NULL, NULL);
 
708
  egg_enum_action_bind (EGG_ENUM_ACTION (action), G_OBJECT (palette), "icon-size");
 
709
  gtk_action_group_add_action (group, action);
 
710
 
 
711
  action = egg_enum_action_new ("ViewOrientation", _("Orientation"), NULL, GTK_TYPE_ORIENTATION);
 
712
  egg_enum_action_bind (EGG_ENUM_ACTION (action), G_OBJECT (palette), "orientation");
 
713
  gtk_action_group_add_action (group, action);
 
714
 
 
715
  action = egg_enum_action_new ("ViewStyle", _("Style"), NULL, GTK_TYPE_TOOLBAR_STYLE);
 
716
  egg_enum_action_bind (EGG_ENUM_ACTION (action), G_OBJECT (palette), "toolbar-style");
 
717
  gtk_action_group_add_action (group, action);
 
718
 
 
719
  action = egg_enum_action_new ("ViewEllipsize", _("Ellipsize Headers"), NULL, PANGO_TYPE_ELLIPSIZE_MODE);
 
720
  egg_enum_action_connect (EGG_ENUM_ACTION (action), view_ellipsize_changed, palette);
 
721
  gtk_action_group_add_action (group, action);
 
722
 
 
723
  action = GTK_ACTION (gtk_toggle_action_new ("ViewExclusive", _("Exclusive Groups"), NULL, NULL));
 
724
  g_signal_connect (action, "toggled", G_CALLBACK (view_exclusive_toggled), palette);
 
725
  gtk_action_group_add_action (group, action);
 
726
 
 
727
  action = GTK_ACTION (gtk_toggle_action_new ("ViewExpand", _("Expand Groups"), NULL, NULL));
 
728
  g_signal_connect (action, "toggled", G_CALLBACK (view_expand_toggled), palette);
 
729
  gtk_action_group_add_action (group, action);
 
730
 
 
731
  gtk_ui_manager_insert_action_group (ui, group, -1);
 
732
 
 
733
  if (!gtk_ui_manager_add_ui_from_string (ui, ui_spec, sizeof ui_spec - 1, &error))
 
734
    {
 
735
      g_message ("building ui_spec failed: %s", error->message);
 
736
      g_clear_error (&error);
 
737
    }
 
738
 
 
739
  menubar = gtk_ui_manager_get_widget (ui, "/menubar");
 
740
  toolbar = gtk_ui_manager_get_widget (ui, "/toolbar");
 
741
 
 
742
  gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), FALSE);
 
743
 
 
744
  /* ===== palette ===== */
 
745
 
 
746
  load_stock_items (EGG_TOOL_PALETTE (palette));
 
747
  load_toggle_items (EGG_TOOL_PALETTE (palette));
 
748
  load_special_items (EGG_TOOL_PALETTE (palette));
 
749
 
 
750
  g_signal_connect (palette, "notify::orientation",
 
751
                    G_CALLBACK (palette_notify_orientation),
 
752
                    NULL);
 
753
 
 
754
  palette_scroller = gtk_scrolled_window_new (NULL, NULL);
 
755
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (palette_scroller),
 
756
                                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
 
757
  gtk_container_set_border_width (GTK_CONTAINER (palette_scroller), 6);
 
758
  gtk_container_add (GTK_CONTAINER (palette_scroller), palette);
 
759
  gtk_widget_show_all (palette_scroller);
 
760
 
 
761
  /* ===== notebook ===== */
 
762
 
 
763
  notebook = gtk_notebook_new ();
 
764
  gtk_container_set_border_width (GTK_CONTAINER (notebook), 6);
 
765
 
 
766
  /* ===== DnD for tool items ===== */
 
767
 
 
768
  g_signal_connect (palette, "drag-data-received",
 
769
                    G_CALLBACK (palette_drag_data_received),
 
770
                    NULL);
 
771
 
 
772
  egg_tool_palette_add_drag_dest (EGG_TOOL_PALETTE (palette),
 
773
                                  palette, GTK_DEST_DEFAULT_ALL,
 
774
                                  EGG_TOOL_PALETTE_DRAG_ITEMS |
 
775
                                  EGG_TOOL_PALETTE_DRAG_GROUPS,
 
776
                                  GDK_ACTION_MOVE);
 
777
 
 
778
  /* ===== passive DnD dest ===== */
 
779
 
 
780
  contents = gtk_drawing_area_new ();
 
781
  gtk_widget_set_app_paintable (contents, TRUE);
 
782
 
 
783
  g_object_connect (contents,
 
784
                    "signal::expose-event",       canvas_expose_event, NULL,
 
785
                    "signal::drag-data-received", passive_canvas_drag_data_received, NULL,
 
786
                    NULL);
 
787
 
 
788
  egg_tool_palette_add_drag_dest (EGG_TOOL_PALETTE (palette),
 
789
                                  contents, GTK_DEST_DEFAULT_ALL,
 
790
                                  EGG_TOOL_PALETTE_DRAG_ITEMS,
 
791
                                  GDK_ACTION_COPY);
 
792
 
 
793
  contents_scroller = gtk_scrolled_window_new (NULL, NULL);
 
794
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (contents_scroller),
 
795
                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
 
796
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (contents_scroller), contents);
 
797
  gtk_container_set_border_width (GTK_CONTAINER (contents_scroller), 6);
 
798
 
 
799
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), contents_scroller,
 
800
                            gtk_label_new ("Passive DnD Mode"));
 
801
 
 
802
  /* ===== interactive DnD dest ===== */
 
803
 
 
804
  contents = gtk_drawing_area_new ();
 
805
  gtk_widget_set_app_paintable (contents, TRUE);
 
806
 
 
807
  g_object_connect (contents,
 
808
                    "signal::expose-event",       canvas_expose_event, NULL,
 
809
                    "signal::drag-motion",        interactive_canvas_drag_motion, NULL,
 
810
                    "signal::drag-data-received", interactive_canvas_drag_data_received, NULL,
 
811
                    "signal::drag-leave",         interactive_canvas_drag_leave, NULL,
 
812
                    "signal::drag-drop",          interactive_canvas_drag_drop, NULL,
 
813
                    NULL);
 
814
 
 
815
  egg_tool_palette_add_drag_dest (EGG_TOOL_PALETTE (palette),
 
816
                                  contents, GTK_DEST_DEFAULT_HIGHLIGHT,
 
817
                                  EGG_TOOL_PALETTE_DRAG_ITEMS,
 
818
                                  GDK_ACTION_COPY);
 
819
 
 
820
  contents_scroller = gtk_scrolled_window_new (NULL, NULL);
 
821
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (contents_scroller),
 
822
                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
 
823
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (contents_scroller), contents);
 
824
  gtk_container_set_border_width (GTK_CONTAINER (contents_scroller), 6);
 
825
 
 
826
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), contents_scroller,
 
827
                            gtk_label_new ("Interactive DnD Mode"));
 
828
 
 
829
  /* ===== hpaned ===== */
 
830
 
 
831
  hpaned = gtk_hpaned_new ();
 
832
  gtk_paned_pack2 (GTK_PANED (hpaned), notebook, TRUE, FALSE);
 
833
 
 
834
  g_object_set_data_full (G_OBJECT (palette), "hpaned",
 
835
                          g_object_ref (hpaned),
 
836
                          g_object_unref);
 
837
 
 
838
  /* ===== vpaned ===== */
 
839
 
 
840
  vpaned = gtk_vpaned_new ();
 
841
  gtk_paned_pack2 (GTK_PANED (vpaned), hpaned, TRUE, FALSE);
 
842
 
 
843
  g_object_set_data_full (G_OBJECT (palette), "vpaned",
 
844
                          g_object_ref (vpaned),
 
845
                          g_object_unref);
 
846
 
 
847
  /* ===== vbox ===== */
 
848
 
 
849
  vbox = gtk_vbox_new (FALSE, 0);
 
850
  gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, TRUE, 0);
 
851
  gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, TRUE, 0);
 
852
  gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
 
853
  gtk_widget_show_all (vbox);
 
854
 
 
855
  /* ===== window ===== */
 
856
 
 
857
  gtk_container_add (GTK_CONTAINER (window), vbox);
 
858
  gtk_window_set_default_size (GTK_WINDOW (window), 600, 500);
 
859
  gtk_window_add_accel_group (GTK_WINDOW (window), gtk_ui_manager_get_accel_group (ui));
 
860
  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
 
861
 
 
862
  /* ===== final fixup ===== */
 
863
 
 
864
  g_object_unref (ui);
 
865
  return window;
 
866
}
 
867
 
 
868
int
 
869
main (int   argc,
 
870
      char *argv[])
 
871
{
 
872
  GtkWidget *ui;
 
873
 
 
874
  gtk_init (&argc, &argv);
 
875
 
 
876
  gtk_rc_parse_string ("                                \
 
877
    style 'egg-tool-item-group' {                       \
 
878
      EggToolItemGroup::expander-size = 10              \
 
879
    }                                                   \
 
880
                                                        \
 
881
    style 'egg-tool-item-group-header' {                \
 
882
      bg[NORMAL] = @selected_bg_color                   \
 
883
      fg[NORMAL] = @selected_fg_color                   \
 
884
      bg[PRELIGHT] = shade(1.04, @selected_bg_color)    \
 
885
      fg[PRELIGHT] = @selected_fg_color                 \
 
886
      bg[ACTIVE] = shade(0.9, @selected_bg_color)       \
 
887
      fg[ACTIVE] = shade(0.9, @selected_fg_color)       \
 
888
                                                        \
 
889
      font_name = 'Sans Serif Bold 10.'                 \
 
890
      GtkButton::inner_border = { 0, 3, 0, 0 }          \
 
891
    }                                                   \
 
892
                                                        \
 
893
    style 'egg-tool-item-group-button' {                \
 
894
      GtkToolButton::icon-spacing = 12                  \
 
895
    }                                                   \
 
896
                                                        \
 
897
    class 'EggToolItemGroup'                            \
 
898
    style 'egg-tool-item-group'                         \
 
899
                                                        \
 
900
    widget_class '*<EggToolItemGroup>.GtkButton*'       \
 
901
    style 'egg-tool-item-group-header'                  \
 
902
                                                        \
 
903
    widget_class '*<EggToolItemGroup>.GtkToolButton'    \
 
904
    style 'egg-tool-item-group-button'                  \
 
905
    ");
 
906
 
 
907
  ui = create_ui ();
 
908
  gtk_widget_show (ui);
 
909
  gtk_main ();
 
910
 
 
911
  return 0;
 
912
}