REALbasic University Resources:

RBU: Glossary Defines common REALbasic programming terms
  Archives Previously published columns
Translations: Dutch Courtesy of Floris van Sandwijk
  Japanese Courtesy of Kazuo Ishizuka
  Chinese Courtesy of Dong Li
  RBU Translation Guide Information on Translating RBU into other languages
Books: Matt's Book (2nd Edition!) Ideal for experienced programmers
  Erick's Book Best for beginning programmers
Websites: Mother Ship The publisher of REALbasic
  RB Webring Links to hundreds of REALbasic websites
  RESExcellence Another REALbasic programming column
  REALbasic Developer Magazine The premiere source for REALbasic instruction.

REALbasic University is Sponsored by

Make your Mac do what YOU want it to. Create games, utilities, cool Mac OS X tricks. Download REALbasic now and create your own software.


Print This Article

REALbasic University: Column 036

RBU Pyramid IX

A program isn't professional until it has a nice About Box -- a window that displays the program's version number and author's information. This week we'll add an About Box to RBU Pyramid.

Adding an About Box

There are as many kinds of About Boxes as there are programs. Some are extremely fancy, offering up animations or amusing tricks. I've seen some simple programs where I know the About Box had to take longer to create than the entire program!

How elaborate you want to make your About Box is up to you: for most programs, a professional looking image is all you need. If you're planning on distributing applications, you might want to consider standardizing on a common About Box design: it gives all your programs a similar look and builds consumer confidence that your programs are of professional quality.

For RBU Pyramid, we're going for a basic window with a pleasant graphic. We're also going to make double use of the About Box by using it as a Splash Screen: an opening graphic that's displayed briefly when the program is launched.

The first choice you must make in designing your About Box is deciding if you're better off creating the entire window in a graphics program or creating the individual elements within REALbasic. For example, you could simply display your program's name in a particular font at a large size using a Statictext control. The advantage of this approach is that it's easy to edit right within REALbasic. The disadvantages are that you can't get too fancy with the graphics, and you can't be sure the user will have the same font you do.

As a graphic designer, I'm more comfortable creating graphics in programs like Adobe Photoshop and Macromedia FreeHand, so I like to use the second approach. That means I create a large graphic that contains most of the content of my About Boxes. Things that might change, such as my mailing address or the program's version number, I add in REALbasic.

I also like my About Boxes to include hot-links to my website(s). In the case of RBU Pyramid, I want links to both the REALbasic University website as well as the REALbasic Developer magazine website. Doing this isn't particularly difficult, but it is a little tricky if you aren't familiar with how RB works. I'll explain more in a minute. For now, let's get started.

I've already done the graphic creation work for you. Save this graphic to your hard disk and put it in your project's Linked Resources folder (or whatever you call it). Then drag it into your project window.

Now for the obvious -- add a new window to your RBU Pyramid project file (File menu, "New Window"). Give it the following settings:

Notice how we set its backdrop property to the graphic we just imported? That means the background of our window will always display that picture. It's already starting to look like a real About Box!

Let's add a statictext item where we'll display the program's version number. Give it the following settings:

You may be wondering what the "#kVersion" stuff is all about. I'll explain. When you precede a property setting with a number sign (#), REALbasic assumes the text following is the name of a constant (the value of a constant never changes while a program is running). In this case, the constant is named kVersion. Using a constant for the program's version number is a great idea: you only have to change it in one place and anywhere your program needs to include the version number, you can just refer to the constant.

