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