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 056

SimplePaint: Part III

At the end of last week's lesson, we had SimplePaint working with different colors, but I showed how we had created a problem, allowing the user to draw into the area of our color indicator:

Obviously, we need fix this.

Preventing Drawing

As they say, in the gruesome words of days past, there's more than one way to skin a cat. I'm sure there are dozens of ways to stop the user from drawing in a certain area, and no doubt creative readers came up with some interesting ideas, but I, of course, being infinitely lazy, prefer the simple approach.

Let's add a new canvas to paintWindow. Give it these settings.

Now your nodrawCanvas might be covering up your paletteCanvas -- if so, simply select nodrawCanvas and choose "Move to Back" from the Format menu.

To prevent drawing within nodrawCanvas, we must add some code to our mouseDrag event. Find that event (it's within paintWindow's Events list) and right after the initial dim x2, y2 as integer line insert this:

  
dim w, h as integer

w = nodrawCanvas.left + nodrawCanvas.width
h = nodrawCanvas.top + nodrawCanvas.height

if (x < w) and (y < h) then
return
end if

Guess what? We're done! This simply checks to see if the cursor is within nodrawCanvas's area, and if so, it returns without doing anything (no drawing). Simple!

If later we decide to add more "controls" to our program, we can just make nodrawCanvas bigger and our program will work without any changes.

Visualizing the Brush

One of the features we want to add to SimplePaint is a way to change the size/shape of the brush. Because of the way we set up the program, this is remarkably simple to do.

There are two things we must do to add this feature. One, we need a visual way to see the current shape of the brush. Second, we need a simple interface the user can use to change the shape/size of the brush.

Because it's more complicated, let's start with the visual display. This will be similar to the color indicator we added last lesson. First, add a staticText label with these settings:

Next, add a canvas with these properties:

Your paintWindow should look something like this:

Double-click on shapeCanvas to open its code editor. For the Paint event, put in this code:

  
dim x, y as integer

// Calc center coordinates
x = me.width \ 2
y = me.height \ 2

if c = rgb(255, 255, 255) then
g.foreColor = rgb(0, 0, 0) // black
g.fillRect(0, 0, g.width - 1, g.height - 1)
end if
drawPixel(g, x, y)

// Draw border
g.foreColor = rgb(0, 0, 0) // black
g.drawRect(0, 0, g.width - 1, g.height - 1)

As you can see, this first figures out the center of the square -- that's where we'll draw the brush shape.

Next, we check to see if the current color is white -- if it is, we fill the entire box with a black background (otherwise the white brush would be invisible).

Then we call our drawPixel routine, telling it draw a "pixel" at the center of shapeCanvas.

Finally, we draw a black border around shapeCanvas, representing the maximum size of a brush.

Quick Quiz: why do we draw the border last? (The answer is that if we did the fill last, it would cover up the border!)

There's one more step we have to do get this to work. Just like with colorCanvas, we must force shapeCanvas to redraw. So go to our changeColor routine and insert shapeCanvas.refresh after colorCanvas.refresh.

Now run the program -- you'll see that the sample brush shape changes color whenever you click on a different color.

Changing the Brush Size

We still need to create a way to change the brush size. The simplest way to do this is with keyboard commands. How about the plus and minus keys to enlarge and shrink the brush?

Kids probably won't mess with the shape of the brush much, but we'll make that a feature since it's easy to do. We'll use the numbers on the numeric keypad to adjust the shape. Numbers 4 and 6 will shorten and lengthen the horizontal dimensions (width) of the brush, and 8 and 2 with stretch or shrink the vertical dimension. The + and - keys will enlarge and shrink both dimensions.

Go to the KeyDown event and add this code to what's already there.

  
if key = "4" then
xWidth = xWidth - 3
if xWidth < 3 then
xWidth = 3
end if
shapeCanvas.refresh
end if

if key = "6" then
xWidth = xWidth + 3
if xWidth > 30 then
xWidth = 30
end if
shapeCanvas.refresh
end if

if key = "2" then
yWidth = yWidth - 3
if yWidth < 3 then
yWidth = 3
end if
shapeCanvas.refresh
end if

if key = "8" then
yWidth = yWidth + 3
if yWidth > 30 then
yWidth = 30
end if
shapeCanvas.refresh
end if

if key = "-" then
xWidth = xWidth - 3
yWidth = yWidth - 3
if xWidth < 3 then
xWidth = 3
end if
if yWidth < 3 then
yWidth = 3
end if
shapeCanvas.refresh
end if

if key = "+" then
xWidth = xWidth + 3
yWidth = yWidth + 3
if xWidth > 30 then
xWidth = 30
end if
if yWidth > 30 then
yWidth = 30
end if
shapeCanvas.refresh
end if

You'll notice that all we do here is modify the xWidth and yWidth values. Very simple, but effective. Most of the code is checks to ensure the values are within range (at least 3 pixels but not more than 30). We also refresh shapeCanvas so it will reflect the new shape.

Go ahead and run the program -- it should let you change the size of the brush by using the number and plus/minus keys.

