Malcolm Cadman wrote:

> Has anyone written a progress bar in SuperBASIC ?
>
> To inform the user of the progress made during a longish operation
like
> processing a file.
>
> A graphical presentation would also be useful.
>
> 0% ****...............100%
>
> ( Crude ASCII illustration above ).
Here are a few ideas for progress bars which I have written. They are
graphical bars in the top left corner of window channel #0. The first
listing sets out the theory for an elapsed time bar, which you can
study and adapt to your own needs. The actual theory is that you
decide on the width of the bar in pixels, then take the total amount
of time that is to represent (in seconds) and divide the width by the
number of seconds to get the number of pixels per second, which may
well be a non-integer like 1.5 pixels per second. Then for each call
to the progress indication, you multiply the elapsed time by the
number of pixels per second and use BLOCK to draw a bar of that width.
A little bit of care is needed if the bar is to be width 0 pixels as
not all versions of S*BASIC will draw a BLOCK of 0 piel width without
an error, also you may wish to draw a block of the full width in the
background colour if elapsed time is 0 and the indicator is likely to
cycle round to 0 again during operation (see example 3 below). The
REMarks should show how it works.

100 REMark graphical progress bar
110 elapsed_col    = 4 : REMark elapsed time shown in this colour
120 background_col = 2 : REMark total time length shown in this colour
130 bar_width  = 100 : REMark pixels representing total time
140 bar_height = 10  : REMark pixels height of bar
150 CLS #0 : INPUT #0,'Time to represent > ';time : REMark seconds
160 pix_per_second = bar_width / time : REMark number of pixels
representing one second
170 CLS #0 : PRINT #0,'0%';
180 BLOCK #0,bar_width,bar_height,12,0,background_col : REMark this
bar shows the full time period
190 CURSOR #0,12+bar_width,0 : PRINT #0,'100%'
200 start_time = DATE : REMark time at which we started, err, timing
210 REPeat loop
220   elapsed_time = DATE-start_time : REMark how far have we got?
225   elapsed_pix = pix_per_second*elapsed_time : REMark how many
pixels represent this time?
227   IF elapsed_pix > bar_width THEN elapsed_pix = bar_width : REMark
might just get larger than maximum time if we check at the tick of a
second
230   BLOCK #0,pix_per_second*elapsed_time,bar_height,12,0,elapsed_col
: REMark the elapsed time bar
240   IF elapsed_time >= time THEN EXIT loop : REMark finished, exit
250 END REPeat loop
260 PRINT #0,'Time finished.'

*End of listing one*

The next listing shows how to generalise the progress bar for a set
number of operations, not just time based. The procedure
SETUP_PROGRESS_BAR initialises things, then the SHOW_PROGRESS routine
has two parameters, the first is the number of steps completed, the
second the total number of steps to be represented. Although the
example again reveolves around time, this modification allows it to be
more easily adapted to show 'steps' rather than time units, e.g. if
you know you have to write 10,000 strings to a file, you could insert
a call to SHOW_PROGRESS strings_done,10000. If this slows things down
too much, a simple MOD test will allow the loop to only call the
routine as often as you feel it needs to be updated (e.g. update only
every 100 string writes):

IF (strings_done MOD 100) = 0 THEN Show_PRogress strings_done,10000

100 REMark graphical progress bar
110 CLS #0 : INPUT #0,'Time to represent > ';time
120 Setup_Progress_Bar
130 start_time = DATE
140 REPeat loop
150   elapsed_time = DATE-start_time
160   Show_Progress elapsed_time,time
170   IF elapsed_time >= time THEN EXIT loop
180 END REPeat loop
190 PRINT #0,'Time finished.'
200 :
210 DEFine PROCedure Setup_Progress_Bar
220   done_col = 4
230   background_col = 2
240   bar_width = 100
250   bar_height = 10
260   CLS #0 : PRINT #0,'0%';
270   BLOCK #0,bar_width,bar_height,12,0,background_col
280   CURSOR #0,12+bar_width,0 : PRINT #0,'100%'
290 END DEFine Setup_Progress_Bar
300 :
310 DEFine PROCedure Show_Progress (done,steps)
320   IF done > 0 THEN BLOCK
#0,done*bar_width/steps,bar_height,12,0,done_col
330 END DEFine Show_Progress

Finally, a silly example showing how to use three progress bars to
represent a weird kind of digital clock. Three progress bars represent
hours elapsed today, minutes elapsed and seconds elapsed. Compile this
and execute it (unlocked if using pointer environment to allow it to
overwrite the display EXEP sillyclock_obj,U)

100 REMark graphical progress bars used as silly digital clock!
120 Setup_Progress_Bars
130 start_time = DATE
140 REPeat loop
150   t$ = DATE$
160   hr = t$(13 TO 14) : Show_Progress hr,24,0 : REMark hours
170   mi = t$(16 TO 17) : Show_Progress mi,60,1 : REMark minutes
180   se = t$(19 TO 20) : Show_Progress se,60,2 : REMark seconds
190 END REPeat loop
200 PRINT #0,'Time finished.'
210 :
220 DEFine PROCedure Setup_Progress_Bars
230   done_col = 4
240   background_col = 2
250   bar_width = 100
260   bar_height = 9 : REMark allows gap between lines
270   CLS #0
280   REMark hours bar
290   PRINT #0,'0'; : BLOCK
#0,bar_width,bar_height,12,0,background_col
300   CURSOR #0,12+bar_width,0 : PRINT #0,'24'
310   REMark minutes bar
320   PRINT #0,'0' : BLOCK
#0,bar_width,bar_height,12,10,background_col
330   CURSOR #0,12+bar_width,10 : PRINT #0,'60'
340   REMark seconds bar
350   PRINT #0,0 : BLOCK #0,bar_width,bar_height,12,20,background_col
360   CURSOR #0,12+bar_width,20 : PRINT #0,'60'
370 END DEFine Setup_Progress_Bar
380 :
390 DEFine PROCedure Show_Progress (done,steps,bar_number)
400   IF done = 0 THEN
410     BLOCK #0,bar_width,bar_height,12,10*bar_number,background_col
420   ELSE
430     BLOCK
#0,done*bar_width/steps,bar_height,12,10*bar_number,done_col
440   END IF
450 END DEFine Show_Progress

A possibility with timed progress bars is to compile them with
QLiberator as external procedures, LRESPR those and start them with
the name of the command generated followed by an exclamation mark
which will allow them to multitask, although they'll be suspended if
their windows are buried.

This email has turned out a bit longer than I thought (sorry
everyone), but might give you a clue as to how to write one to suit
your needs.

--
Dilwyn Jones

Reply via email to