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