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