]> Pileus Git - ~andy/gtk/blob - examples/progressbar/progressbar.c
Replace a lot of idle and timeout calls by the new gdk_threads api.
[~andy/gtk] / examples / progressbar / progressbar.c
1
2 #include <gtk/gtk.h>
3
4 typedef struct _ProgressData {
5   GtkWidget *window;
6   GtkWidget *pbar;
7   int timer;
8   gboolean activity_mode;
9 } ProgressData;
10
11 /* Update the value of the progress bar so that we get
12  * some movement */
13 static gboolean progress_timeout( gpointer data )
14 {
15   ProgressData *pdata = (ProgressData *)data;
16   gdouble new_val;
17   
18   if (pdata->activity_mode) 
19     gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pdata->pbar));
20   else 
21     {
22       /* Calculate the value of the progress bar using the
23        * value range set in the adjustment object */
24       
25       new_val = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (pdata->pbar)) + 0.01;
26       
27       if (new_val > 1.0)
28         new_val = 0.0;
29       
30       /* Set the new value */
31       gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar), new_val);
32     }
33   
34   /* As this is a timeout function, return TRUE so that it
35    * continues to get called */
36   return TRUE;
37
38
39 /* Callback that toggles the text display within the progress bar trough */
40 static void toggle_show_text( GtkWidget    *widget,
41                               ProgressData *pdata )
42 {
43   const gchar *text;
44   
45   text = gtk_progress_bar_get_text (GTK_PROGRESS_BAR (pdata->pbar));
46   if (text && *text)
47     gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pdata->pbar), "");
48   else 
49     gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pdata->pbar), "some text");
50 }
51
52 /* Callback that toggles the activity mode of the progress bar */
53 static void toggle_activity_mode( GtkWidget    *widget,
54                                   ProgressData *pdata )
55 {
56   pdata->activity_mode = !pdata->activity_mode;
57   if (pdata->activity_mode) 
58       gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pdata->pbar));
59   else
60       gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar), 0.0);
61 }
62
63  
64 /* Callback that toggles the orientation of the progress bar */
65 static void toggle_orientation( GtkWidget    *widget,
66                                 ProgressData *pdata )
67 {
68   switch (gtk_progress_bar_get_orientation (GTK_PROGRESS_BAR (pdata->pbar))) {
69   case GTK_PROGRESS_LEFT_TO_RIGHT:
70     gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar), 
71                                       GTK_PROGRESS_RIGHT_TO_LEFT);
72     break;
73   case GTK_PROGRESS_RIGHT_TO_LEFT:
74     gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar), 
75                                       GTK_PROGRESS_LEFT_TO_RIGHT);
76     break;
77   default:;
78     /* do nothing */
79   }
80 }
81
82  
83 /* Clean up allocated memory and remove the timer */
84 static void destroy_progress( GtkWidget    *widget,
85                               ProgressData *pdata)
86 {
87     g_source_remove (pdata->timer);
88     pdata->timer = 0;
89     pdata->window = NULL;
90     g_free (pdata);
91     gtk_main_quit ();
92 }
93
94 int main( int   argc,
95           char *argv[])
96 {
97     ProgressData *pdata;
98     GtkWidget *align;
99     GtkWidget *separator;
100     GtkWidget *table;
101     GtkWidget *button;
102     GtkWidget *check;
103     GtkWidget *vbox;
104
105     gtk_init (&argc, &argv);
106
107     /* Allocate memory for the data that is passed to the callbacks */
108     pdata = g_malloc (sizeof (ProgressData));
109   
110     pdata->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
111     gtk_window_set_resizable (GTK_WINDOW (pdata->window), TRUE);
112
113     g_signal_connect (G_OBJECT (pdata->window), "destroy",
114                       G_CALLBACK (destroy_progress),
115                       (gpointer) pdata);
116     gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
117     gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
118
119     vbox = gtk_vbox_new (FALSE, 5);
120     gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
121     gtk_container_add (GTK_CONTAINER (pdata->window), vbox);
122     gtk_widget_show (vbox);
123   
124     /* Create a centering alignment object */
125     align = gtk_alignment_new (0.5, 0.5, 0, 0);
126     gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 5);
127     gtk_widget_show (align);
128
129     /* Create the GtkProgressBar */
130     pdata->pbar = gtk_progress_bar_new ();
131     pdata->activity_mode = FALSE;
132
133     gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
134     gtk_widget_show (pdata->pbar);
135
136     /* Add a timer callback to update the value of the progress bar */
137     pdata->timer = gdk_threads_add_timeout (100, progress_timeout, pdata);
138
139     separator = gtk_hseparator_new ();
140     gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
141     gtk_widget_show (separator);
142
143     /* rows, columns, homogeneous */
144     table = gtk_table_new (2, 3, FALSE);
145     gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
146     gtk_widget_show (table);
147
148     /* Add a check button to select displaying of the trough text */
149     check = gtk_check_button_new_with_label ("Show text");
150     gtk_table_attach (GTK_TABLE (table), check, 0, 1, 0, 1,
151                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
152                       5, 5);
153     g_signal_connect (G_OBJECT (check), "clicked",
154                       G_CALLBACK (toggle_show_text),
155                       (gpointer) pdata);
156     gtk_widget_show (check);
157
158     /* Add a check button to toggle activity mode */
159     check = gtk_check_button_new_with_label ("Activity mode");
160     gtk_table_attach (GTK_TABLE (table), check, 0, 1, 1, 2,
161                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
162                       5, 5);
163     g_signal_connect (G_OBJECT (check), "clicked",
164                       G_CALLBACK (toggle_activity_mode),
165                       (gpointer) pdata);
166     gtk_widget_show (check);
167
168     /* Add a check button to toggle orientation */
169     check = gtk_check_button_new_with_label ("Right to Left");
170     gtk_table_attach (GTK_TABLE (table), check, 0, 1, 2, 3,
171                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
172                       5, 5);
173     g_signal_connect (G_OBJECT (check), "clicked",
174                       G_CALLBACK (toggle_orientation),
175                       (gpointer) pdata);
176     gtk_widget_show (check);
177
178     /* Add a button to exit the program */
179     button = gtk_button_new_with_label ("close");
180     g_signal_connect_swapped (G_OBJECT (button), "clicked",
181                               G_CALLBACK (gtk_widget_destroy),
182                               G_OBJECT (pdata->window));
183     gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
184
185     /* This makes it so the button is the default. */
186     GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
187
188     /* This grabs this button to be the default button. Simply hitting
189      * the "Enter" key will cause this button to activate. */
190     gtk_widget_grab_default (button);
191     gtk_widget_show (button);
192
193     gtk_widget_show (pdata->window);
194
195     gtk_main ();
196     
197     return 0;
198 }