To add the constant (before we forget), open your globalsModule module and choose "New Constant..." from the Edit menu. Name it kVersion, leave its type string, and put in "0.5" for the value. (As we go along with RBU Pyramid, we'll increment the kVersion value appropriately.)

Good. Go ahead and close globalsModule now.

There are several more things we must add to aboutWindow. Drag on two canvas objects. Give them each the following settings (ignore the super setting for the moment):

 

Why are we putting canvases on the window? These are going be our hot-link buttons. They are special because they must take the user to the appropriate website when clicked, and they must display a pointed finger cursor when the user moves the mouse arrow over them.

Adding a Custom Hot-Link Class

In fact, these canvases are so special we're going to create a custom class for them! Why create a custom class? Well, since we have two of these in this program, it makes sense: we don't have to duplicate the code twice. Also, it will make it easy to reuse this stuff in another program later.

Go to the File menu and choose "New Class". Name it hotCanvasClass and set its super to canvas. Now open it up (double-click on it) and add a new property (Edit menu, "New Property"): url as string.

Within the Events area, go to the Paint event. Here's the code that goes there:

  
g.foreColor = rgb(0, 0, 200) // Blue
g.textSize = 10
g.drawString url, 0, g.height - 3

As you can probably deduce, this simply draws the url property in blue.

Now, in the mouseDown event, put showURL url. That simply tells the user's default web browser to display the URL.

In the mouseEnter event, put me.mouseCursor = fingerCursor, and in the mouseExit event, put me.mouseCursor = arrowCursor. That will cause the canvas to change the cursor when the user points inside the canvas' rectangular shape or moves it outside of it.

For that to work, of course, you'll need fingerCursor. Here's a link to it: download it and put in inside your project's Linked Resources folder and then drag it into your project's window. (If you don't include it in your project, REALbasic will complain that "fingerCursor" is an unknown object when you attempt to compile your program.)

Guess what? That's it for the custom class. Now there's just one more thing. Go back to the two canvases you added to aboutWindow and set their super properties to hotCanvasClass.

Adding a Splash Timer

A "splash screen" is only displayed for a few seconds when a program is launching. The idea is that it gives the user something to look at and pass the time while the program is starting up. It shows that something is happening.

Since we want our About Box to close after a few seconds, we'll use a Timer. Drag one onto aboutWindow. Since timers are invisible (they have no interface for the user), it doesn't matter where you put it.

Rename the timer splashTimer with these settings:

Now open it for editing (double-click) and type in the following code:

  
// Automatically close the splash screen
// when time's up.

self.close

Obviously that's going to close the window when the timer activates. But how do we control when it activates?

Well, since a timer's length of activation starts when its mode value is set to 1, we can set that when the program is launched. Go to your program's app class and in the Open event, insert this at the first beginning:

  
// Opens splash screen
aboutWindow.splashTimer.mode = 1
aboutWindow.showModal

This means when your program is first launched, it will activate the timer and display the window. Since we set splashTimer to a period of 1000 milliseconds, it will close itself after one second.

Activating a Menu Command

The About Box is usually displayed when a user chooses the "About" menu command, so let's add that. Within the REALbasic IDE, you can double-click on the menu object. Click on the Apple icon and then on the blank space that drops down beneath it. There you can type in "About RBU Pyramid..." and press Return. Your menu should look similar to this:

Before we continue, change the name of the menu item to "AppleAbout" like this:

Good. Now the interface has been added -- we just have to teach REALbasic what to do when that menu is chosen. That's a menu "handler" -- it handles the menu call.

Open your app class. From the Edit menu, choose "New Menu Handler..." and in the dialog that's displayed, choose "AppleAbout". When you click "okay" there'll be a new AppleAbout menu item in the Menu Handlers section.

Put in this code (which activates aboutWindow):

  
aboutWindow.showModal

In Detail

We can add menu "handlers" to the entire application via our app class. If we wanted the menu to only be available when a particular window was open, we could add a handler to it to just that window. In this case, the About command should be available at all times, so we add it to the app class.

There's still one more step that critical to getting our menu to work: we must tell REALbasic that the About menu isn't disabled. (By default, all menus except Quit are disabled. RB handles the cut/copy/paste menus automatically.) We enable the menu by going to the app class's EnableMenuItems event and putting in this line:

  
appleAbout.enabled = true

When we add more menus later, we'll have to enable those as well.

Finishing Up

We're not quite finished, however. Let's open up aboutWindow's code editor (select it and press option-tab). In the Open event, put this:

  
rbdCanvas.url = "http://www.rbdeveloper.com/"
rbuCanvas.url = "http://www.applelinks.com/rbu/"

Excellent! That will store the appropriate URL into the url property of each hotCanvas. That's all that we have to do to initialize those objects: they know how to do the rest already.

Now in the KeyDown event, type in self.close. That will make sure that if the user hits any key, it will close the About Box. Do the same for the window's mouseDown event: type in self.close there. That way if the user clicks the mouse it will also close the window.

Whew! I know what was a variety of steps, but hopefully you followed along safely. Your program should have a working About Box now. It should display briefly when you launch the program, and you should be able to activate it by choosing "About" from the Apple menu. You should be able to close it either by clicking the mouse or typing any key. The mouse arrow cursor should change to a finger cursor when you're within the url text on the window, and if you click, it should connect you to the Internet and take you to the appropriate website.

If you would like the complete REALbasic project file for this week's tutorial (including resources), you may download it here.

Next Week

We'll add the cool ability to select background textures to RBU Pyramid's window.

Letters

This week we hear from Jeff, who apparently doesn't like games:

Gentleperson,

I would like you to write about something else on your website. I am not really interested in creating game programs. Could you separate folders for games and non-game programs?

We, REALbasic users, need to learn how to make interesting programs such as input data, saving text information from a source file (list of names, addresses, numbers, etc). An application (homemade) reads the source file into separate boxes - similar to COBAL program. Or, you could show them how to calculate numbers from the list of box(es).

I hope that you would do that for us.

Thank you.

Jeff

Here is an example:

  
From (INPUT) Source File: 4930StreetRoadMA403205085482041
0449StreetRoadCT033058605284490
....

to (OUTPUT) REALbasic application:

Name Street: State: Zip Code: Telephone:

4930 Street Road MA 40320 508 5482041
449 Street Road CT 03305 860 5284490
....

Thanks for the note, Jeff. First, let me say that while I take your concern seriously, I obviously can't please everyone with one column. I'm hoping to launch REALbasic Developer magazine next summer, and in that format we'll have room for a variety of articles.

Second, the basic principles I'm teaching are valid regardless of the end application. For instance, last week's lesson covered creating a preference file system that could be used by any type of program. Just because I'm currently creating a game doesn't mean that you can't use the same techniques to create a different kind of program. Besides, games are often more complex from a programming perspective and that's why they're often used for teaching examples. (They're also less boring than "real" tasks.)

Finally, I see REALbasic University as a long-term project: this is the 36th column, and we've already covered several types of programs (utilities, graphics, animation, etc.). RBU Pyramid is our first game. I like to mix things up a bit, so you'll be seeing a variety of projects as we go along. Feel free to send me ideas for specific projects you'd like me to do. (Part of the reason we're doing RBU Pyramid is a number of people specifically requested I do a card game.)

