| |||||||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||||||
Print This Article REALbasic University: Column 065
FontPrinter: Part FourLast time we got started handling the printing system for our program, and we're almost done. The first thing we want to finish is our print preview feature. This might seem a little tedious to create, but the cool thing is that once we've created this window, we can easily reuse it in other programs simply by dragging in a copy from our hard disk (to export the finished window, drag it from REALbasic to a Finder window).
Building the Print Preview WindowThe reason PrintPreview window is reusuable is because it's extremely self-contained. It only needs a couple global properties to function. It needs p, a picture, and gPrintOkay, a boolean, which it uses to tell us if the user clicked Cancel or Okay. By adding those global properties to other programs you create you can easily use this same PrintPreview window in other projects. Even if you just use it to debug and test a program's printing routines and don't use the feature in the final version of your program, it's a useful resource to keep handy. I use it all the time.
As usual, we begin by building the interface. The Print Preview window only has a few elements, so this isn't difficult. We'll start by adding a canvas with these properties: ![]() Since preview, where we draw the printing graphics, has its "lock" properties checked (lockLeft, lockTop, etc.), preview will grow or shrink with printWindow. Next, we'll add two scrollBars, one vertical, one horizontal. Here are their specs:
Finally, we'll need two pushButtons, called cancelButton and printButton respectively, with the latter set as the default button. The completed window should look something like this: ![]() Now we add some code!
Coding the Print Preview WindowWe'll begin coding the events that our window will encounter. There really are only two that concern us, the Open event, where we'll initialize things, and the Resize event, which is needed if the window size is adjusted. Here's the code for the Open event:
Basically all we're doing here is adjusting the size of the preview window to fit the current screen. We want it as large as possible, but not too big (we leave room for the menubar and the window's titlebar). The first two variables, xDif and yDif, are used to tell us the amount of space between the edge of the window and the start of the drawing area (preview, the canvas where we draw the printing graphics). Then we set w and h to the size of the picture plus the extra area we need for the window's interface elements. (The cool benefit of calculating this on the fly is if you moved the elements or added new ones, this would still work.) The variables w and h tell us the maximum size of window we need (bigger than that would be pointless since the preview area would be bigger than the picture we're drawing). So we next compare w and h with the size of the main screen, screen(0), minus a little for menubar and such. If the picture fits, we're all set: we just make the window the size of w and h. If the picture doesn't fit (the picture is bigger than the main screen), we set the window to as big as we can. Since most printed pages are vertical, we set the window to be as tall as possible (the screen height minus 50 pixels) and set the width to be proportional (the same percentage of the height smaller). Our final initalization is to make sure that gPrintOkay is set to false (our default response is that the user cancelled the printing). Next, we must add code for the Resize event:
All this does is adjust the scrollBars. Since the width and height of the window (i.e. the preview area) effects the amount (if any) we need to scroll, we must be sure we do this any time the window size changes. In point of fact, there's no way for the user to adjust the size of the window, so this only can happen when we adjust the size of the window during initialization (the Open event). Therefore we could have added this into the Open routine, but doing it this way is more logical and is the proper way to do it. In this routine we set the maximum properties of each of our scrollbars to the difference between the picture size and the preview area size. If there is a difference, therefore, that's the amount we need to scroll to see. The final two lines just sets the "thumb" of the scrollbars to a starting point. (You could set it to center, if you prefer, by calculating the center point: .maximum / 2.) Speaking of our scrollbars, let's add the code they need. It's very simple. In the ValueChanged event of each scrollBar put this:
That's it: all it does is tell preview to redraw whenever the scrollbars have been moved. And how does preview draw? Well, that's painfully easy. Go to preview's Paint event and put in this line of code:
All this does is draw the picture, p, at the location specified by the scrollbar values. Note that we make them negative, so if they are postive, the starting drawing point is off the canvas. In other words, if the horizontal scrollbar position is 100, it becomes -100, meaning that p will be drawn starting at -100 in the horizontal direction, meaning that we won't see the first 100 pixels of p. That, effectively, means that p has been scrolled to the left, revealing more of the right side of p. The bigger the value of the horizontal scrollbar, the more to the left the picture shifts. (The same principle works for the vertical scrollbar, except in the up/down direction.) Finally, we need to define what happens when the user clicks the buttons. Both have minimal code. CancelButton's Action event looks like this:
PrintButton's Action event is the opposite:
In both cases the result of the click is saved in the boolean gPrintOkay global property, and the window is closed. Our Print Preview window is finished now. If you want to use the Print Preview window in another program, just drag it out of the project window to a Finder window. That will create a window file on disk you can drag into other projects. You can try to run the program, and it should compile, but if you're wondering why the program isn't working -- nothing happens when you click the Print button -- there's a very simple explanation. While we have a printing method defined, we never call it! Go to both the filePrint menu handler and printButton's Action event and put in this: printIt That will call the printing routine and the program should work now. However, since drawIt is completely empty, nothing will be drawn in the preview window. Just for now, put in this in drawIt:
That should give you something to look at -- feel free to play around with this, adding other drawing commands to see what they do. Remember, printing is just like drawing to the screen. Try the drawline command, change the drawing color, draw boxes or circles. Anything you draw should also print, though while you're just experimenting you can just use the Print Preview to see it. If you would like the complete REALbasic project file for this week's tutorial (including resources), you may download it here. Next WeekWe'll finish FontPrinter by adding the routine to draw the fonts.
LettersToday we have a couple responses to a letter published a couple columns ago regarding the content of REALbasic University. First, from George Bate:
Interesting response, George. I'm not sure I agree that "you can't teach an old dog new tricks." Just because Mr. Gravely may be used to a certain method of programming doesn't mean that OOP can't be learned. The time involved may be more than he can afford, in which case, for practical purposes, he might be better off not bothering, but I believe anyone is capable of learning. I have decided that this is an important subject and I'm going to do a series of columns on it in the very near future: I hopefully will be able to explain OOP in such a way that people from a traditional programming viewpoint will be able to understand it. Next, we hear from Scott, who writes:
Thanks for your letter, Scott. I'm certainly always open to specific suggestions on what I should cover on RBU, and I'll keep your contest program in mind (I'd need more details to create it, of course). As to the code snippet library, it's interesting you mention that. That was discussed at the REALbasic Users meeting at Macworld in July, and I think it would be perfect for REALbasic Developer to do that. It's definitely something I'd like to see happen. Unfortunately, right now I'm a little busy getting the magazine off the ground, but at some point in the future it's something I'm going to do. Meanwhile, back to your comments on coding. There are two types of beginning programmers: the "recipe" programmer who can program if given specific instructions, and concept person who gets inspired by an idea and just needs help over a few humps. The first type does fine as long as there's a tutorial that does exactly what he or she wants to do. The second has the abilty to take concepts from one lesson and apply them to a completely different project. Let me give you an example of the latter in action. Last year we did a series creating a card game, RBU Pyramid. I received some flack (not much, but a little ;-), about covering a mere game. (I will admit I spent way too much time on it.) My thinking was that there were many parts of that game that could teach other concepts. For instance, in that game we created a deck of playing cards on the screen. Each card was a canvas object, created programmatically as a control array each time the program ran. Since all the cards were very similar to each other, this made a lot of sense and the program was easier to write and maintain. Now let's say you were going to do something completely different. Perhaps you're interested in music, and you want to write your own piano keyboard program. Well, you could do it the exact same way. Start with an initial canvas object, duplicate it programmatically (via code) as a control array, and you've got a music keyboard. All you have to do is program the initial object to play a note based on the number object it is so that each key would play a different note. Simple! But let's say you're not into music. However, you mentioned photography in your letter. Well, what if you wanted to write your own iPhoto-like program? You want the screen to display a series of thumbnail pictures, right? Well, do it the same way: duplicate a series of canvas objects, each containing a reference to a different imported picture. You see how this works? Many of the basic ideas you use in one program can be useful in another. In fact, much of the most sophisticated software in the world today was based on technology that originated in "mere" games. I'm just saying this to encourage you to try the tutorials even if you think they won't interest you simply because that's not the kind of thing you are creating. You will learn something, even if you don't realize how important that is at the time. I wish I had the resources to create a tutorial of every kind of program wanted, and eventually, maybe, there'll be a library of instructional material to cover just about everything, but for now, your best bet is to learn as much as you can from one tutorial and apply it to others.
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.
| |||||||||||||||||||||||||||||||