That's it for now -- next week we'll add a way to save pictures.

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

Next Week

We continue with SimplePaint, adding the ability to save drawings.

Letters

Jacqueline has a suggestion for SimplePaint's "draw over the color palette" problem.

Hello Marc,

Thanks for the pretty app!

About the problem in last week column, I think that we can draw a line ( a red one, because kids are fond of red!) on the right of paletteCanvas. In the Paint event of paintWindow we put these lines of code:

  
g.foreColor = rgb(255,0,0)
g.penWidth = 7
g.drawLine 195, 0, 195, me.height

and in MouseDrag:

  
if x2 > 195 + xWidth then
drawPixel(p.graphics, x2, y2)
end

But the blank space on the left of the screen is not very nice -- I should like a better solution.

And now, a little question; in the Paint event of colorCanvas you write:

  
g.fillRect(0, 0, g.width, g.height)

Why do you say g.width and g.height instead of me.width and me.height?

Thank you very much for all!

In answer to your question, it doesn't matter if you use g.width or me.width: the result is the same (since g, in this case, is part of me, g.width will always equal me.width).

As to why I did it the way I did, I don't have a clear answer. I suppose I did it simply because I was focused on g, since we were concentrating on filling it, but I don't know. I also can't think of any negatives to either method, except that occasionally you might redefine g to be different then the graphics property of the current object (me) and in that case the two widths wouldn't necessarily be the same.

Next, we hear from Carol, who's a new reader:

Hi!

As a newcomer to REALBasic, I just discovered RBU. Perfect! Keep up the great work!

I've begun skimming over the RBU archives, and the "in-house programs" article caught my attention. I thought I'd add my "two cents" regarding what I'd like REALBasic to do.

As a collector (antique and contemporary items), I've been searching for a number of years for a program to keep track of my assorted collections. While there are numerous choices for PC users, I have yet to find any for us Mac fans, other than a dealer/inventory control app priced at $575 !?!

After much researching and comparing of the available options (Virtual PC, a PC card, or REALBasic), I've finally decided on REALBasic. After all, they say if you want something done right, do it yourself! Although I have absolutely no background in programming, and am only semi-computer-literate, my initial experimenting with RB's demo has encouraged me to attempt an actual application. THANK YOU for providing the much-needed lessons for beginners like me.

I had also considered purchasing at least one of the related books, so I was also happy to see your comparison between the Dummies book and the Definitive Guide. Apparently there is now a third book, hot off the press, entitled "REALBasic for Mac" (Michael Swaine, Peach Pit Press, January 2002). Have you had a chance to review this one? If so, it would be great to read your views in a future RBU.

One more idea: How about a lesson explaining how to add an import feature for graphics such as scanned photos (my collectibles), and possibly even text from another program such as Multi-Ad Creator or Quark Xpress? Is this possible with REALBasic? If you've already covered this, I apologize. I haven't yet gotten through all of the archived articles -- but I'm working on it!! : )

Thank you for your time.

Carol Mehler

Thanks, Carol!

Your project is an excellent one and I wish you luck. Let us know how it goes. At some point I plan to cover a database project in RBU -- but first I need to learn more about databases.

Michael Swaine's REALbasic book has been delayed, but will be coming out this summer and I do intend to review it.

Finally, your questions about importing text and graphics is an interesting one. Graphics aren't too difficult -- REALbasic can open any graphic format that QuickTime supports. To "import" a picture into your program, you just use the openAsPicture method of a folderItem. The result is a standard RB picture object -- you can then store that in a database or manipulate it or whatever you want.

Text is another matter, however. While plain text is easily worked with, text in proprietary formats such as Microsoft Word, Multi-Ad Creator, or Quark XPress is not. That's because those companies generally don't tell their competitors how their file format works. Some companies reverse engineer the format (figure it out via trial and error), but that's a huge effort. More common is to require the user to export the text from a proprietary program into a standard format, like plain text or RTF (Rich Text Format). Then your program could translate that into a format REALbasic understands. (Plain text is the easiest, of course, but you lose formatting such as coloring, fonts, type sizes, boldface, and italics.)

My own free RTF-to-Styled Text is an example of a REALbasic program working with RTF. It converts RTF to standard Mac styled text format (such as what SimpleText and REALbasic use). The program is open source -- you can download the REALbasic code here. It uses the open source RTFParser library from Belle Nuit Montage.

Finally, Harri has a suggestion for RBU:

Hi Marc!

I'd like to learn to do some 3D animation with REALbasic, so could you please sometime write a column of it.

Thanks for the suggestion, Harri!

Unfortunately, my knowledge of 3D is nil, so I doubt I'll be covering it any time soon (though I'm curious and if I find some time to investigate it, I might do a tutorial of my own).

Not to push my magazine, but you might want to look at a subscription to REALbasic Developer -- we've got a column on 3D in every issue, plus we'll be doing features on 3D as well (Joe Strout, who wrote REALbasic's 3D feature, is one of our authors). The magazine won't be all 3D, of course, but we'll definitely be covering the topic.


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