As to your specific question, reading in data and outputting it in a different format is not too difficult, but the problem is that every person out there probably has a different input format and wants a different output result. It's difficult for me to create a single solution that works for everyone: all I can do is demonstrate some basic techniques that you should be able to adapt to your unique situation.

If we break your problem into several steps we get the following:

  1. Read in text file and save in string variable.
  2. Parse string variable (extract data).
  3. Arrange data in new format and save to new file.

The reading and writing of the text files is a bit beyond what I can do here, but you should be able to figure that out either from RBU examples or from the REALbasic online help.

Parsing the data depends greatly on the format of the data. For instance, in your above example, each piece of data (record) is stored on a separate line. Then each piece of information within that (each field) is a consistent length: i.e. the house number is always four characters, the street is ten, state is two, etc. If that's the case, reading in the data isn't hard:

  
// theLine is the current line of data
houseNum = mid(theLine, 1, 4)
theStreet = mid(theLine, 5, 10)
theState = mid(theLine, 15, 2)
...

In other cases, the data might be of flexible length but separated by a delimiter (such as a tab character). That's even easier:

  
// theLine is the current line of data
houseNum = nthField(theLine, chr(9), 1)
theStreet = nthField(theLine, chr(9), 2)
theState = nthField(theLine, chr(9), 3)
...

Generating the output data can be a little trickier. In the case of your example above, we'd need a routine that inserts x number of spaces (call it padSpaces). Assuming we have that (I'll let you write that simple method), we could do something along the lines of the following:

  
s = houseNum + " " + theStreet
x = 28 - len(s) // 28 is the rightmost position of the string
newLine = padSpaces(x) + s
x = 7 - len(theState) // 7 is the rightmost letter
newLine = newLine + padSpaces(x) + theState

x = 17 - len(theZip) // 17 is the rightmost letter
newLine = newLine + padSpaces(x) + theZip

x = 21 - len(thePhone) // 21 is the rightmost letter
newLine = newLine + padSpaces(x) + thePhone

What we are doing here is right justifying the text. Since we know the desired end character position, we subtract that length from the length of text we're inserting and that difference is the number of spaces we need to insert. We do this with all the data fields and end up with a long newLine variable that contains the entire line. Output that line to a disk file and you're all done!

Hopefully, Jeff, this will get you started in the right direction.


Keep those letters coming! I may not answer your question immediately, but I'll hopefully get around to it in a future column. (If you don't want your correspondence published, just be sure to indicate that when you write. Otherwise I'll assume it's fair game.)


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
is an author, philosopher, graphic designer, photographer, film director, soccer fanatic, and programmer (among other things). He writes for MacOpinion, runs his own software company, Stone Table Software, which sells the revolutionary Z-Write word processor, and is Publisher and Editor of REALbasic Developer. He lives in Northern California with his cats, Mischief and Mayhem, and is rapidly running out of free time.

See the REALbasic University Archives


REALbasic University contents ©2001-2004 by Marc Zeedar and REALbasic Developer. All Rights Reserved.

.

.