| |||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||
Print This Article REALbasic University: Column 103
OOP University: Part Twenty-FiveIn lesson 099 we discussed the challenges in developing a progress bar dialog. While it seems simple, there are a number of obstacles, especially if you allow the user to cancel the action. Since a progress bar is usually in a different window, how do you tell the action to stop? Today we'll create a reusable progress bar system.
A Reusable Progress Bar DialogProgress bars are found throughout all sorts of programs, so it makes sense to design a system that's reusable -- that way you only have to code it once. REALbasic makes this kind of thing remarkably easy as it lets you import external items into multiple projects. You do this by dragging an item into a project window while holding down the Command and Option keys. This links in the external item, but the code is not part of your current project: it's stored externally, so if you fix a bug in that code, all projects that link to that external code are updated as well! We'll begin by creating a basic dialog box. Within a new project, add a window (File menu, "New Window") and name it progressDialog. Make it 300 pixels wide by 180 tall. Set its Frame property to Movable Modal. Like this: ![]() Now because we want to make this progress dialog as flexible as possible (so it can be used in many different programs), we'll build it as a dual progress bar dialog. But as you'll see, it will be easy to use as a single progress bar if we want. So let's begin by adding a couple progressBar objects and four staticText objects to progressDialog. Arrange them like this: ![]() Note how the second bar and text label are indented from the left side. The progressBars should be named (from top to bottom) pBar1 and pBar2, and the staticTexts should be named mainLabel, subLabel, statusLabel, and cancelText. The first two should be textSize 0, the bottom two textSize 10. Now let's open the Code Editor for progressDialog (Option-tab while window is selected) and add a new method (Edit menu, "New Method..."). Give it the name init and on the parameter line put this:
This is going to be our initialization routine for the dialog. Prior to displaying the window, you first call this routine and establish the window's title, whether there are one or two progress bars, and whether the operation is cancellable or not. Here's the code for init:
The above should be self-explanatory, though we haven't covered some of these properties yet. For now, just go ahead and put this in, and I'll explain later when we add these properties. The main thing that happens here is we adjust the dialog based on whether there are one or two progress bars. If there's only one, we move the bottom text labels up (and remove the indent on statusLabel) and make the whole window smaller as well. We also set a local property called cantCancel. We might as well add that now, as long as we're thinking about it. Add a new property to progressDialog (Edit menu, "New Property") like this: cantCancel as boolean. Now we add another method. This one is called startProgress and takes theMessage as string, theMax as integer as parameters. This is the routine that is called to establish the initial message and maximum size of a progresss bar.
Actually, there are two of these, almost identical. The second is startSubProgress and takes the same parameters. Here's the code for it.
As you can see, these routines are very simple: they set the maximum size of the progress bar, and establish an initial text message display. The only difference is that startProgress works on pBar1 and startSubProgress works on pBar2. Next we'll add a method that will be called any time the progress bar needs to be adjusted. This is a simple method that takes the text for the display message and the amount that should be added to the progress bar's value property.
Again, the method is simple. We pass on theMessage as the text to be displayed, and we add the amount passed to the progress bar's value. Since this first method only updates pBar1, we'll need a second method for pBar2:
You may notice that both of these methods include a self.refresh command. This forces the window to redraw after we've changed some of the settings. This is important, because sometimes REALbasic gets so busy doing the actual task (usually within a loop, for instance) that it doesn't update the progress bar window as often as you'd like. Note that both of these routines include a very important piece of code: as they update, they check to see if the user has cancelled the operation. Since not all operations are cancellable, we first check to make sure that cantCancel isn't true (if it is true, we don't bother checking to see if the user has cancelled). If the user has canceled, we pass control to a method called cancel:
This is a very simple method that sets a global property that tells us the user wants to cancel the operation. Important Note: you'll have to make sure this global property is available within every application you write that uses this dialog. More on this in a bit. Finally, we must add a method to stop the progress. This will be called either after the operation is finished, or when the user has cancelled it. Add a new method called stopProgress and give it this code:
This simply sets the two bars to maximum (so the user briefly sees the bars full) and closes the window. Surprisingly, we're almost done with our reusable progress bar dialog. There's only a couple more things to add. In the window's open event, put this:
This simply changes the text displayed by cancelText to be more appropriate for Windows users (who don't have a Command key). Finally, in the keyDown event, add this:
This just keeps watching for the user pressing the cancel keys (Command-period on the Mac, Escape under Windows). If the user does want to cancel, we call our cancel method. That's it! The reusable progress bar dialog is finished. You can drag a copy of the progressDialog window from your project window to your hard drive and later drag it into any projects you want. Ideally you'd link to it in those other programs (using the Command-Option drag thing) so that you only have one resuable progress bar dialog for use in all your programs. Next time I'll demonstrate how to actually use this dialog. If you would like the complete REALbasic project file for this week's tutorial (including resources), you may download it here.
Next WeekUsing our resuable progress bar dialog. NewsREALbasic Developer 2.1 August/September 2003 PublishedThe latest issue of REALbasic Developer magazine is now available! The August/September issue features at ton of great stuff. ![]() First, have you heard the exciting news that the next version of REALbasic will support compiling to Linux? RBD has an exclusive interview with the folks at REAL Software and we get the 411. Speaking of REAL Software, many of you have probably heard David Grogono's name or exchanged emails with him, but exactly who is he? Our interview with REALbasic Product Manager David Grogono reveals all. Find out how he left a life as a sailboat captain to captain REALbasic. 3D guru Joe Strout is back, this time with wild real-time mesh deformations. His example project shows how to simulate cloth flapping in the wind. It's impressive. Then we've got a double bill from Charles Yeomans. First he explains what you need to know about REALbasic 5's new Extends and Assigns keywords, and then he's got an excellent article on how to add a neat "recent items" menu to any program. And of course along with those articles we've got news, reviews, and all our regular columnists! Subscribers should be receiving their issues this week, and if you aren't a subscriber, become one! You can even order all the back issues if you don't want to miss anything.
LettersThis week we've got a question from a reader who prefers not to be named. His question is about resources (in the Mac resource fork of a file):
Look at this project file. It's untested, but should work. I created a method that returns the picture from the file. If the picture isn't found, it returns nil. Here's the method:
Currently this example puts the returned picture into the backdrop property of a canvas, but you could just as easily store the picture into a property or do something else with it. For example, if the window had a property named:
you could write:
to store the picture resource 129 into that variable. However, you would be required to initialize the variable with the newPicture command first. See RB's docs for that. Once you've got the picture in the variable, you can display it either inside a canvas object or inside a window like this:
or
where the last two numbers are the horizontal and vertical coordinates on the object where the upper left portion of the picture will be displayed. You could also modify this method to accept an integer as a parameter, then have it return the picture number you specify. So loadPicture(129) would return the picture with id 129. As it is now, the routine's specific to this picture only. About the Column REALbasic University is a weekly instructional column on programming with REALbasic and is brought to you by REALbasic Developer, the magazine for REALbasic programmers. Each week we answer select reader questions, and we're always open to ideas for future columns. Send your questions to . (Keep your questions simple and specific. General queries like "How do I write my own web browser?" will be neglected.) Your question won't be answered immediately, but will be answered in a future column. (If you don't want your correspondence published, just be sure to indicate that when you write. Otherwise it's fair game.) About the Author See the REALbasic University Archives
REALbasic University contents ©2001-2004 by Marc Zeedar and REALbasic Developer. All Rights Reserved.
| |||||||||||||||||||||||||||