]> Pileus Git - ~andy/gtk/blob - demos/gtk-demo/assistant.c
c753d9068f1704474b1df24f1208c9b3dc9558e5
[~andy/gtk] / demos / gtk-demo / assistant.c
1 /* Assistant
2  *
3  * Demonstrates a sample multistep assistant. Assistants are used to divide
4  * an operation into several simpler sequential steps, and to guide the user
5  * through these steps.
6  */
7
8 #include <gtk/gtk.h>
9 #include "demo-common.h"
10
11 static GtkWidget *assistant = NULL;
12 static GtkWidget *progress_bar = NULL;
13
14 static gboolean
15 apply_changes_gradually (gpointer data)
16 {
17   gdouble fraction;
18
19   /* Work, work, work... */
20   fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (progress_bar));
21   fraction += 0.05;
22
23   if (fraction < 1.0)
24     {
25       gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar), fraction);
26       return TRUE;
27     }
28   else
29     {
30       /* Close automatically once changes are fully applied. */
31       gtk_widget_destroy (assistant);
32       return FALSE;
33     }
34 }
35
36 static void
37 on_assistant_apply (GtkWidget *widget, gpointer data)
38 {
39   /* Start a timer to simulate changes taking a few seconds to apply. */
40   g_timeout_add (100, apply_changes_gradually, NULL);
41 }
42
43 static void
44 on_assistant_close_cancel (GtkWidget *widget, gpointer data)
45 {
46   GtkWidget **assistant = (GtkWidget **) data;
47
48   gtk_widget_destroy (*assistant);
49   *assistant = NULL;
50 }
51
52 static void
53 on_assistant_prepare (GtkWidget *widget, GtkWidget *page, gpointer data)
54 {
55   gint current_page, n_pages;
56   gchar *title;
57
58   current_page = gtk_assistant_get_current_page (GTK_ASSISTANT (widget));
59   n_pages = gtk_assistant_get_n_pages (GTK_ASSISTANT (widget));
60
61   title = g_strdup_printf ("Sample assistant (%d of %d)", current_page + 1, n_pages);
62   gtk_window_set_title (GTK_WINDOW (widget), title);
63   g_free (title);
64
65   /* The fourth page (counting from zero) is the progress page.  The
66   * user clicked Apply to get here so we tell the assistant to commit,
67   * which means the changes up to this point are permanent and cannot
68   * be cancelled or revisited. */
69   if (current_page == 3)
70       gtk_assistant_commit (GTK_ASSISTANT (widget));
71 }
72
73 static void
74 on_entry_changed (GtkWidget *widget, gpointer data)
75 {
76   GtkAssistant *assistant = GTK_ASSISTANT (data);
77   GtkWidget *current_page;
78   gint page_number;
79   const gchar *text;
80
81   page_number = gtk_assistant_get_current_page (assistant);
82   current_page = gtk_assistant_get_nth_page (assistant, page_number);
83   text = gtk_entry_get_text (GTK_ENTRY (widget));
84
85   if (text && *text)
86     gtk_assistant_set_page_complete (assistant, current_page, TRUE);
87   else
88     gtk_assistant_set_page_complete (assistant, current_page, FALSE);
89 }
90
91 static void
92 create_page1 (GtkWidget *assistant)
93 {
94   GtkWidget *box, *label, *entry;
95   GdkPixbuf *pixbuf;
96
97   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 12);
98   gtk_container_set_border_width (GTK_CONTAINER (box), 12);
99
100   label = gtk_label_new ("You must fill out this entry to continue:");
101   gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
102
103   entry = gtk_entry_new ();
104   gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0);
105   g_signal_connect (G_OBJECT (entry), "changed",
106                     G_CALLBACK (on_entry_changed), assistant);
107
108   gtk_widget_show_all (box);
109   gtk_assistant_append_page (GTK_ASSISTANT (assistant), box);
110   gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), box, "Page 1");
111   gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), box, GTK_ASSISTANT_PAGE_INTRO);
112
113   pixbuf = gtk_widget_render_icon (assistant, GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG, NULL);
114   gtk_assistant_set_page_header_image (GTK_ASSISTANT (assistant), box, pixbuf);
115   g_object_unref (pixbuf);
116 }
117
118 static void
119 create_page2 (GtkWidget *assistant)
120 {
121   GtkWidget *box, *checkbutton;
122   GdkPixbuf *pixbuf;
123
124   box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12, FALSE);
125   gtk_container_set_border_width (GTK_CONTAINER (box), 12);
126
127   checkbutton = gtk_check_button_new_with_label ("This is optional data, you may continue "
128                                                  "even if you do not check this");
129   gtk_box_pack_start (GTK_BOX (box), checkbutton, FALSE, FALSE, 0);
130
131   gtk_widget_show_all (box);
132   gtk_assistant_append_page (GTK_ASSISTANT (assistant), box);
133   gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), box, TRUE);
134   gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), box, "Page 2");
135
136   pixbuf = gtk_widget_render_icon (assistant, GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG, NULL);
137   gtk_assistant_set_page_header_image (GTK_ASSISTANT (assistant), box, pixbuf);
138   g_object_unref (pixbuf);
139 }
140
141 static void
142 create_page3 (GtkWidget *assistant)
143 {
144   GtkWidget *label;
145   GdkPixbuf *pixbuf;
146
147   label = gtk_label_new ("This is a confirmation page, press 'Apply' to apply changes");
148
149   gtk_widget_show (label);
150   gtk_assistant_append_page (GTK_ASSISTANT (assistant), label);
151   gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), label, GTK_ASSISTANT_PAGE_CONFIRM);
152   gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), label, TRUE);
153   gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), label, "Confirmation");
154
155   pixbuf = gtk_widget_render_icon (assistant, GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG, NULL);
156   gtk_assistant_set_page_header_image (GTK_ASSISTANT (assistant), label, pixbuf);
157   g_object_unref (pixbuf);
158 }
159
160 static void
161 create_page4 (GtkWidget *assistant)
162 {
163   GtkWidget *page;
164
165   page = gtk_alignment_new (0.5, 0.5, 0.5, 0.0);
166
167   progress_bar = gtk_progress_bar_new ();
168   gtk_container_add (GTK_CONTAINER (page), progress_bar);
169
170   gtk_widget_show_all (page);
171   gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
172   gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_PROGRESS);
173   gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Applying changes");
174
175   /* This prevents the assistant window from being
176    * closed while we're "busy" applying changes. */
177   gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), page, FALSE);
178 }
179
180 GtkWidget*
181 do_assistant (GtkWidget *do_widget)
182 {
183   if (!assistant)
184     {
185       assistant = gtk_assistant_new ();
186
187          gtk_window_set_default_size (GTK_WINDOW (assistant), -1, 300);
188
189       gtk_window_set_screen (GTK_WINDOW (assistant),
190                              gtk_widget_get_screen (do_widget));
191
192       create_page1 (assistant);
193       create_page2 (assistant);
194       create_page3 (assistant);
195       create_page4 (assistant);
196
197       g_signal_connect (G_OBJECT (assistant), "cancel",
198                         G_CALLBACK (on_assistant_close_cancel), &assistant);
199       g_signal_connect (G_OBJECT (assistant), "close",
200                         G_CALLBACK (on_assistant_close_cancel), &assistant);
201       g_signal_connect (G_OBJECT (assistant), "apply",
202                         G_CALLBACK (on_assistant_apply), NULL);
203       g_signal_connect (G_OBJECT (assistant), "prepare",
204                         G_CALLBACK (on_assistant_prepare), NULL);
205     }
206
207   if (!gtk_widget_get_visible (assistant))
208     gtk_widget_show (assistant);
209   else
210     {
211       gtk_widget_destroy (assistant);
212       assistant = NULL;
213     }
214
215   return assistant;
216 }