Menus and Menu Handlers


I have already touched briefly on menus in the previous chapter. All desktop applications have at least one MenuBar, and by default, MenuBar1 is available in any new project. It comes with some MenuItems already in placeExit (or Quit on Macintosh) in the File menu, and Undo, Cut, Copy, Paste, and Delete (or Clear on Macintosh). There is default behavior for Exit, Cut, Copy, and Paste, but you will often want to override it. Likewise, you will need to do your own coding for any additional MenuItems you establish.

There is a three-step process you should go through when creating a MenuBar. The first is to create constants that will be used for the menu text that's displayed to the user. Even though you technically do not have to use constants for menu text, there are plenty of reasons for doing so. The first is that there are some MenuItems that have a common function across the platforms, but that use different names. A MenuItem for preference is one of them, and that will be one of the examples. Beyond that, it also makes it easier in the future to localize your application and, for example, come out with a Spanish language version. Depending on your project, you might think that's a rather fanciful idea, and perhaps it is, but my attitude is that because you have to use constants for a few MenuItems if you want your application to behave properly on all three platforms, you should just go ahead and use them on all MenuItems. Who knows, maybe the app you are creating will be successful beyond your wildest expectations; a lot of people in the world do not speak English, and it really doesn't make sense to arbitrarily lock them out as potential customers.

Adding Menu Constants

I am going to add the following MenuItems: Preferences, Delete, and Subscribe. I will create constants for all of them, like this:

Constant Name: kPreferences as String Default Value: &Options... 


Windows uses the term Options to describe what Macintosh computers call Preferences. I establish the default value as &Options..., and this will be the text that is displayed by default. The & means that O (the letter directly following it) can be used as a shortcut.

To use different text for Macintosh computers, I have to click the + button in the ListBox area below the primary editing area for constants. In the platform column, I select MacOS. In the Language column, I select Default and in the Value column I enter Preferences....

I need to do something similar with Clear, which is called Delete on Windows and Linux computers. I will set this one up like this:

Constant Name: kClear Default Value: Clear 


Because "Clear" is the term that applies to Macintosh computers, I need to add two more items to let REALbasic know what to do on Windows and Linux computers. I follow the same steps that I did before, except that instead of MacOS, I select Windows, and set the value to &Delete, followed by adding another row and selecting Linux, with a value of &Delete as well.

Finally, I have a simple constant to create, which is the one I will use for the Subscribe... MenuItem. I create a constant called kSubscribe, with a default value of Subscribe..., and we are finished.

In case you are wondering, the ellipsis that follows a name on a MenuItem indicates that it will cause a Window to be created that requires some kind of user interaction. MenuItems without ellipses simply execute a command.

Adding the MenuItems

Now that the constants are in place, it is time to return to MenuBar1 and create the MenuItems. Double-click MenuBar1 to get the MenuBar editing tab. You will be able to get a preview of what the MenuBar will look like in all the platforms, and it doesn't matter at this point which "look" you are using. The first thing to do is go to the File menu and select it. Then, in the Editor Toolbar, click the Add Menu Item button. A new space called "untitled" will appear at the bottom of the File menu. While it is selected, go first to the Text area in the Property ListBox to the right and type in the name #App.kSubscribe. The # sign indicates that what follows is a constant rather than literal text. The App.kSubscribe refers to the constant we just created.

REALbasic will automatically create a name for the MenuItem for you, which is the concatenation of the Menu name and the MenuItem name. In this case, the MenuItem will be automatically named FilekSubscribe.

While still in the Properties pane, skip down to the Behaviors area. The first item listed is SubMenu. If checked, a PopupArrow will appear in the visual display of the menu, and you will be able to add submenus to it. Next inline is AutoEnable, which should be checked true for the Subscribe MenuItem. Much like controls, menuitems can be enabled or not enabled. When not enabled, their text is grayed out and they cannot be selected. Setting AutoEnable to true means that the MenuItem will be enabled automatically. In most cases, that means that the MenuItem will be enabled without you having to specify it in code. In the case of Copy and Paste, it means that REALbasic handles determining whether it is enabled, unless you override it.

Windows and Controls all have an EnableMenuItems event. This is triggered at certain times and it gives the developer the opportunity to decide which MenuItems are enabled. Because the Subscribe MenuItem should always be available, I have AutoEnable set to TRue and I will not disable the MenuItem in code.

