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