| |||||||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||||||
Print This Article REALbasic University: Column 023
REALbasic Basics IIILast week we worked with Sliders and BevelButtons. This week we explore TabPanels, GroupBoxes, Contextual Menus, and learn how to add a QuickTime movie to your REALbasic project.
The TabPanel ControlWhen you've got to present many options to a user -- for instance, a zillion preference settings for your program -- you could group releated items and create a separate dialog box for each type preference. But that's confusing for the user, since they must search through multiple dialog boxes to find the option they want to change. A better system is to use a TabPanel control: it allows the user to jump between multiple sets of interfaces all in the same dialog. A good example is Apple's Appearance control panel: ![]() By selecting the appropriate tab at the top, only interface items relating to that category are displayed. For our sample project, RBU Demo, we've got a TabPanel already created with three panels and various items on each panel. Working with TabPanels within the REALbasic IDE can be confusing. Generally they work just like they do when the program is running: clicking on a tab switches to that tab's contents. But if you have a control already selected on another tab, it "shows through" as an invisible selected item. ![]() In the above picture I've got the StaticText from the first tab selected. That's confusing, since it's not on this tab. My advice is to always deselect all objects before you switch tabs so you don't accidentally modify the wrong item. (If the StaticText in the above were a little lower, I might think I had the StaticText in this tab selected.) Another problem with TabPanels is that they aren't entirely reliable. Bugs mean that some controls can bleed through and affect others. For instance, our example has a QuickTime movie on the third tab, and if you play the movie and then switch to a different tab, the movie continues to play on top of the wrong tab: ![]() In general, use TabPanels for simple interfaces and don't try to get too complicated. In our example, we show how to programatically set the tab that's displayed. In TabPanel1's Open event is the following line: me.value = 2 That simply sets the TabPanel to the third panel (remember, panels are numbered starting at zero).
The LittleArrows ControlThe first tab of our example just has a simple StaticText and a CheckBox. But the second tab shows how to use a strange little control called LittleArrows. LittleArrows are used by the Mac OS in many places where it's easier to click to advance or reduce a number rather than type. For instance, in the Date & Time control panel: ![]() Our example's going to do something similar, except with a larger number and a StaticText. When the user clicks the down arrow, we'll reduce the number. When they click the up arrow, we'll increase the number. (To make it even more fun, we'll increase or decrease the number by 10 when the Option key is held down while clicking.) Here's the code for the Down event: dim n as integer First this converts the contents of staticText1 to a number. Then we check to see if the Option key is down. If it is, we subtract 10 from the number. Otherwise we subtract 1. Our final step is to put the new number back into staticText1. We use the format function instead of str because we want the number to have leading zeroes (that way the number is always the same number of characters). We also refresh staticText1 to force it to draw the update. Why do that? Well, if you don't force it to update, the new number won't be drawn until the user lets go of the mouse button. When I tried that, the number incremented to several thousand in the fraction of a second while I clicked down the button! This way after each increase or decrease, the staticText is redrawn, showing the user the current value. The Up event code is identical except it adds instead of subtracts.
Adding a QuickTime MovieThe third tab of our TabPanel is where we'll place a tiny QuickTime movie. I've created a small movie and included it with RBU Demo. Just drag it into your RB project to add it. Using the Properties Palette, I've preset the movie controller to automatically be ready to play my movie, "simple.mov". But having a built-in movie isn't always enough. Wouldn't it be nice if the user could drag in their own movie to play it? How about an MP3 music file? Sure, why not! First, let's define two types of files so our program knows how to work with them. Go to the Edit menu and select "File Types...". In the dialog that comes up, click the "Add..." button. On the right of the first field is a popup menu. You should be able to select the predefined QuickTime movie file type like this: ![]() Selecting it fills in the fields for you automatically. Click okay and do another one, the MP3 file type. ![]() If you don't remember doing this in our previous lessons, all we are doing is naming some Mac file types. That way REALbasic knows what kinds of files our program will work with. Our next step is to tell our movie controller that it should accept file drops of this type. Go to the Open event of moviePlayer1 and put in: me.acceptFileDrop("audio/mp3")
Next, go its DropObject event and put in the following: if obj.folderItemAvailable then All this does is see if a file has been dropped on the control. If so, it tries to open it as a movie and then play it. The refresh command is important because it makes sure the controller is resized if needed. This allows the user to drop QuickTime movies or MP3 files onto the control to play them. It's not super sophisticated, but it works just fine. Going from this to writing your own MP3 player is not a huge leap!
Adding a Contextual MenuAnother great interface tool of modern computing is the ContextualMenu. These are hidden menus that popup when a user clicks the mouse while holding down the Control key. Ideally they live up to their name and are actually contextual: that is, they change depending on the user's current situation. REALbasic has a pretty good implementation of contextual menus, and they're easy to use. The basic process is to drag a ContextualMenu icon onto your window, create some code in a mouseDown event that dynamically creates the menu, and add code to the menu's Action event for whatever the menu's supposed to do. For our example, since we don't actually have anything particularly significant for the menu to do, we simply want something that demonstrates the dynamic nature of the control. So what I decided to do is change the menu text according to what area of the window the user clicks upon. For instance, if the user Control-clicks within the "Scroll Test" area, the contextualMenu will be "Scroll Test item". To do this, we need some way of tracking where the user currently is. This isn't difficult, but it does require a few steps. First, we must create a new Window1 property, cmenu. This is a string variable which will contain the text that will become the contextual menu. So with Window1 open, go to the Edit menu and choose "New Property." Type in "cmenu as string" in the dialog that pops up and click "OK". Now we need to establish a default value for cmenu, so let's add this to whatever code's already in Window1's Open event: // Default contextualMenu1 menu item Next, we must change cmenu as the user moves the mouse around. This is easily done since the only controls we're concerned about are the GroupBox controls. There are four of them, and I built them as a control array (meaning that they all share the same code). Go to GroupBox1's MouseEnter event and put in the following: cmenu = me.caption + " item" Since the me function is always the current control, it will be whichever GroupBox1 the user is entering. So cmenu will be set to that GroupBox's caption, plus the string " item". Next, put this in GroupBox1's MouseExit routine: cmenu = "Window item" This is basically just a default value: if the user clicks outside any GroupBox, the contextual menu will just say "Window item". Since we want our menu to work anywhere inside Window1, we'll put our contextual menu code inside Window1's MouseDown event: if isCMMClick then This first checks to see if the user Control-Clicked: if they did, then we build contextualMenu using the contents of cmenu as the text for the menu, and open it (which displays it). That's it! If you run RBU Demo now, you should be able to Control-Click to bring up a contextual menu where the contents of that menu will change depending on where you click.
That's enough for now. Next we'll finish up with RBU Demo and move on to some other RBU Basics, like how to incorporate classes others have written into your own projects. Next Week: More Basics, including instructions on using pre-built classes.
LettersThis week we hear from Jimmy Isaacson:
I think the scrolling flash you are noticing is just a limitation of REALbasic. I played around with things a bit to see if I could minimize it, and I saw no improvement when I had RB just redraw the changed area. What I did notice is that the flashing only happens when you're using the arrow buttons of the scroll bars. When you drag the "thumb" of the scroll bar, the picture scrolls perfectly smoothly, with no flashing. That makes me think that the problem is not with the scrolling code or RB's ability to redraw quickly, but with how frequently RB updates the picture when you're holding down the mouse button to press an arrow button. (If anyone else has a solution, let me know!) Thanks for the suggestion about the colored boxes, Jimmy. I'll see what I can do. (I'm experimenting with the idea of creating my HTML formatting with Cascading Style Sheets, so I'll implement your idea when I do that.) Keep those letters coming! I may not answer your question immediately, but I'll hopefully get around to in a future column. (If you don't want your correspondence published, just be sure to indicate that when you write. Otherwise I'll assume it's fair game.)
Another REALbasic ColumnFor those of you who can't get enough of REALbasic, there is another REALbasic column on the web. It's written by Erick Tejkowski (author of REALbasic for Dummies) and published on the Resexcellence website. 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.
|
. |
| |||||||||||||||||||||||||||||