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 059

About the Delay

Let me apologize for the delay in publishing this column. I'd love to blame it exclusively on the astonishing, unprecedented success of the U.S. Men's Soccer team leading to late night viewing parties, but in truth several issues converged to make the delay unavoidable.

First, last week I was putting the first issue of REALbasic Developer magazine to bed. (In layman's terms, that means finalizing everything and sending it off to the printer.) The first release of anything is always nerve-wracking, but I'm happy to say that everything's going extremely well and the early reviews of the premiere issue are resoundingly positive. (See the News section at the end of this column for more details.)

Second, I'm in a transition phase at my day job, training my replacement and getting ready to be a full-time magazine publisher and software developer.

And finally, there were SimplePaint incompatibilities with Mac OS X I had to fix before I could release this column, and since I only discovered these last week, I decided to delay publishing.

But enough of that: on with REALbasic University!

SimplePaint: Part VI

In our previous lesson, we added a painting cursor to replace the standard Arrow cursor, and added lots of neat sound effects. Let's continue along that vein today.

Finding the Cursor

Young children often find using the mouse a little strange, especially if they're not familiar with computers. Our new paintCursor, while better than the Arrow cursor, is small, and sometimes can be difficult to find. So we're going to add a cool cursor locator feature!

This is a simple feature, but it requires a few steps. We'll need a simple method that will flash some colored circles at the cursor position. To do that, we'll want a slight delay between each circle drawing (otherwise the circles would draw so fast no one would see them). So let's add a delay method (Edit menu, "Add Method") to paintWindow:

  
dim t as integer

t = ticks
while ticks - t < 2
wend

That's pretty simple code, isn't it? It just waits at least two ticks (a tick is a 60th of a second) before finishing. The function ticks returns the number of ticks since your Mac was booted, so it's a number that's always growing. We save the original tick value, then subtract that from the current value, to see the difference. When that difference exceeds two ticks, the routine is over.

In Detail

A variation of this same code is useful for timing how long an operation takes. For instance, I once had a program where I was trying two different methods of doing something -- which was faster? Since we're only talking about fractions of a second in time it was impossible to tell visually, but by using the ticks function to record the starting time, and then recording the difference at the end of the call, I was able to see which method was superior. This is a common technique to use during debugging and optimizing (making a program more efficient).

Sometimes ticks aren't fast enough for your purpose. You can use the microseconds function instead: it returns time in one millionth of a second intervals!

With our delay method written, we can create a new method, flashCursor. That has this code:

  
dim i, x, y as integer
dim g as graphics

cursorflash.play

x = system.MouseX
y = system.MouseY

g = self.graphics

g.penWidth = 8
g.penHeight = 8
g.foreColor = rgb(255, 255 * .75, 0) // yellow-orange

for i = 1 to 5
g.drawOval(x - (i * 5), y - (i * 5), (i * 5) * 2, (i * 5) * 2)

#if TargetCarbon
Declare function GetWindowPort Lib "CarbonLib" (window as WindowPtr) as integer
Declare sub QDFlushPortBuffer Lib "CarbonLib" (port as Integer, region as Integer)
QDFlushPortBuffer GetWindowPort(self), 0
#endif

delay
next // i
delay
delay

self.refreshRect(x - 25, y - 25, 50, 50)

You notice that this routine plays a new sound called cursorflash. Drag it into your project window to install it.

The next part of this routine uses a REALbasic function called system and retrieves the current x/y coordinates of the mouse cursor in global coordinates. Why do it that way? Well, the only other way to get the cursor's location is via an event like mouseMove. We're not in that event -- we're in a custom method. We could add code to the mouseMove event to record the cursor's location every time the user moves it, but this way is more efficient since we only get the location when we need it.

Once we've got the mouse cursor's current location, we draw a series of ever-larger circles. You'll notice we have some weird code next: a #if followed by some declare stuff. What's all that?

Well, it turns out a cool feature of Mac OS X messes us up. Mac OS X features automatic double buffering -- that's where whatever you draw on the screen is saved as a picture ready to be popped on the screen instantly instead of drawing it bit by bit. The advantage is flicker-free animation. However, in the case of our flashCursor routine, it means that Mac OS X won't refresh the screen until after the final draw command: you won't see the cursor flash at all!

What to do about this? Well, REALbasic itself has no built-in solution, but we can easily make a couple system calls to tell the OS to immediately flush the buffer (draw whatever we've drawn so far). That's what those declare statements do. By protecting those commands with the #if targetCarbon - #endif lines, we ensure that only Carbon (Mac OS X) apps will try to use those commands. The regular refresh commands work for the Mac OS version of SimplePaint.

In Detail

This useful animation tip solved a problem for me, but I can't take credit for the solution. That came from Joe Strout, who works for REAL Software. In his terrific article, "Three Ways to Animate," which appears in the premiere issue of the new REALbasic Developer magazine (see page 18), he explains this problem and offers a solution.

Joe's article details three different animation techniques: using a canvas, a SpriteSurface, and an Rb3DSpace. Each have their own advantages and disadvantages, but rather than trying to figure all that out for yourself, Joe's done all the work. Well worth a read if you're interested in animation.

Note: the first issue of REALbasic Developer will be published in July 2002. Subscriptions are available now.

Once our cursorFlash routine is written, we need a way to activate it. I've chosen to do so via the Tab key. So within your keyDown event, add this bit of code:

  
if key = chr(9) then
flashCursor
end if

Now any time the user presses the Tab key the cursor will flash, showing them the location of the cursor. Cool, eh? Kids love the effect and the cool sound.

Fixing a Mac OS X Compatibility

This will teach me to have different versions of Mac OS X on different machines. For the last column, I tested the Speech routines on an older version of Mac OS X. Then I received reports from readers that it didn't work -- they received a "can't find speechLib" error message.

The solution turned out to be simple. I have no idea why the old code worked on the earlier Mac OS X, but this one works on Mac OS X 10.1.5:

  
dim i as integer

#if targetMacOS then
#if targetCarbon then
declare function SpeakString lib "CarbonLib" (SpeakString as pstring) as integer
#else
declare function SpeakString lib "SpeechLib" (SpeakString as pstring) as integer
#endif
#endif

#if targetMacOS then
i = SpeakString(theString)
return true
#endif

return false

As you can see, I first check to make sure we're running on Mac OS, then under Carbon. If we're not running under Carbon, we call "SpeechLib" instead of "CarbonLib." The rest of the code is the same as before.

Sorry about the problem, but we all learn!

That's it for this week. Last time I promised an "alternative" version of SimplePaint, but I'll release that next week.

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

Next Week

We explore a new project and Marc releases his "Etch-a-Sketch" version of SimplePaint.

News

There are only a few days left to get your REALbasic Developer subscription at the Early Bird discount price. Starting July 1, 2002, the regular price for a one-year (six-issue) subscription will be $32.

The first issue of REALbasic Developer is going to press now and will be delivered in July. To give you a hint at what you'll be missing if you don't subscribe, here's a look at the Table of Contents for the premiere issue:

We're talking over 50 pages of articles, tutorials, columns, reviews, news, and other goodies. Miles and miles of source code (subscribers will be able to download complete RB project files from the RBD website). Subscriptions are a must for all REALbasic fans!

Letters

Dear sir,

By far this is the best and most comprehensive guide to RB that I've found to date, granted I've only been playing with RB for a week now. Which will also tell you something about where I am in terms of understanding everything.

I have just completed most of GenderChanger Tutorial 11 and I have a vague understanding of what's going on. The explanations have been great and I too started out with BASIC years ago. Since then however I have had little if no experience with programming.

Anyhoo, I think the apporach you are taking is a good one and many things ARE going over my newbie head but an equal amount of things are sticking too. So overall it's great to start getting my mind wrapped around the way RB works and a hanful of the Properties/Commands etc. that you've dealt with in the GC tutorial. Not to mention that GC will be a great program for me to use once I am finished! =)

That being said, I am having issues with debugging (who isn't?) but RB gives me some clues as to what's wrong with my code and I've been able to rectify some of my isues with a bit of logic and pouring back over tthe previous tutorials. But I am getting a "Parameters Expected" error on a certain line of code, I have double checked this with your tutorial and it is exactly the same. Is there some other place where i might have to change something other than the idicated line that RB highlights for me? This aspect of debugging is especially frustrating and i fear I haven't the know-how to get through it on my own. Any suggestions?

Sincerely - Keith Bahrenburg

Thanks for the note, Keith!

Debugging is a hugely complex issue. It's something that's been in the back of my mind to cover, and your letter has reminded me of that. I plan to do a series of columns specifically about debugging and we'll cover your situation (and others). I'll discuss standard debugging techniques, reveal some debugging tips of my own, and offer tips from readers.

To get that process started, readers who have debugging tips should send them to me and I'll post them as part of that series.


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.

Email This Article - Comment On This Article

.

Reader Specials

Server Racks Online:
Apple Xserve CompatibleServer Racks and Universal Network Racks
42U KVM Switch Solutions:
High-End Mac and Multi-Platform KVM Matrix switching solutions!
Digital Camera Online:
Great prices on Digital Cameras and accessories!
KVM Switches Online:
Great prices on Mac KVM Switches from the leading manufacturers!
LCD Monitors Online:
Great prices on LCD Monitors from the leading manufacturers!
LCD Projectors Online:
Shop online for LCD Projectors from the leading manufacturers!
USB 2.0 Online:
Great prices on USB 2.0 products from the leading manufacturers

Serious Business Software:
Accounting, Sales, Inventory, CRM, Shipping, Payroll & more!

KVM Switch solutions for MACs:
DAXTEN is a KVM switch, KVM extender and monitor splitter specialist for PC, SUN and MAC applications from name brand manufacturers - offices worldwide.

The "Think Different Store: The iPod Accessories Store - iPod cases, iPod mini, iPod photo, speakers, itrip, inMotion, Soundstage and all other iPod accessories

Earn Cash with the ThinkDifferent Store Affiliates Program

Need A Web Site?
Applelinks Web Hosting Starting at 19.95 a Month

iTunes_RGB_9mm

.

iTunes_RGB_9mm

Cool Mac Gear


iPod 1G-2G
iPod 3G
iPod 4G
iPod Mini
PowerBook-iBook
Keyboard Skins
Garageband