]> Pileus Git - ~andy/gtk/blob - tests/testassistant.c
Replace a lot of idle and timeout calls by the new gdk_threads api.
[~andy/gtk] / tests / testassistant.c
1 /* 
2  * GTK - The GIMP Toolkit
3  * Copyright (C) 1999  Red Hat, Inc.
4  * Copyright (C) 2002  Anders Carlsson <andersca@gnu.org>
5  * Copyright (C) 2003  Matthias Clasen <mclasen@redhat.com>
6  * Copyright (C) 2005  Carlos Garnacho Parro <carlosg@gnome.org>
7  *
8  * All rights reserved.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the
22  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23  * Boston, MA 02111-1307, USA.
24  */
25
26 #include <gtk/gtk.h>
27
28 static GtkWidget*
29 get_test_page (const gchar *text)
30 {
31   return gtk_label_new (text);
32 }
33
34 typedef struct {
35   GtkAssistant *assistant;
36   GtkWidget    *page;
37 } PageData;
38
39 static void
40 complete_cb (GtkWidget *check, 
41              gpointer   data)
42 {
43   PageData *pdata = data;
44   gboolean complete;
45
46   complete = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check));
47
48   gtk_assistant_set_page_complete (pdata->assistant,
49                                    pdata->page,
50                                    complete);
51 }
52              
53 static GtkWidget *
54 add_completion_test_page (GtkWidget   *assistant,
55                           const gchar *text, 
56                           gboolean     visible,
57                           gboolean     complete)
58 {
59   GtkWidget *page;
60   GtkWidget *check;
61   PageData *pdata;
62
63   page = gtk_vbox_new (0, FALSE);
64   check = gtk_check_button_new_with_label ("Complete");
65
66   gtk_container_add (GTK_CONTAINER (page), gtk_label_new (text));
67   gtk_container_add (GTK_CONTAINER (page), check);
68   
69   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), complete);
70
71   pdata = g_new (PageData, 1);
72   pdata->assistant = GTK_ASSISTANT (assistant);
73   pdata->page = page;
74   g_signal_connect (G_OBJECT (check), "toggled", 
75                     G_CALLBACK (complete_cb), pdata);
76
77
78   if (visible)
79     gtk_widget_show_all (page);
80
81   gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
82   gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, text);
83   gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, complete);
84
85   return page;
86 }
87
88 static void
89 cancel_callback (GtkWidget *widget)
90 {
91   g_print ("cancel\n");
92
93   gtk_widget_hide (widget);
94 }
95
96 static void
97 close_callback (GtkWidget *widget)
98 {
99   g_print ("close\n");
100
101   gtk_widget_hide (widget);
102 }
103
104 static void
105 apply_callback (GtkWidget *widget)
106 {
107   g_print ("apply\n");
108 }
109
110 static gboolean
111 progress_timeout (GtkWidget *assistant)
112 {
113   GtkWidget *page, *progress;
114   gint current_page;
115   gdouble value;
116
117   current_page = gtk_assistant_get_current_page (GTK_ASSISTANT (assistant));
118   page = gtk_assistant_get_nth_page (GTK_ASSISTANT (assistant), current_page);
119   progress = GTK_BIN (page)->child;
120
121   value  = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (progress));
122   value += 0.1;
123   gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), value);
124
125   if (value >= 1.0)
126     {
127       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
128       return FALSE;
129     }
130
131   return TRUE;
132 }
133
134 static void
135 prepare_callback (GtkWidget *widget, GtkWidget *page)
136 {
137   if (GTK_IS_LABEL (page))
138     g_print ("prepare: %s\n", gtk_label_get_text (GTK_LABEL (page)));
139   else if (gtk_assistant_get_page_type (GTK_ASSISTANT (widget), page) == GTK_ASSISTANT_PAGE_PROGRESS)
140     {
141       GtkWidget *progress;
142
143       progress = GTK_BIN (page)->child;
144       gtk_assistant_set_page_complete (GTK_ASSISTANT (widget), page, FALSE);
145       gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), 0.0);
146       gdk_threads_add_timeout (300, (GSourceFunc) progress_timeout, widget);
147     }
148   else
149     g_print ("prepare: %d\n", gtk_assistant_get_current_page (GTK_ASSISTANT (widget)));
150 }
151
152 static void
153 create_simple_assistant (GtkWidget *widget)
154 {
155   static GtkWidget *assistant = NULL;
156
157   if (!assistant)
158     {
159       GtkWidget *page;
160
161       assistant = gtk_assistant_new ();
162       gtk_window_set_default_size (GTK_WINDOW (assistant), 400, 300);
163
164       g_signal_connect (G_OBJECT (assistant), "cancel",
165                         G_CALLBACK (cancel_callback), NULL);
166       g_signal_connect (G_OBJECT (assistant), "close",
167                         G_CALLBACK (close_callback), NULL);
168       g_signal_connect (G_OBJECT (assistant), "apply",
169                         G_CALLBACK (apply_callback), NULL);
170       g_signal_connect (G_OBJECT (assistant), "prepare",
171                         G_CALLBACK (prepare_callback), NULL);
172
173       page = get_test_page ("Page 1");
174       gtk_widget_show (page);
175       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
176       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 1");
177       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
178
179       page = get_test_page ("Page 2");
180       gtk_widget_show (page);
181       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
182       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 2");
183       gtk_assistant_set_page_type  (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_CONFIRM);
184       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
185     }
186
187   if (!GTK_WIDGET_VISIBLE (assistant))
188     gtk_widget_show (assistant);
189   else
190     {
191       gtk_widget_destroy (assistant);
192       assistant = NULL;
193     }
194 }
195
196 static void
197 visible_cb (GtkWidget *check, 
198             gpointer   data)
199 {
200   GtkWidget *page = data;
201   gboolean visible;
202
203   visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check));
204
205   g_object_set (G_OBJECT (page), "visible", visible, NULL);
206 }
207
208 static void
209 create_generous_assistant (GtkWidget *widget)
210 {
211   static GtkWidget *assistant = NULL;
212
213   if (!assistant)
214     {
215       GtkWidget *page, *next, *check;
216
217       assistant = gtk_assistant_new ();
218       gtk_window_set_default_size (GTK_WINDOW (assistant), 400, 300);
219
220       g_signal_connect (G_OBJECT (assistant), "cancel",
221                         G_CALLBACK (cancel_callback), NULL);
222       g_signal_connect (G_OBJECT (assistant), "close",
223                         G_CALLBACK (close_callback), NULL);
224       g_signal_connect (G_OBJECT (assistant), "apply",
225                         G_CALLBACK (apply_callback), NULL);
226       g_signal_connect (G_OBJECT (assistant), "prepare",
227                         G_CALLBACK (prepare_callback), NULL);
228
229       page = get_test_page ("Introduction");
230       gtk_widget_show (page);
231       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
232       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Introduction");
233       gtk_assistant_set_page_type  (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_INTRO);
234       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
235
236       page = add_completion_test_page (assistant, "Content", TRUE, FALSE);
237       next = add_completion_test_page (assistant, "More Content", TRUE, TRUE);
238
239       check = gtk_check_button_new_with_label ("Next page visible");
240       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
241       g_signal_connect (G_OBJECT (check), "toggled", 
242                         G_CALLBACK (visible_cb), next);
243       gtk_widget_show (check);
244       gtk_container_add (GTK_CONTAINER (page), check);
245       
246       add_completion_test_page (assistant, "Even More Content", TRUE, TRUE);
247
248       page = get_test_page ("Confirmation");
249       gtk_widget_show (page);
250       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
251       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Confirmation");
252       gtk_assistant_set_page_type  (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_CONFIRM);
253       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
254
255       page = gtk_alignment_new (0.5, 0.5, 0.9, 0.0);
256       gtk_container_add (GTK_CONTAINER (page), gtk_progress_bar_new ());
257       gtk_widget_show_all (page);
258       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
259       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Progress");
260       gtk_assistant_set_page_type  (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_PROGRESS);
261
262       page = get_test_page ("Summary");
263       gtk_widget_show (page);
264       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
265       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Summary");
266       gtk_assistant_set_page_type  (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_SUMMARY);
267       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
268     }
269
270   if (!GTK_WIDGET_VISIBLE (assistant))
271     gtk_widget_show (assistant);
272   else
273     {
274       gtk_widget_destroy (assistant);
275       assistant = NULL;
276     }
277 }
278
279 static gchar selected_branch = 'A';
280
281 static void
282 select_branch (GtkWidget *widget, gchar branch)
283 {
284   selected_branch = branch;
285 }
286
287 static gint
288 nonlinear_assistant_forward_page (gint current_page, gpointer data)
289 {
290   switch (current_page)
291     {
292     case 0:
293       if (selected_branch == 'A')
294         return 1;
295       else
296         return 2;
297     case 1:
298     case 2:
299       return 3;
300     default:
301       return -1;
302     }
303 }
304
305 static void
306 create_nonlinear_assistant (GtkWidget *widget)
307 {
308   static GtkWidget *assistant = NULL;
309
310   if (!assistant)
311     {
312       GtkWidget *page, *button;
313
314       assistant = gtk_assistant_new ();
315       gtk_window_set_default_size (GTK_WINDOW (assistant), 400, 300);
316
317       g_signal_connect (G_OBJECT (assistant), "cancel",
318                         G_CALLBACK (cancel_callback), NULL);
319       g_signal_connect (G_OBJECT (assistant), "close",
320                         G_CALLBACK (close_callback), NULL);
321       g_signal_connect (G_OBJECT (assistant), "apply",
322                         G_CALLBACK (apply_callback), NULL);
323       g_signal_connect (G_OBJECT (assistant), "prepare",
324                         G_CALLBACK (prepare_callback), NULL);
325
326       gtk_assistant_set_forward_page_func (GTK_ASSISTANT (assistant),
327                                            nonlinear_assistant_forward_page,
328                                            NULL, NULL);
329
330       page = gtk_vbox_new (FALSE, 6);
331
332       button = gtk_radio_button_new_with_label (NULL, "branch A");
333       gtk_box_pack_start (GTK_BOX (page), button, FALSE, FALSE, 0);
334       g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (select_branch), GINT_TO_POINTER ('A'));
335       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
336       
337       button = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
338                                                 "branch B");
339       gtk_box_pack_start (GTK_BOX (page), button, FALSE, FALSE, 0);
340       g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (select_branch), GINT_TO_POINTER ('B'));
341
342       gtk_widget_show_all (page);
343       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
344       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 1");
345       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
346       
347       page = get_test_page ("Page 2A");
348       gtk_widget_show (page);
349       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
350       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 2A");
351       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
352
353       page = get_test_page ("Page 2B");
354       gtk_widget_show (page);
355       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
356       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 2B");
357       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
358
359       page = get_test_page ("Confirmation");
360       gtk_widget_show (page);
361       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
362       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Confirmation");
363       gtk_assistant_set_page_type  (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_CONFIRM);
364       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
365     }
366
367   if (!GTK_WIDGET_VISIBLE (assistant))
368     gtk_widget_show (assistant);
369   else
370     {
371       gtk_widget_destroy (assistant);
372       assistant = NULL;
373     }
374 }
375
376 static gint
377 looping_assistant_forward_page (gint current_page, gpointer data)
378 {
379   switch (current_page)
380     {
381     case 0:
382       return 1;
383     case 1:
384       return 2;
385     case 2:
386       return 3;
387     case 3:
388       {
389         GtkAssistant *assistant;
390         GtkWidget *page;
391
392         assistant = (GtkAssistant*) data;
393         page = gtk_assistant_get_nth_page (assistant, current_page);
394
395         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page)))
396           return 0;
397         else
398           return 4;
399       }
400     case 4:
401     default:
402       return -1;
403     }
404 }
405
406 static void
407 create_looping_assistant (GtkWidget *widget)
408 {
409   static GtkWidget *assistant = NULL;
410
411   if (!assistant)
412     {
413       GtkWidget *page;
414
415       assistant = gtk_assistant_new ();
416       gtk_window_set_default_size (GTK_WINDOW (assistant), 400, 300);
417
418       g_signal_connect (G_OBJECT (assistant), "cancel",
419                         G_CALLBACK (cancel_callback), NULL);
420       g_signal_connect (G_OBJECT (assistant), "close",
421                         G_CALLBACK (close_callback), NULL);
422       g_signal_connect (G_OBJECT (assistant), "apply",
423                         G_CALLBACK (apply_callback), NULL);
424       g_signal_connect (G_OBJECT (assistant), "prepare",
425                         G_CALLBACK (prepare_callback), NULL);
426
427       gtk_assistant_set_forward_page_func (GTK_ASSISTANT (assistant),
428                                            looping_assistant_forward_page,
429                                            assistant, NULL);
430
431       page = get_test_page ("Introduction");
432       gtk_widget_show (page);
433       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
434       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Introduction");
435       gtk_assistant_set_page_type  (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_INTRO);
436       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
437
438       page = get_test_page ("Content");
439       gtk_widget_show (page);
440       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
441       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Content");
442       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
443
444       page = get_test_page ("More content");
445       gtk_widget_show (page);
446       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
447       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "More content");
448       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
449
450       page = gtk_check_button_new_with_label ("Loop?");
451       gtk_widget_show (page);
452       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
453       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Loop?");
454       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
455       
456       page = get_test_page ("Confirmation");
457       gtk_widget_show (page);
458       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
459       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Confirmation");
460       gtk_assistant_set_page_type  (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_CONFIRM);
461       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
462     }
463
464   if (!GTK_WIDGET_VISIBLE (assistant))
465     gtk_widget_show (assistant);
466   else
467     {
468       gtk_widget_destroy (assistant);
469       assistant = NULL;
470     }
471 }
472
473 static void
474 create_full_featured_assistant (GtkWidget *widget)
475 {
476   static GtkWidget *assistant = NULL;
477
478   if (!assistant)
479     {
480       GtkWidget *page, *button;
481          GdkPixbuf *pixbuf;
482
483       assistant = gtk_assistant_new ();
484       gtk_window_set_default_size (GTK_WINDOW (assistant), 400, 300);
485
486          button = gtk_button_new_from_stock (GTK_STOCK_STOP);
487          gtk_widget_show (button);
488          gtk_assistant_add_action_widget (GTK_ASSISTANT (assistant), button);
489
490       g_signal_connect (G_OBJECT (assistant), "cancel",
491                         G_CALLBACK (cancel_callback), NULL);
492       g_signal_connect (G_OBJECT (assistant), "close",
493                         G_CALLBACK (close_callback), NULL);
494       g_signal_connect (G_OBJECT (assistant), "apply",
495                         G_CALLBACK (apply_callback), NULL);
496       g_signal_connect (G_OBJECT (assistant), "prepare",
497                         G_CALLBACK (prepare_callback), NULL);
498
499       page = get_test_page ("Page 1");
500       gtk_widget_show (page);
501       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
502       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 1");
503       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
504
505          /* set a side image */
506          pixbuf = gtk_widget_render_icon (page, GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG, NULL);
507          gtk_assistant_set_page_side_image (GTK_ASSISTANT (assistant), page, pixbuf);
508
509          /* set a header image */
510          pixbuf = gtk_widget_render_icon (page, GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG, NULL);
511          gtk_assistant_set_page_header_image (GTK_ASSISTANT (assistant), page, pixbuf);
512
513       page = get_test_page ("Invisible page");
514       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
515
516       page = get_test_page ("Page 3");
517       gtk_widget_show (page);
518       gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
519       gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 3");
520       gtk_assistant_set_page_type  (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_CONFIRM);
521       gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, TRUE);
522
523          /* set a header image */
524          pixbuf = gtk_widget_render_icon (page, GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG, NULL);
525          gtk_assistant_set_page_header_image (GTK_ASSISTANT (assistant), page, pixbuf);
526     }
527
528   if (!GTK_WIDGET_VISIBLE (assistant))
529     gtk_widget_show (assistant);
530   else
531     {
532       gtk_widget_destroy (assistant);
533       assistant = NULL;
534     }
535 }
536
537 struct {
538   gchar *text;
539   void  (*func) (GtkWidget *widget);
540 } buttons[] =
541   {
542     { "simple assistant",        create_simple_assistant },
543     { "generous assistant",      create_generous_assistant },
544     { "nonlinear assistant",     create_nonlinear_assistant },
545     { "looping assistant",       create_looping_assistant },
546     { "full featured assistant", create_full_featured_assistant },
547   };
548
549 int
550 main (int argc, gchar *argv[])
551 {
552   GtkWidget *window, *box, *button;
553   gint i;
554
555   gtk_init (&argc, &argv);
556
557   if (g_getenv ("RTL"))
558     gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);
559
560   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
561
562   g_signal_connect (G_OBJECT (window), "destroy",
563                     G_CALLBACK (gtk_main_quit), NULL);
564   g_signal_connect (G_OBJECT (window), "delete-event",
565                     G_CALLBACK (gtk_false), NULL);
566
567   box = gtk_vbox_new (FALSE, 6);
568   gtk_container_add (GTK_CONTAINER (window), box);
569
570   for (i = 0; i < G_N_ELEMENTS (buttons); i++)
571     {
572       button = gtk_button_new_with_label (buttons[i].text);
573
574       if (buttons[i].func)
575         g_signal_connect (G_OBJECT (button), "clicked",
576                           G_CALLBACK (buttons[i].func), NULL);
577
578       gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
579     }
580
581   gtk_widget_show_all (window);
582   gtk_main ();
583
584   return 0;
585 }