The next two sections in the Properties pane refer to shortcut keys. The first group, called ShortCuts, uses the default shortcut keys for each platform, which means the Command key on Macintosh and the Control key on Windows and Linux. For Subscribe, I assign the character "S" to the Key value and have the Key Modifier CheckBox checked to TRue. This means that on Windows, the user can hold down the Control key and the "S" key simultaneously, and that will serve as the keyboard equivalent of selecting that MenuItem. Likewise, on a Macintosh, it means that Command+S is the keyboard equivalent. I use "S" in this example, even though "S" is normally used as the keyboard equivalent for saving a document. Because subscribe is similar to saving a document and because I do not specifically need a Save MenuItem for this application, the use of "S" seems appropriate.

Figure 5.27. Add a key modifier to a MenuItem.


If you have a lot of MenuItems, using the default shortcut keys may not give you enough options, especially considering that there are standard shortcuts on each platform that you should avoid duplicating. The Alternate Menu Modifier Check Box adds a Shift character to the shortcut. If I were to check it for Subscribe, that would then mean that the user would have to click the Control, Shift, and "S" keys simultaneously to activate the command represented by this MenuItem.

Beyond the Shift key, each platform offers additional keys that are sometimes used in this fashion, and the Platform Specific Shortcut is used to give you more control over which keys are used. You can choose to require the Macintosh Option key, or the Macintosh Control Key, as well as the Alt key on Windows and Linux. If, for example, you wanted Subscribe to require the Option key on Macintosh computers in addition to Command, you would click MacOptionKey and check the CheckBox to true. Then, if you select the Macintosh version of the MenuBar, you will see that the keyboard equivalent of Option+Command+S is listed next to the word Subscribe in the MenuItem.

The next item to add will be the Clear/Delete MenuItem. This will be added just like Subscribe, except that it will be added to the Edit Menu rather than the File Menu. In this instance, I do not set AutoEnable to true because the only time this option should be available to the user is when the user has something selected in the application that is deletable. Other parts of my application will have to update this value when an EnableMenuItems event is triggered.

Finally, I will add Preferences, and this will require some special treatment. As already mentioned, Preferences are called Options on Windows and Linux, but I have taken care of that issue by using constants. In addition to the different names, Preferences on a Macintosh also appear in a special location, whereas Options appear in different locations (often somewhat unpredictably so) on Windows. In this application, the Preferences MenuItem will be added to the Edit Menu, but before adding it, I will click the Add Separator button to have a thin line drawn between the Select All MenuItem and the Preferences item I will be adding. You can also add a Separator by typing a hyphen (-) into the Text property of any MenuItem. After the Separator is added, I add the Preferences MenuItem by selecting the Edit Menu and clicking the Add Menu Item button. After you have done this, make sure the Preferences MenuItem you created is selected, and then move your attention to the Properties pane. In the Super row, click the PopupArrow, and a menu will appear giving you alternatives for the Super class to use for this MenuItem. Select PrefsMenuItem as the Super and then check the OS X view of the MenuBar. You will see that instead of appearing in the Edit Menu, it appears as the first item in the Application Menu, right above the Quit MenuItem.

Adding Menu Handlers

You have now added three new MenuItems to your application, but they do not do anything yet. The next step will be to add menu handlers for them. Menu handlers can be added to the App object and to any Window or Control that can accept the focus. There can be many menu handlers for a single MenuItem, and the one selected is determined by the context of which Control or Window has focus. The Copy MenuItem is a good example of why you would want to do this. It works out of the box with EditFields, so you do not need to do any special handling, but what happens if you want to let your user copy items in a ListBox? This calls for special handling and for a Copy menu handler to be created for our application's ListBox.

Go to the mwNodeListBox and then go to the code editing tab. One of the options on the Editor Toolbar is Add Menu Handler. Click the Add Menu Handler button and you will enter the menu handler editing mode. There is a ComboBox labeled MenuItem name where you can select which MenuItem you want to write this menu handler for. Select EditCopy from the list and you will see that the signature for this menu handler is the following:

MenuHandler EditCopy() As Boolean 


