]> Pileus Git - ~andy/gtk/blob - gtk/testgtk.c
Fixed up some warnings.
[~andy/gtk] / gtk / testgtk.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 #undef  G_LOG_DOMAIN
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <math.h>
25 #include <time.h>
26 #include "gtk.h"
27 #include "../gdk/gdk.h"
28 #include "../gdk/gdkx.h"
29 #include "../gdk/gdkkeysyms.h"
30
31 #include "circles.xbm"
32
33 typedef struct _OptionMenuItem
34 {
35   gchar        *name;
36   GtkSignalFunc func;
37 } OptionMenuItem;
38
39 GtkWidget *
40 shape_create_icon (char     *xpm_file,
41                    gint      x,
42                    gint      y,
43                    gint      px,
44                    gint      py,
45                    gint      window_type);
46
47 static GtkWidget *
48 build_option_menu (OptionMenuItem items[],
49                    gint           num_items,
50                    gint           history,
51                    gpointer       data);
52
53 /* macro, structure and variables used by tree window demos */
54 #define DEFAULT_NUMBER_OF_ITEM  3
55 #define DEFAULT_RECURSION_LEVEL 3
56
57 struct {
58   GSList* selection_mode_group;
59   GtkWidget* single_button;
60   GtkWidget* browse_button;
61   GtkWidget* multiple_button;
62   GtkWidget* draw_line_button;
63   GtkWidget* view_line_button;
64   GtkWidget* no_root_item_button;
65   GtkWidget* nb_item_spinner;
66   GtkWidget* recursion_spinner;
67 } sTreeSampleSelection;
68
69 typedef struct sTreeButtons {
70   guint nb_item_add;
71   GtkWidget* add_button;
72   GtkWidget* remove_button;
73   GtkWidget* subtree_button;
74 } sTreeButtons;
75 /* end of tree section */
76
77 static GtkWidget *
78 build_option_menu (OptionMenuItem items[],
79                    gint           num_items,
80                    gint           history,
81                    gpointer       data)
82 {
83   GtkWidget *omenu;
84   GtkWidget *menu;
85   GtkWidget *menu_item;
86   GSList *group;
87   gint i;
88
89   omenu = gtk_option_menu_new ();
90       
91   menu = gtk_menu_new ();
92   group = NULL;
93   
94   for (i = 0; i < num_items; i++)
95     {
96       menu_item = gtk_radio_menu_item_new_with_label (group, items[i].name);
97       gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
98                           (GtkSignalFunc) items[i].func, data);
99       group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
100       gtk_menu_append (GTK_MENU (menu), menu_item);
101       if (i == history)
102         gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
103       gtk_widget_show (menu_item);
104     }
105
106   gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
107   gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), history);
108   
109   return omenu;
110 }
111
112 static void
113 destroy_tooltips (GtkWidget *widget, GtkWindow **window)
114 {
115   GtkTooltips *tt = gtk_object_get_data (GTK_OBJECT (*window), "tooltips");
116   gtk_object_unref (GTK_OBJECT (tt));
117   *window = NULL;
118 }
119
120 /*
121  * GtkButton
122  */
123
124 static void
125 button_window (GtkWidget *widget,
126                GtkWidget *button)
127 {
128   if (!GTK_WIDGET_VISIBLE (button))
129     gtk_widget_show (button);
130   else
131     gtk_widget_hide (button);
132 }
133
134 static void
135 create_buttons (void)
136 {
137   static GtkWidget *window = NULL;
138   GtkWidget *box1;
139   GtkWidget *box2;
140   GtkWidget *table;
141   GtkWidget *button[10];
142   GtkWidget *separator;
143
144   if (!window)
145     {
146       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
147
148       gtk_signal_connect (GTK_OBJECT (window), "destroy",
149                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
150                           &window);
151
152       gtk_window_set_title (GTK_WINDOW (window), "GtkButton");
153       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
154
155       box1 = gtk_vbox_new (FALSE, 0);
156       gtk_container_add (GTK_CONTAINER (window), box1);
157
158       table = gtk_table_new (3, 3, FALSE);
159       gtk_table_set_row_spacings (GTK_TABLE (table), 5);
160       gtk_table_set_col_spacings (GTK_TABLE (table), 5);
161       gtk_container_set_border_width (GTK_CONTAINER (table), 10);
162       gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
163
164       button[0] = gtk_button_new_with_label ("button1");
165       button[1] = gtk_button_new_with_label ("button2");
166       button[2] = gtk_button_new_with_label ("button3");
167       button[3] = gtk_button_new_with_label ("button4");
168       button[4] = gtk_button_new_with_label ("button5");
169       button[5] = gtk_button_new_with_label ("button6");
170       button[6] = gtk_button_new_with_label ("button7");
171       button[7] = gtk_button_new_with_label ("button8");
172       button[8] = gtk_button_new_with_label ("button9");
173
174       gtk_signal_connect (GTK_OBJECT (button[0]), "clicked",
175                           GTK_SIGNAL_FUNC(button_window),
176                           button[1]);
177
178       gtk_table_attach (GTK_TABLE (table), button[0], 0, 1, 0, 1,
179                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
180
181       gtk_signal_connect (GTK_OBJECT (button[1]), "clicked",
182                           GTK_SIGNAL_FUNC(button_window),
183                           button[2]);
184
185       gtk_table_attach (GTK_TABLE (table), button[1], 1, 2, 1, 2,
186                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
187
188       gtk_signal_connect (GTK_OBJECT (button[2]), "clicked",
189                           GTK_SIGNAL_FUNC(button_window),
190                           button[3]);
191       gtk_table_attach (GTK_TABLE (table), button[2], 2, 3, 2, 3,
192                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
193
194       gtk_signal_connect (GTK_OBJECT (button[3]), "clicked",
195                           GTK_SIGNAL_FUNC(button_window),
196                           button[4]);
197       gtk_table_attach (GTK_TABLE (table), button[3], 0, 1, 2, 3,
198                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
199
200       gtk_signal_connect (GTK_OBJECT (button[4]), "clicked",
201                           GTK_SIGNAL_FUNC(button_window),
202                           button[5]);
203       gtk_table_attach (GTK_TABLE (table), button[4], 2, 3, 0, 1,
204                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
205
206       gtk_signal_connect (GTK_OBJECT (button[5]), "clicked",
207                           GTK_SIGNAL_FUNC(button_window),
208                           button[6]);
209       gtk_table_attach (GTK_TABLE (table), button[5], 1, 2, 2, 3,
210                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
211
212       gtk_signal_connect (GTK_OBJECT (button[6]), "clicked",
213                           GTK_SIGNAL_FUNC(button_window),
214                           button[7]);
215       gtk_table_attach (GTK_TABLE (table), button[6], 1, 2, 0, 1,
216                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
217
218       gtk_signal_connect (GTK_OBJECT (button[7]), "clicked",
219                           GTK_SIGNAL_FUNC(button_window),
220                           button[8]);
221       gtk_table_attach (GTK_TABLE (table), button[7], 2, 3, 1, 2,
222                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
223
224       gtk_signal_connect (GTK_OBJECT (button[8]), "clicked",
225                           GTK_SIGNAL_FUNC(button_window),
226                           button[0]);
227       gtk_table_attach (GTK_TABLE (table), button[8], 0, 1, 1, 2,
228                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
229
230       separator = gtk_hseparator_new ();
231       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
232
233       box2 = gtk_vbox_new (FALSE, 10);
234       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
235       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
236
237       button[9] = gtk_button_new_with_label ("close");
238       gtk_signal_connect_object (GTK_OBJECT (button[9]), "clicked",
239                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
240                                  GTK_OBJECT (window));
241       gtk_box_pack_start (GTK_BOX (box2), button[9], TRUE, TRUE, 0);
242       GTK_WIDGET_SET_FLAGS (button[9], GTK_CAN_DEFAULT);
243       gtk_widget_grab_default (button[9]);
244     }
245
246   if (!GTK_WIDGET_VISIBLE (window))
247     gtk_widget_show_all (window);
248   else
249     gtk_widget_destroy (window);
250 }
251
252 /*
253  * GtkToggleButton
254  */
255
256 static void
257 create_toggle_buttons (void)
258 {
259   static GtkWidget *window = NULL;
260   GtkWidget *box1;
261   GtkWidget *box2;
262   GtkWidget *button;
263   GtkWidget *separator;
264
265   if (!window)
266     {
267       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
268
269       gtk_signal_connect (GTK_OBJECT (window), "destroy",
270                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
271                           &window);
272
273       gtk_window_set_title (GTK_WINDOW (window), "GtkToggleButton");
274       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
275
276       box1 = gtk_vbox_new (FALSE, 0);
277       gtk_container_add (GTK_CONTAINER (window), box1);
278
279       box2 = gtk_vbox_new (FALSE, 10);
280       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
281       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
282
283       button = gtk_toggle_button_new_with_label ("button1");
284       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
285
286       button = gtk_toggle_button_new_with_label ("button2");
287       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
288
289       button = gtk_toggle_button_new_with_label ("button3");
290       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
291
292       separator = gtk_hseparator_new ();
293       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
294
295       box2 = gtk_vbox_new (FALSE, 10);
296       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
297       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
298
299       button = gtk_button_new_with_label ("close");
300       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
301                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
302                                  GTK_OBJECT (window));
303       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
304       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
305       gtk_widget_grab_default (button);
306     }
307
308   if (!GTK_WIDGET_VISIBLE (window))
309     gtk_widget_show_all (window);
310   else
311     gtk_widget_destroy (window);
312 }
313
314 /*
315  * GtkCheckButton
316  */
317
318 static void
319 create_check_buttons (void)
320 {
321   static GtkWidget *window = NULL;
322   GtkWidget *box1;
323   GtkWidget *box2;
324   GtkWidget *button;
325   GtkWidget *separator;
326
327   if (!window)
328     {
329       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
330
331       gtk_signal_connect (GTK_OBJECT (window), "destroy",
332                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
333                           &window);
334
335       gtk_window_set_title (GTK_WINDOW (window), "GtkCheckButton");
336       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
337
338       box1 = gtk_vbox_new (FALSE, 0);
339       gtk_container_add (GTK_CONTAINER (window), box1);
340
341       box2 = gtk_vbox_new (FALSE, 10);
342       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
343       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
344
345       button = gtk_check_button_new_with_label ("button1");
346       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
347
348       button = gtk_check_button_new_with_label ("button2");
349       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
350
351       button = gtk_check_button_new_with_label ("button3");
352       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
353
354       separator = gtk_hseparator_new ();
355       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
356
357       box2 = gtk_vbox_new (FALSE, 10);
358       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
359       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
360
361       button = gtk_button_new_with_label ("close");
362       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
363                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
364                                  GTK_OBJECT (window));
365       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
366       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
367       gtk_widget_grab_default (button);
368     }
369
370   if (!GTK_WIDGET_VISIBLE (window))
371     gtk_widget_show_all (window);
372   else
373     gtk_widget_destroy (window);
374 }
375
376 /*
377  * GtkRadioButton
378  */
379
380 static void
381 create_radio_buttons (void)
382 {
383   static GtkWidget *window = NULL;
384   GtkWidget *box1;
385   GtkWidget *box2;
386   GtkWidget *button;
387   GtkWidget *separator;
388
389   if (!window)
390     {
391       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
392
393       gtk_signal_connect (GTK_OBJECT (window), "destroy",
394                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
395                           &window);
396
397       gtk_window_set_title (GTK_WINDOW (window), "radio buttons");
398       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
399
400       box1 = gtk_vbox_new (FALSE, 0);
401       gtk_container_add (GTK_CONTAINER (window), box1);
402
403       box2 = gtk_vbox_new (FALSE, 10);
404       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
405       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
406
407       button = gtk_radio_button_new_with_label (NULL, "button1");
408       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
409
410       button = gtk_radio_button_new_with_label (
411                  gtk_radio_button_group (GTK_RADIO_BUTTON (button)),
412                  "button2");
413       gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (button), TRUE);
414       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
415
416       button = gtk_radio_button_new_with_label (
417                  gtk_radio_button_group (GTK_RADIO_BUTTON (button)),
418                  "button3");
419       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
420
421       separator = gtk_hseparator_new ();
422       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
423
424       box2 = gtk_vbox_new (FALSE, 10);
425       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
426       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
427
428       button = gtk_button_new_with_label ("close");
429       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
430                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
431                                  GTK_OBJECT (window));
432       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
433       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
434       gtk_widget_grab_default (button);
435     }
436
437   if (!GTK_WIDGET_VISIBLE (window))
438     gtk_widget_show_all (window);
439   else
440     gtk_widget_destroy (window);
441 }
442
443 /*
444  * GtkButtonBox
445  */
446
447 static GtkWidget *
448 create_bbox (gint  horizontal,
449              char* title, 
450              gint  spacing,
451              gint  child_w, 
452              gint  child_h, 
453              gint  layout)
454 {
455   GtkWidget *frame;
456   GtkWidget *bbox;
457   GtkWidget *button;
458         
459   frame = gtk_frame_new (title);
460
461   if (horizontal)
462     bbox = gtk_hbutton_box_new ();
463   else
464     bbox = gtk_vbutton_box_new ();
465
466   gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
467   gtk_container_add (GTK_CONTAINER (frame), bbox);
468
469   gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), layout);
470   gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), spacing);
471   gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), child_w, child_h);
472   
473   button = gtk_button_new_with_label ("OK");
474   gtk_container_add (GTK_CONTAINER (bbox), button);
475   
476   button = gtk_button_new_with_label ("Cancel");
477   gtk_container_add (GTK_CONTAINER (bbox), button);
478   
479   button = gtk_button_new_with_label ("Help");
480   gtk_container_add (GTK_CONTAINER (bbox), button);
481
482   return frame;
483 }
484
485 static void
486 create_button_box (void)
487 {
488   static GtkWidget* window = NULL;
489   GtkWidget *main_vbox;
490   GtkWidget *vbox;
491   GtkWidget *hbox;
492   GtkWidget *frame_horz;
493   GtkWidget *frame_vert;
494         
495   if (!window)
496   {
497     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
498     gtk_window_set_title (GTK_WINDOW (window), "Button Boxes");
499     
500     gtk_signal_connect (GTK_OBJECT (window), "destroy",
501                         GTK_SIGNAL_FUNC(gtk_widget_destroyed),
502                         &window);
503     
504     gtk_container_set_border_width (GTK_CONTAINER (window), 10);
505
506     main_vbox = gtk_vbox_new (FALSE, 0);
507     gtk_container_add (GTK_CONTAINER (window), main_vbox);
508     
509     frame_horz = gtk_frame_new ("Horizontal Button Boxes");
510     gtk_box_pack_start (GTK_BOX (main_vbox), frame_horz, TRUE, TRUE, 10);
511     
512     vbox = gtk_vbox_new (FALSE, 0);
513     gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
514     gtk_container_add (GTK_CONTAINER (frame_horz), vbox);
515
516     gtk_box_pack_start (GTK_BOX (vbox), 
517            create_bbox (TRUE, "Spread", 40, 85, 20, GTK_BUTTONBOX_SPREAD),
518                         TRUE, TRUE, 0);
519
520     gtk_box_pack_start (GTK_BOX (vbox), 
521            create_bbox (TRUE, "Edge", 40, 85, 20, GTK_BUTTONBOX_EDGE),
522                         TRUE, TRUE, 5);
523
524     gtk_box_pack_start (GTK_BOX (vbox), 
525            create_bbox (TRUE, "Start", 40, 85, 20, GTK_BUTTONBOX_START),
526                         TRUE, TRUE, 5);
527
528     gtk_box_pack_start (GTK_BOX (vbox), 
529            create_bbox (TRUE, "End", 40, 85, 20, GTK_BUTTONBOX_END),
530                         TRUE, TRUE, 5);
531
532     frame_vert = gtk_frame_new ("Vertical Button Boxes");
533     gtk_box_pack_start (GTK_BOX (main_vbox), frame_vert, TRUE, TRUE, 10);
534     
535     hbox = gtk_hbox_new (FALSE, 0);
536     gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
537     gtk_container_add (GTK_CONTAINER (frame_vert), hbox);
538
539     gtk_box_pack_start (GTK_BOX (hbox), 
540            create_bbox (FALSE, "Spread", 30, 85, 20, GTK_BUTTONBOX_SPREAD),
541                         TRUE, TRUE, 0);
542
543     gtk_box_pack_start (GTK_BOX (hbox), 
544            create_bbox (FALSE, "Edge", 30, 85, 20, GTK_BUTTONBOX_EDGE),
545                         TRUE, TRUE, 5);
546
547     gtk_box_pack_start (GTK_BOX (hbox), 
548            create_bbox (FALSE, "Start", 30, 85, 20, GTK_BUTTONBOX_START),
549                         TRUE, TRUE, 5);
550
551     gtk_box_pack_start (GTK_BOX (hbox), 
552            create_bbox (FALSE, "End", 30, 85, 20, GTK_BUTTONBOX_END),
553                         TRUE, TRUE, 5);
554   }
555
556   if (!GTK_WIDGET_VISIBLE (window))
557     gtk_widget_show_all (window);
558   else
559     gtk_widget_destroy (window);
560 }
561
562 /*
563  * GtkToolBar
564  */
565
566 static GtkWidget*
567 new_pixmap (char      *filename,
568             GdkWindow *window,
569             GdkColor  *background)
570 {
571   GtkWidget *wpixmap;
572   GdkPixmap *pixmap;
573   GdkBitmap *mask;
574
575   pixmap = gdk_pixmap_create_from_xpm (window, &mask,
576                                        background,
577                                        filename);
578   wpixmap = gtk_pixmap_new (pixmap, mask);
579
580   return wpixmap;
581 }
582
583 static void
584 set_toolbar_horizontal (GtkWidget *widget,
585                         gpointer   data)
586 {
587   gtk_toolbar_set_orientation (GTK_TOOLBAR (data), GTK_ORIENTATION_HORIZONTAL);
588 }
589
590 static void
591 set_toolbar_vertical (GtkWidget *widget,
592                       gpointer   data)
593 {
594   gtk_toolbar_set_orientation (GTK_TOOLBAR (data), GTK_ORIENTATION_VERTICAL);
595 }
596
597 static void
598 set_toolbar_icons (GtkWidget *widget,
599                    gpointer   data)
600 {
601   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_ICONS);
602 }
603
604 static void
605 set_toolbar_text (GtkWidget *widget,
606                   gpointer   data)
607 {
608   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_TEXT);
609 }
610
611 static void
612 set_toolbar_both (GtkWidget *widget,
613                   gpointer   data)
614 {
615   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_BOTH);
616 }
617
618 static void
619 set_toolbar_small_space (GtkWidget *widget,
620                          gpointer   data)
621 {
622   gtk_toolbar_set_space_size (GTK_TOOLBAR (data), 5);
623 }
624
625 static void
626 set_toolbar_big_space (GtkWidget *widget,
627                        gpointer   data)
628 {
629   gtk_toolbar_set_space_size (GTK_TOOLBAR (data), 10);
630 }
631
632 static void
633 set_toolbar_enable (GtkWidget *widget,
634                     gpointer   data)
635 {
636   gtk_toolbar_set_tooltips (GTK_TOOLBAR (data), TRUE);
637 }
638
639 static void
640 set_toolbar_disable (GtkWidget *widget,
641                      gpointer   data)
642 {
643   gtk_toolbar_set_tooltips (GTK_TOOLBAR (data), FALSE);
644 }
645
646 static void
647 set_toolbar_borders (GtkWidget *widget,
648                      gpointer   data)
649 {
650   gtk_toolbar_set_button_relief (GTK_TOOLBAR (data), GTK_RELIEF_NORMAL);
651 }
652
653 static void
654 set_toolbar_borderless (GtkWidget *widget,
655                         gpointer   data)
656 {
657   gtk_toolbar_set_button_relief (GTK_TOOLBAR (data), GTK_RELIEF_NONE);
658 }
659
660 static void
661 set_toolbar_space_style_empty (GtkWidget *widget,
662                                gpointer   data)
663 {
664   gtk_toolbar_set_space_style (GTK_TOOLBAR (data), GTK_TOOLBAR_SPACE_EMPTY);
665 }
666
667 static void
668 set_toolbar_space_style_line (GtkWidget *widget,
669                               gpointer   data)
670 {
671   gtk_toolbar_set_space_style (GTK_TOOLBAR (data), GTK_TOOLBAR_SPACE_LINE);
672 }
673
674 static void
675 create_toolbar (void)
676 {
677   static GtkWidget *window = NULL;
678   GtkWidget *toolbar;
679   GtkWidget *entry;
680
681   if (!window)
682     {
683       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
684       gtk_window_set_title (GTK_WINDOW (window), "Toolbar test");
685       gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, TRUE);
686
687       gtk_signal_connect (GTK_OBJECT (window), "destroy",
688                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
689                           &window);
690
691       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
692       gtk_widget_realize (window);
693
694       toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH);
695       gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_NONE);
696
697       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
698                                "Horizontal", "Horizontal toolbar layout", "Toolbar/Horizontal",
699                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
700                                (GtkSignalFunc) set_toolbar_horizontal, toolbar);
701       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
702                                "Vertical", "Vertical toolbar layout", "Toolbar/Vertical",
703                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
704                                (GtkSignalFunc) set_toolbar_vertical, toolbar);
705
706       gtk_toolbar_append_space (GTK_TOOLBAR(toolbar));
707
708       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
709                                "Icons", "Only show toolbar icons", "Toolbar/IconsOnly",
710                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
711                                (GtkSignalFunc) set_toolbar_icons, toolbar);
712       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
713                                "Text", "Only show toolbar text", "Toolbar/TextOnly",
714                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
715                                (GtkSignalFunc) set_toolbar_text, toolbar);
716       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
717                                "Both", "Show toolbar icons and text", "Toolbar/Both",
718                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
719                                (GtkSignalFunc) set_toolbar_both, toolbar);
720
721       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
722
723       entry = gtk_entry_new ();
724
725       gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), entry, "This is an unusable GtkEntry ;)", "Hey don't click me!!!");
726
727       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
728
729       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
730                                "Small", "Use small spaces", "Toolbar/Small",
731                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
732                                (GtkSignalFunc) set_toolbar_small_space, toolbar);
733       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
734                                "Big", "Use big spaces", "Toolbar/Big",
735                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
736                                (GtkSignalFunc) set_toolbar_big_space, toolbar);
737
738       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
739
740       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
741                                "Enable", "Enable tooltips", NULL,
742                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
743                                (GtkSignalFunc) set_toolbar_enable, toolbar);
744       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
745                                "Disable", "Disable tooltips", NULL,
746                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
747                                (GtkSignalFunc) set_toolbar_disable, toolbar);
748
749       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
750
751       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
752                                "Borders", "Show Borders", NULL,
753                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
754                                (GtkSignalFunc) set_toolbar_borders, toolbar);
755       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
756                                "Borderless", "Hide Borders", NULL,
757                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
758                                (GtkSignalFunc) set_toolbar_borderless, toolbar);
759
760       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
761       
762       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
763                                "Empty", "Empty spaces", NULL,
764                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
765                                (GtkSignalFunc) set_toolbar_space_style_empty, toolbar);
766       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
767                                "Lines", "Lines in spaces", NULL,
768                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
769                                (GtkSignalFunc) set_toolbar_space_style_line, toolbar);
770
771       gtk_container_add (GTK_CONTAINER (window), toolbar);
772     }
773
774   if (!GTK_WIDGET_VISIBLE (window))
775     gtk_widget_show_all (window);
776   else
777     gtk_widget_destroy (window);
778 }
779
780 static GtkWidget*
781 make_toolbar (GtkWidget *window)
782 {
783   GtkWidget *toolbar;
784
785   if (!GTK_WIDGET_REALIZED (window))
786     gtk_widget_realize (window);
787
788   toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH);
789   gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_NONE);
790
791   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
792                            "Horizontal", "Horizontal toolbar layout", NULL,
793                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
794                            (GtkSignalFunc) set_toolbar_horizontal, toolbar);
795   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
796                            "Vertical", "Vertical toolbar layout", NULL,
797                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
798                            (GtkSignalFunc) set_toolbar_vertical, toolbar);
799
800   gtk_toolbar_append_space (GTK_TOOLBAR(toolbar));
801
802   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
803                            "Icons", "Only show toolbar icons", NULL,
804                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
805                            (GtkSignalFunc) set_toolbar_icons, toolbar);
806   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
807                            "Text", "Only show toolbar text", NULL,
808                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
809                            (GtkSignalFunc) set_toolbar_text, toolbar);
810   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
811                            "Both", "Show toolbar icons and text", NULL,
812                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
813                            (GtkSignalFunc) set_toolbar_both, toolbar);
814
815   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
816
817   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
818                            "Small", "Use small spaces", NULL,
819                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
820                            (GtkSignalFunc) set_toolbar_small_space, toolbar);
821   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
822                            "Big", "Use big spaces", "Toolbar/Big",
823                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
824                            (GtkSignalFunc) set_toolbar_big_space, toolbar);
825
826   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
827
828   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
829                            "Enable", "Enable tooltips", NULL,
830                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
831                            (GtkSignalFunc) set_toolbar_enable, toolbar);
832   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
833                            "Disable", "Disable tooltips", NULL,
834                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
835                            (GtkSignalFunc) set_toolbar_disable, toolbar);
836
837   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
838   
839   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
840                            "Borders", "Show Borders", NULL,
841                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
842                            (GtkSignalFunc) set_toolbar_borders, toolbar);
843   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
844                            "Borderless", "Hide Borders", NULL,
845                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
846                            (GtkSignalFunc) set_toolbar_borderless, toolbar);
847
848   return toolbar;
849 }
850
851 /*
852  * GtkStatusBar
853  */
854
855 static guint statusbar_counter = 1;
856
857 static void
858 statusbar_push (GtkWidget *button,
859                 GtkStatusbar *statusbar)
860 {
861   gchar text[1024];
862
863   sprintf (text, "something %d", statusbar_counter++);
864
865   gtk_statusbar_push (statusbar, 1, text);
866 }
867
868 static void
869 statusbar_pop (GtkWidget *button,
870                GtkStatusbar *statusbar)
871 {
872   gtk_statusbar_pop (statusbar, 1);
873 }
874
875 static void
876 statusbar_steal (GtkWidget *button,
877                  GtkStatusbar *statusbar)
878 {
879   gtk_statusbar_remove (statusbar, 1, 4);
880 }
881
882 static void
883 statusbar_popped (GtkStatusbar  *statusbar,
884                   guint          context_id,
885                   const gchar   *text)
886 {
887   if (!statusbar->messages)
888     statusbar_counter = 1;
889 }
890
891 static void
892 statusbar_contexts (GtkStatusbar *statusbar)
893 {
894   gchar *string;
895
896   string = "any context";
897   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
898            string,
899            gtk_statusbar_get_context_id (statusbar, string));
900   
901   string = "idle messages";
902   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
903            string,
904            gtk_statusbar_get_context_id (statusbar, string));
905   
906   string = "some text";
907   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
908            string,
909            gtk_statusbar_get_context_id (statusbar, string));
910
911   string = "hit the mouse";
912   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
913            string,
914            gtk_statusbar_get_context_id (statusbar, string));
915
916   string = "hit the mouse2";
917   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
918            string,
919            gtk_statusbar_get_context_id (statusbar, string));
920 }
921
922 static void
923 statusbar_dump_stack (GtkStatusbar *statusbar)
924 {
925   GSList *list;
926
927   for (list = statusbar->messages; list; list = list->next)
928     {
929       GtkStatusbarMsg *msg;
930
931       msg = list->data;
932       g_print ("context_id: %d, message_id: %d, status_text: \"%s\"\n",
933                msg->context_id,
934                msg->message_id,
935                msg->text);
936     }
937 }
938
939 static void
940 create_statusbar (void)
941 {
942   static GtkWidget *window = NULL;
943   GtkWidget *box1;
944   GtkWidget *box2;
945   GtkWidget *button;
946   GtkWidget *separator;
947   GtkWidget *statusbar;
948
949   if (!window)
950     {
951       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
952
953       gtk_signal_connect (GTK_OBJECT (window), "destroy",
954                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
955                           &window);
956
957       gtk_window_set_title (GTK_WINDOW (window), "statusbar");
958       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
959
960       box1 = gtk_vbox_new (FALSE, 0);
961       gtk_container_add (GTK_CONTAINER (window), box1);
962
963       box2 = gtk_vbox_new (FALSE, 10);
964       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
965       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
966
967       statusbar = gtk_statusbar_new ();
968       gtk_box_pack_end (GTK_BOX (box1), statusbar, TRUE, TRUE, 0);
969       gtk_signal_connect (GTK_OBJECT (statusbar),
970                           "text_popped",
971                           GTK_SIGNAL_FUNC (statusbar_popped),
972                           NULL);
973
974       button = gtk_widget_new (gtk_button_get_type (),
975                                "label", "push something",
976                                "visible", TRUE,
977                                "parent", box2,
978                                "signal::clicked", statusbar_push, statusbar,
979                                NULL);
980
981       button = gtk_widget_new (gtk_button_get_type (),
982                                "label", "pop",
983                                "visible", TRUE,
984                                "parent", box2,
985                                "signal_after::clicked", statusbar_pop, statusbar,
986                                NULL);
987
988       button = gtk_widget_new (gtk_button_get_type (),
989                                "label", "steal #4",
990                                "visible", TRUE,
991                                "parent", box2,
992                                "signal_after::clicked", statusbar_steal, statusbar,
993                                NULL);
994
995       button = gtk_widget_new (gtk_button_get_type (),
996                                "label", "dump stack",
997                                "visible", TRUE,
998                                "parent", box2,
999                                "object_signal::clicked", statusbar_dump_stack, statusbar,
1000                                NULL);
1001
1002       button = gtk_widget_new (gtk_button_get_type (),
1003                                "label", "test contexts",
1004                                "visible", TRUE,
1005                                "parent", box2,
1006                                "object_signal_after::clicked", statusbar_contexts, statusbar,
1007                                NULL);
1008
1009       separator = gtk_hseparator_new ();
1010       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1011
1012       box2 = gtk_vbox_new (FALSE, 10);
1013       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1014       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
1015
1016       button = gtk_button_new_with_label ("close");
1017       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
1018                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
1019                                  GTK_OBJECT (window));
1020       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1021       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1022       gtk_widget_grab_default (button);
1023     }
1024
1025   if (!GTK_WIDGET_VISIBLE (window))
1026     gtk_widget_show_all (window);
1027   else
1028     gtk_widget_destroy (window);
1029 }
1030
1031 /*
1032  * GtkTree
1033  */
1034
1035 static void
1036 cb_tree_destroy_event(GtkWidget* w)
1037 {
1038   sTreeButtons* tree_buttons;
1039
1040   /* free buttons structure associate at this tree */
1041   tree_buttons = gtk_object_get_user_data (GTK_OBJECT (w));
1042   g_free (tree_buttons);
1043 }
1044
1045 static void
1046 cb_add_new_item(GtkWidget* w, GtkTree* tree)
1047 {
1048   sTreeButtons* tree_buttons;
1049   GList* selected_list;
1050   GtkWidget* selected_item;
1051   GtkWidget* subtree;
1052   GtkWidget* item_new;
1053   char buffer[255];
1054
1055   tree_buttons = gtk_object_get_user_data(GTK_OBJECT(tree));
1056
1057   selected_list = GTK_TREE_SELECTION(tree);
1058
1059   if(selected_list == NULL)
1060     {
1061       /* there is no item in tree */
1062       subtree = GTK_WIDGET(tree);
1063     }
1064   else
1065     {
1066       /* list can have only one element */
1067       selected_item = GTK_WIDGET(selected_list->data);
1068       
1069       subtree = GTK_TREE_ITEM_SUBTREE(selected_item);
1070
1071       if(subtree == NULL)
1072         {
1073           /* current selected item have not subtree ... create it */
1074           subtree = gtk_tree_new();
1075           gtk_tree_item_set_subtree(GTK_TREE_ITEM(selected_item), 
1076                                     subtree);
1077         }
1078     }
1079
1080   /* at this point, we know which subtree will be used to add new item */
1081   /* create a new item */
1082   sprintf(buffer, "item add %d", tree_buttons->nb_item_add);
1083   item_new = gtk_tree_item_new_with_label(buffer);
1084   gtk_tree_append(GTK_TREE(subtree), item_new);
1085   gtk_widget_show(item_new);
1086
1087   tree_buttons->nb_item_add++;
1088 }
1089
1090 static void
1091 cb_remove_item(GtkWidget*w, GtkTree* tree)
1092 {
1093   GList* selected_list;
1094   GList* clear_list;
1095   
1096   selected_list = GTK_TREE_SELECTION(tree);
1097
1098   clear_list = NULL;
1099     
1100   while (selected_list) 
1101     {
1102       clear_list = g_list_prepend (clear_list, selected_list->data);
1103       selected_list = selected_list->next;
1104     }
1105   
1106   clear_list = g_list_reverse (clear_list);
1107   gtk_tree_remove_items(tree, clear_list);
1108
1109   g_list_free (clear_list);
1110 }
1111
1112 static void
1113 cb_remove_subtree(GtkWidget*w, GtkTree* tree)
1114 {
1115   GList* selected_list;
1116   GtkTreeItem *item;
1117   
1118   selected_list = GTK_TREE_SELECTION(tree);
1119
1120   if (selected_list)
1121     {
1122       item = GTK_TREE_ITEM (selected_list->data);
1123       if (item->subtree)
1124         gtk_tree_item_remove_subtree (item);
1125     }
1126 }
1127
1128 static void
1129 cb_tree_changed(GtkTree* tree)
1130 {
1131   sTreeButtons* tree_buttons;
1132   GList* selected_list;
1133   guint nb_selected;
1134
1135   tree_buttons = gtk_object_get_user_data(GTK_OBJECT(tree));
1136
1137   selected_list = GTK_TREE_SELECTION(tree);
1138   nb_selected = g_list_length(selected_list);
1139
1140   if(nb_selected == 0) 
1141     {
1142       if(tree->children == NULL)
1143         gtk_widget_set_sensitive(tree_buttons->add_button, TRUE);
1144       else
1145         gtk_widget_set_sensitive(tree_buttons->add_button, FALSE);
1146       gtk_widget_set_sensitive(tree_buttons->remove_button, FALSE);
1147       gtk_widget_set_sensitive(tree_buttons->subtree_button, FALSE);
1148     } 
1149   else 
1150     {
1151       gtk_widget_set_sensitive(tree_buttons->remove_button, TRUE);
1152       gtk_widget_set_sensitive(tree_buttons->add_button, (nb_selected == 1));
1153       gtk_widget_set_sensitive(tree_buttons->subtree_button, (nb_selected == 1));
1154     }  
1155 }
1156
1157 static void 
1158 create_subtree(GtkWidget* item, guint level, guint nb_item_max, guint recursion_level_max)
1159 {
1160   GtkWidget* item_subtree;
1161   GtkWidget* item_new;
1162   guint nb_item;
1163   char buffer[255];
1164   int no_root_item;
1165
1166   if(level == recursion_level_max) return;
1167
1168   if(level == -1)
1169     {
1170       /* query with no root item */
1171       level = 0;
1172       item_subtree = item;
1173       no_root_item = 1;
1174     }
1175   else
1176     {
1177       /* query with no root item */
1178       /* create subtree and associate it with current item */
1179       item_subtree = gtk_tree_new();
1180       no_root_item = 0;
1181     }
1182   
1183   for(nb_item = 0; nb_item < nb_item_max; nb_item++)
1184     {
1185       sprintf(buffer, "item %d-%d", level, nb_item);
1186       item_new = gtk_tree_item_new_with_label(buffer);
1187       gtk_tree_append(GTK_TREE(item_subtree), item_new);
1188       create_subtree(item_new, level+1, nb_item_max, recursion_level_max);
1189       gtk_widget_show(item_new);
1190     }
1191
1192   if(!no_root_item)
1193     gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), item_subtree);
1194 }
1195
1196 static void
1197 create_tree_sample(guint selection_mode, 
1198                    guint draw_line, guint view_line, guint no_root_item,
1199                    guint nb_item_max, guint recursion_level_max) 
1200 {
1201   GtkWidget* window;
1202   GtkWidget* box1;
1203   GtkWidget* box2;
1204   GtkWidget* separator;
1205   GtkWidget* button;
1206   GtkWidget* scrolled_win;
1207   GtkWidget* root_tree;
1208   GtkWidget* root_item;
1209   sTreeButtons* tree_buttons;
1210
1211   /* create tree buttons struct */
1212   if ((tree_buttons = g_malloc (sizeof (sTreeButtons))) == NULL)
1213     {
1214       g_error("can't allocate memory for tree structure !\n");
1215       return;
1216     }
1217   tree_buttons->nb_item_add = 0;
1218
1219   /* create top level window */
1220   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1221   gtk_window_set_title(GTK_WINDOW(window), "Tree Sample");
1222   gtk_signal_connect(GTK_OBJECT(window), "destroy",
1223                      (GtkSignalFunc) cb_tree_destroy_event, NULL);
1224   gtk_object_set_user_data(GTK_OBJECT(window), tree_buttons);
1225
1226   box1 = gtk_vbox_new(FALSE, 0);
1227   gtk_container_add(GTK_CONTAINER(window), box1);
1228   gtk_widget_show(box1);
1229
1230   /* create tree box */
1231   box2 = gtk_vbox_new(FALSE, 0);
1232   gtk_box_pack_start(GTK_BOX(box1), box2, TRUE, TRUE, 0);
1233   gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1234   gtk_widget_show(box2);
1235
1236   /* create scrolled window */
1237   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
1238   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
1239                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1240   gtk_box_pack_start (GTK_BOX (box2), scrolled_win, TRUE, TRUE, 0);
1241   gtk_widget_set_usize (scrolled_win, 200, 200);
1242   gtk_widget_show (scrolled_win);
1243   
1244   /* create root tree widget */
1245   root_tree = gtk_tree_new();
1246   gtk_signal_connect(GTK_OBJECT(root_tree), "selection_changed",
1247                      (GtkSignalFunc)cb_tree_changed,
1248                      (gpointer)NULL);
1249   gtk_object_set_user_data(GTK_OBJECT(root_tree), tree_buttons);
1250   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), root_tree);
1251   gtk_tree_set_selection_mode(GTK_TREE(root_tree), selection_mode);
1252   gtk_tree_set_view_lines(GTK_TREE(root_tree), draw_line);
1253   gtk_tree_set_view_mode(GTK_TREE(root_tree), !view_line);
1254   gtk_widget_show(root_tree);
1255
1256   if ( no_root_item )
1257     {
1258       /* set root tree to subtree function with root item variable */
1259       root_item = GTK_WIDGET(root_tree);
1260     }
1261   else
1262     {
1263       /* create root tree item widget */
1264       root_item = gtk_tree_item_new_with_label("root item");
1265       gtk_tree_append(GTK_TREE(root_tree), root_item);
1266       gtk_widget_show(root_item);
1267      }
1268   create_subtree(root_item, -no_root_item, nb_item_max, recursion_level_max);
1269
1270   box2 = gtk_vbox_new(FALSE, 0);
1271   gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0);
1272   gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1273   gtk_widget_show(box2);
1274
1275   button = gtk_button_new_with_label("Add Item");
1276   gtk_widget_set_sensitive(button, FALSE);
1277   gtk_signal_connect(GTK_OBJECT (button), "clicked",
1278                      (GtkSignalFunc) cb_add_new_item, 
1279                      (gpointer)root_tree);
1280   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1281   gtk_widget_show(button);
1282   tree_buttons->add_button = button;
1283
1284   button = gtk_button_new_with_label("Remove Item(s)");
1285   gtk_widget_set_sensitive(button, FALSE);
1286   gtk_signal_connect(GTK_OBJECT (button), "clicked",
1287                      (GtkSignalFunc) cb_remove_item, 
1288                      (gpointer)root_tree);
1289   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1290   gtk_widget_show(button);
1291   tree_buttons->remove_button = button;
1292
1293   button = gtk_button_new_with_label("Remove Subtree");
1294   gtk_widget_set_sensitive(button, FALSE);
1295   gtk_signal_connect(GTK_OBJECT (button), "clicked",
1296                      (GtkSignalFunc) cb_remove_subtree, 
1297                      (gpointer)root_tree);
1298   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1299   gtk_widget_show(button);
1300   tree_buttons->subtree_button = button;
1301
1302   /* create separator */
1303   separator = gtk_hseparator_new();
1304   gtk_box_pack_start(GTK_BOX(box1), separator, FALSE, FALSE, 0);
1305   gtk_widget_show(separator);
1306
1307   /* create button box */
1308   box2 = gtk_vbox_new(FALSE, 0);
1309   gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0);
1310   gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1311   gtk_widget_show(box2);
1312
1313   button = gtk_button_new_with_label("Close");
1314   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1315   gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
1316                             (GtkSignalFunc) gtk_widget_destroy, 
1317                             GTK_OBJECT(window));
1318   gtk_widget_show(button);
1319
1320   gtk_widget_show(window);
1321 }
1322
1323 static void
1324 cb_create_tree(GtkWidget* w)
1325 {
1326   guint selection_mode = GTK_SELECTION_SINGLE;
1327   guint view_line;
1328   guint draw_line;
1329   guint no_root_item;
1330   guint nb_item;
1331   guint recursion_level;
1332
1333   /* get selection mode choice */
1334   if(GTK_TOGGLE_BUTTON(sTreeSampleSelection.single_button)->active)
1335     selection_mode = GTK_SELECTION_SINGLE;
1336   else
1337     if(GTK_TOGGLE_BUTTON(sTreeSampleSelection.browse_button)->active)
1338       selection_mode = GTK_SELECTION_BROWSE;
1339     else
1340       selection_mode = GTK_SELECTION_MULTIPLE;
1341
1342   /* get options choice */
1343   draw_line = GTK_TOGGLE_BUTTON(sTreeSampleSelection.draw_line_button)->active;
1344   view_line = GTK_TOGGLE_BUTTON(sTreeSampleSelection.view_line_button)->active;
1345   no_root_item = GTK_TOGGLE_BUTTON(sTreeSampleSelection.no_root_item_button)->active;
1346     
1347   /* get levels */
1348   nb_item = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(sTreeSampleSelection.nb_item_spinner));
1349   recursion_level = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(sTreeSampleSelection.recursion_spinner));
1350
1351   if (pow (nb_item, recursion_level) > 10000)
1352     {
1353       g_print ("%g total items? That will take a very long time. Try less\n",
1354                pow (nb_item, recursion_level));
1355       return;
1356     }
1357
1358   create_tree_sample(selection_mode, draw_line, view_line, no_root_item, nb_item, recursion_level);
1359 }
1360
1361 void 
1362 create_tree_mode_window(void)
1363 {
1364   static GtkWidget* window;
1365   GtkWidget* box1;
1366   GtkWidget* box2;
1367   GtkWidget* box3;
1368   GtkWidget* box4;
1369   GtkWidget* box5;
1370   GtkWidget* button;
1371   GtkWidget* frame;
1372   GtkWidget* separator;
1373   GtkWidget* label;
1374   GtkWidget* spinner;
1375   GtkAdjustment *adj;
1376
1377   if (!window)
1378     {
1379       /* create toplevel window  */
1380       window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1381       gtk_window_set_title(GTK_WINDOW(window), "Set Tree Parameters");
1382       gtk_signal_connect (GTK_OBJECT (window), "destroy",
1383                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
1384                           &window);
1385       box1 = gtk_vbox_new(FALSE, 0);
1386       gtk_container_add(GTK_CONTAINER(window), box1);
1387
1388       /* create upper box - selection box */
1389       box2 = gtk_vbox_new(FALSE, 5);
1390       gtk_box_pack_start(GTK_BOX(box1), box2, TRUE, TRUE, 0);
1391       gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1392
1393       box3 = gtk_hbox_new(FALSE, 5);
1394       gtk_box_pack_start(GTK_BOX(box2), box3, TRUE, TRUE, 0);
1395
1396       /* create selection mode frame */
1397       frame = gtk_frame_new("Selection Mode");
1398       gtk_box_pack_start(GTK_BOX(box3), frame, TRUE, TRUE, 0);
1399
1400       box4 = gtk_vbox_new(FALSE, 0);
1401       gtk_container_add(GTK_CONTAINER(frame), box4);
1402       gtk_container_set_border_width(GTK_CONTAINER(box4), 5);
1403
1404       /* create radio button */  
1405       button = gtk_radio_button_new_with_label(NULL, "SINGLE");
1406       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1407       sTreeSampleSelection.single_button = button;
1408
1409       button = gtk_radio_button_new_with_label(gtk_radio_button_group (GTK_RADIO_BUTTON (button)),
1410                                                "BROWSE");
1411       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1412       sTreeSampleSelection.browse_button = button;
1413
1414       button = gtk_radio_button_new_with_label(gtk_radio_button_group (GTK_RADIO_BUTTON (button)),
1415                                                "MULTIPLE");
1416       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1417       sTreeSampleSelection.multiple_button = button;
1418
1419       sTreeSampleSelection.selection_mode_group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
1420
1421       /* create option mode frame */
1422       frame = gtk_frame_new("Options");
1423       gtk_box_pack_start(GTK_BOX(box3), frame, TRUE, TRUE, 0);
1424
1425       box4 = gtk_vbox_new(FALSE, 0);
1426       gtk_container_add(GTK_CONTAINER(frame), box4);
1427       gtk_container_set_border_width(GTK_CONTAINER(box4), 5);
1428
1429       /* create check button */
1430       button = gtk_check_button_new_with_label("Draw line");
1431       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1432       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
1433       sTreeSampleSelection.draw_line_button = button;
1434   
1435       button = gtk_check_button_new_with_label("View Line mode");
1436       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1437       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
1438       sTreeSampleSelection.view_line_button = button;
1439   
1440       button = gtk_check_button_new_with_label("Without Root item");
1441       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1442       sTreeSampleSelection.no_root_item_button = button;
1443
1444       /* create recursion parameter */
1445       frame = gtk_frame_new("Size Parameters");
1446       gtk_box_pack_start(GTK_BOX(box2), frame, TRUE, TRUE, 0);
1447
1448       box4 = gtk_hbox_new(FALSE, 5);
1449       gtk_container_add(GTK_CONTAINER(frame), box4);
1450       gtk_container_set_border_width(GTK_CONTAINER(box4), 5);
1451
1452       /* create number of item spin button */
1453       box5 = gtk_hbox_new(FALSE, 5);
1454       gtk_box_pack_start(GTK_BOX(box4), box5, FALSE, FALSE, 0);
1455
1456       label = gtk_label_new("Number of items : ");
1457       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1458       gtk_box_pack_start (GTK_BOX (box5), label, FALSE, TRUE, 0);
1459
1460       adj = (GtkAdjustment *) gtk_adjustment_new ((gfloat)DEFAULT_NUMBER_OF_ITEM, 1.0, 255.0, 1.0,
1461                                                   5.0, 0.0);
1462       spinner = gtk_spin_button_new (adj, 0, 0);
1463       gtk_box_pack_start (GTK_BOX (box5), spinner, FALSE, TRUE, 0);
1464       sTreeSampleSelection.nb_item_spinner = spinner;
1465   
1466       /* create recursion level spin button */
1467       box5 = gtk_hbox_new(FALSE, 5);
1468       gtk_box_pack_start(GTK_BOX(box4), box5, FALSE, FALSE, 0);
1469
1470       label = gtk_label_new("Depth : ");
1471       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1472       gtk_box_pack_start (GTK_BOX (box5), label, FALSE, TRUE, 0);
1473
1474       adj = (GtkAdjustment *) gtk_adjustment_new ((gfloat)DEFAULT_RECURSION_LEVEL, 0.0, 255.0, 1.0,
1475                                                   5.0, 0.0);
1476       spinner = gtk_spin_button_new (adj, 0, 0);
1477       gtk_box_pack_start (GTK_BOX (box5), spinner, FALSE, TRUE, 0);
1478       sTreeSampleSelection.recursion_spinner = spinner;
1479   
1480       /* create horizontal separator */
1481       separator = gtk_hseparator_new();
1482       gtk_box_pack_start(GTK_BOX(box1), separator, FALSE, FALSE, 0);
1483
1484       /* create bottom button box */
1485       box2 = gtk_hbox_new(TRUE, 10);
1486       gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0);
1487       gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1488
1489       button = gtk_button_new_with_label("Create Tree");
1490       gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1491       gtk_signal_connect(GTK_OBJECT (button), "clicked",
1492                          (GtkSignalFunc) cb_create_tree, NULL);
1493
1494       button = gtk_button_new_with_label("Close");
1495       gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1496       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
1497                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
1498                                  GTK_OBJECT (window));
1499     }
1500   if (!GTK_WIDGET_VISIBLE (window))
1501     gtk_widget_show_all (window);
1502   else
1503     gtk_widget_destroy (window);
1504 }
1505
1506 /*
1507  * GtkHandleBox
1508  */
1509
1510 static void
1511 handle_box_child_signal (GtkHandleBox *hb,
1512                          GtkWidget    *child,
1513                          const gchar  *action)
1514 {
1515   printf ("%s: child <%s> %sed\n",
1516           gtk_type_name (GTK_OBJECT_TYPE (hb)),
1517           gtk_type_name (GTK_OBJECT_TYPE (child)),
1518           action);
1519 }
1520
1521 static void
1522 create_handle_box (void)
1523 {
1524   static GtkWidget* window = NULL;
1525   GtkWidget *handle_box;
1526   GtkWidget *handle_box2;
1527   GtkWidget *vbox;
1528   GtkWidget *hbox;
1529   GtkWidget *toolbar;
1530   GtkWidget *label;
1531   GtkWidget *separator;
1532         
1533   if (!window)
1534   {
1535     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1536     gtk_window_set_title (GTK_WINDOW (window),
1537                           "Handle Box Test");
1538     gtk_window_set_policy (GTK_WINDOW (window),
1539                            TRUE,
1540                            TRUE,
1541                            FALSE);
1542     
1543     gtk_signal_connect (GTK_OBJECT (window), "destroy",
1544                         GTK_SIGNAL_FUNC(gtk_widget_destroyed),
1545                         &window);
1546     
1547     gtk_container_set_border_width (GTK_CONTAINER (window), 20);
1548
1549     vbox = gtk_vbox_new (FALSE, 0);
1550     gtk_container_add (GTK_CONTAINER (window), vbox);
1551     gtk_widget_show (vbox);
1552
1553     label = gtk_label_new ("Above");
1554     gtk_container_add (GTK_CONTAINER (vbox), label);
1555     gtk_widget_show (label);
1556
1557     separator = gtk_hseparator_new ();
1558     gtk_container_add (GTK_CONTAINER (vbox), separator);
1559     gtk_widget_show (separator);
1560     
1561     hbox = gtk_hbox_new (FALSE, 10);
1562     gtk_container_add (GTK_CONTAINER (vbox), hbox);
1563     gtk_widget_show (hbox);
1564
1565     separator = gtk_hseparator_new ();
1566     gtk_container_add (GTK_CONTAINER (vbox), separator);
1567     gtk_widget_show (separator);
1568
1569     label = gtk_label_new ("Below");
1570     gtk_container_add (GTK_CONTAINER (vbox), label);
1571     gtk_widget_show (label);
1572
1573     handle_box = gtk_handle_box_new ();
1574     gtk_container_add (GTK_CONTAINER (hbox), handle_box);
1575     gtk_signal_connect (GTK_OBJECT (handle_box),
1576                         "child_attached",
1577                         GTK_SIGNAL_FUNC (handle_box_child_signal),
1578                         "attached");
1579     gtk_signal_connect (GTK_OBJECT (handle_box),
1580                         "child_detached",
1581                         GTK_SIGNAL_FUNC (handle_box_child_signal),
1582                         "detached");
1583     gtk_widget_show (handle_box);
1584
1585     toolbar = make_toolbar (window);
1586     gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_NORMAL);
1587     gtk_container_add (GTK_CONTAINER (handle_box), toolbar);
1588     gtk_widget_show (toolbar);
1589
1590     handle_box = gtk_handle_box_new ();
1591     gtk_container_add (GTK_CONTAINER (hbox), handle_box);
1592     gtk_signal_connect (GTK_OBJECT (handle_box),
1593                         "child_attached",
1594                         GTK_SIGNAL_FUNC (handle_box_child_signal),
1595                         "attached");
1596     gtk_signal_connect (GTK_OBJECT (handle_box),
1597                         "child_detached",
1598                         GTK_SIGNAL_FUNC (handle_box_child_signal),
1599                         "detached");
1600     gtk_widget_show (handle_box);
1601
1602     handle_box2 = gtk_handle_box_new ();
1603     gtk_container_add (GTK_CONTAINER (handle_box), handle_box2);
1604     gtk_signal_connect (GTK_OBJECT (handle_box2),
1605                         "child_attached",
1606                         GTK_SIGNAL_FUNC (handle_box_child_signal),
1607                         "attached");
1608     gtk_signal_connect (GTK_OBJECT (handle_box2),
1609                         "child_detached",
1610                         GTK_SIGNAL_FUNC (handle_box_child_signal),
1611                         "detached");
1612     gtk_widget_show (handle_box2);
1613
1614     label = gtk_label_new ("Fooo!");
1615     gtk_container_add (GTK_CONTAINER (handle_box2), label);
1616     gtk_widget_show (label);
1617   }
1618
1619   if (!GTK_WIDGET_VISIBLE (window))
1620     gtk_widget_show (window);
1621   else
1622     gtk_widget_destroy (window);
1623 }
1624
1625 /*
1626  * Reparent demo
1627  */
1628
1629 static void
1630 reparent_label (GtkWidget *widget,
1631                 GtkWidget *new_parent)
1632 {
1633   GtkWidget *label;
1634
1635   label = gtk_object_get_user_data (GTK_OBJECT (widget));
1636
1637   gtk_widget_reparent (label, new_parent);
1638 }
1639
1640 static void
1641 set_parent_signal (GtkWidget *child,
1642                    GtkWidget *old_parent,
1643                    gpointer   func_data)
1644 {
1645   g_print ("set_parent for \"%s\": new parent: \"%s\", old parent: \"%s\", data: %d\n",
1646            gtk_type_name (GTK_OBJECT_TYPE (child)),
1647            child->parent ? gtk_type_name (GTK_OBJECT_TYPE (child->parent)) : "NULL",
1648            old_parent ? gtk_type_name (GTK_OBJECT_TYPE (old_parent)) : "NULL",
1649            GPOINTER_TO_INT (func_data));
1650 }
1651
1652 static void
1653 create_reparent (void)
1654 {
1655   static GtkWidget *window = NULL;
1656   GtkWidget *box1;
1657   GtkWidget *box2;
1658   GtkWidget *box3;
1659   GtkWidget *frame;
1660   GtkWidget *button;
1661   GtkWidget *label;
1662   GtkWidget *separator;
1663
1664   if (!window)
1665     {
1666       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1667
1668       gtk_signal_connect (GTK_OBJECT (window), "destroy",
1669                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
1670                           &window);
1671
1672       gtk_window_set_title (GTK_WINDOW (window), "reparent");
1673       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1674
1675       box1 = gtk_vbox_new (FALSE, 0);
1676       gtk_container_add (GTK_CONTAINER (window), box1);
1677
1678       box2 = gtk_hbox_new (FALSE, 5);
1679       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1680       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
1681
1682       label = gtk_label_new ("Hello World");
1683
1684       frame = gtk_frame_new ("Frame 1");
1685       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
1686
1687       box3 = gtk_vbox_new (FALSE, 5);
1688       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
1689       gtk_container_add (GTK_CONTAINER (frame), box3);
1690
1691       button = gtk_button_new_with_label ("switch");
1692       gtk_signal_connect (GTK_OBJECT (button), "clicked",
1693                           GTK_SIGNAL_FUNC(reparent_label),
1694                           box3);
1695       gtk_object_set_user_data (GTK_OBJECT (button), label);
1696       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
1697
1698       gtk_box_pack_start (GTK_BOX (box3), label, FALSE, TRUE, 0);
1699       gtk_signal_connect (GTK_OBJECT (label),
1700                           "parent_set",
1701                           GTK_SIGNAL_FUNC (set_parent_signal),
1702                           GINT_TO_POINTER (42));
1703
1704       frame = gtk_frame_new ("Frame 2");
1705       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
1706
1707       box3 = gtk_vbox_new (FALSE, 5);
1708       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
1709       gtk_container_add (GTK_CONTAINER (frame), box3);
1710
1711       button = gtk_button_new_with_label ("switch");
1712       gtk_signal_connect (GTK_OBJECT (button), "clicked",
1713                           GTK_SIGNAL_FUNC(reparent_label),
1714                           box3);
1715       gtk_object_set_user_data (GTK_OBJECT (button), label);
1716       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
1717
1718       separator = gtk_hseparator_new ();
1719       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1720
1721       box2 = gtk_vbox_new (FALSE, 10);
1722       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1723       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
1724
1725       button = gtk_button_new_with_label ("close");
1726       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
1727                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
1728                                  GTK_OBJECT (window));
1729       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1730       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1731       gtk_widget_grab_default (button);
1732     }
1733
1734   if (!GTK_WIDGET_VISIBLE (window))
1735     gtk_widget_show_all (window);
1736   else
1737     gtk_widget_destroy (window);
1738 }
1739
1740 /*
1741  * Saved Position
1742  */
1743 gint upositionx = 0;
1744 gint upositiony = 0;
1745
1746 static gint
1747 uposition_configure (GtkWidget *window)
1748 {
1749   GtkLabel *lx;
1750   GtkLabel *ly;
1751   gchar buffer[64];
1752
1753   lx = gtk_object_get_data (GTK_OBJECT (window), "x");
1754   ly = gtk_object_get_data (GTK_OBJECT (window), "y");
1755
1756   gdk_window_get_root_origin (window->window, &upositionx, &upositiony);
1757   sprintf (buffer, "%d", upositionx);
1758   gtk_label_set (lx, buffer);
1759   sprintf (buffer, "%d", upositiony);
1760   gtk_label_set (ly, buffer);
1761
1762   return FALSE;
1763 }
1764
1765 static void
1766 create_saved_position (void)
1767 {
1768   static GtkWidget *window = NULL;
1769
1770   if (!window)
1771     {
1772       GtkWidget *hbox;
1773       GtkWidget *main_vbox;
1774       GtkWidget *vbox;
1775       GtkWidget *x_label;
1776       GtkWidget *y_label;
1777       GtkWidget *button;
1778       GtkWidget *label;
1779       GtkWidget *any;
1780
1781       window = gtk_widget_new (GTK_TYPE_WINDOW,
1782                                "type", GTK_WINDOW_TOPLEVEL,
1783                                "signal::configure_event", uposition_configure, NULL,
1784                                "x", upositionx,
1785                                "y", upositiony,
1786                                "title", "Saved Position",
1787                                NULL);
1788
1789       gtk_signal_connect (GTK_OBJECT (window), "destroy",
1790                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
1791                           &window);
1792
1793       main_vbox = gtk_vbox_new (FALSE, 5);
1794       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
1795       gtk_container_add (GTK_CONTAINER (window), main_vbox);
1796
1797       vbox =
1798         gtk_widget_new (gtk_vbox_get_type (),
1799                         "GtkBox::homogeneous", FALSE,
1800                         "GtkBox::spacing", 5,
1801                         "GtkContainer::border_width", 10,
1802                         "GtkWidget::parent", main_vbox,
1803                         "GtkWidget::visible", TRUE,
1804                         NULL);
1805
1806       hbox = gtk_hbox_new (FALSE, 0);
1807       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
1808       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
1809
1810       label = gtk_label_new ("X Origin : ");
1811       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1812       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
1813
1814       x_label = gtk_label_new ("");
1815       gtk_box_pack_start (GTK_BOX (hbox), x_label, TRUE, TRUE, 0);
1816       gtk_object_set_data (GTK_OBJECT (window), "x", x_label);
1817
1818       hbox = gtk_hbox_new (FALSE, 0);
1819       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
1820       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
1821
1822       label = gtk_label_new ("Y Origin : ");
1823       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1824       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
1825
1826       y_label = gtk_label_new ("");
1827       gtk_box_pack_start (GTK_BOX (hbox), y_label, TRUE, TRUE, 0);
1828       gtk_object_set_data (GTK_OBJECT (window), "y", y_label);
1829
1830       any =
1831         gtk_widget_new (gtk_hseparator_get_type (),
1832                         "GtkWidget::visible", TRUE,
1833                         NULL);
1834       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
1835
1836       hbox = gtk_hbox_new (FALSE, 0);
1837       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
1838       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
1839
1840       button = gtk_button_new_with_label ("Close");
1841       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
1842                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
1843                                  GTK_OBJECT (window));
1844       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
1845       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1846       gtk_widget_grab_default (button);
1847       
1848       gtk_widget_show_all (window);
1849     }
1850   else
1851     gtk_widget_destroy (window);
1852 }
1853
1854 /*
1855  * GtkPixmap
1856  */
1857
1858 static void
1859 create_pixmap (void)
1860 {
1861   static GtkWidget *window = NULL;
1862   GtkWidget *box1;
1863   GtkWidget *box2;
1864   GtkWidget *box3;
1865   GtkWidget *button;
1866   GtkWidget *label;
1867   GtkWidget *separator;
1868   GtkWidget *pixmapwid;
1869   GdkPixmap *pixmap;
1870   GdkBitmap *mask;
1871
1872   if (!window)
1873     {
1874       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1875
1876       gtk_signal_connect (GTK_OBJECT (window), "destroy",
1877                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
1878                           &window);
1879
1880       gtk_window_set_title (GTK_WINDOW (window), "GtkPixmap");
1881       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1882       gtk_widget_realize(window);
1883
1884       box1 = gtk_vbox_new (FALSE, 0);
1885       gtk_container_add (GTK_CONTAINER (window), box1);
1886
1887       box2 = gtk_vbox_new (FALSE, 10);
1888       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1889       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
1890
1891       button = gtk_button_new ();
1892       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
1893
1894       pixmap = gdk_pixmap_create_from_xpm (window->window, &mask, NULL,
1895                                            "test.xpm");
1896       pixmapwid = gtk_pixmap_new (pixmap, mask);
1897       gdk_pixmap_unref (pixmap);
1898       gdk_pixmap_unref (mask);
1899
1900       label = gtk_label_new ("Pixmap\ntest");
1901       box3 = gtk_hbox_new (FALSE, 0);
1902       gtk_container_set_border_width (GTK_CONTAINER (box3), 2);
1903       gtk_container_add (GTK_CONTAINER (box3), pixmapwid);
1904       gtk_container_add (GTK_CONTAINER (box3), label);
1905       gtk_container_add (GTK_CONTAINER (button), box3);
1906
1907       separator = gtk_hseparator_new ();
1908       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1909
1910       box2 = gtk_vbox_new (FALSE, 10);
1911       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1912       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
1913
1914       button = gtk_button_new_with_label ("close");
1915       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
1916                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
1917                                  GTK_OBJECT (window));
1918       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1919       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1920       gtk_widget_grab_default (button);
1921     }
1922
1923   if (!GTK_WIDGET_VISIBLE (window))
1924     gtk_widget_show_all (window);
1925   else
1926     gtk_widget_destroy (window);
1927 }
1928
1929 static void
1930 tips_query_widget_entered (GtkTipsQuery   *tips_query,
1931                            GtkWidget      *widget,
1932                            const gchar    *tip_text,
1933                            const gchar    *tip_private,
1934                            GtkWidget      *toggle)
1935 {
1936   if (GTK_TOGGLE_BUTTON (toggle)->active)
1937     {
1938       gtk_label_set (GTK_LABEL (tips_query), tip_text ? "There is a Tip!" : "There is no Tip!");
1939       /* don't let GtkTipsQuery reset it's label */
1940       gtk_signal_emit_stop_by_name (GTK_OBJECT (tips_query), "widget_entered");
1941     }
1942 }
1943
1944 static gint
1945 tips_query_widget_selected (GtkWidget      *tips_query,
1946                             GtkWidget      *widget,
1947                             const gchar    *tip_text,
1948                             const gchar    *tip_private,
1949                             GdkEventButton *event,
1950                             gpointer        func_data)
1951 {
1952   if (widget)
1953     g_print ("Help \"%s\" requested for <%s>\n",
1954              tip_private ? tip_private : "None",
1955              gtk_type_name (GTK_OBJECT_TYPE (widget)));
1956   return TRUE;
1957 }
1958
1959 static void
1960 create_tooltips (void)
1961 {
1962   static GtkWidget *window = NULL;
1963   GtkWidget *box1;
1964   GtkWidget *box2;
1965   GtkWidget *box3;
1966   GtkWidget *button;
1967   GtkWidget *toggle;
1968   GtkWidget *frame;
1969   GtkWidget *tips_query;
1970   GtkWidget *separator;
1971   GtkTooltips *tooltips;
1972
1973   if (!window)
1974     {
1975       window =
1976         gtk_widget_new (gtk_window_get_type (),
1977                         "GtkWindow::type", GTK_WINDOW_TOPLEVEL,
1978                         "GtkContainer::border_width", 0,
1979                         "GtkWindow::title", "Tooltips",
1980                         "GtkWindow::allow_shrink", TRUE,
1981                         "GtkWindow::allow_grow", FALSE,
1982                         "GtkWindow::auto_shrink", TRUE,
1983                         "GtkWidget::width", 200,
1984                         NULL);
1985
1986       gtk_signal_connect (GTK_OBJECT (window), "destroy",
1987                           GTK_SIGNAL_FUNC (destroy_tooltips),
1988                           &window);
1989
1990       tooltips=gtk_tooltips_new();
1991       gtk_object_set_data (GTK_OBJECT (window), "tooltips", tooltips);
1992       
1993       box1 = gtk_vbox_new (FALSE, 0);
1994       gtk_container_add (GTK_CONTAINER (window), box1);
1995
1996       box2 = gtk_vbox_new (FALSE, 10);
1997       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1998       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
1999
2000       button = gtk_toggle_button_new_with_label ("button1");
2001       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2002
2003       gtk_tooltips_set_tip (tooltips,button,"This is button 1", "ContextHelp/buttons/1");
2004
2005       button = gtk_toggle_button_new_with_label ("button2");
2006       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2007
2008       gtk_tooltips_set_tip (tooltips,
2009                             button,
2010                             "This is button 2. This is also a really long tooltip which probably won't fit on a single line and will therefore need to be wrapped. Hopefully the wrapping will work correctly.",
2011                             "ContextHelp/buttons/2_long");
2012
2013       toggle = gtk_toggle_button_new_with_label ("Override TipsQuery Label");
2014       gtk_box_pack_start (GTK_BOX (box2), toggle, TRUE, TRUE, 0);
2015
2016       gtk_tooltips_set_tip (tooltips, toggle, "Toggle TipsQuery view.", "Hi msw! ;)");
2017
2018       box3 =
2019         gtk_widget_new (gtk_vbox_get_type (),
2020                         "GtkBox::homogeneous", FALSE,
2021                         "GtkBox::spacing", 5,
2022                         "GtkContainer::border_width", 5,
2023                         "GtkWidget::visible", TRUE,
2024                         NULL);
2025
2026       tips_query = gtk_tips_query_new ();
2027
2028       button =
2029         gtk_widget_new (gtk_button_get_type (),
2030                         "GtkButton::label", "[?]",
2031                         "GtkWidget::visible", TRUE,
2032                         "GtkWidget::parent", box3,
2033                         "GtkObject::object_signal::clicked", gtk_tips_query_start_query, tips_query,
2034                         NULL);
2035       gtk_box_set_child_packing (GTK_BOX (box3), button, FALSE, FALSE, 0, GTK_PACK_START);
2036       gtk_tooltips_set_tip (tooltips,
2037                             button,
2038                             "Start the Tooltips Inspector",
2039                             "ContextHelp/buttons/?");
2040       
2041       
2042       gtk_widget_set (tips_query,
2043                       "GtkWidget::visible", TRUE,
2044                       "GtkWidget::parent", box3,
2045                       "GtkTipsQuery::caller", button,
2046                       "GtkObject::signal::widget_entered", tips_query_widget_entered, toggle,
2047                       "GtkObject::signal::widget_selected", tips_query_widget_selected, NULL,
2048                       NULL);
2049       
2050       frame =
2051         gtk_widget_new (gtk_frame_get_type (),
2052                         "GtkFrame::label", "ToolTips Inspector",
2053                         "GtkFrame::label_xalign", (double) 0.5,
2054                         "GtkContainer::border_width", 0,
2055                         "GtkWidget::visible", TRUE,
2056                         "GtkWidget::parent", box2,
2057                         "GtkContainer::child", box3,
2058                         NULL);
2059       gtk_box_set_child_packing (GTK_BOX (box2), frame, TRUE, TRUE, 10, GTK_PACK_START);
2060
2061       separator = gtk_hseparator_new ();
2062       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2063
2064       box2 = gtk_vbox_new (FALSE, 10);
2065       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2066       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2067
2068       button = gtk_button_new_with_label ("close");
2069       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2070                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2071                                  GTK_OBJECT (window));
2072       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2073       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2074       gtk_widget_grab_default (button);
2075
2076       gtk_tooltips_set_tip (tooltips, button, "Push this button to close window", "ContextHelp/buttons/Close");
2077     }
2078
2079   if (!GTK_WIDGET_VISIBLE (window))
2080     gtk_widget_show_all (window);
2081   else
2082     gtk_widget_destroy (window);
2083 }
2084
2085 /*
2086  * Menu demo
2087  */
2088
2089 static GtkWidget*
2090 create_menu (gint depth, gboolean tearoff)
2091 {
2092   GtkWidget *menu;
2093   GtkWidget *menuitem;
2094   GSList *group;
2095   char buf[32];
2096   int i, j;
2097
2098   if (depth < 1)
2099     return NULL;
2100
2101   menu = gtk_menu_new ();
2102   group = NULL;
2103
2104   if (tearoff)
2105     {
2106       menuitem = gtk_tearoff_menu_item_new ();
2107       gtk_menu_append (GTK_MENU (menu), menuitem);
2108       gtk_widget_show (menuitem);
2109     }
2110
2111   for (i = 0, j = 1; i < 5; i++, j++)
2112     {
2113       sprintf (buf, "item %2d - %d", depth, j);
2114       menuitem = gtk_radio_menu_item_new_with_label (group, buf);
2115       group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
2116       if (depth % 2)
2117         gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
2118       gtk_menu_append (GTK_MENU (menu), menuitem);
2119       gtk_widget_show (menuitem);
2120       if (i == 3)
2121         gtk_widget_set_sensitive (menuitem, FALSE);
2122
2123       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (depth - 1, TRUE));
2124     }
2125
2126   return menu;
2127 }
2128
2129 static void
2130 create_menus (void)
2131 {
2132   static GtkWidget *window = NULL;
2133   GtkWidget *box1;
2134   GtkWidget *box2;
2135   GtkWidget *button;
2136   GtkWidget *optionmenu;
2137   GtkWidget *separator;
2138   
2139   if (!window)
2140     {
2141       GtkWidget *menubar;
2142       GtkWidget *menu;
2143       GtkWidget *menuitem;
2144       GtkAccelGroup *accel_group;
2145       
2146       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2147       
2148       gtk_signal_connect (GTK_OBJECT (window), "destroy",
2149                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
2150                           &window);
2151       gtk_signal_connect (GTK_OBJECT (window), "delete-event",
2152                           GTK_SIGNAL_FUNC (gtk_true),
2153                           NULL);
2154       
2155       accel_group = gtk_accel_group_new ();
2156       gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
2157
2158       gtk_window_set_title (GTK_WINDOW (window), "menus");
2159       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2160       
2161       
2162       box1 = gtk_vbox_new (FALSE, 0);
2163       gtk_container_add (GTK_CONTAINER (window), box1);
2164       gtk_widget_show (box1);
2165       
2166       menubar = gtk_menu_bar_new ();
2167       gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
2168       gtk_widget_show (menubar);
2169       
2170       menu = create_menu (2, TRUE);
2171       
2172       menuitem = gtk_menu_item_new_with_label ("test\nline2");
2173       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
2174       gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
2175       gtk_widget_show (menuitem);
2176       
2177       menuitem = gtk_menu_item_new_with_label ("foo");
2178       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (3, TRUE));
2179       gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
2180       gtk_widget_show (menuitem);
2181
2182       menuitem = gtk_menu_item_new_with_label ("bar");
2183       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (4, TRUE));
2184       gtk_menu_item_right_justify (GTK_MENU_ITEM (menuitem));
2185       gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
2186       gtk_widget_show (menuitem);
2187       
2188       box2 = gtk_vbox_new (FALSE, 10);
2189       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2190       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2191       gtk_widget_show (box2);
2192       
2193       menu = create_menu (1, FALSE);
2194       gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
2195
2196       menuitem = gtk_check_menu_item_new_with_label ("Accelerate Me");
2197       gtk_menu_append (GTK_MENU (menu), menuitem);
2198       gtk_widget_show (menuitem);
2199       gtk_widget_add_accelerator (menuitem,
2200                                   "activate",
2201                                   accel_group,
2202                                   GDK_F1,
2203                                   0,
2204                                   GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE);
2205       menuitem = gtk_check_menu_item_new_with_label ("Accelerator Locked");
2206       gtk_menu_append (GTK_MENU (menu), menuitem);
2207       gtk_widget_show (menuitem);
2208       gtk_widget_add_accelerator (menuitem,
2209                                   "activate",
2210                                   accel_group,
2211                                   GDK_F2,
2212                                   0,
2213                                   GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
2214       menuitem = gtk_check_menu_item_new_with_label ("Accelerators Frozen");
2215       gtk_menu_append (GTK_MENU (menu), menuitem);
2216       gtk_widget_show (menuitem);
2217       gtk_widget_add_accelerator (menuitem,
2218                                   "activate",
2219                                   accel_group,
2220                                   GDK_F2,
2221                                   0,
2222                                   GTK_ACCEL_VISIBLE);
2223       gtk_widget_add_accelerator (menuitem,
2224                                   "activate",
2225                                   accel_group,
2226                                   GDK_F3,
2227                                   0,
2228                                   GTK_ACCEL_VISIBLE);
2229       gtk_widget_lock_accelerators (menuitem);
2230       
2231       optionmenu = gtk_option_menu_new ();
2232       gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
2233       gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), 3);
2234       gtk_box_pack_start (GTK_BOX (box2), optionmenu, TRUE, TRUE, 0);
2235       gtk_widget_show (optionmenu);
2236
2237       separator = gtk_hseparator_new ();
2238       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2239       gtk_widget_show (separator);
2240
2241       box2 = gtk_vbox_new (FALSE, 10);
2242       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2243       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2244       gtk_widget_show (box2);
2245
2246       button = gtk_button_new_with_label ("close");
2247       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2248                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2249                                  GTK_OBJECT (window));
2250       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2251       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2252       gtk_widget_grab_default (button);
2253       gtk_widget_show (button);
2254     }
2255
2256   if (!GTK_WIDGET_VISIBLE (window))
2257     gtk_widget_show (window);
2258   else
2259     gtk_widget_destroy (window);
2260 }
2261
2262 static void
2263 gtk_ifactory_cb (gpointer             callback_data,
2264                  guint                callback_action,
2265                  GtkWidget           *widget)
2266 {
2267   g_message ("ItemFactory: activated \"%s\"", gtk_item_factory_path_from_widget (widget));
2268 }
2269
2270 static GtkItemFactoryEntry menu_items[] =
2271 {
2272   { "/_File",            NULL,         0,                     0, "<Branch>" },
2273   { "/File/tearoff1",    NULL,         gtk_ifactory_cb,       0, "<Tearoff>" },
2274   { "/File/_New",        "<control>N", gtk_ifactory_cb,       0 },
2275   { "/File/_Open",       "<control>O", gtk_ifactory_cb,       0 },
2276   { "/File/_Save",       "<control>S", gtk_ifactory_cb,       0 },
2277   { "/File/Save _As...", NULL,         gtk_ifactory_cb,       0 },
2278   { "/File/sep1",        NULL,         gtk_ifactory_cb,       0, "<Separator>" },
2279   { "/File/_Quit",       "<control>Q", gtk_ifactory_cb,       0 },
2280
2281   { "/_Preferences",                    NULL, 0,               0, "<Branch>" },
2282   { "/_Preferences/_Color",             NULL, 0,               0, "<Branch>" },
2283   { "/_Preferences/Color/_Red",         NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
2284   { "/_Preferences/Color/_Green",       NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
2285   { "/_Preferences/Color/_Blue",        NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
2286   { "/_Preferences/_Shape",             NULL, 0,               0, "<Branch>" },
2287   { "/_Preferences/Shape/_Square",      NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
2288   { "/_Preferences/Shape/_Rectangle",   NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
2289   { "/_Preferences/Shape/_Oval",        NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
2290
2291   { "/_Help",            NULL,         0,                     0, "<LastBranch>" },
2292   { "/Help/_About",      NULL,         gtk_ifactory_cb,       0 },
2293 };
2294
2295 static int nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
2296
2297 static void
2298 create_item_factory (void)
2299 {
2300   static GtkWidget *window = NULL;
2301   
2302   if (!window)
2303     {
2304       GtkWidget *box1;
2305       GtkWidget *box2;
2306       GtkWidget *separator;
2307       GtkWidget *label;
2308       GtkWidget *button;
2309       GtkAccelGroup *accel_group;
2310       GtkItemFactory *item_factory;
2311       
2312       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2313       
2314       gtk_signal_connect (GTK_OBJECT (window), "destroy",
2315                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
2316                           &window);
2317       gtk_signal_connect (GTK_OBJECT (window), "delete-event",
2318                           GTK_SIGNAL_FUNC (gtk_true),
2319                           NULL);
2320       
2321       accel_group = gtk_accel_group_new ();
2322       item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);
2323       gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
2324       gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
2325       gtk_window_set_title (GTK_WINDOW (window), "Item Factory");
2326       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2327       
2328       box1 = gtk_vbox_new (FALSE, 0);
2329       gtk_container_add (GTK_CONTAINER (window), box1);
2330       
2331       gtk_box_pack_start (GTK_BOX (box1),
2332                           gtk_item_factory_get_widget (item_factory, "<main>"),
2333                           FALSE, FALSE, 0);
2334
2335       label = gtk_label_new ("Type\n<alt>\nto start");
2336       gtk_widget_set_usize (label, 200, 200);
2337       gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
2338       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
2339
2340
2341       separator = gtk_hseparator_new ();
2342       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2343
2344
2345       box2 = gtk_vbox_new (FALSE, 10);
2346       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2347       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2348
2349       button = gtk_button_new_with_label ("close");
2350       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2351                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2352                                  GTK_OBJECT (window));
2353       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2354       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2355       gtk_widget_grab_default (button);
2356
2357       gtk_widget_show_all (window);
2358     }
2359   else
2360     gtk_widget_destroy (window);
2361 }
2362
2363 /*
2364  * GtkScrolledWindow
2365  */
2366
2367 static void
2368 scrolled_windows_remove (GtkWidget *widget, GtkWidget *scrollwin)
2369 {
2370   static GtkWidget *parent = NULL;
2371   static GtkWidget *float_parent;
2372
2373   if (parent)
2374     {
2375       gtk_widget_reparent (scrollwin, parent);
2376       gtk_widget_destroy (float_parent);
2377       float_parent = NULL;
2378       parent = NULL;
2379     }
2380   else
2381     {
2382       parent = widget->parent;
2383       float_parent = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2384       gtk_widget_reparent (scrollwin, float_parent);
2385       gtk_widget_show (float_parent);
2386     }
2387 }
2388
2389 /*
2390  create_modal_window
2391  */
2392
2393 static gboolean
2394 cmw_destroy_cb(GtkWidget *widget)
2395 {
2396   /* This is needed to get out of gtk_main */
2397   gtk_main_quit ();
2398
2399   return FALSE;
2400 }
2401
2402 static void
2403 cmw_color (GtkWidget *widget, GtkWidget *parent)
2404 {
2405     GtkWidget *csd;
2406
2407     csd=gtk_color_selection_dialog_new ("This is a modal color selection dialog");
2408
2409     /* Set as modal */
2410     gtk_window_set_modal (GTK_WINDOW(csd),TRUE);
2411
2412     /* And mark it as a transient dialog */
2413     gtk_window_set_transient_for (GTK_WINDOW (csd), GTK_WINDOW (parent));
2414     
2415     gtk_signal_connect (GTK_OBJECT(csd), "destroy",
2416                         GTK_SIGNAL_FUNC(cmw_destroy_cb),NULL);
2417
2418     gtk_signal_connect_object (GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(csd)->ok_button),
2419                                "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
2420                                GTK_OBJECT (csd));
2421     gtk_signal_connect_object (GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(csd)->cancel_button),
2422                                "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
2423                                GTK_OBJECT (csd));
2424     
2425     /* wait until destroy calls gtk_main_quit */
2426     gtk_widget_show (csd);    
2427     gtk_main ();
2428 }
2429
2430 static void
2431 cmw_file (GtkWidget *widget, GtkWidget *parent)
2432 {
2433     GtkWidget *fs;
2434
2435     fs = gtk_file_selection_new("This is a modal file selection dialog");
2436
2437     /* Set as modal */
2438     gtk_window_set_modal (GTK_WINDOW(fs),TRUE);
2439
2440     /* And mark it as a transient dialog */
2441     gtk_window_set_transient_for (GTK_WINDOW (fs), GTK_WINDOW (parent));
2442
2443     gtk_signal_connect (GTK_OBJECT(fs), "destroy",
2444                         GTK_SIGNAL_FUNC(cmw_destroy_cb),NULL);
2445
2446     gtk_signal_connect_object (GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
2447                                "clicked",GTK_SIGNAL_FUNC(gtk_widget_destroy),
2448                                GTK_OBJECT (fs));
2449     gtk_signal_connect_object (GTK_OBJECT(GTK_FILE_SELECTION(fs)->cancel_button),
2450                                "clicked",GTK_SIGNAL_FUNC(gtk_widget_destroy),
2451                                GTK_OBJECT (fs));
2452     
2453     /* wait until destroy calls gtk_main_quit */
2454     gtk_widget_show (fs);
2455     
2456     gtk_main();
2457 }
2458
2459
2460 static void
2461 create_modal_window (void)
2462 {
2463   GtkWidget *window = NULL;
2464   GtkWidget *box1,*box2;
2465   GtkWidget *frame1;
2466   GtkWidget *btnColor,*btnFile,*btnClose;
2467
2468   /* Create modal window (Here you can use any window descendent )*/
2469   window=gtk_window_new (GTK_WINDOW_TOPLEVEL);
2470   gtk_window_set_title (GTK_WINDOW(window),"This window is modal");
2471
2472   /* Set window as modal */
2473   gtk_window_set_modal (GTK_WINDOW(window),TRUE);
2474
2475   /* Create widgets */
2476   box1 = gtk_vbox_new (FALSE,5);
2477    frame1 = gtk_frame_new ("Standard dialogs in modal form");
2478     box2 = gtk_vbox_new (TRUE,5);
2479      btnColor = gtk_button_new_with_label ("Color");
2480      btnFile = gtk_button_new_with_label ("File Selection");
2481      btnClose = gtk_button_new_with_label ("Close");
2482
2483   /* Init widgets */
2484   gtk_container_set_border_width (GTK_CONTAINER(box1),3);
2485   gtk_container_set_border_width (GTK_CONTAINER(box2),3);
2486     
2487   /* Pack widgets */
2488   gtk_container_add (GTK_CONTAINER (window), box1);
2489    gtk_box_pack_start (GTK_BOX (box1), frame1, TRUE, TRUE, 4);
2490     gtk_container_add (GTK_CONTAINER (frame1), box2);
2491      gtk_box_pack_start (GTK_BOX (box2), btnColor, FALSE, FALSE, 4);
2492      gtk_box_pack_start (GTK_BOX (box2), btnFile, FALSE, FALSE, 4);
2493    gtk_box_pack_start (GTK_BOX (box1), gtk_hseparator_new (), FALSE, FALSE, 4);
2494    gtk_box_pack_start (GTK_BOX (box1), btnClose, FALSE, FALSE, 4);
2495    
2496   /* connect signals */
2497   gtk_signal_connect_object (GTK_OBJECT (btnClose), "clicked",
2498                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
2499                              GTK_OBJECT (window));
2500
2501   gtk_signal_connect (GTK_OBJECT (window), "destroy",
2502                       GTK_SIGNAL_FUNC (cmw_destroy_cb),NULL);
2503   
2504   gtk_signal_connect (GTK_OBJECT (btnColor), "clicked",
2505                       GTK_SIGNAL_FUNC (cmw_color),window);
2506   gtk_signal_connect (GTK_OBJECT (btnFile), "clicked",
2507                       GTK_SIGNAL_FUNC (cmw_file),window);
2508
2509   /* Show widgets */
2510   gtk_widget_show_all (window);
2511
2512   /* wait until dialog get destroyed */
2513   gtk_main();
2514 }
2515
2516 /*
2517  * GtkScrolledWindow
2518  */
2519
2520 static void
2521 create_scrolled_windows (void)
2522 {
2523   static GtkWidget *window;
2524   GtkWidget *scrolled_window;
2525   GtkWidget *table;
2526   GtkWidget *button;
2527   char buffer[32];
2528   int i, j;
2529
2530   if (!window)
2531     {
2532       window = gtk_dialog_new ();
2533
2534       gtk_signal_connect (GTK_OBJECT (window), "destroy",
2535                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
2536                           &window);
2537
2538       gtk_window_set_title (GTK_WINDOW (window), "dialog");
2539       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2540
2541
2542       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
2543       gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
2544       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
2545                                       GTK_POLICY_AUTOMATIC,
2546                                       GTK_POLICY_AUTOMATIC);
2547       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
2548                           scrolled_window, TRUE, TRUE, 0);
2549       gtk_widget_show (scrolled_window);
2550
2551       table = gtk_table_new (20, 20, FALSE);
2552       gtk_table_set_row_spacings (GTK_TABLE (table), 10);
2553       gtk_table_set_col_spacings (GTK_TABLE (table), 10);
2554       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), table);
2555       gtk_container_set_focus_hadjustment (GTK_CONTAINER (table),
2556                                            gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
2557       gtk_container_set_focus_vadjustment (GTK_CONTAINER (table),
2558                                            gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
2559       gtk_widget_show (table);
2560
2561       for (i = 0; i < 20; i++)
2562         for (j = 0; j < 20; j++)
2563           {
2564             sprintf (buffer, "button (%d,%d)\n", i, j);
2565             button = gtk_toggle_button_new_with_label (buffer);
2566             gtk_table_attach_defaults (GTK_TABLE (table), button,
2567                                        i, i+1, j, j+1);
2568             gtk_widget_show (button);
2569           }
2570
2571
2572       button = gtk_button_new_with_label ("close");
2573       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2574                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2575                                  GTK_OBJECT (window));
2576       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2577       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
2578                           button, TRUE, TRUE, 0);
2579       gtk_widget_grab_default (button);
2580       gtk_widget_show (button);
2581
2582       button = gtk_button_new_with_label ("remove");
2583       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2584                                  GTK_SIGNAL_FUNC(scrolled_windows_remove),
2585                                  GTK_OBJECT (scrolled_window));
2586       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2587       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
2588                           button, TRUE, TRUE, 0);
2589       gtk_widget_grab_default (button);
2590       gtk_widget_show (button);
2591
2592       gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);
2593     }
2594
2595   if (!GTK_WIDGET_VISIBLE (window))
2596     gtk_widget_show (window);
2597   else
2598     gtk_widget_destroy (window);
2599 }
2600
2601 /*
2602  * GtkEntry
2603  */
2604
2605 static void
2606 entry_toggle_editable (GtkWidget *checkbutton,
2607                        GtkWidget *entry)
2608 {
2609    gtk_entry_set_editable(GTK_ENTRY(entry),
2610                           GTK_TOGGLE_BUTTON(checkbutton)->active);
2611 }
2612
2613 static void
2614 entry_toggle_sensitive (GtkWidget *checkbutton,
2615                         GtkWidget *entry)
2616 {
2617    gtk_widget_set_sensitive (entry, GTK_TOGGLE_BUTTON(checkbutton)->active);
2618 }
2619
2620 static void
2621 entry_toggle_visibility (GtkWidget *checkbutton,
2622                         GtkWidget *entry)
2623 {
2624    gtk_entry_set_visibility(GTK_ENTRY(entry),
2625                          GTK_TOGGLE_BUTTON(checkbutton)->active);
2626 }
2627
2628 static void
2629 create_entry (void)
2630 {
2631   static GtkWidget *window = NULL;
2632   GtkWidget *box1;
2633   GtkWidget *box2;
2634   GtkWidget *editable_check;
2635   GtkWidget *sensitive_check;
2636   GtkWidget *entry, *cb;
2637   GtkWidget *button;
2638   GtkWidget *separator;
2639   GList *cbitems = NULL;
2640
2641   if (!window)
2642     {
2643       cbitems = g_list_append(cbitems, "item0");
2644       cbitems = g_list_append(cbitems, "item1 item1");
2645       cbitems = g_list_append(cbitems, "item2 item2 item2");
2646       cbitems = g_list_append(cbitems, "item3 item3 item3 item3");
2647       cbitems = g_list_append(cbitems, "item4 item4 item4 item4 item4");
2648       cbitems = g_list_append(cbitems, "item5 item5 item5 item5 item5 item5");
2649       cbitems = g_list_append(cbitems, "item6 item6 item6 item6 item6");
2650       cbitems = g_list_append(cbitems, "item7 item7 item7 item7");
2651       cbitems = g_list_append(cbitems, "item8 item8 item8");
2652       cbitems = g_list_append(cbitems, "item9 item9");
2653
2654       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2655
2656       gtk_signal_connect (GTK_OBJECT (window), "destroy",
2657                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
2658                           &window);
2659
2660       gtk_window_set_title (GTK_WINDOW (window), "entry");
2661       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2662
2663
2664       box1 = gtk_vbox_new (FALSE, 0);
2665       gtk_container_add (GTK_CONTAINER (window), box1);
2666       gtk_widget_show (box1);
2667
2668
2669       box2 = gtk_vbox_new (FALSE, 10);
2670       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2671       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2672       gtk_widget_show (box2);
2673
2674       entry = gtk_entry_new ();
2675       gtk_entry_set_text (GTK_ENTRY (entry), "hello world");
2676       gtk_editable_select_region (GTK_EDITABLE (entry), 0, 5);
2677       gtk_box_pack_start (GTK_BOX (box2), entry, TRUE, TRUE, 0);
2678       gtk_widget_show (entry);
2679
2680       cb = gtk_combo_new ();
2681       gtk_combo_set_popdown_strings (GTK_COMBO (cb), cbitems);
2682       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO(cb)->entry), "hello world");
2683       gtk_editable_select_region (GTK_EDITABLE (GTK_COMBO(cb)->entry),
2684                                   0, -1);
2685       gtk_box_pack_start (GTK_BOX (box2), cb, TRUE, TRUE, 0);
2686       gtk_widget_show (cb);
2687
2688       editable_check = gtk_check_button_new_with_label("Editable");
2689       gtk_box_pack_start (GTK_BOX (box2), editable_check, FALSE, TRUE, 0);
2690       gtk_signal_connect (GTK_OBJECT(editable_check), "toggled",
2691                           GTK_SIGNAL_FUNC(entry_toggle_editable), entry);
2692       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(editable_check), TRUE);
2693       gtk_widget_show (editable_check);
2694
2695       editable_check = gtk_check_button_new_with_label("Visible");
2696       gtk_box_pack_start (GTK_BOX (box2), editable_check, FALSE, TRUE, 0);
2697       gtk_signal_connect (GTK_OBJECT(editable_check), "toggled",
2698                           GTK_SIGNAL_FUNC(entry_toggle_visibility), entry);
2699       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(editable_check), TRUE);
2700       gtk_widget_show (editable_check);
2701
2702       sensitive_check = gtk_check_button_new_with_label("Sensitive");
2703       gtk_box_pack_start (GTK_BOX (box2), sensitive_check, FALSE, TRUE, 0);
2704       gtk_signal_connect (GTK_OBJECT(sensitive_check), "toggled",
2705                           GTK_SIGNAL_FUNC(entry_toggle_sensitive), entry);
2706       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(sensitive_check), TRUE);
2707       gtk_widget_show (sensitive_check);
2708
2709       separator = gtk_hseparator_new ();
2710       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2711       gtk_widget_show (separator);
2712
2713
2714       box2 = gtk_vbox_new (FALSE, 10);
2715       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2716       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2717       gtk_widget_show (box2);
2718
2719
2720       button = gtk_button_new_with_label ("close");
2721       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2722                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2723                                  GTK_OBJECT (window));
2724       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2725       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2726       gtk_widget_grab_default (button);
2727       gtk_widget_show (button);
2728     }
2729
2730   if (!GTK_WIDGET_VISIBLE (window))
2731     gtk_widget_show (window);
2732   else
2733     gtk_widget_destroy (window);
2734 }
2735
2736 /*
2737  * GtkSpinButton
2738  */
2739
2740 static GtkWidget *spinner1;
2741
2742 static void
2743 toggle_snap (GtkWidget *widget, GtkSpinButton *spin)
2744 {
2745   gtk_spin_button_set_snap_to_ticks (spin, GTK_TOGGLE_BUTTON (widget)->active);
2746 }
2747
2748 static void
2749 toggle_numeric (GtkWidget *widget, GtkSpinButton *spin)
2750 {
2751   gtk_spin_button_set_numeric (spin, GTK_TOGGLE_BUTTON (widget)->active);
2752 }
2753
2754 static void
2755 change_digits (GtkWidget *widget, GtkSpinButton *spin)
2756 {
2757   gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinner1),
2758                               gtk_spin_button_get_value_as_int (spin));
2759 }
2760
2761 static void
2762 get_value (GtkWidget *widget, gpointer data)
2763 {
2764   gchar buf[32];
2765   GtkLabel *label;
2766   GtkSpinButton *spin;
2767
2768   spin = GTK_SPIN_BUTTON (spinner1);
2769   label = GTK_LABEL (gtk_object_get_user_data (GTK_OBJECT (widget)));
2770   if (GPOINTER_TO_INT (data) == 1)
2771     sprintf (buf, "%d", gtk_spin_button_get_value_as_int (spin));
2772   else
2773     sprintf (buf, "%0.*f", spin->digits,
2774              gtk_spin_button_get_value_as_float (spin));
2775   gtk_label_set (label, buf);
2776 }
2777
2778 static void
2779 create_spins (void)
2780 {
2781   static GtkWidget *window = NULL;
2782   GtkWidget *frame;
2783   GtkWidget *hbox;
2784   GtkWidget *main_vbox;
2785   GtkWidget *vbox;
2786   GtkWidget *vbox2;
2787   GtkWidget *spinner2;
2788   GtkWidget *spinner;
2789   GtkWidget *button;
2790   GtkWidget *label;
2791   GtkWidget *val_label;
2792   GtkAdjustment *adj;
2793
2794   if (!window)
2795     {
2796       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2797       
2798       gtk_signal_connect (GTK_OBJECT (window), "destroy",
2799                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
2800                           &window);
2801       
2802       gtk_window_set_title (GTK_WINDOW (window), "GtkSpinButton");
2803       
2804       main_vbox = gtk_vbox_new (FALSE, 5);
2805       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 10);
2806       gtk_container_add (GTK_CONTAINER (window), main_vbox);
2807       
2808       frame = gtk_frame_new ("Not accelerated");
2809       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
2810       
2811       vbox = gtk_vbox_new (FALSE, 0);
2812       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
2813       gtk_container_add (GTK_CONTAINER (frame), vbox);
2814       
2815       /* Day, month, year spinners */
2816       
2817       hbox = gtk_hbox_new (FALSE, 0);
2818       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
2819       
2820       vbox2 = gtk_vbox_new (FALSE, 0);
2821       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
2822       
2823       label = gtk_label_new ("Day :");
2824       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2825       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
2826       
2827       adj = (GtkAdjustment *) gtk_adjustment_new (1.0, 1.0, 31.0, 1.0,
2828                                                   5.0, 0.0);
2829       spinner = gtk_spin_button_new (adj, 0, 0);
2830       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
2831       gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinner),
2832                                        GTK_SHADOW_OUT);
2833       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
2834
2835       vbox2 = gtk_vbox_new (FALSE, 0);
2836       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
2837       
2838       label = gtk_label_new ("Month :");
2839       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2840       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
2841       
2842       adj = (GtkAdjustment *) gtk_adjustment_new (1.0, 1.0, 12.0, 1.0,
2843                                                   5.0, 0.0);
2844       spinner = gtk_spin_button_new (adj, 0, 0);
2845       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
2846       gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinner),
2847                                        GTK_SHADOW_ETCHED_IN);
2848       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
2849       
2850       vbox2 = gtk_vbox_new (FALSE, 0);
2851       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
2852
2853       label = gtk_label_new ("Year :");
2854       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2855       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
2856
2857       adj = (GtkAdjustment *) gtk_adjustment_new (1998.0, 0.0, 2100.0, 
2858                                                   1.0, 100.0, 0.0);
2859       spinner = gtk_spin_button_new (adj, 0, 0);
2860       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
2861       gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinner),
2862                                        GTK_SHADOW_IN);
2863       gtk_widget_set_usize (spinner, 55, 0);
2864       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
2865
2866       frame = gtk_frame_new ("Accelerated");
2867       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
2868   
2869       vbox = gtk_vbox_new (FALSE, 0);
2870       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
2871       gtk_container_add (GTK_CONTAINER (frame), vbox);
2872       
2873       hbox = gtk_hbox_new (FALSE, 0);
2874       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
2875       
2876       vbox2 = gtk_vbox_new (FALSE, 0);
2877       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
2878       
2879       label = gtk_label_new ("Value :");
2880       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2881       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
2882
2883       adj = (GtkAdjustment *) gtk_adjustment_new (0.0, -10000.0, 10000.0,
2884                                                   0.5, 100.0, 0.0);
2885       spinner1 = gtk_spin_button_new (adj, 1.0, 2);
2886       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner1), TRUE);
2887       gtk_widget_set_usize (spinner1, 100, 0);
2888       gtk_box_pack_start (GTK_BOX (vbox2), spinner1, FALSE, TRUE, 0);
2889
2890       vbox2 = gtk_vbox_new (FALSE, 0);
2891       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
2892
2893       label = gtk_label_new ("Digits :");
2894       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2895       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
2896
2897       adj = (GtkAdjustment *) gtk_adjustment_new (2, 1, 5, 1, 1, 0);
2898       spinner2 = gtk_spin_button_new (adj, 0.0, 0);
2899       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner2), TRUE);
2900       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
2901                           GTK_SIGNAL_FUNC (change_digits),
2902                           (gpointer) spinner2);
2903       gtk_box_pack_start (GTK_BOX (vbox2), spinner2, FALSE, TRUE, 0);
2904
2905       hbox = gtk_hbox_new (FALSE, 0);
2906       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
2907
2908       button = gtk_check_button_new_with_label ("Snap to 0.5-ticks");
2909       gtk_signal_connect (GTK_OBJECT (button), "clicked",
2910                           GTK_SIGNAL_FUNC (toggle_snap),
2911                           spinner1);
2912       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
2913       gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (button), TRUE);
2914
2915       button = gtk_check_button_new_with_label ("Numeric only input mode");
2916       gtk_signal_connect (GTK_OBJECT (button), "clicked",
2917                           GTK_SIGNAL_FUNC (toggle_numeric),
2918                           spinner1);
2919       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
2920       gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (button), TRUE);
2921
2922       val_label = gtk_label_new ("");
2923
2924       hbox = gtk_hbox_new (FALSE, 0);
2925       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
2926
2927       button = gtk_button_new_with_label ("Value as Int");
2928       gtk_object_set_user_data (GTK_OBJECT (button), val_label);
2929       gtk_signal_connect (GTK_OBJECT (button), "clicked",
2930                           GTK_SIGNAL_FUNC (get_value),
2931                           GINT_TO_POINTER (1));
2932       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
2933
2934       button = gtk_button_new_with_label ("Value as Float");
2935       gtk_object_set_user_data (GTK_OBJECT (button), val_label);
2936       gtk_signal_connect (GTK_OBJECT (button), "clicked",
2937                           GTK_SIGNAL_FUNC (get_value),
2938                           GINT_TO_POINTER (2));
2939       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
2940
2941       gtk_box_pack_start (GTK_BOX (vbox), val_label, TRUE, TRUE, 0);
2942       gtk_label_set (GTK_LABEL (val_label), "0");
2943
2944       hbox = gtk_hbox_new (FALSE, 0);
2945       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
2946   
2947       button = gtk_button_new_with_label ("Close");
2948       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2949                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
2950                                  GTK_OBJECT (window));
2951       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
2952     }
2953
2954   if (!GTK_WIDGET_VISIBLE (window))
2955     gtk_widget_show_all (window);
2956   else
2957     gtk_widget_destroy (window);
2958 }
2959
2960 /*
2961  * Cursors
2962  */
2963
2964 static gint
2965 cursor_expose_event (GtkWidget *widget,
2966                      GdkEvent  *event,
2967                      gpointer   user_data)
2968 {
2969   GtkDrawingArea *darea;
2970   GdkDrawable *drawable;
2971   GdkGC *black_gc;
2972   GdkGC *gray_gc;
2973   GdkGC *white_gc;
2974   guint max_width;
2975   guint max_height;
2976
2977   g_return_val_if_fail (widget != NULL, TRUE);
2978   g_return_val_if_fail (GTK_IS_DRAWING_AREA (widget), TRUE);
2979
2980   darea = GTK_DRAWING_AREA (widget);
2981   drawable = widget->window;
2982   white_gc = widget->style->white_gc;
2983   gray_gc = widget->style->bg_gc[GTK_STATE_NORMAL];
2984   black_gc = widget->style->black_gc;
2985   max_width = widget->allocation.width;
2986   max_height = widget->allocation.height;
2987
2988   gdk_draw_rectangle (drawable, white_gc,
2989                       TRUE,
2990                       0,
2991                       0,
2992                       max_width,
2993                       max_height / 2);
2994
2995   gdk_draw_rectangle (drawable, black_gc,
2996                       TRUE,
2997                       0,
2998                       max_height / 2,
2999                       max_width,
3000                       max_height / 2);
3001
3002   gdk_draw_rectangle (drawable, gray_gc,
3003                       TRUE,
3004                       max_width / 3,
3005                       max_height / 3,
3006                       max_width / 3,
3007                       max_height / 3);
3008
3009   return TRUE;
3010 }
3011
3012 static void
3013 set_cursor (GtkWidget *spinner,
3014             GtkWidget *widget)
3015 {
3016   guint c;
3017   GdkCursor *cursor;
3018   GtkWidget *label;
3019   GtkFlagValue *vals;
3020
3021   c = CLAMP (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinner)), 0, 152);
3022   c &= 0xfe;
3023
3024   label = gtk_object_get_user_data (GTK_OBJECT (spinner));
3025   vals = gtk_type_enum_get_values (GTK_TYPE_GDK_CURSOR_TYPE);
3026   while (vals && vals->value != c)
3027     vals++;
3028   if (vals)
3029     gtk_label_set (GTK_LABEL (label), vals->value_nick);
3030   else
3031     gtk_label_set (GTK_LABEL (label), "<unknown>");
3032
3033   cursor = gdk_cursor_new (c);
3034   gdk_window_set_cursor (widget->window, cursor);
3035   gdk_cursor_destroy (cursor);
3036 }
3037
3038 static gint
3039 cursor_event (GtkWidget          *widget,
3040               GdkEvent           *event,
3041               GtkSpinButton      *spinner)
3042 {
3043   if ((event->type == GDK_BUTTON_PRESS) &&
3044       ((event->button.button == 1) ||
3045        (event->button.button == 3)))
3046     {
3047       gtk_spin_button_spin (spinner, event->button.button == 1 ?
3048                             GTK_SPIN_STEP_FORWARD : GTK_SPIN_STEP_BACKWARD, 0);
3049       return TRUE;
3050     }
3051
3052   return FALSE;
3053 }
3054
3055 static void
3056 create_cursors (void)
3057 {
3058   static GtkWidget *window = NULL;
3059   GtkWidget *frame;
3060   GtkWidget *hbox;
3061   GtkWidget *main_vbox;
3062   GtkWidget *vbox;
3063   GtkWidget *darea;
3064   GtkWidget *spinner;
3065   GtkWidget *button;
3066   GtkWidget *label;
3067   GtkWidget *any;
3068   GtkAdjustment *adj;
3069
3070   if (!window)
3071     {
3072       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3073       
3074       gtk_signal_connect (GTK_OBJECT (window), "destroy",
3075                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
3076                           &window);
3077       
3078       gtk_window_set_title (GTK_WINDOW (window), "Cursors");
3079       
3080       main_vbox = gtk_vbox_new (FALSE, 5);
3081       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
3082       gtk_container_add (GTK_CONTAINER (window), main_vbox);
3083
3084       vbox =
3085         gtk_widget_new (gtk_vbox_get_type (),
3086                         "GtkBox::homogeneous", FALSE,
3087                         "GtkBox::spacing", 5,
3088                         "GtkContainer::border_width", 10,
3089                         "GtkWidget::parent", main_vbox,
3090                         "GtkWidget::visible", TRUE,
3091                         NULL);
3092
3093       hbox = gtk_hbox_new (FALSE, 0);
3094       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
3095       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
3096       
3097       label = gtk_label_new ("Cursor Value : ");
3098       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
3099       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
3100       
3101       adj = (GtkAdjustment *) gtk_adjustment_new (0,
3102                                                   0, 152,
3103                                                   2,
3104                                                   10, 0);
3105       spinner = gtk_spin_button_new (adj, 0, 0);
3106       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0);
3107
3108       frame =
3109         gtk_widget_new (gtk_frame_get_type (),
3110                         "GtkFrame::shadow", GTK_SHADOW_ETCHED_IN,
3111                         "GtkFrame::label_xalign", 0.5,
3112                         "GtkFrame::label", "Cursor Area",
3113                         "GtkContainer::border_width", 10,
3114                         "GtkWidget::parent", vbox,
3115                         "GtkWidget::visible", TRUE,
3116                         NULL);
3117
3118       darea = gtk_drawing_area_new ();
3119       gtk_widget_set_usize (darea, 80, 80);
3120       gtk_container_add (GTK_CONTAINER (frame), darea);
3121       gtk_signal_connect (GTK_OBJECT (darea),
3122                           "expose_event",
3123                           GTK_SIGNAL_FUNC (cursor_expose_event),
3124                           NULL);
3125       gtk_widget_set_events (darea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
3126       gtk_signal_connect (GTK_OBJECT (darea),
3127                           "button_press_event",
3128                           GTK_SIGNAL_FUNC (cursor_event),
3129                           spinner);
3130       gtk_widget_show (darea);
3131
3132       gtk_signal_connect (GTK_OBJECT (spinner), "changed",
3133                           GTK_SIGNAL_FUNC (set_cursor),
3134                           darea);
3135
3136       label = gtk_widget_new (GTK_TYPE_LABEL,
3137                               "visible", TRUE,
3138                               "label", "XXX",
3139                               "parent", vbox,
3140                               NULL);
3141       gtk_container_child_set (GTK_CONTAINER (vbox), label,
3142                                "expand", FALSE,
3143                                NULL);
3144       gtk_object_set_user_data (GTK_OBJECT (spinner), label);
3145
3146       any =
3147         gtk_widget_new (gtk_hseparator_get_type (),
3148                         "GtkWidget::visible", TRUE,
3149                         NULL);
3150       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
3151   
3152       hbox = gtk_hbox_new (FALSE, 0);
3153       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
3154       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
3155
3156       button = gtk_button_new_with_label ("Close");
3157       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
3158                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
3159                                  GTK_OBJECT (window));
3160       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
3161
3162       gtk_widget_show_all (window);
3163
3164       set_cursor (spinner, darea);
3165     }
3166   else
3167     gtk_widget_destroy (window);
3168 }
3169
3170 /*
3171  * GtkList
3172  */
3173
3174 static void
3175 list_add (GtkWidget *widget,
3176           GtkWidget *list)
3177 {
3178   static int i = 1;
3179   gchar buffer[64];
3180   GtkWidget *list_item;
3181   GtkContainer *container;
3182
3183   container = GTK_CONTAINER (list);
3184
3185   sprintf (buffer, "added item %d", i++);
3186   list_item = gtk_list_item_new_with_label (buffer);
3187   gtk_widget_show (list_item);
3188
3189   gtk_container_add (container, list_item);
3190 }
3191
3192 static void
3193 list_remove (GtkWidget *widget,
3194              GtkWidget *list)
3195 {
3196   GList *tmp_list;
3197   GList *clear_list;
3198
3199   tmp_list = GTK_LIST (list)->selection;
3200   clear_list = NULL;
3201
3202   while (tmp_list)
3203     {
3204       clear_list = g_list_prepend (clear_list, tmp_list->data);
3205       tmp_list = tmp_list->next;
3206     }
3207
3208   clear_list = g_list_reverse (clear_list);
3209
3210   gtk_list_remove_items (GTK_LIST (list), clear_list);
3211
3212   g_list_free (clear_list);
3213 }
3214
3215 static void
3216 list_clear (GtkWidget *widget,
3217             GtkWidget *list)
3218 {
3219   gtk_list_clear_items (GTK_LIST (list), 0, -1);
3220 }
3221
3222 static void
3223 list_undo_selection (GtkWidget *widget,
3224                      GtkWidget *list)
3225 {
3226   gtk_list_undo_selection (GTK_LIST (list));
3227 }
3228
3229 #define RADIOMENUTOGGLED(_rmi_, __i) { \
3230   GSList * __g; \
3231   __i = 0; \
3232   __g = gtk_radio_menu_item_group(_rmi_); \
3233   while( __g  && !((GtkCheckMenuItem *)(__g->data))->active) { \
3234     __g = __g->next; \
3235     __i++; \
3236   }\
3237 }
3238
3239 static GtkWidget *list_omenu;
3240
3241 static void 
3242 list_toggle_sel_mode (GtkWidget *widget, GtkList *list)
3243 {
3244   gint i;
3245
3246   if (!GTK_WIDGET_MAPPED (widget))
3247     return;
3248
3249   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
3250                     (((GtkOptionMenu *)list_omenu)->menu_item), i);
3251
3252   gtk_list_set_selection_mode (list, (GtkSelectionMode) (3-i));
3253 }
3254
3255 static void
3256 create_list (void)
3257 {
3258   static GtkWidget *window = NULL;
3259   GtkWidget *box1;
3260   GtkWidget *box2;
3261   GtkWidget *hbox;
3262   GtkWidget *label;
3263   GtkWidget *scrolled_win;
3264   GtkWidget *list;
3265   GtkWidget *button;
3266   GtkWidget *separator;
3267   GtkWidget *menu;
3268   GtkWidget *menu_item;
3269   GSList *group;
3270   FILE *infile;
3271
3272   if (!window)
3273     {
3274       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3275
3276       gtk_signal_connect (GTK_OBJECT (window), "destroy",
3277                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
3278                           &window);
3279
3280       gtk_window_set_title (GTK_WINDOW (window), "list");
3281       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3282
3283       box1 = gtk_vbox_new (FALSE, 0);
3284       gtk_container_add (GTK_CONTAINER (window), box1);
3285
3286       box2 = gtk_vbox_new (FALSE, 10);
3287       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3288       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3289
3290       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
3291       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
3292                                       GTK_POLICY_AUTOMATIC,
3293                                       GTK_POLICY_AUTOMATIC);
3294       gtk_box_pack_start (GTK_BOX (box2), scrolled_win, TRUE, TRUE, 0);
3295       gtk_widget_set_usize (scrolled_win, -1, 300);
3296
3297       list = gtk_list_new ();
3298       gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_EXTENDED);
3299       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
3300       gtk_container_set_focus_vadjustment
3301         (GTK_CONTAINER (list),
3302          gtk_scrolled_window_get_vadjustment
3303          (GTK_SCROLLED_WINDOW (scrolled_win)));
3304       gtk_container_set_focus_hadjustment
3305         (GTK_CONTAINER (list),
3306          gtk_scrolled_window_get_hadjustment
3307          (GTK_SCROLLED_WINDOW (scrolled_win)));
3308
3309       if ((infile = fopen("gtkenums.h", "r")))
3310         {
3311           char buffer[256];
3312           char *pos;
3313           GtkWidget *item;
3314
3315           while (fgets (buffer, 256, infile))
3316             {
3317               if ((pos = strchr (buffer, '\n')))
3318                 *pos = 0;
3319               item = gtk_list_item_new_with_label (buffer);
3320               gtk_container_add (GTK_CONTAINER (list), item);
3321             }
3322           
3323           fclose (infile);
3324         }
3325
3326       hbox = gtk_hbox_new (TRUE, 10);
3327       gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, TRUE, 0);
3328
3329       button = gtk_button_new_with_label ("Undo Selection");
3330       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3331                           GTK_SIGNAL_FUNC(list_undo_selection),
3332                           list);
3333       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
3334
3335       button = gtk_button_new_with_label ("Remove Selection");
3336       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3337                           GTK_SIGNAL_FUNC (list_remove),
3338                           list);
3339       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
3340
3341       button = gtk_button_new_with_label ("Clear List");
3342       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3343                           GTK_SIGNAL_FUNC (list_clear),
3344                           list);
3345       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
3346
3347       hbox = gtk_hbox_new (FALSE, 10);
3348       gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, TRUE, 0);
3349
3350       button = gtk_button_new_with_label ("Insert Row");
3351       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3352                           GTK_SIGNAL_FUNC (list_add),
3353                           list);
3354       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
3355
3356       label = gtk_label_new ("Selection Mode :");
3357       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3358                           GTK_SIGNAL_FUNC(list_remove),
3359                           list);
3360       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
3361
3362       list_omenu = gtk_option_menu_new ();
3363       menu = gtk_menu_new ();
3364       group = NULL;
3365       
3366       menu_item = gtk_radio_menu_item_new_with_label (group, "Single");
3367       gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
3368                           GTK_SIGNAL_FUNC (list_toggle_sel_mode), list);
3369       group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
3370       gtk_menu_append (GTK_MENU (menu), menu_item);
3371       gtk_widget_show (menu_item);
3372       
3373       menu_item = gtk_radio_menu_item_new_with_label (group, "Browse");
3374       gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
3375                           GTK_SIGNAL_FUNC (list_toggle_sel_mode), list);
3376       group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
3377       gtk_menu_append (GTK_MENU (menu), menu_item);
3378       gtk_widget_show (menu_item);
3379       
3380       menu_item = gtk_radio_menu_item_new_with_label (group, "Multiple");
3381       gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
3382                       GTK_SIGNAL_FUNC (list_toggle_sel_mode), list);
3383       group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
3384       gtk_menu_append (GTK_MENU (menu), menu_item);
3385       gtk_widget_show (menu_item);
3386       
3387       menu_item = gtk_radio_menu_item_new_with_label (group, "Extended");
3388       gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
3389                           GTK_SIGNAL_FUNC (list_toggle_sel_mode), list);
3390       group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
3391       gtk_menu_append (GTK_MENU (menu), menu_item);
3392       gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
3393       gtk_widget_show (menu_item);
3394       
3395       gtk_option_menu_set_menu (GTK_OPTION_MENU (list_omenu), menu);
3396       gtk_box_pack_start (GTK_BOX (hbox), list_omenu, FALSE, TRUE, 0);
3397       
3398       gtk_option_menu_set_history (GTK_OPTION_MENU (list_omenu), 3);
3399
3400       separator = gtk_hseparator_new ();
3401       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3402
3403
3404       box2 = gtk_vbox_new (FALSE, 10);
3405       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3406       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3407
3408       button = gtk_button_new_with_label ("close");
3409       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
3410                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
3411                                  GTK_OBJECT (window));
3412       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3413
3414       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3415       gtk_widget_grab_default (button);
3416     }
3417
3418   if (!GTK_WIDGET_VISIBLE (window))
3419     gtk_widget_show_all (window);
3420   else
3421     gtk_widget_destroy (window);
3422 }
3423
3424 /*
3425  * GtkCList
3426  */
3427
3428 static char * book_open_xpm[] = {
3429 "16 16 4 1",
3430 "       c None s None",
3431 ".      c black",
3432 "X      c #808080",
3433 "o      c white",
3434 "                ",
3435 "  ..            ",
3436 " .Xo.    ...    ",
3437 " .Xoo. ..oo.    ",
3438 " .Xooo.Xooo...  ",
3439 " .Xooo.oooo.X.  ",
3440 " .Xooo.Xooo.X.  ",
3441 " .Xooo.oooo.X.  ",
3442 " .Xooo.Xooo.X.  ",
3443 " .Xooo.oooo.X.  ",
3444 "  .Xoo.Xoo..X.  ",
3445 "   .Xo.o..ooX.  ",
3446 "    .X..XXXXX.  ",
3447 "    ..X.......  ",
3448 "     ..         ",
3449 "                "};
3450
3451 static char * book_closed_xpm[] = {
3452 "16 16 6 1",
3453 "       c None s None",
3454 ".      c black",
3455 "X      c red",
3456 "o      c yellow",
3457 "O      c #808080",
3458 "#      c white",
3459 "                ",
3460 "       ..       ",
3461 "     ..XX.      ",
3462 "   ..XXXXX.     ",
3463 " ..XXXXXXXX.    ",
3464 ".ooXXXXXXXXX.   ",
3465 "..ooXXXXXXXXX.  ",
3466 ".X.ooXXXXXXXXX. ",
3467 ".XX.ooXXXXXX..  ",
3468 " .XX.ooXXX..#O  ",
3469 "  .XX.oo..##OO. ",
3470 "   .XX..##OO..  ",
3471 "    .X.#OO..    ",
3472 "     ..O..      ",
3473 "      ..        ",
3474 "                "};
3475
3476 static char * mini_page_xpm[] = {
3477 "16 16 4 1",
3478 "       c None s None",
3479 ".      c black",
3480 "X      c white",
3481 "o      c #808080",
3482 "                ",
3483 "   .......      ",
3484 "   .XXXXX..     ",
3485 "   .XoooX.X.    ",
3486 "   .XXXXX....   ",
3487 "   .XooooXoo.o  ",
3488 "   .XXXXXXXX.o  ",
3489 "   .XooooooX.o  ",
3490 "   .XXXXXXXX.o  ",
3491 "   .XooooooX.o  ",
3492 "   .XXXXXXXX.o  ",
3493 "   .XooooooX.o  ",
3494 "   .XXXXXXXX.o  ",
3495 "   ..........o  ",
3496 "    oooooooooo  ",
3497 "                "};
3498
3499 static char * gtk_mini_xpm[] = {
3500 "15 20 17 1",
3501 "       c None",
3502 ".      c #14121F",
3503 "+      c #278828",
3504 "@      c #9B3334",
3505 "#      c #284C72",
3506 "$      c #24692A",
3507 "%      c #69282E",
3508 "&      c #37C539",
3509 "*      c #1D2F4D",
3510 "=      c #6D7076",
3511 "-      c #7D8482",
3512 ";      c #E24A49",
3513 ">      c #515357",
3514 ",      c #9B9C9B",
3515 "'      c #2FA232",
3516 ")      c #3CE23D",
3517 "!      c #3B6CCB",
3518 "               ",
3519 "      ***>     ",
3520 "    >.*!!!*    ",
3521 "   ***....#*=  ",
3522 "  *!*.!!!**!!# ",
3523 " .!!#*!#*!!!!# ",
3524 " @%#!.##.*!!$& ",
3525 " @;%*!*.#!#')) ",
3526 " @;;@%!!*$&)'' ",
3527 " @%.%@%$'&)$+' ",
3528 " @;...@$'*'*)+ ",
3529 " @;%..@$+*.')$ ",
3530 " @;%%;;$+..$)# ",
3531 " @;%%;@$$$'.$# ",
3532 " %;@@;;$$+))&* ",
3533 "  %;;;@+$&)&*  ",
3534 "   %;;@'))+>   ",
3535 "    %;@'&#     ",
3536 "     >%$$      ",
3537 "      >=       "};
3538
3539 #define TESTGTK_CLIST_COLUMNS 20
3540 static gint clist_rows = 0;
3541 static GtkWidget *clist_omenu;
3542
3543 static void
3544 add1000_clist (GtkWidget *widget, gpointer data)
3545 {
3546   gint i, row;
3547   char text[TESTGTK_CLIST_COLUMNS][50];
3548   char *texts[TESTGTK_CLIST_COLUMNS];
3549   GdkBitmap *mask;
3550   GdkPixmap *pixmap;
3551   GtkCList  *clist;
3552
3553   clist = GTK_CLIST (data);
3554
3555   pixmap = gdk_pixmap_create_from_xpm_d (clist->clist_window,
3556                                          &mask, 
3557                                          &GTK_WIDGET (data)->style->white,
3558                                          gtk_mini_xpm);
3559
3560   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
3561     {
3562       texts[i] = text[i];
3563       sprintf (text[i], "Column %d", i);
3564     }
3565   
3566   texts[3] = NULL;
3567   sprintf (text[1], "Right");
3568   sprintf (text[2], "Center");
3569   
3570   gtk_clist_freeze (GTK_CLIST (data));
3571   for (i = 0; i < 1000; i++)
3572     {
3573       sprintf (text[0], "CListRow %d", rand() % 10000);
3574       row = gtk_clist_append (clist, texts);
3575       gtk_clist_set_pixtext (clist, row, 3, "gtk+", 5, pixmap, mask);
3576     }
3577
3578   gtk_clist_thaw (GTK_CLIST (data));
3579
3580   gdk_pixmap_unref (pixmap);
3581   gdk_bitmap_unref (mask);
3582 }
3583
3584 static void
3585 add10000_clist (GtkWidget *widget, gpointer data)
3586 {
3587   gint i;
3588   char text[TESTGTK_CLIST_COLUMNS][50];
3589   char *texts[TESTGTK_CLIST_COLUMNS];
3590
3591   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
3592     {
3593       texts[i] = text[i];
3594       sprintf (text[i], "Column %d", i);
3595     }
3596   
3597   sprintf (text[1], "Right");
3598   sprintf (text[2], "Center");
3599   
3600   gtk_clist_freeze (GTK_CLIST (data));
3601   for (i = 0; i < 10000; i++)
3602     {
3603       sprintf (text[0], "CListRow %d", rand() % 10000);
3604       gtk_clist_append (GTK_CLIST (data), texts);
3605     }
3606   gtk_clist_thaw (GTK_CLIST (data));
3607 }
3608
3609 void
3610 clear_clist (GtkWidget *widget, gpointer data)
3611 {
3612   gtk_clist_clear (GTK_CLIST (data));
3613   clist_rows = 0;
3614 }
3615
3616 void
3617 remove_row_clist (GtkWidget *widget, gpointer data)
3618 {
3619   gtk_clist_remove (GTK_CLIST (data), GTK_CLIST (data)->focus_row);
3620   clist_rows--;
3621 }
3622
3623 void
3624 show_titles_clist (GtkWidget *widget, gpointer data)
3625 {
3626   gtk_clist_column_titles_show (GTK_CLIST (data));
3627 }
3628
3629 void
3630 hide_titles_clist (GtkWidget *widget, gpointer data)
3631 {
3632   gtk_clist_column_titles_hide (GTK_CLIST (data));
3633 }
3634
3635 void
3636 select_clist (GtkWidget *widget,
3637               gint row, 
3638               gint column, 
3639               GdkEventButton * bevent,
3640               GtkWidget *button)
3641 {
3642   gint i;
3643   guint8 spacing;
3644   gchar *text;
3645   GdkPixmap *pixmap;
3646   GdkBitmap *mask;
3647   GList *list;
3648
3649   g_print ("GtkCList Selection: row %d column %d button %d\n", 
3650            row, column, bevent ? bevent->button : 0);
3651
3652   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
3653     {
3654       switch (gtk_clist_get_cell_type (GTK_CLIST (widget), row, i))
3655         {
3656         case GTK_CELL_TEXT:
3657           g_print ("CELL %d GTK_CELL_TEXT\n", i);
3658           gtk_clist_get_text (GTK_CLIST (widget), row, i, &text);
3659           g_print ("TEXT: %s\n", text);
3660           break;
3661
3662         case GTK_CELL_PIXMAP:
3663           g_print ("CELL %d GTK_CELL_PIXMAP\n", i);
3664           gtk_clist_get_pixmap (GTK_CLIST (widget), row, i, &pixmap, &mask);
3665           g_print ("PIXMAP: %p\n", pixmap);
3666           g_print ("MASK: %p\n", mask);
3667           break;
3668
3669         case GTK_CELL_PIXTEXT:
3670           g_print ("CELL %d GTK_CELL_PIXTEXT\n", i);
3671           gtk_clist_get_pixtext (GTK_CLIST (widget), row, i, &text, &spacing, &pixmap, &mask);
3672           g_print ("TEXT: %s\n", text);
3673           g_print ("SPACING: %d\n", spacing);
3674           g_print ("PIXMAP: %p\n", pixmap);
3675           g_print ("MASK: %p\n", mask);
3676           break;
3677
3678         default:
3679           break;
3680         }
3681     }
3682
3683   /* print selections list */
3684   g_print ("\nSelected Rows:");
3685   list = GTK_CLIST (widget)->selection;
3686   while (list)
3687     {
3688       g_print (" %d ", GPOINTER_TO_INT (list->data));
3689       list = list->next;
3690     }
3691
3692   g_print ("\n\n\n");
3693 }
3694
3695 void
3696 unselect_clist (GtkWidget *widget,
3697                 gint row, 
3698                 gint column, 
3699                 GdkEventButton * bevent,
3700                 GtkWidget *button)
3701 {
3702   gint i;
3703   guint8 spacing;
3704   gchar *text;
3705   GdkPixmap *pixmap;
3706   GdkBitmap *mask;
3707   GList *list;
3708
3709   g_print ("GtkCList Unselection: row %d column %d button %d\n", 
3710            row, column, bevent ? bevent->button : 0);
3711
3712   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
3713     {
3714       switch (gtk_clist_get_cell_type (GTK_CLIST (widget), row, i))
3715         {
3716         case GTK_CELL_TEXT:
3717           g_print ("CELL %d GTK_CELL_TEXT\n", i);
3718           gtk_clist_get_text (GTK_CLIST (widget), row, i, &text);
3719           g_print ("TEXT: %s\n", text);
3720           break;
3721
3722         case GTK_CELL_PIXMAP:
3723           g_print ("CELL %d GTK_CELL_PIXMAP\n", i);
3724           gtk_clist_get_pixmap (GTK_CLIST (widget), row, i, &pixmap, &mask);
3725           g_print ("PIXMAP: %p\n", pixmap);
3726           g_print ("MASK: %p\n", mask);
3727           break;
3728
3729         case GTK_CELL_PIXTEXT:
3730           g_print ("CELL %d GTK_CELL_PIXTEXT\n", i);
3731           gtk_clist_get_pixtext (GTK_CLIST (widget), row, i, &text, &spacing, &pixmap, &mask);
3732           g_print ("TEXT: %s\n", text);
3733           g_print ("SPACING: %d\n", spacing);
3734           g_print ("PIXMAP: %p\n", pixmap);
3735           g_print ("MASK: %p\n", mask);
3736           break;
3737
3738         default:
3739           break;
3740         }
3741     }
3742
3743   /* print selections list */
3744   g_print ("\nSelected Rows:");
3745   list = GTK_CLIST (widget)->selection;
3746   while (list)
3747     {
3748       g_print (" %d ", GPOINTER_TO_INT (list->data));
3749       list = list->next;
3750     }
3751
3752   g_print ("\n\n\n");
3753 }
3754
3755 static void
3756 insert_row_clist (GtkWidget *widget, gpointer data)
3757 {
3758   static char *text[] =
3759   {
3760     "This", "is", "an", "inserted", "row.",
3761     "This", "is", "an", "inserted", "row.",
3762     "This", "is", "an", "inserted", "row.",
3763     "This", "is", "an", "inserted", "row."
3764   };
3765
3766   static GtkStyle *style1 = NULL;
3767   static GtkStyle *style2 = NULL;
3768   static GtkStyle *style3 = NULL;
3769   gint row;
3770   
3771   if (GTK_CLIST (data)->focus_row >= 0)
3772     row = gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row,
3773                             text);
3774   else
3775     row = gtk_clist_prepend (GTK_CLIST (data), text);
3776
3777   if (!style1)
3778     {
3779       GdkColor col1;
3780       GdkColor col2;
3781
3782       col1.red   = 0;
3783       col1.green = 56000;
3784       col1.blue  = 0;
3785       col2.red   = 32000;
3786       col2.green = 0;
3787       col2.blue  = 56000;
3788
3789       style1 = gtk_style_copy (GTK_WIDGET (data)->style);
3790       style1->bg[GTK_STATE_PRELIGHT] = col1;
3791       style1->bg[GTK_STATE_SELECTED] = col2;
3792
3793       style2 = gtk_style_copy (GTK_WIDGET (data)->style);
3794       style2->fg[GTK_STATE_PRELIGHT] = col1;
3795       style2->fg[GTK_STATE_SELECTED] = col2;
3796
3797       style3 = gtk_style_copy (GTK_WIDGET (data)->style);
3798       style3->fg[GTK_STATE_PRELIGHT] = col1;
3799       style3->bg[GTK_STATE_PRELIGHT] = col2;
3800       gdk_font_unref (style3->font);
3801       style3->font =
3802         gdk_font_load ("-*-courier-medium-*-*-*-*-120-*-*-*-*-*-*");
3803     }
3804
3805   gtk_clist_set_cell_style (GTK_CLIST (data), row, 3, style1);
3806   gtk_clist_set_cell_style (GTK_CLIST (data), row, 4, style2);
3807   gtk_clist_set_cell_style (GTK_CLIST (data), row, 0, style3);
3808
3809   clist_rows++;
3810 }
3811
3812 static void
3813 clist_warning_test (GtkWidget *button,
3814                     GtkWidget *clist)
3815 {
3816   GtkWidget *child;
3817   static gboolean add_remove = FALSE;
3818
3819   add_remove = !add_remove;
3820
3821   child = gtk_label_new ("Test");
3822   gtk_widget_ref (child);
3823   gtk_object_sink (GTK_OBJECT (child));
3824
3825   if (add_remove)
3826     gtk_container_add (GTK_CONTAINER (clist), child);
3827   else
3828     {
3829       child->parent = clist;
3830       gtk_container_remove (GTK_CONTAINER (clist), child);
3831       child->parent = NULL;
3832     }
3833
3834   gtk_widget_destroy (child);
3835   gtk_widget_unref (child);
3836 }
3837
3838 static void
3839 undo_selection (GtkWidget *button, GtkCList *clist)
3840 {
3841   gtk_clist_undo_selection (clist);
3842 }
3843
3844 static void 
3845 clist_toggle_sel_mode (GtkWidget *widget, GtkCList *clist)
3846 {
3847   gint i;
3848
3849   if (!GTK_WIDGET_MAPPED (widget))
3850     return;
3851
3852   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
3853                     (((GtkOptionMenu *)clist_omenu)->menu_item), i);
3854
3855   gtk_clist_set_selection_mode (clist, (GtkSelectionMode) (3-i));
3856 }
3857
3858 static void 
3859 clist_click_column (GtkCList *clist, gint column, gpointer data)
3860 {
3861   if (column == 4)
3862     gtk_clist_set_column_visibility (clist, column, FALSE);
3863   else if (column == clist->sort_column)
3864     {
3865       if (clist->sort_type == GTK_SORT_ASCENDING)
3866         clist->sort_type = GTK_SORT_DESCENDING;
3867       else
3868         clist->sort_type = GTK_SORT_ASCENDING;
3869     }
3870   else
3871     gtk_clist_set_sort_column (clist, column);
3872
3873   gtk_clist_sort (clist);
3874 }
3875
3876 static void
3877 create_clist (void)
3878 {
3879   gint i;
3880   static GtkWidget *window = NULL;
3881
3882   static char *titles[] =
3883   {
3884     "auto resize", "not resizeable", "max width 100", "min width 50",
3885     "hide column", "Title 5", "Title 6", "Title 7",
3886     "Title 8",  "Title 9",  "Title 10", "Title 11", "Title 12",
3887     "Title 13", "Title 14", "Title 15", "Title 16", "Title 17",
3888     "Title 18", "Title 19"
3889   };
3890
3891   static OptionMenuItem items[] =
3892   {
3893     { "Single",   clist_toggle_sel_mode },
3894     { "Browse",   clist_toggle_sel_mode },
3895     { "Multiple", clist_toggle_sel_mode },
3896     { "Extended", clist_toggle_sel_mode }
3897   };
3898
3899   char text[TESTGTK_CLIST_COLUMNS][50];
3900   char *texts[TESTGTK_CLIST_COLUMNS];
3901
3902   GtkWidget *box1;
3903   GtkWidget *box2;
3904   GtkWidget *clist;
3905   GtkWidget *button;
3906   GtkWidget *separator;
3907   GtkWidget *scrolled_win;
3908
3909   GtkWidget *undo_button;
3910   GtkWidget *label;
3911
3912   GtkStyle *style;
3913   GdkColor col1;
3914   GdkColor col2;
3915
3916   if (!window)
3917     {
3918       clist_rows = 0;
3919       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3920
3921       gtk_signal_connect (GTK_OBJECT (window), "destroy",
3922                           GTK_SIGNAL_FUNC (gtk_widget_destroyed), &window);
3923
3924       gtk_window_set_title (GTK_WINDOW (window), "clist");
3925       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3926
3927       box1 = gtk_vbox_new (FALSE, 0);
3928       gtk_container_add (GTK_CONTAINER (window), box1);
3929
3930       box2 = gtk_hbox_new (FALSE, 10);
3931       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3932       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
3933
3934       /* create GtkCList here so we have a pointer to throw at the 
3935        * button callbacks -- more is done with it later */
3936       clist = gtk_clist_new_with_titles (TESTGTK_CLIST_COLUMNS, titles);
3937       gtk_widget_show (clist);
3938       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
3939       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
3940                                       GTK_POLICY_AUTOMATIC, 
3941                                       GTK_POLICY_AUTOMATIC);
3942       gtk_container_add (GTK_CONTAINER (scrolled_win), clist);
3943
3944       gtk_signal_connect (GTK_OBJECT (clist), "click_column",
3945                           (GtkSignalFunc) clist_click_column, NULL);
3946
3947       /* control buttons */
3948       button = gtk_button_new_with_label ("Add 1,000 Rows With Pixmaps");
3949       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3950
3951       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3952                           (GtkSignalFunc) add1000_clist, (gpointer) clist);
3953
3954       button = gtk_button_new_with_label ("Add 10,000 Rows");
3955       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3956
3957       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3958                           (GtkSignalFunc) add10000_clist, (gpointer) clist);
3959
3960       button = gtk_button_new_with_label ("Clear List");
3961       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3962
3963       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3964                           (GtkSignalFunc) clear_clist, (gpointer) clist);
3965
3966       button = gtk_button_new_with_label ("Remove Row");
3967       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3968
3969       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3970                           (GtkSignalFunc) remove_row_clist, (gpointer) clist);
3971
3972       /* second layer of buttons */
3973       box2 = gtk_hbox_new (FALSE, 10);
3974       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3975       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
3976
3977       button = gtk_button_new_with_label ("Insert Row");
3978       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3979
3980       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3981                           (GtkSignalFunc) insert_row_clist, (gpointer) clist);
3982
3983       button = gtk_button_new_with_label ("Show Title Buttons");
3984       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3985
3986       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3987                           (GtkSignalFunc) show_titles_clist, (gpointer) clist);
3988
3989       button = gtk_button_new_with_label ("Hide Title Buttons");
3990       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3991
3992       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3993                           (GtkSignalFunc) hide_titles_clist, (gpointer) clist);
3994
3995       button = gtk_button_new_with_label ("Warning Test");
3996       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3997
3998       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3999                           (GtkSignalFunc) clist_warning_test,(gpointer) clist);
4000
4001       box2 = gtk_hbox_new (FALSE, 10);
4002       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4003       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
4004
4005       undo_button = gtk_button_new_with_label ("Undo last selection");
4006       gtk_box_pack_start (GTK_BOX (box2), undo_button, TRUE, TRUE, 0);
4007       gtk_signal_connect (GTK_OBJECT (undo_button), "clicked",
4008                           (GtkSignalFunc) undo_selection, (gpointer) clist);
4009
4010       label = gtk_label_new ("Selection Mode :");
4011       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
4012
4013       clist_omenu = build_option_menu (items, 4, 3, clist);
4014       gtk_box_pack_start (GTK_BOX (box2), clist_omenu, FALSE, TRUE, 0);
4015
4016       /* vbox for the list itself */
4017       box2 = gtk_vbox_new (FALSE, 10);
4018       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4019       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
4020
4021       /* 
4022        * the rest of the clist configuration
4023        */
4024
4025       /*
4026       gtk_signal_connect (GTK_OBJECT (clist), 
4027                           "select_row",
4028                           (GtkSignalFunc) select_clist, 
4029                           undo_button);
4030
4031       gtk_signal_connect (GTK_OBJECT (clist), 
4032                           "unselect_row",
4033                           (GtkSignalFunc) unselect_clist, 
4034                           undo_button);
4035       */
4036
4037       gtk_clist_set_row_height (GTK_CLIST (clist), 18);
4038       gtk_widget_set_usize (clist, -1, 300);
4039
4040       for (i = 1; i < TESTGTK_CLIST_COLUMNS; i++)
4041         gtk_clist_set_column_width (GTK_CLIST (clist), i, 80);
4042
4043       gtk_clist_set_column_auto_resize (GTK_CLIST (clist), 0, TRUE);
4044       gtk_clist_set_column_resizeable (GTK_CLIST (clist), 1, FALSE);
4045       gtk_clist_set_column_max_width (GTK_CLIST (clist), 2, 100);
4046       gtk_clist_set_column_min_width (GTK_CLIST (clist), 3, 50);
4047
4048       gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_EXTENDED);
4049
4050       gtk_clist_set_column_justification (GTK_CLIST (clist), 1,
4051                                           GTK_JUSTIFY_RIGHT);
4052       gtk_clist_set_column_justification (GTK_CLIST (clist), 2,
4053                                           GTK_JUSTIFY_CENTER);
4054       
4055       for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
4056         {
4057           texts[i] = text[i];
4058           sprintf (text[i], "Column %d", i);
4059         }
4060
4061       sprintf (text[1], "Right");
4062       sprintf (text[2], "Center");
4063
4064       col1.red   = 56000;
4065       col1.green = 0;
4066       col1.blue  = 0;
4067       col2.red   = 0;
4068       col2.green = 56000;
4069       col2.blue  = 32000;
4070
4071       style = gtk_style_new ();
4072       style->fg[GTK_STATE_PRELIGHT] = col1;
4073       style->bg[GTK_STATE_PRELIGHT] = col2;
4074       
4075       gdk_font_unref (style->font);
4076       style->font =
4077         gdk_font_load ("-adobe-helvetica-bold-r-*-*-*-140-*-*-*-*-*-*");
4078
4079       for (i = 0; i < 10; i++)
4080         {
4081           sprintf (text[0], "CListRow %d", clist_rows++);
4082           gtk_clist_append (GTK_CLIST (clist), texts);
4083
4084           switch (i % 4)
4085             {
4086             case 2:
4087               gtk_clist_set_row_style (GTK_CLIST (clist), i, style);
4088               break;
4089             default:
4090               gtk_clist_set_cell_style (GTK_CLIST (clist), i, i % 4, style);
4091               break;
4092             }
4093         }
4094
4095       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
4096       gtk_box_pack_start (GTK_BOX (box2), scrolled_win, TRUE, TRUE, 0);
4097
4098       separator = gtk_hseparator_new ();
4099       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
4100
4101       box2 = gtk_vbox_new (FALSE, 10);
4102       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4103       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
4104
4105       button = gtk_button_new_with_label ("close");
4106       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
4107                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
4108                                  GTK_OBJECT (window));
4109
4110       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
4111       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4112       gtk_widget_grab_default (button);
4113     }
4114
4115   if (!GTK_WIDGET_VISIBLE (window))
4116     gtk_widget_show_all (window);
4117   else
4118     {
4119       clist_rows = 0;
4120       gtk_widget_destroy (window);
4121     }
4122 }
4123
4124 /*
4125  * GtkCTree
4126  */
4127
4128 GdkPixmap *pixmap1;
4129 GdkPixmap *pixmap2;
4130 GdkPixmap *pixmap3;
4131 GdkBitmap *mask1;
4132 GdkBitmap *mask2;
4133 GdkBitmap *mask3;
4134
4135 static gint books = 0;
4136 static gint pages = 0;
4137
4138 static GtkWidget *book_label;
4139 static GtkWidget *page_label;
4140 static GtkWidget *sel_label;
4141 static GtkWidget *vis_label;
4142 static GtkWidget *omenu1;
4143 static GtkWidget *omenu2;
4144 static GtkWidget *omenu3;
4145 static GtkWidget *omenu4;
4146 static GtkWidget *spin1;
4147 static GtkWidget *spin2;
4148 static GtkWidget *spin3;
4149 static gint line_style;
4150
4151 void after_press (GtkCTree *ctree, gpointer data)
4152 {
4153   char buf[80];
4154
4155   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
4156   gtk_label_set (GTK_LABEL (sel_label), buf);
4157
4158   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
4159   gtk_label_set (GTK_LABEL (vis_label), buf);
4160
4161   sprintf (buf, "%d", books);
4162   gtk_label_set (GTK_LABEL (book_label), buf);
4163
4164   sprintf (buf, "%d", pages);
4165   gtk_label_set (GTK_LABEL (page_label), buf);
4166 }
4167
4168 void after_move (GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent, 
4169                  GtkCTreeNode *sibling, gpointer data)
4170 {
4171   char *source;
4172   char *target1;
4173   char *target2;
4174
4175   gtk_ctree_get_node_info (ctree, child, &source, 
4176                            NULL, NULL, NULL, NULL, NULL, NULL, NULL);
4177   if (parent)
4178     gtk_ctree_get_node_info (ctree, parent, &target1, 
4179                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
4180   if (sibling)
4181     gtk_ctree_get_node_info (ctree, sibling, &target2, 
4182                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
4183
4184   g_print ("Moving \"%s\" to \"%s\" with sibling \"%s\".\n", source,
4185            (parent) ? target1 : "nil", (sibling) ? target2 : "nil");
4186 }
4187
4188 gint button_press (GtkCTree *ctree, GdkEventButton *event, gpointer data)
4189 {
4190   gint row;
4191   gint column;
4192   GtkCTreeNode *work;
4193   gint res;
4194   
4195   res = gtk_clist_get_selection_info (GTK_CLIST (ctree), event->x, event->y, 
4196                                       &row, &column);
4197   if (!res && event->button != 3)
4198     return FALSE;
4199
4200   work = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list, row));
4201
4202   switch (event->button)
4203     {
4204     case 1:
4205       if (GTK_CLIST (ctree)->selection_mode == GTK_SELECTION_MULTIPLE &&
4206           event->state & GDK_SHIFT_MASK)
4207         gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree),"button_press_event");
4208       break;
4209     case  2:
4210       if (GTK_CTREE_ROW (work)->children && 
4211           gtk_ctree_is_hot_spot (ctree, event->x, event->y))
4212         {
4213           if (GTK_CTREE_ROW (work)->expanded)
4214             gtk_ctree_collapse_recursive (ctree, work);
4215           else
4216             gtk_ctree_expand_recursive (ctree, work);
4217           after_press (ctree, NULL);
4218           gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree),
4219                                         "button_press_event");
4220         }
4221       break;
4222     default:
4223       break;
4224     }
4225   return FALSE;
4226 }
4227
4228 gint button_release (GtkCTree *ctree, GdkEventButton *event, gpointer data)
4229 {
4230   gint row;
4231   gint column;
4232   GtkCTreeNode *work;
4233   gint res;
4234   
4235   res = gtk_clist_get_selection_info (GTK_CLIST (ctree), event->x, event->y, 
4236                                       &row, &column);
4237   if (!res || event->button != 1)
4238     return FALSE;
4239
4240   work = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list, row));
4241
4242   if (GTK_CLIST (ctree)->selection_mode == GTK_SELECTION_MULTIPLE &&
4243       event->state & GDK_SHIFT_MASK)
4244     {
4245       if (GTK_CTREE_ROW (work)->row.state == GTK_STATE_SELECTED) 
4246             gtk_ctree_unselect_recursive (ctree, work);
4247       else
4248         gtk_ctree_select_recursive (ctree, work);
4249       after_press (ctree, NULL);
4250       gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree), 
4251                                     "button_release_event");
4252     }
4253   return FALSE;
4254 }
4255
4256 void count_items (GtkCTree *ctree, GtkCTreeNode *list)
4257 {
4258   if (GTK_CTREE_ROW (list)->is_leaf)
4259     pages--;
4260   else
4261     books--;
4262 }
4263
4264 void expand_all (GtkWidget *widget, GtkCTree *ctree)
4265 {
4266   gtk_ctree_expand_recursive (ctree, NULL);
4267   after_press (ctree, NULL);
4268 }
4269
4270 void collapse_all (GtkWidget *widget, GtkCTree *ctree)
4271 {
4272   gtk_ctree_collapse_recursive (ctree, NULL);
4273   after_press (ctree, NULL);
4274 }
4275
4276 void select_all (GtkWidget *widget, GtkCTree *ctree)
4277 {
4278   gtk_ctree_select_recursive (ctree, NULL);
4279   after_press (ctree, NULL);
4280 }
4281
4282 void change_style (GtkWidget *widget, GtkCTree *ctree)
4283 {
4284   static GtkStyle *style1 = NULL;
4285   static GtkStyle *style2 = NULL;
4286
4287   GtkCTreeNode *node;
4288   GdkColor col1;
4289   GdkColor col2;
4290
4291   if (GTK_CLIST (ctree)->focus_row >= 0)
4292     node = GTK_CTREE_NODE
4293       (g_list_nth (GTK_CLIST (ctree)->row_list,GTK_CLIST (ctree)->focus_row));
4294   else
4295     node = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
4296
4297   if (!node)
4298     return;
4299
4300   if (!style1)
4301     {
4302       col1.red   = 0;
4303       col1.green = 56000;
4304       col1.blue  = 0;
4305       col2.red   = 32000;
4306       col2.green = 0;
4307       col2.blue  = 56000;
4308
4309       style1 = gtk_style_new ();
4310       style1->bg[GTK_STATE_PRELIGHT] = col1;
4311       style1->fg[GTK_STATE_SELECTED] = col2;
4312
4313       style2 = gtk_style_new ();
4314       style2->bg[GTK_STATE_SELECTED] = col2;
4315       style2->fg[GTK_STATE_PRELIGHT] = col1;
4316       style2->bg[GTK_STATE_PRELIGHT] = col2;
4317       gdk_font_unref (style2->font);
4318       style2->font =
4319         gdk_font_load ("-*-courier-medium-*-*-*-*-300-*-*-*-*-*-*");
4320     }
4321
4322   gtk_ctree_node_set_cell_style (ctree, node, 1, style1);
4323   gtk_ctree_node_set_cell_style (ctree, node, 0, style2);
4324
4325   if (GTK_CTREE_ROW (node)->children)
4326     gtk_ctree_node_set_row_style (ctree, GTK_CTREE_ROW (node)->children,
4327                                   style2);
4328 }
4329
4330 void unselect_all (GtkWidget *widget, GtkCTree *ctree)
4331 {
4332   gtk_ctree_unselect_recursive (ctree, NULL);
4333   after_press (ctree, NULL);
4334 }
4335
4336 void remove_selection (GtkWidget *widget, GtkCTree *ctree)
4337 {
4338   GtkCList *clist;
4339   GtkCTreeNode *node;
4340   GList *selection;
4341   GList *list = NULL;
4342
4343   clist = GTK_CLIST (ctree);
4344
4345   gtk_clist_freeze (clist);
4346
4347   for (selection = clist->selection; selection; selection = selection->next)
4348     list = g_list_prepend (list, selection->data);
4349
4350   selection = clist->selection;
4351   while (selection)
4352     {
4353       node = selection->data;
4354
4355       if (!g_list_find (list, node))
4356         break;
4357
4358       if (GTK_CTREE_ROW (node)->is_leaf)
4359         pages--;
4360       else
4361         gtk_ctree_post_recursive (ctree, node, 
4362                                   (GtkCTreeFunc) count_items, NULL);
4363
4364       gtk_ctree_remove_node (ctree, node);
4365       selection = clist->selection;
4366     }
4367   g_list_free (list);
4368   gtk_clist_thaw (clist);
4369   after_press (ctree, NULL);
4370 }
4371
4372 struct _ExportStruct {
4373   gchar *tree;
4374   gchar *info;
4375   gboolean is_leaf;
4376 };
4377
4378 typedef struct _ExportStruct ExportStruct;
4379
4380 gboolean
4381 gnode2ctree (GtkCTree   *ctree,
4382              guint       depth,
4383              GNode        *gnode,
4384              GtkCTreeNode *cnode,
4385              gpointer    data)
4386 {
4387   ExportStruct *es;
4388   GdkPixmap *pixmap_closed;
4389   GdkBitmap *mask_closed;
4390   GdkPixmap *pixmap_opened;
4391   GdkBitmap *mask_opened;
4392
4393   if (!cnode || !gnode || (!(es = gnode->data)))
4394     return FALSE;
4395
4396   if (es->is_leaf)
4397     {
4398       pixmap_closed = pixmap3;
4399       mask_closed = mask3;
4400       pixmap_opened = NULL;
4401       mask_opened = NULL;
4402     }
4403   else
4404     {
4405       pixmap_closed = pixmap1;
4406       mask_closed = mask1;
4407       pixmap_opened = pixmap2;
4408       mask_opened = mask2;
4409     }
4410
4411   gtk_ctree_set_node_info (ctree, cnode, es->tree, 2, pixmap_closed,
4412                            mask_closed, pixmap_opened, mask_opened,
4413                            es->is_leaf, (depth < 3));
4414   gtk_ctree_node_set_text (ctree, cnode, 1, es->info);
4415   g_free (es);
4416   gnode->data = NULL;
4417
4418   return TRUE;
4419 }
4420
4421 gboolean
4422 ctree2gnode (GtkCTree   *ctree,
4423              guint       depth,
4424              GNode        *gnode,
4425              GtkCTreeNode *cnode,
4426              gpointer    data)
4427 {
4428   ExportStruct *es;
4429
4430   if (!cnode || !gnode)
4431     return FALSE;
4432   
4433   es = g_new (ExportStruct, 1);
4434   gnode->data = es;
4435   es->is_leaf = GTK_CTREE_ROW (cnode)->is_leaf;
4436   es->tree = GTK_CELL_PIXTEXT (GTK_CTREE_ROW (cnode)->row.cell[0])->text;
4437   es->info = GTK_CELL_PIXTEXT (GTK_CTREE_ROW (cnode)->row.cell[1])->text;
4438   return TRUE;
4439 }
4440
4441 void export_ctree (GtkWidget *widget, GtkCTree *ctree)
4442 {
4443   char *title[] = { "Tree" , "Info" };
4444   static GtkWidget *export_window = NULL;
4445   static GtkCTree *export_ctree;
4446   GtkWidget *vbox;
4447   GtkWidget *scrolled_win;
4448   GtkWidget *button;
4449   GtkWidget *sep;
4450   GNode *gnode;
4451   GtkCTreeNode *node;
4452
4453   if (!export_window)
4454     {
4455       export_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4456   
4457       gtk_signal_connect (GTK_OBJECT (export_window), "destroy",
4458                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
4459                           &export_window);
4460
4461       gtk_window_set_title (GTK_WINDOW (export_window), "exported ctree");
4462       gtk_container_set_border_width (GTK_CONTAINER (export_window), 5);
4463
4464       vbox = gtk_vbox_new (FALSE, 0);
4465       gtk_container_add (GTK_CONTAINER (export_window), vbox);
4466       
4467       button = gtk_button_new_with_label ("Close");
4468       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, TRUE, 0);
4469
4470       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
4471                                  (GtkSignalFunc) gtk_widget_destroy,
4472                                  GTK_OBJECT(export_window));
4473
4474       sep = gtk_hseparator_new ();
4475       gtk_box_pack_end (GTK_BOX (vbox), sep, FALSE, TRUE, 10);
4476
4477       export_ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
4478       gtk_ctree_set_line_style (export_ctree, GTK_CTREE_LINES_DOTTED);
4479
4480       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
4481       gtk_container_add (GTK_CONTAINER (scrolled_win),
4482                          GTK_WIDGET (export_ctree));
4483       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
4484                                       GTK_POLICY_AUTOMATIC,
4485                                       GTK_POLICY_AUTOMATIC);
4486       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
4487       gtk_clist_set_selection_mode (GTK_CLIST (export_ctree),
4488                                     GTK_SELECTION_EXTENDED);
4489       gtk_clist_set_column_width (GTK_CLIST (export_ctree), 0, 200);
4490       gtk_clist_set_column_width (GTK_CLIST (export_ctree), 1, 200);
4491       gtk_widget_set_usize (GTK_WIDGET (export_ctree), 300, 200);
4492     }
4493
4494   if (!GTK_WIDGET_VISIBLE (export_window))
4495     gtk_widget_show_all (export_window);
4496       
4497   gtk_clist_clear (GTK_CLIST (export_ctree));
4498
4499   node = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list,
4500                                      GTK_CLIST (ctree)->focus_row));
4501   if (!node)
4502     return;
4503
4504   gnode = gtk_ctree_export_to_gnode (ctree, NULL, NULL, node,
4505                                      ctree2gnode, NULL);
4506   if (gnode)
4507     {
4508       gtk_ctree_insert_gnode (export_ctree, NULL, NULL, gnode,
4509                               gnode2ctree, NULL);
4510       g_node_destroy (gnode);
4511     }
4512 }
4513
4514 void change_indent (GtkWidget *widget, GtkCTree *ctree)
4515 {
4516   gtk_ctree_set_indent (ctree, GTK_ADJUSTMENT (widget)->value);
4517 }
4518
4519 void change_spacing (GtkWidget *widget, GtkCTree *ctree)
4520 {
4521   gtk_ctree_set_spacing (ctree, GTK_ADJUSTMENT (widget)->value);
4522 }
4523
4524 void change_row_height (GtkWidget *widget, GtkCList *clist)
4525 {
4526   gtk_clist_set_row_height (clist, GTK_ADJUSTMENT (widget)->value);
4527 }
4528
4529 void toggle_reorderable (GtkWidget *widget, GtkCTree *ctree)
4530 {
4531   gtk_ctree_set_reorderable (ctree, GTK_TOGGLE_BUTTON (widget)->active);
4532 }
4533
4534 void set_background (GtkCTree *ctree, GtkCTreeNode *node, gpointer data)
4535 {
4536   GtkStyle *style = NULL;
4537   
4538   if (!node)
4539     return;
4540   
4541   if (ctree->line_style != GTK_CTREE_LINES_TABBED)
4542     {
4543       if (!GTK_CTREE_ROW (node)->is_leaf)
4544         style = GTK_CTREE_ROW (node)->row.data;
4545       else if (GTK_CTREE_ROW (node)->parent)
4546         style = GTK_CTREE_ROW (GTK_CTREE_ROW (node)->parent)->row.data;
4547     }
4548
4549   gtk_ctree_node_set_row_style (ctree, node, style);
4550 }
4551
4552 void ctree_toggle_line_style (GtkWidget *widget, GtkCTree *ctree)
4553 {
4554   gint i;
4555
4556   if (!GTK_WIDGET_MAPPED (widget))
4557     return;
4558
4559   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
4560                     (((GtkOptionMenu *)omenu1)->menu_item), i);
4561   
4562   if ((ctree->line_style == GTK_CTREE_LINES_TABBED && 
4563        ((GtkCTreeLineStyle) (3 - i)) != GTK_CTREE_LINES_TABBED) ||
4564       (ctree->line_style != GTK_CTREE_LINES_TABBED && 
4565        ((GtkCTreeLineStyle) (3 - i)) == GTK_CTREE_LINES_TABBED))
4566     gtk_ctree_pre_recursive (ctree, NULL, set_background, NULL);
4567   gtk_ctree_set_line_style (ctree, 3 - i);
4568   line_style = 3 - i;
4569 }
4570
4571 void ctree_toggle_expander_style (GtkWidget *widget, GtkCTree *ctree)
4572 {
4573   gint i;
4574
4575   if (!GTK_WIDGET_MAPPED (widget))
4576     return;
4577
4578   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
4579                     (((GtkOptionMenu *)omenu2)->menu_item), i);
4580   
4581   gtk_ctree_set_expander_style (ctree, (GtkCTreeExpanderStyle) (3 - i));
4582 }
4583
4584 void ctree_toggle_justify (GtkWidget *widget, GtkCTree *ctree)
4585 {
4586   gint i;
4587
4588   if (!GTK_WIDGET_MAPPED (widget))
4589     return;
4590
4591   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
4592                     (((GtkOptionMenu *)omenu3)->menu_item), i);
4593
4594   gtk_clist_set_column_justification (GTK_CLIST (ctree), ctree->tree_column, 
4595                                       (GtkJustification) (1 - i));
4596 }
4597
4598 void ctree_toggle_sel_mode (GtkWidget *widget, GtkCTree *ctree)
4599 {
4600   gint i;
4601
4602   if (!GTK_WIDGET_MAPPED (widget))
4603     return;
4604
4605   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
4606                     (((GtkOptionMenu *)omenu4)->menu_item), i);
4607
4608   gtk_clist_set_selection_mode (GTK_CLIST (ctree), (GtkSelectionMode) (3 - i));
4609   after_press (ctree, NULL);
4610 }
4611     
4612 void build_recursive (GtkCTree *ctree, gint cur_depth, gint depth, 
4613                       gint num_books, gint num_pages, GtkCTreeNode *parent)
4614 {
4615   gchar *text[2];
4616   gchar buf1[60];
4617   gchar buf2[60];
4618   GtkCTreeNode *sibling;
4619   gint i;
4620
4621   text[0] = buf1;
4622   text[1] = buf2;
4623   sibling = NULL;
4624
4625   for (i = num_pages + num_books; i > num_books; i--)
4626     {
4627       pages++;
4628       sprintf (buf1, "Page %02d", (gint) rand() % 100);
4629       sprintf (buf2, "Item %d-%d", cur_depth, i);
4630       sibling = gtk_ctree_insert_node (ctree, parent, sibling, text, 5,
4631                                        pixmap3, mask3, NULL, NULL,
4632                                        TRUE, FALSE);
4633
4634       if (parent && ctree->line_style == GTK_CTREE_LINES_TABBED)
4635         gtk_ctree_node_set_row_style (ctree, sibling,
4636                                       GTK_CTREE_ROW (parent)->row.style);
4637     }
4638
4639   if (cur_depth == depth)
4640     return;
4641
4642   for (i = num_books; i > 0; i--)
4643     {
4644       GtkStyle *style;
4645
4646       books++;
4647       sprintf (buf1, "Book %02d", (gint) rand() % 100);
4648       sprintf (buf2, "Item %d-%d", cur_depth, i);
4649       sibling = gtk_ctree_insert_node (ctree, parent, sibling, text, 5,
4650                                        pixmap1, mask1, pixmap2, mask2,
4651                                        FALSE, FALSE);
4652
4653       style = gtk_style_new ();
4654       switch (cur_depth % 3)
4655         {
4656         case 0:
4657           style->bg[GTK_STATE_PRELIGHT].red   = 10000 * (cur_depth % 6);
4658           style->bg[GTK_STATE_PRELIGHT].green = 0;
4659           style->bg[GTK_STATE_PRELIGHT].blue  = 65535 - ((i * 10000) % 65535);
4660           break;
4661         case 1:
4662           style->bg[GTK_STATE_PRELIGHT].red   = 10000 * (cur_depth % 6);
4663           style->bg[GTK_STATE_PRELIGHT].green = 65535 - ((i * 10000) % 65535);
4664           style->bg[GTK_STATE_PRELIGHT].blue  = 0;
4665           break;
4666         default:
4667           style->bg[GTK_STATE_PRELIGHT].red   = 65535 - ((i * 10000) % 65535);
4668           style->bg[GTK_STATE_PRELIGHT].green = 0;
4669           style->bg[GTK_STATE_PRELIGHT].blue  = 10000 * (cur_depth % 6);
4670           break;
4671         }
4672       gtk_ctree_node_set_row_data_full (ctree, sibling, style,
4673                                         (GtkDestroyNotify) gtk_style_unref);
4674
4675       if (ctree->line_style == GTK_CTREE_LINES_TABBED)
4676         gtk_ctree_node_set_row_style (ctree, sibling, style);
4677
4678       build_recursive (ctree, cur_depth + 1, depth, num_books, num_pages,
4679                        sibling);
4680     }
4681 }
4682
4683 void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
4684 {
4685   gchar *text [2];
4686   gchar label1[] = "Root";
4687   gchar label2[] = "";
4688   GtkCTreeNode *parent;
4689   GtkStyle *style;
4690   guint b, d, p, n;
4691
4692   text[0] = label1;
4693   text[1] = label2;
4694   
4695   d = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1)); 
4696   b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
4697   p = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin3));
4698
4699   n = ((pow (b, d) - 1) / (b - 1)) * (p + 1);
4700
4701   if (n > 100000)
4702     {
4703       g_print ("%d total items? Try less\n",n);
4704       return;
4705     }
4706
4707   gtk_clist_freeze (GTK_CLIST (ctree));
4708   gtk_clist_clear (GTK_CLIST (ctree));
4709
4710   books = 1;
4711   pages = 0;
4712
4713   parent = gtk_ctree_insert_node (ctree, NULL, NULL, text, 5, pixmap1,
4714                                   mask1, pixmap2, mask2, FALSE, TRUE);
4715
4716   style = gtk_style_new ();
4717   style->bg[GTK_STATE_PRELIGHT].red   = 0;
4718   style->bg[GTK_STATE_PRELIGHT].green = 45000;
4719   style->bg[GTK_STATE_PRELIGHT].blue  = 55000;
4720   gtk_ctree_node_set_row_data_full (ctree, parent, style,
4721                                     (GtkDestroyNotify) gtk_style_unref);
4722
4723   if (ctree->line_style == GTK_CTREE_LINES_TABBED)
4724     gtk_ctree_node_set_row_style (ctree, parent, style);
4725
4726   build_recursive (ctree, 1, d, b, p, parent);
4727   gtk_clist_thaw (GTK_CLIST (ctree));
4728   after_press (ctree, NULL);
4729 }
4730
4731 static void 
4732 ctree_click_column (GtkCTree *ctree, gint column, gpointer data)
4733 {
4734   GtkCList *clist;
4735
4736   clist = GTK_CLIST (ctree);
4737
4738   if (column == clist->sort_column)
4739     {
4740       if (clist->sort_type == GTK_SORT_ASCENDING)
4741         clist->sort_type = GTK_SORT_DESCENDING;
4742       else
4743         clist->sort_type = GTK_SORT_ASCENDING;
4744     }
4745   else
4746     gtk_clist_set_sort_column (clist, column);
4747
4748   gtk_ctree_sort_recursive (ctree, NULL);
4749 }
4750
4751 void create_ctree (void)
4752 {
4753   static GtkWidget *window = NULL;
4754   GtkTooltips *tooltips;
4755   GtkCTree *ctree;
4756   GtkWidget *scrolled_win;
4757   GtkWidget *vbox;
4758   GtkWidget *bbox;
4759   GtkWidget *mbox;
4760   GtkWidget *hbox;
4761   GtkWidget *hbox2;
4762   GtkWidget *frame;
4763   GtkWidget *label;
4764   GtkWidget *button;
4765   GtkWidget *check;
4766   GtkAdjustment *adj;
4767   GtkWidget *spinner;
4768   GdkColor transparent;
4769
4770   char *title[] = { "Tree" , "Info" };
4771   char buf[80];
4772
4773   static OptionMenuItem items1[] =
4774   {
4775     { "No lines", ctree_toggle_line_style },
4776     { "Solid",    ctree_toggle_line_style },
4777     { "Dotted",   ctree_toggle_line_style },
4778     { "Tabbed",   ctree_toggle_line_style }
4779   };
4780
4781   static OptionMenuItem items2[] =
4782   {
4783     { "None",     ctree_toggle_expander_style },
4784     { "Square",   ctree_toggle_expander_style },
4785     { "Triangle", ctree_toggle_expander_style },
4786     { "Circular", ctree_toggle_expander_style }
4787   };
4788
4789   static OptionMenuItem items3[] =
4790   {
4791     { "Left",  ctree_toggle_justify },
4792     { "Right", ctree_toggle_justify }
4793   };
4794
4795   static OptionMenuItem items4[] =
4796   {
4797     { "Single",   ctree_toggle_sel_mode },
4798     { "Browse",   ctree_toggle_sel_mode },
4799     { "Multiple", ctree_toggle_sel_mode },
4800     { "Extended", ctree_toggle_sel_mode }
4801   };
4802
4803   if (!window)
4804     {
4805       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4806
4807       gtk_signal_connect (GTK_OBJECT (window), "destroy",
4808                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
4809                           &window);
4810
4811       gtk_window_set_title (GTK_WINDOW (window), "GtkCTree");
4812       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4813
4814       tooltips = gtk_tooltips_new ();
4815       gtk_object_ref (GTK_OBJECT (tooltips));
4816       gtk_object_sink (GTK_OBJECT (tooltips));
4817
4818       gtk_object_set_data_full (GTK_OBJECT (window), "tooltips", tooltips,
4819                                 (GtkDestroyNotify) gtk_object_unref);
4820
4821       vbox = gtk_vbox_new (FALSE, 0);
4822       gtk_container_add (GTK_CONTAINER (window), vbox);
4823
4824       hbox = gtk_hbox_new (FALSE, 5);
4825       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4826       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
4827       
4828       label = gtk_label_new ("Depth :");
4829       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4830       
4831       adj = (GtkAdjustment *) gtk_adjustment_new (4, 1, 10, 1, 5, 0);
4832       spin1 = gtk_spin_button_new (adj, 0, 0);
4833       gtk_box_pack_start (GTK_BOX (hbox), spin1, FALSE, TRUE, 5);
4834   
4835       label = gtk_label_new ("Books :");
4836       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4837       
4838       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
4839       spin2 = gtk_spin_button_new (adj, 0, 0);
4840       gtk_box_pack_start (GTK_BOX (hbox), spin2, FALSE, TRUE, 5);
4841
4842       label = gtk_label_new ("Pages :");
4843       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4844       
4845       adj = (GtkAdjustment *) gtk_adjustment_new (5, 1, 20, 1, 5, 0);
4846       spin3 = gtk_spin_button_new (adj, 0, 0);
4847       gtk_box_pack_start (GTK_BOX (hbox), spin3, FALSE, TRUE, 5);
4848
4849       button = gtk_button_new_with_label ("Close");
4850       gtk_box_pack_end (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4851
4852       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
4853                                  (GtkSignalFunc) gtk_widget_destroy,
4854                                  GTK_OBJECT(window));
4855
4856       button = gtk_button_new_with_label ("Rebuild tree");
4857       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4858
4859       ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
4860       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4861                           GTK_SIGNAL_FUNC (rebuild_tree), ctree);
4862       
4863       gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
4864       line_style = GTK_CTREE_LINES_DOTTED;
4865
4866       gtk_ctree_set_reorderable (ctree, TRUE);
4867       gtk_signal_connect (GTK_OBJECT (ctree), "click_column",
4868                           (GtkSignalFunc) ctree_click_column,
4869                           NULL);
4870       gtk_signal_connect (GTK_OBJECT (ctree), "button_press_event",
4871                           GTK_SIGNAL_FUNC (button_press), NULL);
4872       gtk_signal_connect_after (GTK_OBJECT (ctree), "button_press_event",
4873                                 GTK_SIGNAL_FUNC (after_press), NULL);
4874       gtk_signal_connect (GTK_OBJECT (ctree), "button_release_event",
4875                           GTK_SIGNAL_FUNC (button_release), NULL);
4876       gtk_signal_connect_after (GTK_OBJECT (ctree), "button_release_event",
4877                                 GTK_SIGNAL_FUNC (after_press), NULL);
4878       gtk_signal_connect_after (GTK_OBJECT (ctree), "tree_move",
4879                                 GTK_SIGNAL_FUNC (after_move), NULL);
4880       gtk_signal_connect_after (GTK_OBJECT (ctree), "end_selection",
4881                                 GTK_SIGNAL_FUNC (after_press), NULL);
4882       gtk_signal_connect_after (GTK_OBJECT (ctree), "toggle_focus_row",
4883                                 GTK_SIGNAL_FUNC (after_press), NULL);
4884       gtk_signal_connect_after (GTK_OBJECT (ctree), "select_all",
4885                                 GTK_SIGNAL_FUNC (after_press), NULL);
4886       gtk_signal_connect_after (GTK_OBJECT (ctree), "unselect_all",
4887                                 GTK_SIGNAL_FUNC (after_press), NULL);
4888       gtk_signal_connect_after (GTK_OBJECT (ctree), "scroll_vertical",
4889                                 GTK_SIGNAL_FUNC (after_press), NULL);
4890       
4891       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
4892       gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (ctree));
4893       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
4894                                       GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
4895       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
4896       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
4897       gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_EXTENDED);
4898       gtk_clist_set_column_auto_resize (GTK_CLIST (ctree), 0, TRUE);
4899       gtk_clist_set_column_width (GTK_CLIST (ctree), 1, 200);
4900
4901       bbox = gtk_hbox_new (FALSE, 5);
4902       gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
4903       gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, TRUE, 0);
4904
4905       mbox = gtk_vbox_new (TRUE, 5);
4906       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
4907
4908       label = gtk_label_new ("Row height :");
4909       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
4910
4911       label = gtk_label_new ("Indent :");
4912       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
4913
4914       label = gtk_label_new ("Spacing :");
4915       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
4916
4917       mbox = gtk_vbox_new (TRUE, 5);
4918       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
4919
4920       adj = (GtkAdjustment *) gtk_adjustment_new (20, 12, 100, 1, 10, 0);
4921       spinner = gtk_spin_button_new (adj, 0, 0);
4922       gtk_tooltips_set_tip (tooltips, spinner,
4923                             "Row height of list items", NULL);
4924       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
4925                           GTK_SIGNAL_FUNC (change_row_height), ctree);
4926       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
4927       gtk_clist_set_row_height ( GTK_CLIST (ctree), adj->value);
4928
4929       adj = (GtkAdjustment *) gtk_adjustment_new (20, 0, 60, 1, 10, 0);
4930       spinner = gtk_spin_button_new (adj, 0, 0);
4931       gtk_tooltips_set_tip (tooltips, spinner, "Tree indentation.", NULL);
4932       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
4933                           GTK_SIGNAL_FUNC (change_indent), ctree);
4934       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
4935
4936       adj = (GtkAdjustment *) gtk_adjustment_new (5, 0, 60, 1, 10, 0);
4937       spinner = gtk_spin_button_new (adj, 0, 0);
4938       gtk_tooltips_set_tip (tooltips, spinner, "Tree spacing.", NULL);
4939       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
4940                           GTK_SIGNAL_FUNC (change_spacing), ctree);
4941       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
4942
4943       mbox = gtk_vbox_new (TRUE, 5);
4944       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
4945
4946       hbox = gtk_hbox_new (FALSE, 5);
4947       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
4948
4949       button = gtk_button_new_with_label ("Expand all");
4950       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4951                           GTK_SIGNAL_FUNC (expand_all), ctree);
4952       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4953
4954       button = gtk_button_new_with_label ("Collapse all");
4955       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4956                           GTK_SIGNAL_FUNC (collapse_all), ctree);
4957       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4958
4959       button = gtk_button_new_with_label ("Change Style");
4960       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4961                           GTK_SIGNAL_FUNC (change_style), ctree);
4962       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4963
4964       button = gtk_button_new_with_label ("Export tree");
4965       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4966                           GTK_SIGNAL_FUNC (export_ctree), ctree);
4967       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4968
4969       hbox = gtk_hbox_new (FALSE, 5);
4970       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
4971
4972       button = gtk_button_new_with_label ("Select all");
4973       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4974                           GTK_SIGNAL_FUNC (select_all), ctree);
4975       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4976
4977       button = gtk_button_new_with_label ("Unselect all");
4978       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4979                           GTK_SIGNAL_FUNC (unselect_all), ctree);
4980       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4981
4982       button = gtk_button_new_with_label ("Remove selection");
4983       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4984                           GTK_SIGNAL_FUNC (remove_selection), ctree);
4985       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4986
4987       check = gtk_check_button_new_with_label ("Reorderable");
4988       gtk_tooltips_set_tip (tooltips, check,
4989                             "Tree items can be reordered by dragging.", NULL);
4990       gtk_signal_connect (GTK_OBJECT (check), "clicked",
4991                           GTK_SIGNAL_FUNC (toggle_reorderable), ctree);
4992       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
4993       gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (check), TRUE);
4994
4995       hbox = gtk_hbox_new (TRUE, 5);
4996       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
4997       
4998       omenu1 = build_option_menu (items1, 4, 2, ctree);
4999       gtk_tooltips_set_tip (tooltips, omenu1, "The tree's line style.", NULL);
5000       gtk_box_pack_start (GTK_BOX (hbox), omenu1, FALSE, TRUE, 0);
5001       
5002       omenu2 = build_option_menu (items2, 4, 1, ctree);
5003       gtk_tooltips_set_tip (tooltips, omenu2, "The tree's expander style.",
5004                             NULL);
5005       gtk_box_pack_start (GTK_BOX (hbox), omenu2, FALSE, TRUE, 0);
5006
5007       omenu3 = build_option_menu (items3, 2, 0, ctree);
5008       gtk_tooltips_set_tip (tooltips, omenu3, "The tree's justification.",
5009                             NULL);
5010       gtk_box_pack_start (GTK_BOX (hbox), omenu3, FALSE, TRUE, 0);
5011       
5012       omenu4 = build_option_menu (items4, 4, 3, ctree);
5013       gtk_tooltips_set_tip (tooltips, omenu4, "The list's selection mode.",
5014                             NULL);
5015       gtk_box_pack_start (GTK_BOX (hbox), omenu4, FALSE, TRUE, 0);
5016       
5017       gtk_widget_realize (window);
5018       
5019       pixmap1 = gdk_pixmap_create_from_xpm_d (window->window, &mask1, 
5020                                               &transparent, book_closed_xpm);
5021       pixmap2 = gdk_pixmap_create_from_xpm_d (window->window, &mask2, 
5022                                               &transparent, book_open_xpm);
5023       pixmap3 = gdk_pixmap_create_from_xpm_d (window->window, &mask3,
5024                                               &transparent, mini_page_xpm);
5025       
5026       gtk_widget_set_usize (GTK_WIDGET (ctree), 0, 300);
5027       
5028       frame = gtk_frame_new (NULL);
5029       gtk_container_set_border_width (GTK_CONTAINER (frame), 0);
5030       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
5031       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
5032       
5033       hbox = gtk_hbox_new (TRUE, 2);
5034       gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
5035       gtk_container_add (GTK_CONTAINER (frame), hbox);
5036       
5037       frame = gtk_frame_new (NULL);
5038       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
5039       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
5040       
5041       hbox2 = gtk_hbox_new (FALSE, 0);
5042       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
5043       gtk_container_add (GTK_CONTAINER (frame), hbox2);
5044       
5045       label = gtk_label_new ("Books :");
5046       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
5047       
5048       sprintf (buf, "%d", books);
5049       book_label = gtk_label_new (buf);
5050       gtk_box_pack_end (GTK_BOX (hbox2), book_label, FALSE, TRUE, 5);
5051       
5052       frame = gtk_frame_new (NULL);
5053       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
5054       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
5055       
5056       hbox2 = gtk_hbox_new (FALSE, 0);
5057       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
5058       gtk_container_add (GTK_CONTAINER (frame), hbox2);
5059       
5060       label = gtk_label_new ("Pages :");
5061       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
5062       
5063       sprintf (buf, "%d", pages);
5064       page_label = gtk_label_new (buf);
5065       gtk_box_pack_end (GTK_BOX (hbox2), page_label, FALSE, TRUE, 5);
5066       
5067       frame = gtk_frame_new (NULL);
5068       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
5069       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
5070       
5071       hbox2 = gtk_hbox_new (FALSE, 0);
5072       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
5073       gtk_container_add (GTK_CONTAINER (frame), hbox2);
5074       
5075       label = gtk_label_new ("Selected :");
5076       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
5077       
5078       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
5079       sel_label = gtk_label_new (buf);
5080       gtk_box_pack_end (GTK_BOX (hbox2), sel_label, FALSE, TRUE, 5);
5081       
5082       frame = gtk_frame_new (NULL);
5083       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
5084       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
5085       
5086       hbox2 = gtk_hbox_new (FALSE, 0);
5087       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
5088       gtk_container_add (GTK_CONTAINER (frame), hbox2);
5089       
5090       label = gtk_label_new ("Visible :");
5091       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
5092       
5093       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
5094       vis_label = gtk_label_new (buf);
5095       gtk_box_pack_end (GTK_BOX (hbox2), vis_label, FALSE, TRUE, 5);
5096
5097       rebuild_tree (NULL, ctree);
5098     }
5099
5100   if (!GTK_WIDGET_VISIBLE (window))
5101     gtk_widget_show_all (window);
5102   else
5103     gtk_widget_destroy (window);
5104 }
5105
5106 /*
5107  * GtkColorSelection
5108  */
5109
5110 void
5111 color_selection_ok (GtkWidget               *w,
5112                     GtkColorSelectionDialog *cs)
5113 {
5114   GtkColorSelection *colorsel;
5115   gdouble color[4];
5116
5117   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
5118
5119   gtk_color_selection_get_color(colorsel,color);
5120   gtk_color_selection_set_color(colorsel,color);
5121 }
5122
5123 void
5124 color_selection_changed (GtkWidget *w,
5125                          GtkColorSelectionDialog *cs)
5126 {
5127   GtkColorSelection *colorsel;
5128   gdouble color[4];
5129
5130   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
5131   gtk_color_selection_get_color(colorsel,color);
5132 }
5133
5134 void
5135 create_color_selection (void)
5136 {
5137   static GtkWidget *window = NULL;
5138
5139   if (!window)
5140     {
5141       window = gtk_color_selection_dialog_new ("color selection dialog");
5142
5143       gtk_color_selection_set_opacity (
5144         GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
5145         TRUE);
5146
5147       gtk_color_selection_set_update_policy(
5148         GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
5149         GTK_UPDATE_CONTINUOUS);
5150
5151       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
5152
5153       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5154                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5155                           &window);
5156
5157       gtk_signal_connect (
5158         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
5159         "color_changed",
5160         GTK_SIGNAL_FUNC(color_selection_changed),
5161         window);
5162
5163       gtk_signal_connect (
5164         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->ok_button),
5165         "clicked",
5166         GTK_SIGNAL_FUNC(color_selection_ok),
5167         window);
5168
5169       gtk_signal_connect_object (
5170         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->cancel_button),
5171         "clicked",
5172         GTK_SIGNAL_FUNC(gtk_widget_destroy),
5173         GTK_OBJECT (window));
5174     }
5175
5176   if (!GTK_WIDGET_VISIBLE (window))
5177     gtk_widget_show (window);
5178   else
5179     gtk_widget_destroy (window);
5180 }
5181
5182 /*
5183  * GtkFileSelection
5184  */
5185
5186 void
5187 file_selection_hide_fileops (GtkWidget *widget,
5188                              GtkFileSelection *fs)
5189 {
5190   gtk_file_selection_hide_fileop_buttons (fs);
5191 }
5192
5193 void
5194 file_selection_ok (GtkWidget        *w,
5195                    GtkFileSelection *fs)
5196 {
5197   g_print ("%s\n", gtk_file_selection_get_filename (fs));
5198   gtk_widget_destroy (GTK_WIDGET (fs));
5199 }
5200
5201 void
5202 create_file_selection (void)
5203 {
5204   static GtkWidget *window = NULL;
5205   GtkWidget *button;
5206
5207   if (!window)
5208     {
5209       window = gtk_file_selection_new ("file selection dialog");
5210
5211       gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (window));
5212
5213       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
5214
5215       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5216                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5217                           &window);
5218
5219       gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (window)->ok_button),
5220                           "clicked", GTK_SIGNAL_FUNC(file_selection_ok),
5221                           window);
5222       gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (window)->cancel_button),
5223                                  "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
5224                                  GTK_OBJECT (window));
5225       
5226       button = gtk_button_new_with_label ("Hide Fileops");
5227       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5228                           (GtkSignalFunc) file_selection_hide_fileops, 
5229                           (gpointer) window);
5230       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
5231                           button, FALSE, FALSE, 0);
5232       gtk_widget_show (button);
5233
5234       button = gtk_button_new_with_label ("Show Fileops");
5235       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5236                                  (GtkSignalFunc) gtk_file_selection_show_fileop_buttons, 
5237                                  (gpointer) window);
5238       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
5239                           button, FALSE, FALSE, 0);
5240       gtk_widget_show (button);
5241     }
5242   
5243   if (!GTK_WIDGET_VISIBLE (window))
5244     gtk_widget_show (window);
5245   else
5246     gtk_widget_destroy (window);
5247 }
5248
5249 /*
5250  * GtkFontSelection
5251  */
5252
5253 void
5254 font_selection_ok (GtkWidget              *w,
5255                    GtkFontSelectionDialog *fs)
5256 {
5257   g_print ("%s\n", gtk_font_selection_dialog_get_font_name (fs));
5258   gtk_widget_destroy (GTK_WIDGET (fs));
5259 }
5260
5261 void
5262 create_font_selection (void)
5263 {
5264   static GtkWidget *window = NULL;
5265
5266   if (!window)
5267     {
5268       window = gtk_font_selection_dialog_new ("Font Selection Dialog");
5269
5270       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
5271
5272       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5273                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5274                           &window);
5275
5276       gtk_signal_connect (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->ok_button),
5277                           "clicked", GTK_SIGNAL_FUNC(font_selection_ok),
5278                           GTK_FONT_SELECTION_DIALOG (window));
5279       gtk_signal_connect_object (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->cancel_button),
5280                                  "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
5281                                  GTK_OBJECT (window));
5282     }
5283   
5284   if (!GTK_WIDGET_VISIBLE (window))
5285     gtk_widget_show (window);
5286   else
5287     gtk_widget_destroy (window);
5288 }
5289
5290 /*
5291  * GtkDialog
5292  */
5293
5294 static GtkWidget *dialog_window = NULL;
5295
5296 static void
5297 label_toggle (GtkWidget  *widget,
5298               GtkWidget **label)
5299 {
5300   if (!(*label))
5301     {
5302       *label = gtk_label_new ("Dialog Test");
5303       gtk_signal_connect (GTK_OBJECT (*label),
5304                           "destroy",
5305                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
5306                           label);
5307       gtk_misc_set_padding (GTK_MISC (*label), 10, 10);
5308       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
5309                           *label, TRUE, TRUE, 0);
5310       gtk_widget_show (*label);
5311     }
5312   else
5313     gtk_widget_destroy (*label);
5314 }
5315
5316 static void
5317 create_dialog (void)
5318 {
5319   static GtkWidget *label;
5320   GtkWidget *button;
5321
5322   if (!dialog_window)
5323     {
5324       dialog_window = gtk_dialog_new ();
5325
5326       gtk_signal_connect (GTK_OBJECT (dialog_window), "destroy",
5327                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5328                           &dialog_window);
5329
5330       gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
5331       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5332       gtk_widget_set_usize (dialog_window, 200, 110);
5333
5334       button = gtk_button_new_with_label ("OK");
5335       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5336       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area), 
5337                           button, TRUE, TRUE, 0);
5338       gtk_widget_grab_default (button);
5339       gtk_widget_show (button);
5340
5341       button = gtk_button_new_with_label ("Toggle");
5342       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5343                           GTK_SIGNAL_FUNC (label_toggle),
5344                           &label);
5345       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5346       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
5347                           button, TRUE, TRUE, 0);
5348       gtk_widget_show (button);
5349
5350       label = NULL;
5351     }
5352
5353   if (!GTK_WIDGET_VISIBLE (dialog_window))
5354     gtk_widget_show (dialog_window);
5355   else
5356     gtk_widget_destroy (dialog_window);
5357 }
5358
5359 /* Event Watcher
5360  */
5361 static gboolean event_watcher_enter_id = 0;
5362 static gboolean event_watcher_leave_id = 0;
5363
5364 static gboolean
5365 event_watcher (GtkObject      *object,
5366                guint           signal_id,
5367                guint           n_params,
5368                GtkArg         *params,
5369                gpointer        data)
5370 {
5371   g_print ("Watch: \"%s\" emitted for %s\n",
5372            gtk_signal_name (signal_id),
5373            gtk_type_name (GTK_OBJECT_TYPE (object)));
5374
5375   return TRUE;
5376 }
5377
5378 static void
5379 event_watcher_down (void)
5380 {
5381   if (event_watcher_enter_id)
5382     {
5383       guint signal_id;
5384
5385       signal_id = gtk_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5386       gtk_signal_remove_emission_hook (signal_id, event_watcher_enter_id);
5387       event_watcher_enter_id = 0;
5388       signal_id = gtk_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5389       gtk_signal_remove_emission_hook (signal_id, event_watcher_leave_id);
5390       event_watcher_leave_id = 0;
5391     }
5392 }
5393
5394 static void
5395 event_watcher_toggle (void)
5396 {
5397   if (event_watcher_enter_id)
5398     event_watcher_down ();
5399   else
5400     {
5401       guint signal_id;
5402
5403       signal_id = gtk_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5404       event_watcher_enter_id = gtk_signal_add_emission_hook (signal_id, event_watcher, NULL);
5405       signal_id = gtk_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5406       event_watcher_leave_id = gtk_signal_add_emission_hook (signal_id, event_watcher, NULL);
5407     }
5408 }
5409
5410 static void
5411 create_event_watcher (void)
5412 {
5413   GtkWidget *button;
5414
5415   if (!dialog_window)
5416     {
5417       dialog_window = gtk_dialog_new ();
5418
5419       gtk_signal_connect (GTK_OBJECT (dialog_window), "destroy",
5420                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
5421                           &dialog_window);
5422       gtk_signal_connect (GTK_OBJECT (dialog_window),
5423                           "destroy",
5424                           GTK_SIGNAL_FUNC (event_watcher_down),
5425                           NULL);
5426
5427       gtk_window_set_title (GTK_WINDOW (dialog_window), "Event Watcher");
5428       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5429       gtk_widget_set_usize (dialog_window, 200, 110);
5430
5431       button = gtk_toggle_button_new_with_label ("Activate Watch");
5432       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5433                           GTK_SIGNAL_FUNC (event_watcher_toggle),
5434                           NULL);
5435       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
5436       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
5437                           button, TRUE, TRUE, 0);
5438       gtk_widget_show (button);
5439
5440       button = gtk_button_new_with_label ("Close");
5441       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5442                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
5443                                  (GtkObject*) dialog_window);
5444       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5445       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
5446                           button, TRUE, TRUE, 0);
5447       gtk_widget_grab_default (button);
5448       gtk_widget_show (button);
5449     }
5450
5451   if (!GTK_WIDGET_VISIBLE (dialog_window))
5452     gtk_widget_show (dialog_window);
5453   else
5454     gtk_widget_destroy (dialog_window);
5455 }
5456
5457 /*
5458  * GtkRange
5459  */
5460
5461 static void
5462 create_range_controls (void)
5463 {
5464   static GtkWidget *window = NULL;
5465   GtkWidget *box1;
5466   GtkWidget *box2;
5467   GtkWidget *button;
5468   GtkWidget *scrollbar;
5469   GtkWidget *scale;
5470   GtkWidget *separator;
5471   GtkObject *adjustment;
5472
5473   if (!window)
5474     {
5475       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5476
5477       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5478                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5479                           &window);
5480
5481       gtk_window_set_title (GTK_WINDOW (window), "range controls");
5482       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5483
5484
5485       box1 = gtk_vbox_new (FALSE, 0);
5486       gtk_container_add (GTK_CONTAINER (window), box1);
5487       gtk_widget_show (box1);
5488
5489
5490       box2 = gtk_vbox_new (FALSE, 10);
5491       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5492       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
5493       gtk_widget_show (box2);
5494
5495
5496       adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
5497
5498       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
5499       gtk_widget_set_usize (GTK_WIDGET (scale), 150, 30);
5500       gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
5501       gtk_scale_set_digits (GTK_SCALE (scale), 1);
5502       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5503       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
5504       gtk_widget_show (scale);
5505
5506       scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adjustment));
5507       gtk_range_set_update_policy (GTK_RANGE (scrollbar), 
5508                                    GTK_UPDATE_CONTINUOUS);
5509       gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
5510       gtk_widget_show (scrollbar);
5511
5512
5513       separator = gtk_hseparator_new ();
5514       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
5515       gtk_widget_show (separator);
5516
5517
5518       box2 = gtk_vbox_new (FALSE, 10);
5519       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5520       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5521       gtk_widget_show (box2);
5522
5523
5524       button = gtk_button_new_with_label ("close");
5525       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5526                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
5527                                  GTK_OBJECT (window));
5528       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5529       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5530       gtk_widget_grab_default (button);
5531       gtk_widget_show (button);
5532     }
5533
5534   if (!GTK_WIDGET_VISIBLE (window))
5535     gtk_widget_show (window);
5536   else
5537     gtk_widget_destroy (window);
5538 }
5539
5540 /*
5541  * GtkRulers
5542  */
5543
5544 void
5545 create_rulers (void)
5546 {
5547   static GtkWidget *window = NULL;
5548   GtkWidget *table;
5549   GtkWidget *ruler;
5550
5551   if (!window)
5552     {
5553       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5554       gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, FALSE);
5555
5556       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5557                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5558                           &window);
5559
5560       gtk_window_set_title (GTK_WINDOW (window), "rulers");
5561       gtk_widget_set_usize (window, 300, 300);
5562       gtk_widget_set_events (window, 
5563                              GDK_POINTER_MOTION_MASK 
5564                              | GDK_POINTER_MOTION_HINT_MASK);
5565       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5566
5567       table = gtk_table_new (2, 2, FALSE);
5568       gtk_container_add (GTK_CONTAINER (window), table);
5569       gtk_widget_show (table);
5570
5571       ruler = gtk_hruler_new ();
5572       gtk_ruler_set_metric (GTK_RULER (ruler), GTK_CENTIMETERS);
5573       gtk_ruler_set_range (GTK_RULER (ruler), 100, 0, 0, 20);
5574
5575       gtk_signal_connect_object (
5576         GTK_OBJECT (window), 
5577         "motion_notify_event",
5578         GTK_SIGNAL_FUNC(
5579           GTK_WIDGET_CLASS (GTK_OBJECT (ruler)->klass)->motion_notify_event),
5580         GTK_OBJECT (ruler));
5581
5582       gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1,
5583                         GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
5584       gtk_widget_show (ruler);
5585
5586
5587       ruler = gtk_vruler_new ();
5588       gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
5589
5590       gtk_signal_connect_object (
5591         GTK_OBJECT (window), 
5592         "motion_notify_event",
5593         GTK_SIGNAL_FUNC (GTK_WIDGET_CLASS (GTK_OBJECT (ruler)->klass)->motion_notify_event),
5594         GTK_OBJECT (ruler));
5595
5596       gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2,
5597                         GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
5598       gtk_widget_show (ruler);
5599     }
5600
5601   if (!GTK_WIDGET_VISIBLE (window))
5602     gtk_widget_show (window);
5603   else
5604     gtk_widget_destroy (window);
5605 }
5606
5607 static void
5608 text_toggle_editable (GtkWidget *checkbutton,
5609                        GtkWidget *text)
5610 {
5611    gtk_text_set_editable(GTK_TEXT(text),
5612                           GTK_TOGGLE_BUTTON(checkbutton)->active);
5613 }
5614
5615 static void
5616 text_toggle_word_wrap (GtkWidget *checkbutton,
5617                        GtkWidget *text)
5618 {
5619    gtk_text_set_word_wrap(GTK_TEXT(text),
5620                           GTK_TOGGLE_BUTTON(checkbutton)->active);
5621 }
5622
5623 struct {
5624   GdkColor color;
5625   gchar *name;
5626 } text_colors[] = {
5627  { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
5628  { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
5629  { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
5630  { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
5631  { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" }, 
5632  { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
5633  { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
5634  { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
5635 };
5636
5637 int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
5638
5639 /*
5640  * GtkText
5641  */
5642 void
5643 text_insert_random (GtkWidget *w, GtkText *text)
5644 {
5645   int i;
5646   char c;
5647    for (i=0; i<10; i++)
5648     {
5649       c = 'A' + rand() % ('Z' - 'A');
5650       gtk_text_set_point (text, rand() % gtk_text_get_length (text));
5651       gtk_text_insert (text, NULL, NULL, NULL, &c, 1);
5652     }
5653 }
5654
5655 void
5656 create_text (void)
5657 {
5658   int i, j;
5659
5660   static GtkWidget *window = NULL;
5661   GtkWidget *box1;
5662   GtkWidget *box2;
5663   GtkWidget *hbox;
5664   GtkWidget *button;
5665   GtkWidget *check;
5666   GtkWidget *separator;
5667   GtkWidget *table;
5668   GtkWidget *hscrollbar;
5669   GtkWidget *vscrollbar;
5670   GtkWidget *text;
5671   GdkFont *font;
5672
5673   FILE *infile;
5674
5675   if (!window)
5676     {
5677       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5678       gtk_widget_set_name (window, "text window");
5679       gtk_widget_set_usize (window, 500, 500);
5680       gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, FALSE);
5681
5682       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5683                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5684                           &window);
5685
5686       gtk_window_set_title (GTK_WINDOW (window), "test");
5687       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5688
5689
5690       box1 = gtk_vbox_new (FALSE, 0);
5691       gtk_container_add (GTK_CONTAINER (window), box1);
5692       gtk_widget_show (box1);
5693
5694
5695       box2 = gtk_vbox_new (FALSE, 10);
5696       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5697       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
5698       gtk_widget_show (box2);
5699
5700
5701       table = gtk_table_new (2, 2, FALSE);
5702       gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2);
5703       gtk_table_set_col_spacing (GTK_TABLE (table), 0, 2);
5704       gtk_box_pack_start (GTK_BOX (box2), table, TRUE, TRUE, 0);
5705       gtk_widget_show (table);
5706
5707       text = gtk_text_new (NULL, NULL);
5708       gtk_text_set_editable (GTK_TEXT (text), TRUE);
5709       gtk_table_attach (GTK_TABLE (table), text, 0, 1, 0, 1,
5710                         GTK_EXPAND | GTK_SHRINK | GTK_FILL,
5711                         GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
5712       gtk_widget_grab_focus (text);
5713       gtk_widget_show (text);
5714
5715       hscrollbar = gtk_hscrollbar_new (GTK_TEXT (text)->hadj);
5716       gtk_table_attach (GTK_TABLE (table), hscrollbar, 0, 1, 1, 2,
5717                         GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL, 0, 0);
5718       gtk_widget_show (hscrollbar);
5719
5720       vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
5721       gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 0, 1,
5722                         GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
5723       gtk_widget_show (vscrollbar);
5724
5725       gtk_text_freeze (GTK_TEXT (text));
5726
5727       font = gdk_font_load ("-adobe-courier-medium-r-normal--*-120-*-*-*-*-*-*");
5728
5729       for (i=0; i<ntext_colors; i++)
5730         {
5731           gtk_text_insert (GTK_TEXT (text), font, NULL, NULL, 
5732                            text_colors[i].name, -1);
5733           gtk_text_insert (GTK_TEXT (text), font, NULL, NULL, "\t", -1);
5734
5735           for (j=0; j<ntext_colors; j++)
5736             {
5737               gtk_text_insert (GTK_TEXT (text), font,
5738                                &text_colors[j].color, &text_colors[i].color,
5739                                "XYZ", -1);
5740             }
5741           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\n", -1);
5742         }
5743
5744       /* The Text widget will reference count the font, so we
5745        * unreference it here
5746        */
5747       gdk_font_unref (font);
5748
5749       infile = fopen("testgtk.c", "r");
5750       
5751       if (infile)
5752         {
5753           char *buffer;
5754           int nbytes_read, nbytes_alloc;
5755           
5756           nbytes_read = 0;
5757           nbytes_alloc = 1024;
5758           buffer = g_new (char, nbytes_alloc);
5759           while (1)
5760             {
5761               int len;
5762               if (nbytes_alloc < nbytes_read + 1024)
5763                 {
5764                   nbytes_alloc *= 2;
5765                   buffer = g_realloc (buffer, nbytes_alloc);
5766                 }
5767               len = fread (buffer + nbytes_read, 1, 1024, infile);
5768               nbytes_read += len;
5769               if (len < 1024)
5770                 break;
5771             }
5772           
5773           gtk_text_insert (GTK_TEXT (text), NULL, NULL,
5774                            NULL, buffer, nbytes_read);
5775           g_free(buffer);
5776           fclose (infile);
5777         }
5778       
5779       gtk_text_thaw (GTK_TEXT (text));
5780
5781       hbox = gtk_hbutton_box_new ();
5782       gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, FALSE, 0);
5783       gtk_widget_show (hbox);
5784
5785       check = gtk_check_button_new_with_label("Editable");
5786       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, FALSE, 0);
5787       gtk_signal_connect (GTK_OBJECT(check), "toggled",
5788                           GTK_SIGNAL_FUNC(text_toggle_editable), text);
5789       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(check), TRUE);
5790       gtk_widget_show (check);
5791
5792       check = gtk_check_button_new_with_label("Wrap Words");
5793       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
5794       gtk_signal_connect (GTK_OBJECT(check), "toggled",
5795                           GTK_SIGNAL_FUNC(text_toggle_word_wrap), text);
5796       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(check), FALSE);
5797       gtk_widget_show (check);
5798
5799       separator = gtk_hseparator_new ();
5800       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
5801       gtk_widget_show (separator);
5802
5803
5804       box2 = gtk_vbox_new (FALSE, 10);
5805       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5806       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5807       gtk_widget_show (box2);
5808
5809
5810       button = gtk_button_new_with_label ("insert random");
5811       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5812                           GTK_SIGNAL_FUNC(text_insert_random),
5813                           GTK_TEXT (text));
5814       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5815       gtk_widget_show (button);
5816
5817       button = gtk_button_new_with_label ("close");
5818       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5819                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
5820                                  GTK_OBJECT (window));
5821       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5822       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5823       gtk_widget_grab_default (button);
5824       gtk_widget_show (button);
5825     }
5826
5827   if (!GTK_WIDGET_VISIBLE (window))
5828     gtk_widget_show (window);
5829   else
5830     gtk_widget_destroy (window);
5831 }
5832
5833 /*
5834  * GtkNotebook
5835  */
5836
5837 GdkPixmap *book_open;
5838 GdkPixmap *book_closed;
5839 GdkBitmap *book_open_mask;
5840 GdkBitmap *book_closed_mask;
5841 GtkWidget *sample_notebook;
5842
5843 static void
5844 page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
5845 {
5846   GtkNotebookPage *oldpage;
5847   GtkWidget *pixwid;
5848
5849   oldpage = GTK_NOTEBOOK (widget)->cur_page;
5850
5851   if (page == oldpage)
5852     return;
5853   pixwid = ((GtkBoxChild*)
5854             (GTK_BOX (page->tab_label)->children->data))->widget;
5855   gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask);
5856   pixwid = ((GtkBoxChild*)
5857             (GTK_BOX (page->menu_label)->children->data))->widget;
5858   gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask);
5859
5860   if (oldpage)
5861     {
5862       pixwid = ((GtkBoxChild*)
5863                 (GTK_BOX (oldpage->tab_label)->children->data))->widget;
5864       gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask);
5865       pixwid = ((GtkBoxChild*)
5866                 (GTK_BOX (oldpage->menu_label)->children->data))->widget;
5867       gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask);
5868     }
5869 }
5870
5871 static void
5872 tab_fill (GtkToggleButton *button, GtkWidget *child)
5873 {
5874   gboolean expand;
5875   GtkPackType pack_type;
5876
5877   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
5878                                         &expand, NULL, &pack_type);
5879   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
5880                                       expand, button->active, pack_type);
5881 }
5882
5883 static void
5884 tab_expand (GtkToggleButton *button, GtkWidget *child)
5885 {
5886   gboolean fill;
5887   GtkPackType pack_type;
5888
5889   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
5890                                         NULL, &fill, &pack_type);
5891   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
5892                                       button->active, fill, pack_type);
5893 }
5894
5895 static void
5896 tab_pack (GtkToggleButton *button, GtkWidget *child)
5897           
5898
5899   gboolean expand;
5900   gboolean fill;
5901
5902   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
5903                                         &expand, &fill, NULL);
5904   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
5905                                       expand, fill, button->active);
5906 }
5907
5908 static void
5909 create_pages (GtkNotebook *notebook, gint start, gint end)
5910 {
5911   GtkWidget *child = NULL;
5912   GtkWidget *button;
5913   GtkWidget *label;
5914   GtkWidget *hbox;
5915   GtkWidget *vbox;
5916   GtkWidget *label_box;
5917   GtkWidget *menu_box;
5918   GtkWidget *pixwid;
5919   gint i;
5920   char buffer[32];
5921
5922   for (i = start; i <= end; i++)
5923     {
5924       sprintf (buffer, "Page %d", i);
5925
5926       child = gtk_frame_new (buffer);
5927       gtk_container_set_border_width (GTK_CONTAINER (child), 10);
5928
5929       vbox = gtk_vbox_new (TRUE,0);
5930       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
5931       gtk_container_add (GTK_CONTAINER (child), vbox);
5932
5933       hbox = gtk_hbox_new (TRUE,0);
5934       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
5935
5936       button = gtk_check_button_new_with_label ("Fill Tab");
5937       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5938       gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (button), TRUE);
5939       gtk_signal_connect (GTK_OBJECT (button), "toggled",
5940                           GTK_SIGNAL_FUNC (tab_fill), child);
5941
5942       button = gtk_check_button_new_with_label ("Expand Tab");
5943       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5944       gtk_signal_connect (GTK_OBJECT (button), "toggled",
5945       GTK_SIGNAL_FUNC (tab_expand), child);
5946
5947       button = gtk_check_button_new_with_label ("Pack end");
5948       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5949       gtk_signal_connect (GTK_OBJECT (button), "toggled",
5950                           GTK_SIGNAL_FUNC (tab_pack), child);
5951
5952       button = gtk_button_new_with_label ("Hide Page");
5953       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
5954       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5955                                  GTK_SIGNAL_FUNC (gtk_widget_hide),
5956                                  GTK_OBJECT (child));
5957
5958       gtk_widget_show_all (child);
5959
5960       label_box = gtk_hbox_new (FALSE, 0);
5961       pixwid = gtk_pixmap_new (book_closed, book_closed_mask);
5962       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
5963       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
5964       label = gtk_label_new (buffer);
5965       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
5966       gtk_widget_show_all (label_box);
5967
5968       menu_box = gtk_hbox_new (FALSE, 0);
5969       pixwid = gtk_pixmap_new (book_closed, book_closed_mask);
5970       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
5971       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
5972       label = gtk_label_new (buffer);
5973       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
5974       gtk_widget_show_all (menu_box);
5975       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
5976     }
5977 }
5978
5979 static void
5980 rotate_notebook (GtkButton   *button,
5981                  GtkNotebook *notebook)
5982 {
5983   gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4);
5984 }
5985
5986 static void
5987 show_all_pages (GtkButton   *button,
5988                 GtkNotebook *notebook)
5989 {  
5990   gtk_container_foreach (GTK_CONTAINER (notebook),
5991                          (GtkCallback) gtk_widget_show, NULL);
5992 }
5993
5994 static void
5995 standard_notebook (GtkButton   *button,
5996                    GtkNotebook *notebook)
5997 {
5998   gint i;
5999
6000   gtk_notebook_set_show_tabs (notebook, TRUE);
6001   gtk_notebook_set_scrollable (notebook, FALSE);
6002   if (g_list_length (notebook->children) == 15)
6003     for (i = 0; i < 10; i++)
6004       gtk_notebook_remove_page (notebook, 5);
6005 }
6006
6007 static void
6008 notabs_notebook (GtkButton   *button,
6009                  GtkNotebook *notebook)
6010 {
6011   gint i;
6012
6013   gtk_notebook_set_show_tabs (notebook, FALSE);
6014   if (g_list_length (notebook->children) == 15)
6015     for (i = 0; i < 10; i++)
6016       gtk_notebook_remove_page (notebook, 5);
6017 }
6018
6019 static void
6020 scrollable_notebook (GtkButton   *button,
6021                      GtkNotebook *notebook)
6022 {
6023   gtk_notebook_set_show_tabs (notebook, TRUE);
6024   gtk_notebook_set_scrollable (notebook, TRUE);
6025   if (g_list_length (notebook->children) == 5)
6026     create_pages (notebook, 6, 15);
6027 }
6028
6029 static void
6030 notebook_popup (GtkToggleButton *button,
6031                 GtkNotebook     *notebook)
6032 {
6033   if (button->active)
6034     gtk_notebook_popup_enable (notebook);
6035   else
6036     gtk_notebook_popup_disable (notebook);
6037 }
6038
6039 static void
6040 notebook_homogeneous (GtkToggleButton *button,
6041                       GtkNotebook     *notebook)
6042 {
6043   gtk_notebook_set_homogeneous_tabs (notebook, button->active);
6044 }
6045
6046 static void
6047 create_notebook (void)
6048 {
6049   static GtkWidget *window = NULL;
6050   GtkWidget *box1;
6051   GtkWidget *box2;
6052   GtkWidget *button;
6053   GtkWidget *separator;
6054   GtkWidget *omenu;
6055   GdkColor *transparent = NULL;
6056   GtkWidget *label;
6057
6058   static OptionMenuItem items[] =
6059   {
6060     { "Standard",   standard_notebook },
6061     { "No tabs",    notabs_notebook },
6062     { "Scrollable", scrollable_notebook }
6063   };
6064
6065   if (!window)
6066     {
6067       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6068
6069       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6070                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6071                           &window);
6072
6073       gtk_window_set_title (GTK_WINDOW (window), "notebook");
6074       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6075
6076       box1 = gtk_vbox_new (FALSE, 0);
6077       gtk_container_add (GTK_CONTAINER (window), box1);
6078
6079       sample_notebook = gtk_notebook_new ();
6080       gtk_signal_connect (GTK_OBJECT (sample_notebook), "switch_page",
6081                           GTK_SIGNAL_FUNC (page_switch), NULL);
6082       gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP);
6083       gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0);
6084       gtk_container_set_border_width (GTK_CONTAINER (sample_notebook), 10);
6085
6086       gtk_widget_realize (sample_notebook);
6087       book_open = gdk_pixmap_create_from_xpm_d (sample_notebook->window,
6088                                                 &book_open_mask, 
6089                                                 transparent, 
6090                                                 book_open_xpm);
6091       book_closed = gdk_pixmap_create_from_xpm_d (sample_notebook->window,
6092                                                   &book_closed_mask,
6093                                                   transparent, 
6094                                                   book_closed_xpm);
6095
6096       create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5);
6097
6098       separator = gtk_hseparator_new ();
6099       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
6100       
6101       box2 = gtk_hbox_new (FALSE, 5);
6102       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6103       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6104
6105       button = gtk_check_button_new_with_label ("popup menu");
6106       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
6107       gtk_signal_connect (GTK_OBJECT(button), "clicked",
6108                           GTK_SIGNAL_FUNC (notebook_popup),
6109                           GTK_OBJECT (sample_notebook));
6110
6111       button = gtk_check_button_new_with_label ("homogeneous tabs");
6112       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
6113       gtk_signal_connect (GTK_OBJECT(button), "clicked",
6114                           GTK_SIGNAL_FUNC (notebook_homogeneous),
6115                           GTK_OBJECT (sample_notebook));
6116
6117       box2 = gtk_hbox_new (FALSE, 5);
6118       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6119       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6120
6121       label = gtk_label_new ("Notebook Style :");
6122       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
6123
6124       omenu = build_option_menu (items, 3, 0, sample_notebook);
6125       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
6126
6127       button = gtk_button_new_with_label ("Show all Pages");
6128       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
6129       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6130                           GTK_SIGNAL_FUNC (show_all_pages), sample_notebook);
6131
6132       box2 = gtk_hbox_new (TRUE, 10);
6133       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6134       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6135
6136       button = gtk_button_new_with_label ("prev");
6137       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6138                                  GTK_SIGNAL_FUNC (gtk_notebook_prev_page),
6139                                  GTK_OBJECT (sample_notebook));
6140       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6141
6142       button = gtk_button_new_with_label ("next");
6143       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6144                                  GTK_SIGNAL_FUNC (gtk_notebook_next_page),
6145                                  GTK_OBJECT (sample_notebook));
6146       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6147
6148       button = gtk_button_new_with_label ("rotate");
6149       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6150                           GTK_SIGNAL_FUNC (rotate_notebook), sample_notebook);
6151       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6152
6153       separator = gtk_hseparator_new ();
6154       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
6155
6156       button = gtk_button_new_with_label ("close");
6157       gtk_container_set_border_width (GTK_CONTAINER (button), 5);
6158       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6159                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
6160                                  GTK_OBJECT (window));
6161       gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
6162       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6163       gtk_widget_grab_default (button);
6164     }
6165
6166   if (!GTK_WIDGET_VISIBLE (window))
6167     gtk_widget_show_all (window);
6168   else
6169     gtk_widget_destroy (window);
6170 }
6171
6172 /*
6173  * GtkPanes
6174  */
6175
6176 void
6177 toggle_resize (GtkWidget *widget, GtkWidget *child)
6178 {
6179   GtkPaned *paned = GTK_PANED (child->parent);
6180   gboolean is_child1 = (child == paned->child1);
6181   gboolean resize, shrink;
6182
6183   resize = is_child1 ? paned->child1_resize : paned->child2_resize;
6184   shrink = is_child1 ? paned->child1_shrink : paned->child2_shrink;
6185
6186   gtk_widget_ref (child);
6187   gtk_container_remove (GTK_CONTAINER (child->parent), child);
6188   if (is_child1)
6189     gtk_paned_pack1 (paned, child, !resize, shrink);
6190   else
6191     gtk_paned_pack2 (paned, child, !resize, shrink);
6192   gtk_widget_unref (child);
6193 }
6194
6195 void
6196 toggle_shrink (GtkWidget *widget, GtkWidget *child)
6197 {
6198   GtkPaned *paned = GTK_PANED (child->parent);
6199   gboolean is_child1 = (child == paned->child1);
6200   gboolean resize, shrink;
6201
6202   resize = is_child1 ? paned->child1_resize : paned->child2_resize;
6203   shrink = is_child1 ? paned->child1_shrink : paned->child2_shrink;
6204
6205   gtk_widget_ref (child);
6206   gtk_container_remove (GTK_CONTAINER (child->parent), child);
6207   if (is_child1)
6208     gtk_paned_pack1 (paned, child, resize, !shrink);
6209   else
6210     gtk_paned_pack2 (paned, child, resize, !shrink);
6211   gtk_widget_unref (child);
6212 }
6213
6214 GtkWidget *
6215 create_pane_options (GtkPaned *paned,
6216                      const gchar *frame_label,
6217                      const gchar *label1,
6218                      const gchar *label2)
6219 {
6220   GtkWidget *frame;
6221   GtkWidget *table;
6222   GtkWidget *label;
6223   GtkWidget *check_button;
6224   
6225   frame = gtk_frame_new (frame_label);
6226   gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
6227   
6228   table = gtk_table_new (3, 2, 4);
6229   gtk_container_add (GTK_CONTAINER (frame), table);
6230   
6231   label = gtk_label_new (label1);
6232   gtk_table_attach_defaults (GTK_TABLE (table), label,
6233                              0, 1, 0, 1);
6234   
6235   check_button = gtk_check_button_new_with_label ("Resize");
6236   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6237                              0, 1, 1, 2);
6238   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
6239                       GTK_SIGNAL_FUNC (toggle_resize),
6240                       paned->child1);
6241   
6242   check_button = gtk_check_button_new_with_label ("Shrink");
6243   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6244                              0, 1, 2, 3);
6245   gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (check_button),
6246                                TRUE);
6247   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
6248                       GTK_SIGNAL_FUNC (toggle_shrink),
6249                       paned->child1);
6250   
6251   label = gtk_label_new (label2);
6252   gtk_table_attach_defaults (GTK_TABLE (table), label,
6253                              1, 2, 0, 1);
6254   
6255   check_button = gtk_check_button_new_with_label ("Resize");
6256   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6257                              1, 2, 1, 2);
6258   gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (check_button),
6259                                TRUE);
6260   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
6261                       GTK_SIGNAL_FUNC (toggle_resize),
6262                       paned->child2);
6263   
6264   check_button = gtk_check_button_new_with_label ("Shrink");
6265   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6266                              1, 2, 2, 3);
6267   gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (check_button),
6268                                TRUE);
6269   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
6270                       GTK_SIGNAL_FUNC (toggle_shrink),
6271                       paned->child2);
6272
6273   return frame;
6274 }
6275
6276 void
6277 create_panes (void)
6278 {
6279   static GtkWidget *window = NULL;
6280   GtkWidget *frame;
6281   GtkWidget *hpaned;
6282   GtkWidget *vpaned;
6283   GtkWidget *button;
6284   GtkWidget *vbox;
6285
6286   if (!window)
6287     {
6288       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6289
6290       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6291                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6292                           &window);
6293
6294       gtk_window_set_title (GTK_WINDOW (window), "Panes");
6295       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6296
6297       vbox = gtk_vbox_new (FALSE, 0);
6298       gtk_container_add (GTK_CONTAINER (window), vbox);
6299       
6300       vpaned = gtk_vpaned_new ();
6301       gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
6302       gtk_container_set_border_width (GTK_CONTAINER(vpaned), 5);
6303
6304       hpaned = gtk_hpaned_new ();
6305       gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
6306
6307       frame = gtk_frame_new (NULL);
6308       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6309       gtk_widget_set_usize (frame, 60, 60);
6310       gtk_paned_add1 (GTK_PANED (hpaned), frame);
6311       
6312       button = gtk_button_new_with_label ("Hi there");
6313       gtk_container_add (GTK_CONTAINER(frame), button);
6314
6315       frame = gtk_frame_new (NULL);
6316       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6317       gtk_widget_set_usize (frame, 80, 60);
6318       gtk_paned_add2 (GTK_PANED (hpaned), frame);
6319
6320       frame = gtk_frame_new (NULL);
6321       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6322       gtk_widget_set_usize (frame, 60, 80);
6323       gtk_paned_add2 (GTK_PANED (vpaned), frame);
6324
6325       /* Now create toggle buttons to control sizing */
6326
6327       gtk_box_pack_start (GTK_BOX (vbox),
6328                           create_pane_options (GTK_PANED (hpaned),
6329                                                "Horizontal",
6330                                                "Left",
6331                                                "Right"),
6332                           FALSE, FALSE, 0);
6333
6334       gtk_box_pack_start (GTK_BOX (vbox),
6335                           create_pane_options (GTK_PANED (vpaned),
6336                                                "Vertical",
6337                                                "Top",
6338                                                "Bottom"),
6339                           FALSE, FALSE, 0);
6340
6341       gtk_widget_show_all (vbox);
6342     }
6343
6344   if (!GTK_WIDGET_VISIBLE (window))
6345     gtk_widget_show (window);
6346   else
6347     gtk_widget_destroy (window);
6348 }
6349
6350 /*
6351  * Drag -N- Drop
6352  */
6353
6354 #if 0
6355 gint
6356 dnd_drop_destroy_popup (GtkWidget *widget, GtkWindow **window)
6357 {
6358   if(GTK_IS_BUTTON(widget)) /* I.e. they clicked the close button */
6359     gtk_widget_destroy(GTK_WIDGET(*window));
6360   else {
6361     gtk_grab_remove(GTK_WIDGET(*window));
6362     *window = NULL;
6363   }
6364
6365   return FALSE;
6366 }
6367
6368 void
6369 dnd_drop (GtkWidget *button, GdkEvent *event)
6370 {
6371   static GtkWidget *window = NULL;
6372   GtkWidget *vbox, *lbl, *btn;
6373   gchar *msg;
6374
6375   /* DND doesn't obey gtk_grab's, so check if we're already displaying
6376    * drop modal dialog first
6377    */
6378   if (window)
6379     return;
6380
6381   window = gtk_window_new(GTK_WINDOW_DIALOG);
6382   gtk_container_set_border_width (GTK_CONTAINER(window), 10);
6383
6384   gtk_signal_connect (GTK_OBJECT (window), "destroy",
6385                       GTK_SIGNAL_FUNC(dnd_drop_destroy_popup),
6386                       &window);
6387   gtk_signal_connect (GTK_OBJECT (window), "delete-event",
6388                       GTK_SIGNAL_FUNC(gtk_false),
6389                       &window);
6390
6391   vbox = gtk_vbox_new(FALSE, 5);
6392
6393   /* Display message that we got from drop source */
6394   msg = g_malloc(strlen(event->dropdataavailable.data)
6395                  + strlen(event->dropdataavailable.data_type) + 100);
6396   sprintf(msg, "Drop data of type %s was:\n\n%s",
6397           event->dropdataavailable.data_type,
6398           (char *)event->dropdataavailable.data);
6399   lbl = gtk_label_new(msg);
6400   gtk_label_set_justify(GTK_LABEL(lbl), GTK_JUSTIFY_FILL);
6401   g_free(msg);
6402   gtk_widget_show(lbl);
6403   gtk_box_pack_start_defaults(GTK_BOX(vbox), lbl);
6404
6405   /* Provide an obvious way out of this heinousness */
6406   btn = gtk_button_new_with_label("Continue with life in\nspite of this oppression");
6407   gtk_signal_connect_object (GTK_OBJECT (btn), "clicked",
6408                              GTK_SIGNAL_FUNC(gtk_widget_destroy),
6409                              GTK_OBJECT (window));
6410   gtk_widget_show(btn);
6411   gtk_box_pack_start_defaults(GTK_BOX(vbox), btn);
6412
6413   gtk_container_add(GTK_CONTAINER(window), vbox);
6414
6415   gtk_widget_show(vbox);
6416   gtk_grab_add(window);
6417   gtk_widget_show(window);
6418 }
6419
6420 void
6421 dnd_drag_request (GtkWidget *button, GdkEvent *event)
6422 {
6423 #define DND_STRING "Bill Gates demands royalties for\nyour use of his innovation."
6424   gtk_widget_dnd_data_set (button, event, DND_STRING, strlen(DND_STRING) + 1);
6425 }
6426
6427 void
6428 create_dnd (void)
6429 {
6430   static GtkWidget *window = NULL;
6431   GtkWidget *box1;
6432   GtkWidget *box2;
6433   GtkWidget *box3;
6434   GtkWidget *frame;
6435   GtkWidget *button;
6436   GtkWidget *separator;
6437
6438   /* For clarity... */
6439   char *possible_drag_types[] = {"text/plain"};
6440   char *accepted_drop_types[] = {"text/plain"};
6441
6442   static GtkWidget *drag_icon = NULL;
6443   static GtkWidget *drop_icon = NULL;
6444
6445   if (!window)
6446     {
6447       GdkPoint hotspot = {5,5};
6448       
6449       if (!drag_icon)
6450         {
6451           drag_icon = shape_create_icon ("Modeller.xpm",
6452                                          440, 140, 0,0, GTK_WINDOW_POPUP);
6453           
6454           gtk_signal_connect (GTK_OBJECT (drag_icon), "destroy",
6455                               GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6456                               &drag_icon);
6457
6458           gtk_widget_hide (drag_icon);
6459         }
6460       
6461       if (!drop_icon)
6462         {
6463           drop_icon = shape_create_icon ("3DRings.xpm",
6464                                          440, 140, 0,0, GTK_WINDOW_POPUP);
6465           
6466           gtk_signal_connect (GTK_OBJECT (drop_icon), "destroy",
6467                               GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6468                               &drop_icon);
6469
6470           gtk_widget_hide (drop_icon);
6471         }
6472
6473       gdk_dnd_set_drag_shape(drag_icon->window,
6474                              &hotspot,
6475                              drop_icon->window,
6476                              &hotspot);
6477
6478       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6479
6480       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6481                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6482                           &window);
6483
6484       gtk_window_set_title (GTK_WINDOW (window), "Drag -N- Drop");
6485       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6486
6487       box1 = gtk_vbox_new (FALSE, 0);
6488       gtk_container_add (GTK_CONTAINER (window), box1);
6489       gtk_widget_show (box1);
6490
6491       box2 = gtk_hbox_new (FALSE, 5);
6492       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6493       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
6494       gtk_widget_show (box2);
6495
6496       frame = gtk_frame_new ("Drag");
6497       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
6498       gtk_widget_show (frame);
6499
6500       box3 = gtk_vbox_new (FALSE, 5);
6501       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
6502       gtk_container_add (GTK_CONTAINER (frame), box3);
6503       gtk_widget_show (box3);
6504
6505       /*
6506        * FROM Button
6507        */
6508       button = gtk_button_new_with_label ("Drag me!");
6509       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
6510       gtk_widget_show (button);
6511
6512       /*
6513        * currently, the widget has to be realized to
6514        * set dnd on it, this needs to change
6515        */
6516       gtk_widget_realize (button);
6517       gtk_signal_connect (GTK_OBJECT (button),
6518                           "drag_request_event",
6519                           GTK_SIGNAL_FUNC(dnd_drag_request),
6520                           button);
6521       
6522       gtk_widget_dnd_drag_set (button, TRUE, possible_drag_types, 1);
6523
6524
6525       frame = gtk_frame_new ("Drop");
6526       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
6527       gtk_widget_show (frame);
6528
6529       box3 = gtk_vbox_new (FALSE, 5);
6530       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
6531       gtk_container_add (GTK_CONTAINER (frame), box3);
6532       gtk_widget_show (box3);
6533
6534
6535       /*
6536        * TO Button
6537        */
6538       button = gtk_button_new_with_label ("To");
6539       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
6540       gtk_widget_show (button);
6541
6542       gtk_widget_realize (button);
6543       gtk_signal_connect (GTK_OBJECT (button), 
6544                           "drop_data_available_event",
6545                           GTK_SIGNAL_FUNC(dnd_drop),
6546                           button);
6547
6548       gtk_widget_dnd_drop_set (button, TRUE, accepted_drop_types, 1, FALSE);
6549
6550
6551       separator = gtk_hseparator_new ();
6552       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
6553       gtk_widget_show (separator);
6554
6555
6556       box2 = gtk_vbox_new (FALSE, 10);
6557       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6558       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6559       gtk_widget_show (box2);
6560
6561
6562       button = gtk_button_new_with_label ("close");
6563
6564       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6565                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
6566                                  GTK_OBJECT (window));
6567
6568       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6569       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6570       gtk_widget_grab_default (button);
6571       gtk_widget_show (button);
6572     }
6573
6574   if (!GTK_WIDGET_VISIBLE (window))
6575     gtk_widget_show (window);
6576   else
6577     gtk_widget_destroy (window);
6578 }
6579 #endif
6580
6581 /*
6582  * Shaped Windows
6583  */
6584
6585 static GdkWindow *root_win = NULL;
6586
6587 typedef struct _cursoroffset {gint x,y;} CursorOffset;
6588
6589 static void
6590 shape_pressed (GtkWidget *widget, GdkEventButton *event)
6591 {
6592   CursorOffset *p;
6593
6594   /* ignore double and triple click */
6595   if (event->type != GDK_BUTTON_PRESS)
6596     return;
6597
6598   p = gtk_object_get_user_data (GTK_OBJECT(widget));
6599   p->x = (int) event->x;
6600   p->y = (int) event->y;
6601
6602   gtk_grab_add (widget);
6603   gdk_pointer_grab (widget->window, TRUE,
6604                     GDK_BUTTON_RELEASE_MASK |
6605                     GDK_BUTTON_MOTION_MASK |
6606                     GDK_POINTER_MOTION_HINT_MASK,
6607                     NULL, NULL, 0);
6608 }
6609
6610 static void
6611 shape_released (GtkWidget *widget)
6612 {
6613   gtk_grab_remove (widget);
6614   gdk_pointer_ungrab (0);
6615 }
6616
6617 static void
6618 shape_motion (GtkWidget      *widget, 
6619               GdkEventMotion *event)
6620 {
6621   gint xp, yp;
6622   CursorOffset * p;
6623   GdkModifierType mask;
6624
6625   p = gtk_object_get_user_data (GTK_OBJECT (widget));
6626
6627   /*
6628    * Can't use event->x / event->y here 
6629    * because I need absolute coordinates.
6630    */
6631   gdk_window_get_pointer (root_win, &xp, &yp, &mask);
6632   gtk_widget_set_uposition (widget, xp  - p->x, yp  - p->y);
6633 }
6634
6635 GtkWidget *
6636 shape_create_icon (char     *xpm_file,
6637                    gint      x,
6638                    gint      y,
6639                    gint      px,
6640                    gint      py,
6641                    gint      window_type)
6642 {
6643   GtkWidget *window;
6644   GtkWidget *pixmap;
6645   GtkWidget *fixed;
6646   CursorOffset* icon_pos;
6647   GdkGC* gc;
6648   GdkBitmap *gdk_pixmap_mask;
6649   GdkPixmap *gdk_pixmap;
6650   GtkStyle *style;
6651
6652   style = gtk_widget_get_default_style ();
6653   gc = style->black_gc; 
6654
6655   /*
6656    * GDK_WINDOW_TOPLEVEL works also, giving you a title border
6657    */
6658   window = gtk_window_new (window_type);
6659   
6660   fixed = gtk_fixed_new ();
6661   gtk_widget_set_usize (fixed, 100,100);
6662   gtk_container_add (GTK_CONTAINER (window), fixed);
6663   gtk_widget_show (fixed);
6664   
6665   gtk_widget_set_events (window, 
6666                          gtk_widget_get_events (window) |
6667                          GDK_BUTTON_MOTION_MASK |
6668                          GDK_POINTER_MOTION_HINT_MASK |
6669                          GDK_BUTTON_PRESS_MASK);
6670
6671   gtk_widget_realize (window);
6672   gdk_pixmap = gdk_pixmap_create_from_xpm (window->window, &gdk_pixmap_mask, 
6673                                            &style->bg[GTK_STATE_NORMAL],
6674                                            xpm_file);
6675
6676   pixmap = gtk_pixmap_new (gdk_pixmap, gdk_pixmap_mask);
6677   gtk_fixed_put (GTK_FIXED (fixed), pixmap, px,py);
6678   gtk_widget_show (pixmap);
6679   
6680   gtk_widget_shape_combine_mask (window, gdk_pixmap_mask, px,py);
6681
6682
6683   gtk_signal_connect (GTK_OBJECT (window), "button_press_event",
6684                       GTK_SIGNAL_FUNC (shape_pressed),NULL);
6685   gtk_signal_connect (GTK_OBJECT (window), "button_release_event",
6686                       GTK_SIGNAL_FUNC (shape_released),NULL);
6687   gtk_signal_connect (GTK_OBJECT (window), "motion_notify_event",
6688                       GTK_SIGNAL_FUNC (shape_motion),NULL);
6689
6690   icon_pos = g_new (CursorOffset, 1);
6691   gtk_object_set_user_data(GTK_OBJECT(window), icon_pos);
6692
6693   gtk_widget_set_uposition (window, x, y);
6694   gtk_widget_show (window);
6695   
6696   return window;
6697 }
6698
6699 void 
6700 create_shapes (void)
6701 {
6702   /* Variables used by the Drag/Drop and Shape Window demos */
6703   static GtkWidget *modeller = NULL;
6704   static GtkWidget *sheets = NULL;
6705   static GtkWidget *rings = NULL;
6706
6707   root_win = gdk_window_foreign_new (GDK_ROOT_WINDOW ());
6708
6709   if (!modeller)
6710     {
6711       modeller = shape_create_icon ("Modeller.xpm",
6712                                     440, 140, 0,0, GTK_WINDOW_POPUP);
6713
6714       gtk_signal_connect (GTK_OBJECT (modeller), "destroy",
6715                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6716                           &modeller);
6717     }
6718   else
6719     gtk_widget_destroy (modeller);
6720
6721   if (!sheets)
6722     {
6723       sheets = shape_create_icon ("FilesQueue.xpm",
6724                                   580, 170, 0,0, GTK_WINDOW_POPUP);
6725
6726       gtk_signal_connect (GTK_OBJECT (sheets), "destroy",
6727                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6728                           &sheets);
6729
6730     }
6731   else
6732     gtk_widget_destroy (sheets);
6733
6734   if (!rings)
6735     {
6736       rings = shape_create_icon ("3DRings.xpm",
6737                                  460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
6738
6739       gtk_signal_connect (GTK_OBJECT (rings), "destroy",
6740                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6741                           &rings);
6742     }
6743   else
6744     gtk_widget_destroy (rings);
6745 }
6746
6747 /*
6748  * WM Hints demo
6749  */
6750
6751 void
6752 create_wmhints (void)
6753 {
6754   static GtkWidget *window = NULL;
6755   GtkWidget *label;
6756   GtkWidget *separator;
6757   GtkWidget *button;
6758   GtkWidget *box1;
6759   GtkWidget *box2;
6760
6761   GdkBitmap *circles;
6762
6763   if (!window)
6764     {
6765       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6766
6767       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6768                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6769                           &window);
6770
6771       gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
6772       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6773
6774       gtk_widget_realize (window);
6775       
6776       circles = gdk_bitmap_create_from_data (window->window,
6777                                              circles_bits,
6778                                              circles_width,
6779                                              circles_height);
6780       gdk_window_set_icon (window->window, NULL,
6781                            circles, circles);
6782       
6783       gdk_window_set_icon_name (window->window, "WMHints Test Icon");
6784   
6785       gdk_window_set_decorations (window->window, GDK_DECOR_ALL | GDK_DECOR_MENU);
6786       gdk_window_set_functions (window->window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
6787       
6788       box1 = gtk_vbox_new (FALSE, 0);
6789       gtk_container_add (GTK_CONTAINER (window), box1);
6790       gtk_widget_show (box1);
6791
6792       label = gtk_label_new ("Try iconizing me!");
6793       gtk_widget_set_usize (label, 150, 50);
6794       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
6795       gtk_widget_show (label);
6796
6797
6798       separator = gtk_hseparator_new ();
6799       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
6800       gtk_widget_show (separator);
6801
6802
6803       box2 = gtk_vbox_new (FALSE, 10);
6804       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6805       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6806       gtk_widget_show (box2);
6807
6808
6809       button = gtk_button_new_with_label ("close");
6810
6811       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6812                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
6813                                  GTK_OBJECT (window));
6814
6815       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6816       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6817       gtk_widget_grab_default (button);
6818       gtk_widget_show (button);
6819     }
6820
6821   if (!GTK_WIDGET_VISIBLE (window))
6822     gtk_widget_show (window);
6823   else
6824     gtk_widget_destroy (window);
6825 }
6826
6827 /*
6828  * GtkProgressBar
6829  */
6830
6831 typedef struct _ProgressData {
6832   GtkWidget *window;
6833   GtkWidget *pbar;
6834   GtkWidget *block_spin;
6835   GtkWidget *x_align_spin;
6836   GtkWidget *y_align_spin;
6837   GtkWidget *step_spin;
6838   GtkWidget *act_blocks_spin;
6839   GtkWidget *label;
6840   GtkWidget *omenu1;
6841   GtkWidget *omenu2;
6842   GtkWidget *entry;
6843   int timer;
6844 } ProgressData;
6845
6846 gint
6847 progress_timeout (gpointer data)
6848 {
6849   gfloat new_val;
6850   GtkAdjustment *adj;
6851
6852   adj = GTK_PROGRESS (data)->adjustment;
6853
6854   new_val = adj->value + 1;
6855   if (new_val > adj->upper)
6856     new_val = adj->lower;
6857
6858   gtk_progress_set_value (GTK_PROGRESS (data), new_val);
6859
6860   return TRUE;
6861 }
6862
6863 static void
6864 destroy_progress (GtkWidget     *widget,
6865                   ProgressData **pdata)
6866 {
6867   gtk_timeout_remove ((*pdata)->timer);
6868   (*pdata)->timer = 0;
6869   (*pdata)->window = NULL;
6870   g_free (*pdata);
6871   *pdata = NULL;
6872 }
6873
6874 static void
6875 progressbar_toggle_orientation (GtkWidget *widget, ProgressData *pdata)
6876 {
6877   gint i;
6878
6879   if (!GTK_WIDGET_MAPPED (widget))
6880     return;
6881
6882   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
6883                     (((GtkOptionMenu *)(pdata->omenu1))->menu_item), i);
6884
6885   gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
6886                             (GtkProgressBarOrientation) (3-i));
6887 }
6888
6889 static void
6890 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
6891 {
6892   gtk_progress_set_show_text (GTK_PROGRESS (pdata->pbar),
6893                               GTK_TOGGLE_BUTTON (widget)->active);
6894   gtk_widget_set_sensitive (pdata->entry, GTK_TOGGLE_BUTTON (widget)->active);
6895   gtk_widget_set_sensitive (pdata->x_align_spin,
6896                             GTK_TOGGLE_BUTTON (widget)->active);
6897   gtk_widget_set_sensitive (pdata->y_align_spin,
6898                             GTK_TOGGLE_BUTTON (widget)->active);
6899 }
6900
6901 static void
6902 progressbar_toggle_bar_style (GtkWidget *widget, ProgressData *pdata)
6903 {
6904   gint i;
6905
6906   if (!GTK_WIDGET_MAPPED (widget))
6907     return;
6908
6909   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
6910                     (((GtkOptionMenu *)(pdata->omenu2))->menu_item), i);
6911
6912   i = 1 - i;
6913
6914   if (i == 1)
6915     gtk_widget_set_sensitive (pdata->block_spin, TRUE);
6916   else
6917     gtk_widget_set_sensitive (pdata->block_spin, FALSE);
6918
6919   gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),
6920                                   (GtkProgressBarStyle) i);
6921 }
6922
6923 static void
6924 progress_value_changed (GtkAdjustment *adj, ProgressData *pdata)
6925 {
6926   char buf[20];
6927
6928   if (GTK_PROGRESS (pdata->pbar)->activity_mode)
6929     sprintf (buf, "???");
6930   else
6931     sprintf (buf, "%.0f%%", 100 *
6932              gtk_progress_get_current_percentage (GTK_PROGRESS (pdata->pbar)));
6933   gtk_label_set (GTK_LABEL (pdata->label), buf);
6934 }
6935
6936 static void
6937 adjust_blocks (GtkAdjustment *adj, ProgressData *pdata)
6938 {
6939   gtk_progress_set_percentage (GTK_PROGRESS (pdata->pbar), 0);
6940   gtk_progress_bar_set_discrete_blocks (GTK_PROGRESS_BAR (pdata->pbar),
6941      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->block_spin)));
6942 }
6943
6944 static void
6945 adjust_step (GtkAdjustment *adj, ProgressData *pdata)
6946 {
6947   gtk_progress_bar_set_activity_step (GTK_PROGRESS_BAR (pdata->pbar),
6948      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->step_spin)));
6949 }
6950
6951 static void
6952 adjust_act_blocks (GtkAdjustment *adj, ProgressData *pdata)
6953 {
6954   gtk_progress_bar_set_activity_blocks (GTK_PROGRESS_BAR (pdata->pbar),
6955                gtk_spin_button_get_value_as_int 
6956                       (GTK_SPIN_BUTTON (pdata->act_blocks_spin)));
6957 }
6958
6959 static void
6960 adjust_align (GtkAdjustment *adj, ProgressData *pdata)
6961 {
6962   gtk_progress_set_text_alignment (GTK_PROGRESS (pdata->pbar),
6963          gtk_spin_button_get_value_as_float 
6964                                    (GTK_SPIN_BUTTON (pdata->x_align_spin)),
6965          gtk_spin_button_get_value_as_float
6966                                    (GTK_SPIN_BUTTON (pdata->y_align_spin)));
6967 }
6968
6969 static void
6970 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
6971 {
6972   gtk_progress_set_activity_mode (GTK_PROGRESS (pdata->pbar),
6973                                   GTK_TOGGLE_BUTTON (widget)->active);
6974   gtk_widget_set_sensitive (pdata->step_spin, 
6975                             GTK_TOGGLE_BUTTON (widget)->active);
6976   gtk_widget_set_sensitive (pdata->act_blocks_spin, 
6977                             GTK_TOGGLE_BUTTON (widget)->active);
6978 }
6979
6980 static void
6981 entry_changed (GtkWidget *widget, ProgressData *pdata)
6982 {
6983   gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
6984                           gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
6985 }
6986
6987 void
6988 create_progress_bar (void)
6989 {
6990   GtkWidget *button;
6991   GtkWidget *vbox;
6992   GtkWidget *vbox2;
6993   GtkWidget *hbox;
6994   GtkWidget *check;
6995   GtkWidget *frame;
6996   GtkWidget *tab;
6997   GtkWidget *label;
6998   GtkWidget *align;
6999   GtkAdjustment *adj;
7000   static ProgressData *pdata = NULL;
7001
7002   static OptionMenuItem items1[] =
7003   {
7004     { "Left-Right", progressbar_toggle_orientation },
7005     { "Right-Left", progressbar_toggle_orientation },
7006     { "Bottom-Top", progressbar_toggle_orientation },
7007     { "Top-Bottom", progressbar_toggle_orientation }
7008   };
7009
7010   static OptionMenuItem items2[] =
7011   {
7012     { "Continuous", progressbar_toggle_bar_style },
7013     { "Discrete",   progressbar_toggle_bar_style }
7014   };
7015
7016   if (!pdata)
7017     pdata = g_new0 (ProgressData, 1);
7018
7019   if (!pdata->window)
7020     {
7021       pdata->window = gtk_dialog_new ();
7022
7023       gtk_window_set_policy (GTK_WINDOW (pdata->window), FALSE, FALSE, TRUE);
7024
7025       gtk_signal_connect (GTK_OBJECT (pdata->window), "destroy",
7026                           GTK_SIGNAL_FUNC (destroy_progress),
7027                           &pdata);
7028
7029       pdata->timer = 0;
7030
7031       gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
7032       gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
7033
7034       vbox = gtk_vbox_new (FALSE, 5);
7035       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
7036       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->vbox), 
7037                           vbox, FALSE, TRUE, 0);
7038
7039       frame = gtk_frame_new ("Progress");
7040       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
7041
7042       vbox2 = gtk_vbox_new (FALSE, 5);
7043       gtk_container_add (GTK_CONTAINER (frame), vbox2);
7044
7045       align = gtk_alignment_new (0.5, 0.5, 0, 0);
7046       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
7047
7048       adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, 300, 0, 0, 0);
7049       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7050                           GTK_SIGNAL_FUNC (progress_value_changed), pdata);
7051
7052       pdata->pbar = gtk_progress_bar_new_with_adjustment (adj);
7053       gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
7054                                       "%v from [%l,%u] (=%p%%)");
7055       gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
7056       pdata->timer = gtk_timeout_add (100, progress_timeout, pdata->pbar);
7057
7058       align = gtk_alignment_new (0.5, 0.5, 0, 0);
7059       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
7060
7061       hbox = gtk_hbox_new (FALSE, 5);
7062       gtk_container_add (GTK_CONTAINER (align), hbox);
7063       label = gtk_label_new ("Label updated by user :"); 
7064       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
7065       pdata->label = gtk_label_new ("");
7066       gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
7067
7068       frame = gtk_frame_new ("Options");
7069       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
7070
7071       vbox2 = gtk_vbox_new (FALSE, 5);
7072       gtk_container_add (GTK_CONTAINER (frame), vbox2);
7073
7074       tab = gtk_table_new (7, 2, FALSE);
7075       gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
7076
7077       label = gtk_label_new ("Orientation :");
7078       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
7079                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7080                         5, 5);
7081       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
7082
7083       pdata->omenu1 = build_option_menu (items1, 4, 0, pdata);
7084       hbox = gtk_hbox_new (FALSE, 0);
7085       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
7086                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7087                         5, 5);
7088       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
7089       
7090       check = gtk_check_button_new_with_label ("Show text");
7091       gtk_signal_connect (GTK_OBJECT (check), "clicked",
7092                           GTK_SIGNAL_FUNC (toggle_show_text),
7093                           pdata);
7094       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 1, 2,
7095                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7096                         5, 5);
7097
7098       hbox = gtk_hbox_new (FALSE, 0);
7099       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 1, 2,
7100                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7101                         5, 5);
7102
7103       label = gtk_label_new ("Format : ");
7104       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
7105
7106       pdata->entry = gtk_entry_new ();
7107       gtk_signal_connect (GTK_OBJECT (pdata->entry), "changed",
7108                           GTK_SIGNAL_FUNC (entry_changed),
7109                           pdata);
7110       gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
7111       gtk_entry_set_text (GTK_ENTRY (pdata->entry), "%v from [%l,%u] (=%p%%)");
7112       gtk_widget_set_usize (pdata->entry, 100, -1);
7113       gtk_widget_set_sensitive (pdata->entry, FALSE);
7114
7115       label = gtk_label_new ("Text align :");
7116       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 2, 3,
7117                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7118                         5, 5);
7119       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
7120
7121       hbox = gtk_hbox_new (FALSE, 0);
7122       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 2, 3,
7123                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7124                         5, 5);
7125
7126       label = gtk_label_new ("x :");
7127       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
7128       
7129       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
7130       pdata->x_align_spin = gtk_spin_button_new (adj, 0, 1);
7131       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7132                           GTK_SIGNAL_FUNC (adjust_align), pdata);
7133       gtk_box_pack_start (GTK_BOX (hbox), pdata->x_align_spin, FALSE, TRUE, 0);
7134       gtk_widget_set_sensitive (pdata->x_align_spin, FALSE);
7135
7136       label = gtk_label_new ("y :");
7137       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
7138
7139       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
7140       pdata->y_align_spin = gtk_spin_button_new (adj, 0, 1);
7141       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7142                           GTK_SIGNAL_FUNC (adjust_align), pdata);
7143       gtk_box_pack_start (GTK_BOX (hbox), pdata->y_align_spin, FALSE, TRUE, 0);
7144       gtk_widget_set_sensitive (pdata->y_align_spin, FALSE);
7145
7146       label = gtk_label_new ("Bar Style :");
7147       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 3, 4,
7148                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7149                         5, 5);
7150       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
7151
7152       pdata->omenu2 = build_option_menu (items2, 2, 0, pdata);
7153       hbox = gtk_hbox_new (FALSE, 0);
7154       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 3, 4,
7155                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7156                         5, 5);
7157       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu2, TRUE, TRUE, 0);
7158
7159       label = gtk_label_new ("Block count :");
7160       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 4, 5,
7161                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7162                         5, 5);
7163       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
7164
7165       hbox = gtk_hbox_new (FALSE, 0);
7166       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 4, 5,
7167                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7168                         5, 5);
7169       adj = (GtkAdjustment *) gtk_adjustment_new (10, 2, 20, 1, 5, 0);
7170       pdata->block_spin = gtk_spin_button_new (adj, 0, 0);
7171       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7172                           GTK_SIGNAL_FUNC (adjust_blocks), pdata);
7173       gtk_box_pack_start (GTK_BOX (hbox), pdata->block_spin, FALSE, TRUE, 0);
7174       gtk_widget_set_sensitive (pdata->block_spin, FALSE);
7175
7176       check = gtk_check_button_new_with_label ("Activity mode");
7177       gtk_signal_connect (GTK_OBJECT (check), "clicked",
7178                           GTK_SIGNAL_FUNC (toggle_activity_mode),
7179                           pdata);
7180       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 5, 6,
7181                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7182                         5, 5);
7183
7184       hbox = gtk_hbox_new (FALSE, 0);
7185       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 5, 6,
7186                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7187                         5, 5);
7188       label = gtk_label_new ("Step size : ");
7189       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
7190       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
7191       pdata->step_spin = gtk_spin_button_new (adj, 0, 0);
7192       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7193                           GTK_SIGNAL_FUNC (adjust_step), pdata);
7194       gtk_box_pack_start (GTK_BOX (hbox), pdata->step_spin, FALSE, TRUE, 0);
7195       gtk_widget_set_sensitive (pdata->step_spin, FALSE);
7196
7197       hbox = gtk_hbox_new (FALSE, 0);
7198       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 6, 7,
7199                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7200                         5, 5);
7201       label = gtk_label_new ("Blocks :     ");
7202       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
7203       adj = (GtkAdjustment *) gtk_adjustment_new (5, 2, 10, 1, 5, 0);
7204       pdata->act_blocks_spin = gtk_spin_button_new (adj, 0, 0);
7205       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7206                           GTK_SIGNAL_FUNC (adjust_act_blocks), pdata);
7207       gtk_box_pack_start (GTK_BOX (hbox), pdata->act_blocks_spin, FALSE, TRUE,
7208                           0);
7209       gtk_widget_set_sensitive (pdata->act_blocks_spin, FALSE);
7210
7211       button = gtk_button_new_with_label ("close");
7212       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7213                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
7214                                  GTK_OBJECT (pdata->window));
7215       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7216       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->action_area), 
7217                           button, TRUE, TRUE, 0);
7218       gtk_widget_grab_default (button);
7219     }
7220
7221   if (!GTK_WIDGET_VISIBLE (pdata->window))
7222     gtk_widget_show_all (pdata->window);
7223   else
7224     gtk_widget_destroy (pdata->window);
7225 }
7226
7227 /*
7228  * Color Preview
7229  */
7230
7231 static int color_idle = 0;
7232
7233 gint
7234 color_idle_func (GtkWidget *preview)
7235 {
7236   static int count = 1;
7237   guchar buf[768];
7238   int i, j, k;
7239
7240   for (i = 0; i < 256; i++)
7241     {
7242       for (j = 0, k = 0; j < 256; j++)
7243         {
7244           buf[k+0] = i + count;
7245           buf[k+1] = 0;
7246           buf[k+2] = j + count;
7247           k += 3;
7248         }
7249
7250       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
7251     }
7252
7253   count += 1;
7254
7255   gtk_widget_draw (preview, NULL);
7256
7257   return TRUE;
7258 }
7259
7260 static void
7261 color_preview_destroy (GtkWidget  *widget,
7262                        GtkWidget **window)
7263 {
7264   gtk_idle_remove (color_idle);
7265   color_idle = 0;
7266
7267   *window = NULL;
7268 }
7269
7270 void
7271 create_color_preview (void)
7272 {
7273   static GtkWidget *window = NULL;
7274   GtkWidget *preview;
7275   guchar buf[768];
7276   int i, j, k;
7277
7278   if (!window)
7279     {
7280       gtk_widget_push_visual (gdk_rgb_get_visual ());
7281       gtk_widget_push_colormap (gdk_rgb_get_cmap ());
7282       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7283       gtk_widget_pop_colormap ();
7284       gtk_widget_pop_visual ();
7285
7286       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7287                           GTK_SIGNAL_FUNC(color_preview_destroy),
7288                           &window);
7289
7290       gtk_window_set_title (GTK_WINDOW (window), "test");
7291       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
7292
7293       preview = gtk_preview_new (GTK_PREVIEW_COLOR);
7294       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
7295       gtk_container_add (GTK_CONTAINER (window), preview);
7296
7297       for (i = 0; i < 256; i++)
7298         {
7299           for (j = 0, k = 0; j < 256; j++)
7300             {
7301               buf[k+0] = i;
7302               buf[k+1] = 0;
7303               buf[k+2] = j;
7304               k += 3;
7305             }
7306
7307           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
7308         }
7309
7310       color_idle = gtk_idle_add ((GtkFunction) color_idle_func, preview);
7311     }
7312
7313   if (!GTK_WIDGET_VISIBLE (window))
7314     gtk_widget_show_all (window);
7315   else
7316     gtk_widget_destroy (window);
7317 }
7318
7319 /*
7320  * Gray Preview
7321  */
7322
7323 static int gray_idle = 0;
7324
7325 gint
7326 gray_idle_func (GtkWidget *preview)
7327 {
7328   static int count = 1;
7329   guchar buf[256];
7330   int i, j;
7331
7332   for (i = 0; i < 256; i++)
7333     {
7334       for (j = 0; j < 256; j++)
7335         buf[j] = i + j + count;
7336
7337       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
7338     }
7339
7340   count += 1;
7341
7342   gtk_widget_draw (preview, NULL);
7343
7344   return TRUE;
7345 }
7346
7347 static void
7348 gray_preview_destroy (GtkWidget  *widget,
7349                       GtkWidget **window)
7350 {
7351   gtk_idle_remove (gray_idle);
7352   gray_idle = 0;
7353
7354   *window = NULL;
7355 }
7356
7357 void
7358 create_gray_preview (void)
7359 {
7360   static GtkWidget *window = NULL;
7361   GtkWidget *preview;
7362   guchar buf[256];
7363   int i, j;
7364
7365   if (!window)
7366     {
7367       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7368
7369       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7370                           GTK_SIGNAL_FUNC(gray_preview_destroy),
7371                           &window);
7372
7373       gtk_window_set_title (GTK_WINDOW (window), "test");
7374       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
7375
7376       preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
7377       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
7378       gtk_container_add (GTK_CONTAINER (window), preview);
7379
7380       for (i = 0; i < 256; i++)
7381         {
7382           for (j = 0; j < 256; j++)
7383             buf[j] = i + j;
7384
7385           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
7386         }
7387
7388       gray_idle = gtk_idle_add ((GtkFunction) gray_idle_func, preview);
7389     }
7390
7391   if (!GTK_WIDGET_VISIBLE (window))
7392     gtk_widget_show_all (window);
7393   else
7394     gtk_widget_destroy (window);
7395 }
7396
7397
7398 /*
7399  * Selection Test
7400  */
7401
7402 void
7403 selection_test_received (GtkWidget *list, GtkSelectionData *data)
7404 {
7405   GdkAtom *atoms;
7406   GtkWidget *list_item;
7407   GList *item_list;
7408   int i, l;
7409
7410   if (data->length < 0)
7411     {
7412       g_print ("Selection retrieval failed\n");
7413       return;
7414     }
7415   if (data->type != GDK_SELECTION_TYPE_ATOM)
7416     {
7417       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
7418       return;
7419     }
7420
7421   /* Clear out any current list items */
7422
7423   gtk_list_clear_items (GTK_LIST(list), 0, -1);
7424
7425   /* Add new items to list */
7426
7427   atoms = (GdkAtom *)data->data;
7428
7429   item_list = NULL;
7430   l = data->length / sizeof (GdkAtom);
7431   for (i = 0; i < l; i++)
7432     {
7433       char *name;
7434       name = gdk_atom_name (atoms[i]);
7435       if (name != NULL)
7436         {
7437           list_item = gtk_list_item_new_with_label (name);
7438           g_free (name);
7439         }
7440       else
7441         list_item = gtk_list_item_new_with_label ("(bad atom)");
7442
7443       gtk_widget_show (list_item);
7444       item_list = g_list_append (item_list, list_item);
7445     }
7446
7447   gtk_list_append_items (GTK_LIST (list), item_list);
7448
7449   return;
7450 }
7451
7452 void
7453 selection_test_get_targets (GtkWidget *widget, GtkWidget *list)
7454 {
7455   static GdkAtom targets_atom = GDK_NONE;
7456
7457   if (targets_atom == GDK_NONE)
7458     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
7459
7460   gtk_selection_convert (list, GDK_SELECTION_PRIMARY, targets_atom,
7461                          GDK_CURRENT_TIME);
7462 }
7463
7464 void
7465 create_selection_test (void)
7466 {
7467   static GtkWidget *window = NULL;
7468   GtkWidget *button;
7469   GtkWidget *vbox;
7470   GtkWidget *scrolled_win;
7471   GtkWidget *list;
7472   GtkWidget *label;
7473
7474   if (!window)
7475     {
7476       window = gtk_dialog_new ();
7477
7478       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7479                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7480                           &window);
7481
7482       gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
7483       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7484
7485       /* Create the list */
7486
7487       vbox = gtk_vbox_new (FALSE, 5);
7488       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
7489       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox,
7490                           TRUE, TRUE, 0);
7491
7492       label = gtk_label_new ("Gets available targets for current selection");
7493       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
7494
7495       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
7496       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
7497                                       GTK_POLICY_AUTOMATIC, 
7498                                       GTK_POLICY_AUTOMATIC);
7499       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
7500       gtk_widget_set_usize (scrolled_win, 100, 200);
7501
7502       list = gtk_list_new ();
7503       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
7504
7505       gtk_signal_connect (GTK_OBJECT(list), "selection_received",
7506                           GTK_SIGNAL_FUNC (selection_test_received), NULL);
7507
7508       /* .. And create some buttons */
7509       button = gtk_button_new_with_label ("Get Targets");
7510       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
7511                           button, TRUE, TRUE, 0);
7512
7513       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7514                           GTK_SIGNAL_FUNC (selection_test_get_targets), list);
7515
7516       button = gtk_button_new_with_label ("Quit");
7517       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
7518                           button, TRUE, TRUE, 0);
7519
7520       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7521                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
7522                                  GTK_OBJECT (window));
7523     }
7524
7525   if (!GTK_WIDGET_VISIBLE (window))
7526     gtk_widget_show_all (window);
7527   else
7528     gtk_widget_destroy (window);
7529 }
7530
7531 /*
7532  * Gamma Curve
7533  */
7534
7535 void
7536 create_gamma_curve (void)
7537 {
7538   static GtkWidget *window = NULL, *curve;
7539   static int count = 0;
7540   gfloat vec[256];
7541   gint max;
7542   gint i;
7543
7544   if (!window)
7545     {
7546       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7547       gtk_window_set_title (GTK_WINDOW (window), "test");
7548       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
7549
7550       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7551                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7552                           &window);
7553
7554       curve = gtk_gamma_curve_new ();
7555       gtk_container_add (GTK_CONTAINER (window), curve);
7556       gtk_widget_show (curve);
7557     }
7558
7559   max = 127 + (count % 2)*128;
7560   gtk_curve_set_range (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
7561                        0, max, 0, max);
7562   for (i = 0; i < max; ++i)
7563     vec[i] = (127 / sqrt (max)) * sqrt (i);
7564   gtk_curve_set_vector (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
7565                         max, vec);
7566
7567   if (!GTK_WIDGET_VISIBLE (window))
7568     gtk_widget_show (window);
7569   else if (count % 4 == 3)
7570     {
7571       gtk_widget_destroy (window);
7572       window = NULL;
7573     }
7574
7575   ++count;
7576 }
7577
7578 /*
7579  * Test scrolling
7580  */
7581
7582 static int scroll_test_pos = 0.0;
7583 static GdkGC *scroll_test_gc = NULL;
7584
7585 static gint
7586 scroll_test_expose (GtkWidget *widget, GdkEventExpose *event,
7587                     GtkAdjustment *adj)
7588 {
7589   gint i,j;
7590   gint imin, imax, jmin, jmax;
7591   
7592   imin = (event->area.x) / 10;
7593   imax = (event->area.x + event->area.width + 9) / 10;
7594
7595   jmin = ((int)adj->value + event->area.y) / 10;
7596   jmax = ((int)adj->value + event->area.y + event->area.height + 9) / 10;
7597
7598   gdk_window_clear_area (widget->window,
7599                          event->area.x, event->area.y,
7600                          event->area.width, event->area.height);
7601
7602   for (i=imin; i<imax; i++)
7603     for (j=jmin; j<jmax; j++)
7604       if ((i+j) % 2)
7605         gdk_draw_rectangle (widget->window, 
7606                             widget->style->black_gc,
7607                             TRUE,
7608                             10*i, 10*j - (int)adj->value, 1+i%10, 1+j%10);
7609
7610   return TRUE;
7611 }
7612
7613 static void
7614 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
7615                        GtkAdjustment *adj)
7616 {
7617   adj->page_increment = 0.9 * widget->allocation.height;
7618   adj->page_size = widget->allocation.height;
7619
7620   gtk_signal_emit_by_name (GTK_OBJECT (adj), "changed");
7621 }
7622
7623 static void
7624 scroll_test_adjustment_changed (GtkAdjustment *adj, GtkWidget *widget)
7625 {
7626   gint source_min = (int)adj->value - scroll_test_pos;
7627   gint source_max = source_min + widget->allocation.height;
7628   gint dest_min = 0;
7629   gint dest_max = widget->allocation.height;
7630   GdkRectangle rect;
7631   GdkEvent *event;
7632
7633   scroll_test_pos = adj->value;
7634
7635   if (!GTK_WIDGET_DRAWABLE (widget))
7636     return;
7637
7638   if (source_min < 0)
7639     {
7640       rect.x = 0; 
7641       rect.y = 0;
7642       rect.width = widget->allocation.width;
7643       rect.height = -source_min;
7644       if (rect.height > widget->allocation.height)
7645         rect.height = widget->allocation.height;
7646
7647       source_min = 0;
7648       dest_min = rect.height;
7649     }
7650   else
7651     {
7652       rect.x = 0;
7653       rect.y = 2*widget->allocation.height - source_max;
7654       if (rect.y < 0)
7655         rect.y = 0;
7656       rect.width = widget->allocation.width;
7657       rect.height = widget->allocation.height - rect.y;
7658
7659       source_max = widget->allocation.height;
7660       dest_max = rect.y;
7661     }
7662
7663   if (source_min != source_max)
7664     {
7665       if (scroll_test_gc == NULL)
7666         {
7667           scroll_test_gc = gdk_gc_new (widget->window);
7668           gdk_gc_set_exposures (scroll_test_gc, TRUE);
7669         }
7670
7671       gdk_draw_pixmap (widget->window,
7672                        scroll_test_gc,
7673                        widget->window,
7674                        0, source_min,
7675                        0, dest_min,
7676                        widget->allocation.width,
7677                        source_max - source_min);
7678
7679       /* Make sure graphics expose events are processed before scrolling
7680        * again */
7681       
7682       while ((event = gdk_event_get_graphics_expose (widget->window)) != NULL)
7683         {
7684           gtk_widget_event (widget, event);
7685           if (event->expose.count == 0)
7686             {
7687               gdk_event_free (event);
7688               break;
7689             }
7690           gdk_event_free (event);
7691         }
7692     }
7693
7694   if (rect.height != 0)
7695     gtk_widget_draw (widget, &rect);
7696 }
7697
7698
7699 void
7700 create_scroll_test (void)
7701 {
7702   static GtkWidget *window = NULL;
7703   GtkWidget *hbox;
7704   GtkWidget *drawing_area;
7705   GtkWidget *scrollbar;
7706   GtkWidget *button;
7707   GtkAdjustment *adj;
7708   GdkGeometry geometry;
7709   GdkWindowHints geometry_mask;
7710   
7711   if (!window)
7712     {
7713       window = gtk_dialog_new ();
7714
7715       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7716                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7717                           &window);
7718
7719       gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
7720       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7721
7722       hbox = gtk_hbox_new (FALSE, 0);
7723       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox,
7724                           TRUE, TRUE, 0);
7725       gtk_widget_show (hbox);
7726
7727       drawing_area = gtk_drawing_area_new ();
7728       gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 200, 200);
7729       gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
7730       gtk_widget_show (drawing_area);
7731
7732       gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK);
7733
7734       adj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0));
7735       scroll_test_pos = 0.0;
7736
7737       scrollbar = gtk_vscrollbar_new (adj);
7738       gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
7739       gtk_widget_show (scrollbar);
7740
7741       gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
7742                           GTK_SIGNAL_FUNC (scroll_test_expose), adj);
7743       gtk_signal_connect (GTK_OBJECT (drawing_area), "configure_event",
7744                           GTK_SIGNAL_FUNC (scroll_test_configure), adj);
7745
7746       
7747       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7748                           GTK_SIGNAL_FUNC (scroll_test_adjustment_changed),
7749                           drawing_area);
7750       
7751       /* .. And create some buttons */
7752
7753       button = gtk_button_new_with_label ("Quit");
7754       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
7755                           button, TRUE, TRUE, 0);
7756
7757       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7758                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
7759                                  GTK_OBJECT (window));
7760       gtk_widget_show (button);
7761
7762       /* Set up gridded geometry */
7763
7764       geometry_mask = GDK_HINT_MIN_SIZE | 
7765                        GDK_HINT_BASE_SIZE | 
7766                        GDK_HINT_RESIZE_INC;
7767
7768       geometry.min_width = 20;
7769       geometry.min_height = 20;
7770       geometry.base_width = 0;
7771       geometry.base_height = 0;
7772       geometry.width_inc = 10;
7773       geometry.height_inc = 10;
7774       
7775       gtk_window_set_geometry_hints (GTK_WINDOW (window),
7776                                drawing_area, &geometry, geometry_mask);
7777     }
7778
7779   if (!GTK_WIDGET_VISIBLE (window))
7780     gtk_widget_show (window);
7781   else
7782     gtk_widget_destroy (window);
7783 }
7784
7785 /*
7786  * Timeout Test
7787  */
7788
7789 static int timer = 0;
7790
7791 gint
7792 timeout_test (GtkWidget *label)
7793 {
7794   static int count = 0;
7795   static char buffer[32];
7796
7797   sprintf (buffer, "count: %d", ++count);
7798   gtk_label_set (GTK_LABEL (label), buffer);
7799
7800   return TRUE;
7801 }
7802
7803 void
7804 start_timeout_test (GtkWidget *widget,
7805                     GtkWidget *label)
7806 {
7807   if (!timer)
7808     {
7809       timer = gtk_timeout_add (100, (GtkFunction) timeout_test, label);
7810     }
7811 }
7812
7813 void
7814 stop_timeout_test (GtkWidget *widget,
7815                    gpointer   data)
7816 {
7817   if (timer)
7818     {
7819       gtk_timeout_remove (timer);
7820       timer = 0;
7821     }
7822 }
7823
7824 void
7825 destroy_timeout_test (GtkWidget  *widget,
7826                       GtkWidget **window)
7827 {
7828   stop_timeout_test (NULL, NULL);
7829
7830   *window = NULL;
7831 }
7832
7833 void
7834 create_timeout_test (void)
7835 {
7836   static GtkWidget *window = NULL;
7837   GtkWidget *button;
7838   GtkWidget *label;
7839
7840   if (!window)
7841     {
7842       window = gtk_dialog_new ();
7843
7844       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7845                           GTK_SIGNAL_FUNC(destroy_timeout_test),
7846                           &window);
7847
7848       gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
7849       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7850
7851       label = gtk_label_new ("count: 0");
7852       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
7853       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7854                           label, TRUE, TRUE, 0);
7855       gtk_widget_show (label);
7856
7857       button = gtk_button_new_with_label ("close");
7858       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7859                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
7860                                  GTK_OBJECT (window));
7861       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7862       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
7863                           button, TRUE, TRUE, 0);
7864       gtk_widget_grab_default (button);
7865       gtk_widget_show (button);
7866
7867       button = gtk_button_new_with_label ("start");
7868       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7869                           GTK_SIGNAL_FUNC(start_timeout_test),
7870                           label);
7871       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7872       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
7873                           button, TRUE, TRUE, 0);
7874       gtk_widget_show (button);
7875
7876       button = gtk_button_new_with_label ("stop");
7877       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7878                           GTK_SIGNAL_FUNC(stop_timeout_test),
7879                           NULL);
7880       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7881       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
7882                           button, TRUE, TRUE, 0);
7883       gtk_widget_show (button);
7884     }
7885
7886   if (!GTK_WIDGET_VISIBLE (window))
7887     gtk_widget_show (window);
7888   else
7889     gtk_widget_destroy (window);
7890 }
7891
7892 /*
7893  * Idle Test
7894  */
7895
7896 static int idle = 0;
7897
7898 static gint
7899 idle_test (GtkWidget *label)
7900 {
7901   static int count = 0;
7902   static char buffer[32];
7903
7904   sprintf (buffer, "count: %d", ++count);
7905   gtk_label_set (GTK_LABEL (label), buffer);
7906
7907   return TRUE;
7908 }
7909
7910 static void
7911 start_idle_test (GtkWidget *widget,
7912                  GtkWidget *label)
7913 {
7914   if (!idle)
7915     {
7916       idle = gtk_idle_add ((GtkFunction) idle_test, label);
7917     }
7918 }
7919
7920 static void
7921 stop_idle_test (GtkWidget *widget,
7922                 gpointer   data)
7923 {
7924   if (idle)
7925     {
7926       gtk_idle_remove (idle);
7927       idle = 0;
7928     }
7929 }
7930
7931 static void
7932 destroy_idle_test (GtkWidget  *widget,
7933                    GtkWidget **window)
7934 {
7935   stop_idle_test (NULL, NULL);
7936
7937   *window = NULL;
7938 }
7939
7940 static void
7941 toggle_idle_container (GtkObject *button,
7942                        GtkContainer *container)
7943 {
7944   gtk_container_set_resize_mode (container, (guint) gtk_object_get_user_data (button));
7945 }
7946
7947 static void
7948 create_idle_test (void)
7949 {
7950   static GtkWidget *window = NULL;
7951   GtkWidget *button;
7952   GtkWidget *label;
7953   GtkWidget *container;
7954
7955   if (!window)
7956     {
7957       GtkWidget *frame;
7958       GtkWidget *box;
7959
7960       window = gtk_dialog_new ();
7961
7962       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7963                           GTK_SIGNAL_FUNC(destroy_idle_test),
7964                           &window);
7965
7966       gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
7967       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7968
7969       label = gtk_label_new ("count: 0");
7970       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
7971       gtk_widget_show (label);
7972       
7973       container =
7974         gtk_widget_new (GTK_TYPE_HBOX,
7975                         "GtkWidget::visible", TRUE,
7976                         /* "GtkContainer::child", gtk_widget_new (GTK_TYPE_HBOX,
7977                          * "GtkWidget::visible", TRUE,
7978                          */
7979                          "GtkContainer::child", label,
7980                         /* NULL), */
7981                         NULL);
7982       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7983                           container, TRUE, TRUE, 0);
7984
7985       frame =
7986         gtk_widget_new (GTK_TYPE_FRAME,
7987                         "GtkContainer::border_width", 5,
7988                         "GtkFrame::label", "Label Container",
7989                         "GtkWidget::visible", TRUE,
7990                         "GtkWidget::parent", GTK_DIALOG (window)->vbox,
7991                         NULL);
7992       box =
7993         gtk_widget_new (GTK_TYPE_VBOX,
7994                         "GtkWidget::visible", TRUE,
7995                         "GtkWidget::parent", frame,
7996                         NULL);
7997       button =
7998         gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
7999                         "GtkButton::label", "Resize-Parent",
8000                         "GtkObject::user_data", (void*)GTK_RESIZE_PARENT,
8001                         "GtkObject::signal::clicked", toggle_idle_container, container,
8002                         "GtkWidget::visible", TRUE,
8003                         "GtkWidget::parent", box,
8004                         NULL);
8005       button =
8006         gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
8007                         "GtkButton::label", "Resize-Queue",
8008                         "GtkObject::user_data", (void*)GTK_RESIZE_QUEUE,
8009                         "GtkObject::signal::clicked", toggle_idle_container, container,
8010                         "GtkRadioButton::group", button,
8011                         "GtkWidget::visible", TRUE,
8012                         "GtkWidget::parent", box,
8013                         NULL);
8014       button =
8015         gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
8016                         "GtkButton::label", "Resize-Immediate",
8017                         "GtkObject::user_data", (void*)GTK_RESIZE_IMMEDIATE,
8018                         "GtkObject::signal::clicked", toggle_idle_container, container,
8019                         "GtkRadioButton::group", button,
8020                         "GtkWidget::visible", TRUE,
8021                         "GtkWidget::parent", box,
8022                         NULL);
8023       
8024
8025       button = gtk_button_new_with_label ("close");
8026       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8027                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
8028                                  GTK_OBJECT (window));
8029       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8030       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
8031                           button, TRUE, TRUE, 0);
8032       gtk_widget_grab_default (button);
8033       gtk_widget_show (button);
8034
8035       button = gtk_button_new_with_label ("start");
8036       gtk_signal_connect (GTK_OBJECT (button), "clicked",
8037                           GTK_SIGNAL_FUNC(start_idle_test),
8038                           label);
8039       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8040       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
8041                           button, TRUE, TRUE, 0);
8042       gtk_widget_show (button);
8043
8044       button = gtk_button_new_with_label ("stop");
8045       gtk_signal_connect (GTK_OBJECT (button), "clicked",
8046                           GTK_SIGNAL_FUNC(stop_idle_test),
8047                           NULL);
8048       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8049       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
8050                           button, TRUE, TRUE, 0);
8051       gtk_widget_show (button);
8052     }
8053
8054   if (!GTK_WIDGET_VISIBLE (window))
8055     gtk_widget_show (window);
8056   else
8057     gtk_widget_destroy (window);
8058 }
8059
8060 /*
8061  * rc file test
8062  */
8063
8064 void
8065 reload_rc_file (void)
8066 {
8067   GList *toplevels;
8068
8069   if (gtk_rc_reparse_all ())
8070     {
8071       toplevels = gdk_window_get_toplevels();
8072       while (toplevels)
8073         {
8074           GtkWidget *widget;
8075           gdk_window_get_user_data (toplevels->data, (gpointer *)&widget);
8076           
8077           if (widget)
8078             gtk_widget_reset_rc_styles (widget);
8079           
8080           toplevels = toplevels->next;
8081         }
8082       g_list_free (toplevels);
8083     }
8084 }
8085
8086 void
8087 reload_all_rc_files (void)
8088 {
8089   static GdkAtom atom_rcfiles = GDK_NONE;
8090
8091   GdkEventClient sev;
8092   int i;
8093   
8094   if (!atom_rcfiles)
8095     atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
8096
8097   for(i = 0; i < 5; i++)
8098     sev.data.l[i] = 0;
8099   sev.data_format = 32;
8100   sev.message_type = atom_rcfiles;
8101   gdk_event_send_clientmessage_toall ((GdkEvent *) &sev);
8102 }
8103
8104 void
8105 create_rc_file (void)
8106 {
8107   static GtkWidget *window = NULL;
8108   GtkWidget *button;
8109
8110   if (!window)
8111     {
8112       window = gtk_dialog_new ();
8113
8114       gtk_signal_connect (GTK_OBJECT (window), "destroy",
8115                           GTK_SIGNAL_FUNC(destroy_idle_test),
8116                           &window);
8117
8118       gtk_window_set_title (GTK_WINDOW (window), "Reload Rc file");
8119       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8120
8121       button = gtk_button_new_with_label ("Reload");
8122       gtk_signal_connect (GTK_OBJECT (button), "clicked",
8123                           GTK_SIGNAL_FUNC(reload_rc_file), NULL);
8124       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8125       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
8126                           button, TRUE, TRUE, 0);
8127       gtk_widget_grab_default (button);
8128       gtk_widget_show (button);
8129
8130       button = gtk_button_new_with_label ("Reload All");
8131       gtk_signal_connect (GTK_OBJECT (button), "clicked",
8132                           GTK_SIGNAL_FUNC(reload_all_rc_files), NULL);
8133       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8134       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
8135                           button, TRUE, TRUE, 0);
8136       gtk_widget_show (button);
8137
8138       button = gtk_button_new_with_label ("Close");
8139       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8140                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
8141                                  GTK_OBJECT (window));
8142       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8143       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
8144                           button, TRUE, TRUE, 0);
8145       gtk_widget_show (button);
8146
8147     }
8148
8149   if (!GTK_WIDGET_VISIBLE (window))
8150     gtk_widget_show (window);
8151   else
8152     gtk_widget_destroy (window);
8153 }
8154
8155 /*
8156  * Test of recursive mainloop
8157  */
8158
8159 void
8160 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
8161 {
8162   *window = NULL;
8163   gtk_main_quit ();
8164 }
8165
8166 void
8167 create_mainloop (void)
8168 {
8169   static GtkWidget *window = NULL;
8170   GtkWidget *label;
8171   GtkWidget *button;
8172
8173   if (!window)
8174     {
8175       window = gtk_dialog_new ();
8176
8177       gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
8178
8179       gtk_signal_connect (GTK_OBJECT (window), "destroy",
8180                           GTK_SIGNAL_FUNC(mainloop_destroyed),
8181                           &window);
8182
8183       label = gtk_label_new ("In recursive main loop...");
8184       gtk_misc_set_padding (GTK_MISC(label), 20, 20);
8185
8186       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), label,
8187                           TRUE, TRUE, 0);
8188       gtk_widget_show (label);
8189
8190       button = gtk_button_new_with_label ("Leave");
8191       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, 
8192                           FALSE, TRUE, 0);
8193
8194       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8195                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
8196                                  GTK_OBJECT (window));
8197
8198       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8199       gtk_widget_grab_default (button);
8200
8201       gtk_widget_show (button);
8202     }
8203
8204   if (!GTK_WIDGET_VISIBLE (window))
8205     {
8206       gtk_widget_show (window);
8207
8208       g_print ("create_mainloop: start\n");
8209       gtk_main ();
8210       g_print ("create_mainloop: done\n");
8211     }
8212   else
8213     gtk_widget_destroy (window);
8214 }
8215
8216 gint
8217 layout_expose_handler (GtkWidget *widget, GdkEventExpose *event)
8218 {
8219   GtkLayout *layout;
8220
8221   gint i,j;
8222   gint imin, imax, jmin, jmax;
8223   
8224   layout = GTK_LAYOUT (widget);
8225
8226   imin = (layout->xoffset + event->area.x) / 10;
8227   imax = (layout->xoffset + event->area.x + event->area.width + 9) / 10;
8228
8229   jmin = (layout->yoffset + event->area.y) / 10;
8230   jmax = (layout->yoffset + event->area.y + event->area.height + 9) / 10;
8231
8232   gdk_window_clear_area (widget->window,
8233                          event->area.x, event->area.y,
8234                          event->area.width, event->area.height);
8235
8236   for (i=imin; i<imax; i++)
8237     for (j=jmin; j<jmax; j++)
8238       if ((i+j) % 2)
8239         gdk_draw_rectangle (layout->bin_window,
8240                             widget->style->black_gc,
8241                             TRUE,
8242                             10*i - layout->xoffset, 10*j - layout->yoffset, 
8243                             1+i%10, 1+j%10);
8244   
8245   return TRUE;
8246 }
8247
8248 void create_layout (void)
8249 {
8250   static GtkWidget *window = NULL;
8251   GtkWidget *layout;
8252   GtkWidget *scrolledwindow;
8253   GtkWidget *button;
8254
8255   if (!window)
8256     {
8257       gchar buf[16];
8258
8259       gint i, j;
8260       
8261       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8262       gtk_signal_connect (GTK_OBJECT (window), "destroy",
8263                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8264                           &window);
8265
8266       gtk_window_set_title (GTK_WINDOW (window), "Layout");
8267       gtk_widget_set_usize (window, 200, 200);
8268
8269       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
8270
8271       gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
8272       
8273       layout = gtk_layout_new (NULL, NULL);
8274       gtk_container_add (GTK_CONTAINER (scrolledwindow), layout);
8275       
8276       gtk_widget_set_events (layout, GDK_EXPOSURE_MASK);
8277       gtk_signal_connect (GTK_OBJECT (layout), "expose_event",
8278                           GTK_SIGNAL_FUNC (layout_expose_handler), NULL);
8279       
8280       gtk_layout_set_size (GTK_LAYOUT (layout), 1600, 64000);
8281       
8282       for (i=0 ; i < 16 ; i++)
8283         for (j=0 ; j < 16 ; j++)
8284           {
8285             sprintf(buf, "Button %d, %d", i, j);
8286             if ((i + j) % 2)
8287               /* button = gtk_button_new_with_label (buf); */
8288               button = gtk_combo_new();
8289             else
8290               button = gtk_label_new (buf);
8291
8292             gtk_layout_put (GTK_LAYOUT (layout), button,
8293                             j*100, i*100);
8294           }
8295
8296       for (i=16; i < 640; i++)
8297         {
8298           sprintf(buf, "Button %d, %d", i, 0);
8299           if (i % 2)
8300             button = gtk_button_new_with_label (buf);
8301           else
8302             button = gtk_label_new (buf);
8303
8304           gtk_layout_put (GTK_LAYOUT (layout), button,
8305                           0, i*100);
8306         }
8307     }
8308
8309   if (!GTK_WIDGET_VISIBLE (window))
8310     gtk_widget_show_all (window);
8311   else
8312     gtk_widget_destroy (window);
8313 }
8314
8315 /*
8316  * Main Window and Exit
8317  */
8318
8319 void
8320 do_exit (GtkWidget *widget, GtkWidget *window)
8321 {
8322   gtk_widget_destroy (window);
8323   gtk_main_quit ();
8324 }
8325
8326 void
8327 create_main_window (void)
8328 {
8329   struct {
8330     char *label;
8331     void (*func) ();
8332   } buttons[] =
8333     {
8334       { "button box", create_button_box },
8335       { "buttons", create_buttons },
8336       { "check buttons", create_check_buttons },
8337       { "clist", create_clist},
8338       { "color selection", create_color_selection },
8339       { "ctree", create_ctree },
8340       { "cursors", create_cursors },
8341       { "dialog", create_dialog },
8342       /*      { "dnd", create_dnd }, */
8343       { "entry", create_entry },
8344       { "event watcher", create_event_watcher },
8345       { "file selection", create_file_selection },
8346       { "font selection", create_font_selection },
8347       { "gamma curve", create_gamma_curve },
8348       { "handle box", create_handle_box },
8349       { "item factory", create_item_factory },
8350       { "layout", create_layout },
8351       { "list", create_list },
8352       { "menus", create_menus },
8353       { "modal window", create_modal_window },
8354       { "notebook", create_notebook },
8355       { "panes", create_panes },
8356       { "pixmap", create_pixmap },
8357       { "preview color", create_color_preview },
8358       { "preview gray", create_gray_preview },
8359       { "progress bar", create_progress_bar },
8360       { "radio buttons", create_radio_buttons },
8361       { "range controls", create_range_controls },
8362       { "rc file", create_rc_file },
8363       { "reparent", create_reparent },
8364       { "rulers", create_rulers },
8365       { "saved position", create_saved_position },
8366       { "scrolled windows", create_scrolled_windows },
8367       { "shapes", create_shapes },
8368       { "spinbutton", create_spins },
8369       { "statusbar", create_statusbar },
8370       { "test idle", create_idle_test },
8371       { "test mainloop", create_mainloop },
8372       { "test scrolling", create_scroll_test },
8373       { "test selection", create_selection_test },
8374       { "test timeout", create_timeout_test },
8375       { "text", create_text },
8376       { "toggle buttons", create_toggle_buttons },
8377       { "toolbar", create_toolbar },
8378       { "tooltips", create_tooltips },
8379       { "tree", create_tree_mode_window},
8380       { "WM hints", create_wmhints },
8381     };
8382   int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
8383   GtkWidget *window;
8384   GtkWidget *box1;
8385   GtkWidget *box2;
8386   GtkWidget *scrolled_window;
8387   GtkWidget *button;
8388   GtkWidget *label;
8389   gchar buffer[64];
8390   GtkWidget *separator;
8391   int i;
8392
8393   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8394   gtk_window_set_policy (GTK_WINDOW (window), FALSE, FALSE, FALSE);
8395   gtk_widget_set_name (window, "main window");
8396   gtk_widget_set_usize (window, 200, 400);
8397   gtk_widget_set_uposition (window, 20, 20);
8398
8399   gtk_signal_connect (GTK_OBJECT (window), "destroy",
8400                       GTK_SIGNAL_FUNC(gtk_main_quit),
8401                       NULL);
8402   gtk_signal_connect (GTK_OBJECT (window), "delete-event",
8403                       GTK_SIGNAL_FUNC (gtk_false),
8404                       NULL);
8405
8406   box1 = gtk_vbox_new (FALSE, 0);
8407   gtk_container_add (GTK_CONTAINER (window), box1);
8408
8409   if (gtk_micro_version > 0)
8410     sprintf (buffer,
8411              "Gtk+ v%d.%d.%d",
8412              gtk_major_version,
8413              gtk_minor_version,
8414              gtk_micro_version);
8415   else
8416     sprintf (buffer,
8417              "Gtk+ v%d.%d",
8418              gtk_major_version,
8419              gtk_minor_version);
8420
8421   label = gtk_label_new (buffer);
8422   gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
8423
8424   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
8425   gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
8426   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
8427                                   GTK_POLICY_AUTOMATIC, 
8428                                   GTK_POLICY_AUTOMATIC);
8429   gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
8430
8431   box2 = gtk_vbox_new (FALSE, 0);
8432   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8433   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), box2);
8434   gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
8435                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
8436   gtk_widget_show (box2);
8437
8438   for (i = 0; i < nbuttons; i++)
8439     {
8440       button = gtk_button_new_with_label (buttons[i].label);
8441       if (buttons[i].func)
8442         gtk_signal_connect (GTK_OBJECT (button), 
8443                             "clicked", 
8444                             GTK_SIGNAL_FUNC(buttons[i].func),
8445                             NULL);
8446       else
8447         gtk_widget_set_sensitive (button, FALSE);
8448       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8449     }
8450
8451   separator = gtk_hseparator_new ();
8452   gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
8453
8454   box2 = gtk_vbox_new (FALSE, 10);
8455   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8456   gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8457
8458   button = gtk_button_new_with_label ("close");
8459   gtk_signal_connect (GTK_OBJECT (button), "clicked",
8460                       GTK_SIGNAL_FUNC (do_exit),
8461                       window);
8462   gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8463   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8464   gtk_widget_grab_default (button);
8465
8466   gtk_widget_show_all (window);
8467 }
8468
8469 int
8470 main (int argc, char *argv[])
8471 {
8472   GtkBindingSet *binding_set;
8473
8474   srand (time (NULL));
8475
8476   gtk_set_locale ();
8477
8478   gtk_rc_add_default_file ("testgtkrc");
8479
8480   gtk_init (&argc, &argv);
8481
8482   gdk_rgb_init ();
8483
8484   /* bindings test
8485    */
8486   binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_WIDGET));
8487   gtk_binding_entry_add_signal (binding_set,
8488                                 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
8489                                 "debug_msg",
8490                                 1,
8491                                 GTK_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
8492
8493   create_main_window ();
8494
8495   gtk_main ();
8496
8497   return 0;
8498 }