| |||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||
Print This Article REALbasic University: Column 056
SimplePaint: Part IIIAt 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 DrawingAs 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:
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 BrushOne 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:
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.
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 SizeWe 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.
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 WeekWe continue with SimplePaint, adding the ability to save drawings.
LettersJacqueline has a suggestion for SimplePaint's "draw over the color palette" problem.
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! 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:
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 See the REALbasic University Archives
REALbasic University contents ©2001-2004 by Marc Zeedar and REALbasic Developer. All Rights Reserved.
| |||||||||||||||||||||||||||