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 046

RBU Pyramid XIX: Polishing Part III

Last week we added our safeShuffle routine, which hopefully ensures RBU Pyramid won't deal impossible shuffles. But we aren't quite finished polishing the program.

Adding Another Preference

The first thing we need to do is add a way to save the gSafeShuffle setting. That way the user only has to set it one time and the game will always use that setting. Fortunately, because of the preferences system we're using, this isn't difficult.

Open prefModule and go to the savePrefs routine. Within the main if-then statement, put in these lines:

  
// Save SafeShuffle setting
t.writeline "#safeshuffle " + bStr(gSafeShuffle)

This simple writes another line to the preference file. It uses the word "safeshuffle" as the directive name, and then adds either a "true" or "false" depending on whether gSafeShuffle is true or false. (Remember, the bStr function we wrote a while back accepts a boolean and returns true or false in text form.)

The modification to loadPrefs is just as easy: anywhere within the select statement just add this:

  
case "safeshuffle"
gSafeShuffle = gDirectives(i).text = "on" or left(gDirectives(i).text, 1) = "t"

This looks for a directive named "safeshuffle" and if it finds it, checks to see if the setting is "on" or true. The "on" part isn't necessary, but I like to support it for more flexibility in case the preference file is manually edited. This way the setting could be "on" / "off" or "true" / "false" -- and since we only check the leftmost character of the setting, just "t" also works!

Adding a Mac OS X Icon

Our program runs well under Mac OS, but it's got some problems under Mac OS X. We'll deal with some of those next week, in our "bug fix" round. But today, we want to polish the program by adding one of those big, really nice Mac OS X icons to RBU Pyramid. How do we do that?

Working with icons under regular Mac OS isn't too hard, since Apple's free ResEdit includes a basic icon editor. You can also copy icon resources or a picture from a painting program like Adobe Photoshop and paste them right on the application icon within the Build Settings dialog (or Build Application, in versions of REALbasic prior to 4.0). Under Mac OS, this generally works well enough.

You're technically missing a few icon resources (like the older black-and-white kind), and extremely picky people will tell you you ought to edit every single icon variation by hand, but since hardly anybody has a black-and-white Mac these days, it works fine in most cases.

To add an application icon for Mac OS programs, you can paste an icon over this default icon within the "Build Settings" dialog ("Build Application" in older versions of RB).

Mac OS X is a different animal, however. Mac OS X adds two new icon sizes, a "huge" size of 48 x 48, and a giant "thumbnail" size that's a whopping 128 x 128. That's how come Mac OS X programs are able to use those photorealistic icons of hard drives and stuff. Regular Mac OS icons max out at 32 x 32.

To support these new icon sizes, Mac OS X uses a completely new icon format that is incompatible with the old way. If you build a Mac OS X application using the paste method, your Mac OS X program will use REALbasic's default "cube" app icon (Classic apps will still use the old icon like before).

Even worse, because ResEdit hasn't been updated in years, it can't work with the new Mac OS X style icons. So what do you do?

The answer, unfortunately, is that you must spend some money. Fortunately, it's not much money. There are a number of excellent icon editing programs out there that will solve this dilemma, but the best value is undoubtedly Iconographer from Mscape Software. It sells for a mere $15, comes in both Classic and Mac OS X versions, and has all sorts of sweet features, such as the ability to understand Photoshop's transparencies when you copy and paste from Photoshop.


[Click for full view -- 315KB file]

You could create your entire icon within Iconographer, but I prefer to work in traditional graphics programs first and finish them off in Iconographer. That's just because I'm more comfortable in FreeHand and Photoshop.

Before we continue, let me say that I'm not an illustrator and I'll admit up front that I'm a terrible icon artist. My designs vary between "competent" and "hideous," depending on who's doing the judging. People who can create icons truly impress me: it's a talent to be able to draw something stylish and recognizable with just a handful of pixels.

Proper icons should always be created by hand, pixel-by-pixel, for each icon size. I, of course, being such a bad icon artist, ignore that rule. I figure I can create a giant icon and resize it downward, which does not work very well. So ignore my bad habits and do your icons the right way! (Or hire an icon artist.)

In the case of RBU Pyramid, I'd originally created a Mac OS-style icon that wasn't that bad. It's certainly not fancy, but it gets the idea of a pyramid solitaire game across:

Under Mac OS X, however, that 32 x 32 pixel icon looks rather pathetic, so in the spirit of polishing, I decided to create a 128 x 128 thumbnail version with a great deal more detail.

The creation of icons probably merits a few columns of its own, but it's really beyond the scope of today's tutorial for me to explain every detail of how I created this, so in short I drew the card shapes in FreeHand, took those as layers into Photoshop and added shadows, and assembled the final icon in Iconographer. The mask is "fuzzy" -- it has transparency -- and I created that in Photoshop. That's what allows the soft shadows of the cards to blend in with whatever background the icon is on.

