3 * Copyright (c) 2003, Division of Imaging Science and Biomedical Engineering,
4 * University of Manchester, UK. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
9 * . Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
12 * . Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * . Neither the name of the University of Manchester nor the names of its
17 * contributors may be used to endorse or promote products derived from this
18 * software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
35 * Program : TINA
36 * File :
37 * Date :
38 * Version :
39 * CVS Id :
41 * Notes :
43 * Extra widgets for the mousetool: Gtk progress bar.
48 * @file wdgtsGtk_tw_progressbar.c
49 * @brief Create and update a GTK progress bar.
51 * Notes: the Gtk progress bar is different from any other widget in TINA (at the
52 * time of writing) since it is used only to display information to the user:
53 * there is no user interaction with it. Therefore, it bypasses the standard TINA
54 * callback system (since we will never need to interact with one during macro
55 * replays).
57 * Progress bars have to be updated in the middle of the processing they monitor,
58 * which is also unique in TINA. The TINA programming philospohy calls for very
59 * little integration with the widget set, to ensure that widget set interfaces
60 * can be changed easily. This creates a problem for the progress bar, since it
61 * is necessary to return to the Gtk main loop in order to display changes in
62 * progress. Therefore, the standard approaches of using a Gtk timeout or
63 * starting a nested Gtk main loop are not suitable.
65 * The solution I have adopted is to create the progress bar in a new window,
66 * separate to the standard TINA window creation command. This window is made
67 * modal, preventing all interaction with other TINA windows whilst it is
68 * displayed.
70 * The progress bar is initiated with a call to
72 * void *tw_progressbar_start(char *name, char *text)
74 * The name argument is a label that will appear in the window above the progress
75 * bar. The text argument allows the user to provide text that will appear within
76 * the bar and can be changed during processing. Both are copied rather than used,
77 * and so must be freed by the caller. The return is a TINA structure that wraps
78 * the progress bar, and contains the pointer to the window containing the progress
79 * bar (allowing it to be cleanly destroyed when the user is finished with it).
81 * The progress fraction can be updated with a call to
83 * void tw_progressbar_set_fraction(void *tw_pbar, double fraction)
85 * where the tw_pbar argument is a pointer to a TINA progress bar structure, and
86 * the fraction argument is the completion fraction (0.0 to 1.0). The text
87 * displayed within the bar can be updated with a call to
89 * void tw_progressbar_set_text(void *tw_pbar, char *text)
91 * where the tw_pbar argument is a pointer to a TINA progress bar structure, and
92 * the text argument is the new text to display within the bar. This can be
93 * used to provide additional information to the user about the internal details
94 * of the task being monitored. The actual update of the displayed progress bar
95 * occurs when one of these two functions is called; they call individual
96 * iterations of the Gtk main loop until all pending events have been processed.
98 * When the processing monitored by the progress bar finishes, the progress bar
99 * window must be destroyed with a call to
101 * void tw_progressbar_stop(void *tw_pbar)
103 * This destroys the window containing the progress bar (thus destroying all of
104 * its child widgets and freeing any allocated memory) and frees the TINA progress
105 * bar structure. Note that attempting to destroy a progress bar by clicking on the
106 * delete button in the title bar would result in strings of Gtk errors appearing
107 * in the terminal from which TINA was launched, as TINA would be attempting to
108 * update a progress bar that no longer existed (and I don't want to attempt to
109 * allow the user to interrput processing by using the delete button). The
110 * "deletable" property of the window containing the progress bar if therefore
111 * set to FALSE; however, the implementation of this depends on window manager
112 * policy, and so it is not guaranteed to prevent a delete button being displayed
113 * on all systems. Therefore, the delete event itself exists (to prevent a default
114 * one that destroys the window from being used), and simply prints a message (that
115 * may be familiar to those who have read The Hitch-hikers Guide to the Galaxy).
120 #include <gtk/gtk.h>
122 #include <tina/sys/sysPro.h>
123 #include <tinatool/wdgts/gtk2/wdgtsGtk_tw_tool.h>
125 #include "wdgtsGtk_tw_progressbar.h"
127 #if HAVE_CONFIG_H
128 # include <config.h>
133 * @brief Set the completion fraction of a progress bar widget.
134 * @param tw_pbar Pointer to the tw_progressbar structure for the progress bar widget.
135 * @param fraction Completion fraction to display.
137 * Notes: the fraction must be between 0.0 and 1.0: it translates
138 * directly to the proportion of the bar that is filled.
141 void tw_progressbar_set_fraction(void *tw_pbar, double fraction)
143 Tw_progressbar *pbar = NULL;
145 if(tw_pbar==NULL) return;
146 if(fraction<0.0) fraction = 0.0;
147 if(fraction>1.0) fraction = 1.0;
149 pbar = (Tw_progressbar *)tw_pbar;
150 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pbar->pbar), fraction);
152 /*gtk_main_iteration_do(FALSE); *//* Hit one iteration to make the events pending */
153 while (gtk_events_pending() /*|| gdk_events_pending()*/)
161 * @brief Set the within-bar text of a progress bar widget.
162 * @param tw_pbar Pointer to the tw_progressbar structure for the progress bar widget.
163 * @param text The within-bar text to display.
166 void tw_progressbar_set_text(void *tw_pbar, char *text)
168 Tw_progressbar *pbar = NULL;
170 if(tw_pbar==NULL) return;
172 pbar = (Tw_progressbar *)tw_pbar;
173 gtk_progress_bar_set_text(GTK_PROGRESS_BAR (pbar->pbar), text);
175 /*gtk_main_iteration_do(FALSE); *//* Hit one iteration to make the events pending */
176 while (gtk_events_pending() /*|| gdk_events_pending()*/)
183 * @brief Stop a progress bar widget, returning control to TINA and freeing memory.
184 * @param tw_pbar Pointer to the tw_progressbar structure for the progress bar widget.
187 void tw_progressbar_stop(void *tw_pbar)
189 Tw_progressbar *pbar = NULL;
190 GtkWidget *window=NULL;
192 if(tw_pbar==NULL) return;
194 pbar = (Tw_progressbar *)tw_pbar;
195 window = GTK_WIDGET(pbar->window);
202 * @brief Gtk signal func for delete events in progress bars.
203 * @param widget The progress bar widget.
204 * @param event The delete event
205 * @param data Always NULL in this case.
207 * The Gtk library version available on the NiAC lab Suns at the time of writing is
208 * too old to have the gtk_window_set_deletable function, and so progress bars
209 * cannot have their deletable property set to FALSE; this is also dependent on
210 * window manager behaviour. This function provides a backup; it only exists to
211 * prevent the default behaviour (destroy the window). Returning TRUE ensures
212 * that no further inherited Gtk behaviour will be called after this function.
215 static gboolean pbar_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
217 format("WARNING: please do not try to close the progress bar.\n");
219 return TRUE;
224 * @brief Create a progress bar window/widget.
225 * @param name Text label to appear above the progress bar.
226 * @param text Text lable to appear superimposed on the progress bar.
227 * @return void* twc Pointer to the progress bar widget.
229 * Notes: the arguments to this function are copied, not used directly,
230 * so any memory allocated to hold them should be freed by the caller.
232 * Notes: the progress bar is contained within a newly created window,
233 * (see comments at the top of this file), which is made modal (so that
234 * the user cannot interact with the rest of TINA during processing).
236 * Notes: progress bars should ideally have their deletable property
237 * set to FLASE, so that the user cannot close them. However, the
238 * relevant function (gtk_window_set_deletable) was introduced in
239 * Gtk v. 2.10, which is newer than the library version availble on
240 * Solaris at the time of writing. Therefore, the relevant line is
241 * commented out in this function, and
244 void *tw_progressbar_start(char *name, char *text)
246 Tw_progressbar *tw_pbar=ralloc(sizeof(Tw_progressbar));
247 GtkWidget *window = NULL;
248 GtkWidget *label = NULL;
249 GtkWidget *table = NULL;
250 GtkWidget *pbar = NULL;
252 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
253 gtk_window_set_modal(GTK_WINDOW(window), TRUE);
254 gtk_window_set_keep_above(GTK_WINDOW(window), TRUE);
255 gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
256 /* gtk_window_set_deletable(GTK_WINDOW(window), FALSE); */
257 gtk_signal_connect (GTK_OBJECT (window), "delete_event", GTK_SIGNAL_FUNC (pbar_delete_event), NULL);
259 gtk_container_border_width (GTK_CONTAINER (window), 10);
260 table = gtk_table_new(3,2,TRUE);
261 gtk_container_add (GTK_CONTAINER (window), table);
263 label = gtk_label_new (name);
264 gtk_table_attach_defaults(GTK_TABLE(table), label, 0,2,0,1);
267 pbar = gtk_progress_bar_new();
268 gtk_table_attach_defaults(GTK_TABLE(table), pbar, 0,2,1,2);
269 gtk_widget_show (pbar);
274 tw_pbar->window = window;
275 tw_pbar->pbar = pbar;
276 if(text!=NULL) tw_progressbar_set_text(tw_pbar, text);
277 tw_progressbar_set_fraction(tw_pbar, 0.0);
279 return (void *)tw_pbar;
This page was automatically generated by the
Visit the LXR main site for more