"Wake up, Welopez! That confounded snoring is hurting my ears!"
"Huh? Who… where?" I guess I had fallen asleep waiting for that double-buffer sort to run to completion. Or perhaps I was waiting for that really huge image slide show to finish loading.
One of those pesky Worbles was sitting atop the track-ball I use inplace of a mouse. "I'm sorry," I told him. "I was doing something here, I don't quite remember what, and I guess I dozed off. Sometimes we need a progress bar in Just Basic, to sort of give the user how long he or she will be waiting for a process to finish. Liberty Basic can access some DLL files built into Windows, but I don't know how to do that with Just Basic."
"If it's just a little 'eye-candy' you want, Welopez, we can do something about that. My name is Bickley. The Worble in Chief says I'm a master at goofing off and wasting time."
"Now you're talking, Bickley. I'd like to add some snazzy graphics to my programs to show my chums what a fantastic programmer I am!"
"Whoa, hoss! Don't get carried away with yourself! This won't take an awesome amount of ability, anyone can use these simple tricks. Let's start with that standard Progress Bar you see in many applications when a program is loading. We'll make our own, and you can use any color you like. I'm fond of green, because we don't have any plants inside a CPU. Don't you think plants lend atmosphere to a living space?"
I admitted I did, truthfully I can't grow much of anything besides weeds.
"Okay, lets write a little code, just as a demonstration."
NOMAINWIN
WindowWidth=400
WindowHeight=200
UpperLeftX=INT((DisplayWidth-WindowWidth)/2)
UpperLeftY=INT((DisplayHeight-WindowHeight)/2)
GRAPHICBOX #1.gbx, 10, 20, 370, 36
STATICTEXT #1.stxt, "", 100, 80, 370, 30
BUTTON #1.btn1, "Again", [again], UL, 130, 120, 60, 30
BUTTON #1.btn2, "Quit", [quit], UL 200, 120, 60, 30
OPEN "Progress Bar" FOR WINDOW AS #1
PRINT #1, "trapclose [quit]"
PRINT #1.gbx, "backcolor 150 255 45" 'Set another color here if you like
PRINT #1.gbx, "DOWN"
PRINT #1, "font verdana 12 bold" 'Set font for all controls
[again]
PRINT #1.gbx, "CLS" 'Clear the graphicbox to begin again
WHILE x < 372 'Two pixels more than width of the graphicbox
PRINT #1.gbx, "boxfilled "; x ;" 36" 'The box is x long and 36 high
partComp = x/372 'Percentage of part complete
partComp = INT(partComp * 100) 'Get the INT value to print percent
IF x>=370 THEN PRINT #1.stxt, "Progress is complete." _
ELSE PRINT #1.stxt, "Progress is "; partComp ; "% complete."
CALL shortPause
x=x+1 'Move the bar one more pixel right
WEND
x=0 'Reset when done so we can do it again
WAIT
[quit]
CLOSE #1
END
SUB shortPause
print #1, "disable" 'Prevents mouse input during shortPause
TIMER 25, [cont] 'Set pause here, more is longer.
WAIT
[cont]
TIMER 0
print #1, "enable" 'Enable the window again
END SUB
"Wow! That didn't take much time, Bickley! What's it do?"
"This is simply a demo, Welopez, and it runs so fast I had to insert a SUB to put a shortPause into the display loop. All we need is a GRAPHICBOX for a graphic display, and a STATICTEXT as a text display. First I set my favorite color, and then I began printing a BOXFILLED at the left end of the graphicbox. With each pass through the loop, I make the box longer by 1 pixel." Bickley ran the program and I watched as the green bar moved across the screen. It was sort of nifty, but I would really have chosen red to add passion to my program.
"In this demo, I calculated the percentage complete based upon how much of the graphic box had been completed. In the real world, such as loading a file or loops through a sorting routine, you would use an input loop to compare LOF(#file) being loaded, against the number of bytes currently loaded. When the value has reached 100%, then you can exit the routine and close the window. Because every application will have a different file, you'll have to write the routine specifically for your program. If you're displaying the progress of a sorting routine, you can put an accumulator inside the loop and increment it for each pass. Divide the current accumulator value by the maximum number of passes you will have to make in the worst case scenario, and you have the percent completed. Again, you exit the routine and close the window when you reach 100%."
"That's easy for you to say, Bickley. You Worbles know everything that goes on inside a computer. I have to keep checking the Help Files to see what I can do."
"We weren't born with the ability, Welopez. Just be thankful your Help Files are not a large as ours! We have to know every application on your computer, and our help is written in binary!"
"If you want something a little more eye-catching than a simple progress bar, you can use a graphic image, but first you'll have to create a BMP image for display. Here's the one I created using MS Paint."
"Hmm, that looks sort of familiar, Bickley."
"It should… a junior geek at Microsoft copied my idea for this graphic and claimed all the credit!"
NOMAINWIN
WindowWidth=400
WindowHeight=200
UpperLeftX=INT((DisplayWidth-WindowWidth)/2)
UpperLeftY=INT((DisplayHeight-WindowHeight)/2)
loadbmp "balls", "tri-balls.bmp"
GRAPHICBOX #1.gbx, 10, 20, 370, 25
STATICTEXT #1.stxt, "", 80, 70, 370, 30
BUTTON #1.btn1, "Again", [again], UL, 120, 120, 70, 30
BUTTON #1.btn2, "Quit", [quit], UL 220, 120, 70, 30
OPEN "Progress Bar" FOR WINDOW AS #1
PRINT #1, "trapclose [quit]"
PRINT #1, "font verdana 12 bold"
[again]
x=0 : y=2 : reps=0
PRINT #1.gbx, "CLS"
WHILE x<374
PRINT #1.gbx, "drawbmp balls "; x; " -5"
CALL shortPause
x=(x+y)
IF x > 305 OR x < 0 THEN y=(-1*y)
reps=reps+1
current = reps/1000
current = INT(current * 100)
PRINT #1.stxt, "Progress is "; current ; "% complete."
IF reps > 1000 THEN EXIT WHILE 'Sets the limit for repeating
WEND
PRINT #1.gbx, "CLS" 'Clear the graphic box when complete
WAIT
[quit]
UNLOADBMP "balls"
CLOSE #1
END
SUB shortPause
print #1, "disable" 'Prevents mouse input during shortPause
TIMER 10, [cont] 'Set pause here, more is longer.
WAIT
[cont]
TIMER 0
print #1, "enable" 'Enable the window again
END SUB
"We reused the same shortPause in this code, but we had to get a little more creative to display the animation. You'll have to experiment with the parameters to place and print your image, depending upon the size of your graphicbox and BMP image.
"Again, because this is only a demo, we had to insert a timer to slow down the animation. Print #1.gbx, "drawbmp balls "; x; " -5" determines where the image will be printed. The variable x changes with each pass through the loop."
"How do you make the animation move back and forth, Bickley?"
"That's not so difficult, Welopez, we set x=x+y with each pass through the loop. Initially, we assigned y a value of 2 (pixels) before beginning the loop. After testing the animation a few times, we determined the right and left limits of x+y, and when we want the animation to change direction we change the sign of y with y=(-1*y). If we had previously been increasing with a positive value, now we are decreasing with a negative value, until we reach the other limit and change the sign of y again."
"Wow! That's a really nifty trick!"
"Be sure you don't make y too large. A larger value will move the animation faster, but if you don't have any margin at the right and left side of your image, the colored portion will not be erased when the image is moved and printed again."
"Can't we clear the graphicbox with a "CLS" command?"
"Yes, you could, but that's just more work for Pablo and his art department. They use gallons and gallons of paint in a routine like this, and Pablo doesn't want to overload them. The Worbles Artists and Painters Guild may begin to issue demands, ya know? If we allow a few pixels for a margin at each side of the image, then the Worbles only have to paint a small part of the box, and they don't get as upset. Take my word for it, those painters are the laziest Worbles in the barrel, Welopez. If you make them work too hard, they may get sloppy and miss spots, then your image will 'flicker' more than necessary."
"Okay, I see you're counting repetitions through the loop using the variable reps. Why did you then assign it to variable current?"
"Use your head for more than just keeping your ears apart so you'll have a place to park your glasses, Welopez. Reps is the total number of passes we want to make, 1000. If we divide reps by 1000 to compute the percentage currently complete, reps will never reach a value of 1000, will it?"
"Oops, you're right, of course. We'd go into an endless loop and…"
"Right! We'd have a few more FUBAR Worbles which we aren't much good to anyone. Besides, we are only using reps to set a limit for this demo. When you are actually loading a file, or displaying the progress of a routine, you will have a real variable to work with and compute your percentage. Well, I think you've got the general idea of things, Welopez. Keep in mind, you'll have to determine the size of the file you are loading and the method of keeping track of how much has been loaded to compute the percentage to display and when to exit. Because files are different and the application you will be using it for will change with each program, you have to do that yourself."
"Oh, I think you've given me a lot of help and steered me along the right path, Bickley. Thanks for all your help." I gave him a high-five by pressing my pinky-finger against his upraised hand, and he disappeared somewhere inside my track-ball.
Hmmm, Bickley certainly had given me some ideas, and now that I had an idea how the code worked, I could make lots of changes to it to suit my own needs. I might even be good enough to land a programming job! I picked up the telephone and dialed long distance. "Hello… Microsoft?"