Next, I used ResEdit to create a blank file which I named Resources and I put it in the "Linked Resources" folder of RBU Pyramid. This is very important, because we need a way to get the new icon into our project.

Then I used Iconographer's "Save Into File..." command and chose the file Resources. Iconographer automatically saved the icon as resource number 128, which is the proper number for an application icon. (If RBU Pyramid created documents that required a custom icon, its resource number would be 129.)

I made sure that I saved the icon as "Mac OS Universal (Resources)" format (that's vital).

Finally, I dragged the file named Resources into my project window. That's it! Now when I build the application, the new icons will automatically be included!

To test this, I went to REALbasic's "Build Settings" dialog via the command on the File menu. (With versions of REALbasic earlier than 4.0, this is called "Build Application" and it won't look the same as this screenshot.)

I set everything up like you see here and then built the applications (in RB 4, using the "Build Application" command on the File menu). The result is a Mac OS X application that uses the large 128 x 128 icon when appropriate, and the less detailed red-and-gray version when small. You can see both in this view in the Finder:

What's really sweet is the way the larger icon automagically resizes when it's in the Dock and you've got magnification turned on:

Doesn't that look better than the red-and-gray version? Granted, the card symbols are rather oddly shaped when you study them closely, but that's because I allowed Photoshop to generate them from the original vector artwork instead of hand-drawing perfect hearts and spades and stuff, pixel-by-pixel.

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

Next Week

We fix bugs!

Letters

Our letter this week is a nice tip from Richard Sinclair. He writes in response to JP Taylor's TabPanel problem (mentioned in an earlier column).

Although I'm a rank amateur at RB (working on my first app, actually); I may have a more elegant solution to JP's problem.

Rather than paste the controls, because the Paste remembers layers (as in many graphics apps) ... why not use the duplicate function, as I have with much success. Simply select the controls in their current tab, switch to the tab you would like them duplicated to, and hit command D. Immediately move them up five and left five to counteract the duplicate commands default move, and you're there. Obviously you can omit that last part if you don't need them in the exact same position. Bonus: Say you want to have the same control, in the same place, in all five tabs of a five tab panel. Create the first, and position and customize it. Switch to the next tab (with the control still selected) and duplicate. Move the control up and over five (as described above). Immediately, before you do anything else (including de-select), switch to the next tab and duplicate (command d) again ... without the move. Repeat for each tab. Not only will they duplicate, they will all be in the right place as the duplicate function will remember the move and duplicate it as well.

Just thought I'd pass that along. (Of course, since my version of RB is not quite as new as JP's, it may not work as I've described any more).

Thanks for the tip, Richard!

Next, we've got a note from Paul Thompson, who wonders:

Hello again Marc

Do you know of any plugs-ins which would add long-lamented BASIC commands to RealBasic? I'm talking about examples such as:

1) a simple if...then statement such as

  
if a then b else c

rather than

  
if a then
b
else
c
end if

2) the return of the Input and Data commands

3) a modified Select Case where you can use Booleans such as

  
select case x
case (x<5)
etc

I know you can get around these with other commands but they have a conciseness and simplicity that I miss.

Paul Thompson Reading, UK

I doubt the structural commands you talk about in 1 and 3 could be done via a plug-in. Plug-ins usually add new commands; they don't revise the way existing code works. I would suggest you tell REAL Software what you're wanting so they can expand REALbasic's syntax.

The "input" command is harder to simulate in a GUI environment, though you could write your own dialog box class that prompts the user for a line of text (similar to the msgBox command, except that it returns a value). There were actually suggestions that REAL Software include this at the REALbasic User's Group meeting at Macworld in San Francisco this past January: my suggestion was to make it work similar to the "display dialog" command in AppleScript. We'll see if they add that for REALbasic 4.5.

The "data" command, however, can easily be duplicated within REALbasic. I do this kind of thing all the time. For instance, let's say you wanted to assign each month name to a different array element. You could do something like this:

  
dim monthArray(12) as string

monthArray(1) = "Jan"
monthArray(1) = "Feb"
monthArray(1) = "March"
...

But that's a lot of ugly typing. It's not bad for something that only has twelve elements. But if you had lots of data to load, it would be exceedingly yucky.

BASIC's "data" command would be ideal here: include a list of items and load them one-by-one into the array. Hey, guess what? We can do that! Just use the nthField function like this:

  
dim months as string
dim monthArray(12) as string
dim i as integer

months ="Jan Feb March April May June July August "
months = months + "Sept Oct Nov Dec"

for i = 1 to 12
monthArray(i) = nthField(months, " ", i)
next

The months string can be as large as you like: as long as your data has a consistent delimiter, you can grab individual pieces of data from it.


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.

.

.