The return value lets you tell REALbasic whether you are handling the MenuItem or whether it should allow the next item in line to handle it. For example, I may decide to also implement an EditCopy menu handler for the Window that contains this ListBox. If I return true from this menu handler, the Window version of the menu handler will not be called. If I return False (or not anything at all), the Window menu handler will be called after this menu handler is finished executing.

Add the following code to the EditCopy menu handler:

MenuHandler EditCopy() as Boolean Dim s as String Dim cb as Clipboard s = me.List(Me.ListIndex) cb = new Clipboard cb.SetText(s) cb.Close End MenuHandler 


The Clipboard class gives you access to the application's clipboard (called Scrap on a Macintosh). You can instantiate the Clipboard class and get any text that is already on the application's Clipboard, or you can add your own data to it. After you have set the data, the Clipboard should be Closed. In this example, I get the text from the selected row of the ListBox and add that to the Clipboard object. It can now be pasted into any application, not just the REALbasic application.

MenuHandler EditPaste() as Boolean   Dim cb as New Clipboard   If cb.TextAvailable Then     If Me.ListIndex > -1 Then       InsertRow(Me.ListIndex, cb.text)     End If   End If   cb.Close End MenuHandler 


In addition to text, pictures can be added to the Clipboard object, and raw data can be added as well. Raw data is used to copy and process application-specific information from within your application. When using raw data, you pass a string that represents the type of the application data. This is derived from the AddMacData method, which accepts a four-character creator code. Windows and Linux do not use creator codes, but you can create any string identified that your application will recognize so that you can copy and paste proprietary data formats within your application.

The mwNode method toString returns an XML representation (as a string) of the node object, and this will be used as the raw data for the revised EditCopy menu handler:

MenuHandler EditCopy() as Boolean   Dim node as String   Dim cb as Clipboard   node = getSelectedNode().toString()   cb = new Clipboard   cb.AddRawData(node, "RSSReader")   cb.Close   Return True End MenuHandler 


When the EditPaste menu handler is called, it tests to see if there is any "RSSReader" data available; if there is, it uses that data to instantiate a new object and insert that object into the ListBox:

MenuHandler EditPaste() as Boolean   Dim cb as New Clipboard   Dim s as String   Dim node as mwNode   If cb.RawDataAvailable("RSSReader") Then     s = cb.RawData("RSSReader")     node = new mwNode(s)     Me.InsertRow(me.ListIndex, node.getName)     Me.CellTag(me.LastIndex, 0) = node   End If   cb.Close End MenuHandler 


One additional kind of menu that helps to make an application more usable is a contextual menu. These are menus that appear in context when a user clicks the right mouse button (or holds down the Control key while clicking the mouse button on Macs). There are two ways of adding Contextual MenuItems to an application. The old way is to use the ContextualMenu Control, but REALbasic 2005 provides a new and much improved way of handling ContextualMenus by using the following two events in Windows and Controls:

Function ConstructContextualMenu(base as MenuItem, x as Integer, y as Integer) as Boolean Function ContextualMenuAction(HitItem as MenuItem)as Boolean 


The ConstructContextualMenu event fired every time the user requests a contextual menu and you, as the developer do not have to specifically test to see what keys are being pressed or anything like that. The base MenuItem is the root MenuItem to which you append MenuItems that will be displayed to the user.

Function ConstructContextualMenu(base as MenuItem, x as Integer, y as Integer) Dim mitem as menuitem   mitem = new MenuItem   mitem.Text = "Hi"   base.Append(mitem)   return true End Function 


When the user makes a selection, the ContextualMenuAction event is fired. The MenuItem that was selected is passed as the HitItem.

Function ContextualMenuAction(HitItem as MenuItem) as Boolean if hitItem.text = "Hi" then   beep end if End Function 


Windows and MenuBars

You can have more than one MenuBar object in your application, and you can associate them with individual Windows or change them as you see fit. Recall that the MenuBar stays in the same position on the Macintosh rather than being associated with the application Window itself, but you get the same effect. You can use the following Window properties to manage this process

Window.MenuBarVisible as Boolean Window.MenuBar as MenuBar 





REALbasic Cross-Platform Application Development
REALbasic Cross-Platform Application Development
ISBN: 0672328135
EAN: 2147483647
Year: 2004
Pages: 149

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net