Moon Travel Planner: Modifying and Using Properties

There are a few properties that you should set for your application to configure it properly for the Finder and the operating system. These include the bundle identifier (CFBundleIdentifier) and the application’s creator code (CFBundleSignature). There are other properties you need to set so you can display version and copyright information to the user. You’ll set these properties, then create an About window that accesses the property list from within your application.

Besides modifying the property list, there are a number of steps you’ll need to follow to actually create the window and get it to function in the Moon Travel Planner we’ve worked on so far. In this section you’ll:

  1. Modify the property list.

  2. Create a new window.

  3. Write code that opens and displays the About window.

  4. Write an event handler for the About window.

Modify the Property List

You’ll set the bundle identifier first. The bundle identifier is used to locate the application bundle at runtime (see Section 10.1.1).” It must be unique, so define it as a Java-style package name; for example com.mycompany.myapp or edu.ABCSchool.myapp.

  1. Open the Moon Travel Planner project if it is not already open.

  2. Click the Targets tab, then click Moon Travel Planner in the Targets list.

  3. Click Application Settings, then click Expert.

  4. Click New Sibling, type CFBundleIdentifier as the property name, and press Return.

  5. Double-click the Value column, type com.apple.moontravelapp as the property value, and press Return.

Next you’ll modify the property list so the creator code (CFBundleSignature) is MTPP. As you saw in Table 10.1 the default value is ????. In Chapter 5 we mentioned MTPP has already been registered with Apple as the creator code for Moon Travel Planner. In fact, we used the creator code to set up control IDs in Chapter 5 and declared a constant (kMTPApplicationSignature) in Chapter 6 to represent the creator code. We need to add the creator code to the property list so the Finder is aware of Moon Travel Planner’s existence.

In the Expert mode property list, double-click ????, the value that’s listed for CFBundleSignature, then type MTPP.

The properties the application displays in the About window should be localized. So you’ll modify the default properties in the InfoPlist.strings file:

  1. Click the Files tab, then click InfoPlist.strings in the Resources group of the Groups & Files list. You should see three strings that Project Builder added for you automatically.

    /* Localized versions of Info.plist keys */
    CFBundleName = "Moon Travel Planner";
    CFBundleShortVersionString = "Moon Travel Planner version 0.1";
    CFBundleGetInfoString = "Moon Travel Planner version 0.1, Copyright 2000 
    MyGreatSoftware.";
  2. Modify the keys in the files so they have the following values:

    CFBundleShortVersionString = "Moon Travel Planner version 1.0.1";
    CFBundleGetInfoString = "version 1.0.1, copyright 2001, Lunar Software, Inc.";

Create a New Window

You’ll use Interface Builder to create a new window. As you recall from Section 10.1.4 the window needs to be movable, have a close control, and show a title in the title bar.

  1. Click main.nib in the Resources group of the Groups & Files list.

  2. Create a new window. Click the Windows button in the Carbon palette, then drag the icon of the window on the left to the desktop.

  3. Name the window object. In the Instances pane of the main.nib window, double-click the word “Window” that’s under the icon of the window you just created, type AboutWindow, and press Return.

  4. Assign a title to the window. With the window active, choose Show Info from the Tools menu, choose Attributes from the pop-up menu, type About Moon Travel in the Title text field, and press Return. We need to shorten the name to Moon Travel, because the window will be too small to fit About Moon Travel Planner.

  5. Set the window’s controls in the Control group. Make sure Close Box is the only option selected.

  6. Set the window’s attributes in the Attribute group. Make sure Standard Handler is the only option selected.

  7. Set the window class as Document.

  8. Set the Theme Brush setting as Dialog.

  9. Resize the window to 264 by 165 pixels. This allows for the application icon, application title, two lines of configuration information, and takes into account the spacing suggested in Inside Mac OS X: Aqua Human Interface Guidelines. Choose Size in the pop-up menu, choose Width/Height from the right Content Rect pop-up menu, and type 264 for width and 165 for height.

  10. Add the Moon Travel Planner application icon to the interface. You can use the same PICT you used for the main window. Follow the instructions in Chapter 5 for adding an image to the interface. Make sure you use the dimensions 64 by 64 when you size the PICT control.

  11. Choose Show Layout Rectangles from the Layout menu. You can align items more precisely using the edges of the layout rectangles.

  12. Adjust the spacing of the Moon Travel Planner application icon so it follows the recommendations in Inside Mac OS X: Aqua Human Interface Guidelines. The current guidelines call for a spacing of 8 pixels from the top icon to the bottom of the title bar. With the icon selected, choose Show Info from the Tools menu, then choose Size from the pop-up menu. Choose Top/Left from the Bounds pop-up menu and type 8 for the y-value.

  13. Center the Moon Travel Planner application icon. With the application icon selected, choose Alignment > Make Centered Column from the Layout menu.

  14. Add a static text field below the application icon. This is the application title. From the Controls palette, drag the object named Static Text to the area below the icon.

  15. Enter Moon Travel Planner as the static text field’s value. Double-click the field so a blinking insertion point appears. Type Moon Travel Planner and press Return.

  16. Adjust the spacing of the Moon Travel Planner text so it follows the recommendations in Inside Mac OS X: Aqua Human Interface Guidelines. The current guidelines call for the top of the Moon Travel Planner text’s layout rectangle to be 12 pixels from the bottom of the Moon Travel Planner application icon. You actually need to calculate the spacing from the top of the window to the top of the Moon Travel Planner text layout rectangle. That spacing is 8 + 64 + 12, or 84. Eight pixels for the space between the top of the window and the top of the application icon, 64 pixels for the height of the application icon, and 12 pixels for the space between the bottom of the application icon and the top of the Moon Travel Planner text layout rectangle. With the Moon Travel Planner static text field selected, choose Size from the Info window pop-up menu. Choose Top/Left from the Bounds pop-up menu and type 84 for the y-value.

  17. Center the Moon Travel Planner text and adjust the spacing. With the Moon Travel Planner static text field selected, choose Alignment > Make Centered Column from the Layout window.

  18. Add a static text field below the application name. You’ll display the version information in this field.

  19. Delete the title of the static text item. The static text field needs to be blank so you can write version information to it. In the Static Text Info window, choose Attributes from the pop-up menu, then delete “Static Text” from the Title text field.

  20. Enter MTTP as the static text field’s signature and 132 as its ID. Choose Control from the pop-up menu in the Static Text Info window. In the Control ID section, type MTTP in the Signature field and 132 in the ID field. You’ll use these values later to access the static text field when you display the version information.

  21. Turn off the Alignment rectangles. Choose Hide Alignment Rectangles from the Layout menu.

  22. Position the About window where you’d like it to appear when the user opens it. Where you position the window in Interface Builder determines its position when the user opens it.

  23. Choose Save from the File menu.

Create the About Window from the nib File

In Chapter 3 we saw that Project Builder automatically included code to create the main window from the main.nib file. Now that you’ve added a third window to the main.nib file—the About window-you need to add code to your main function to create the About window from the one you added to the main.nib file. You need to use the function CreateWindowFromNib. You must pass it three parameters, the nib reference from which to get the window description, the name of the window object, and a pointer to a window reference. You already have this code in your main function to create a nib reference from your main.nib file:

err = CreateNibReference (CFSTR ("main"), &nibRef);

You’ll pass nibRef as the first parameter to CreateWindowFromNib.

The second parameter must be a CFString object. For this you need to pass the name of the window object, which you named “AboutWindow” in Section 10.2.2. You must convert “AboutWindow” to a CFString object using the function CFSTR. So for the second parameter, you’ll pass CFSTR("AboutWindow").

The third parameter needs to be a pointer to a window reference. After you call the function, this will refer to the About window. First you must declare the window reference. You can modify the global declaration in the main.c file so it includes the About window. It should look like this once it has been modified:

// Global window references.
WindowRef       gMainWindow, 
                gMoonFactsWindow,
                gAboutWindow;

Now that you have all the parameters in place, you can add the code to create the About window. You should also check for an error, and if the window can’t be created, jump to a label that causes the application not to launch. Add this code to the main function, just after the code that creates the main window:

err = CreateWindowFromNib (nibRef, CFSTR ("AboutWindow"), &gAboutWindow);
require_no_err(err, CantCreateWindow);

Write a Function to Handle the About Command

You assigned a command to the About menu item in Chapter 7. Now it’s time to write a function that handles the command by showing the About window, getting version information from the property list, and writing the version information to the window.

The first thing we need to do is add constants used in the function. You need a constant to represent the command you assigned to the About menu item, and a constant to represent the control ID you assigned to the static text field.

Add the constants shown in Example 10.1 to the main.c file, at the top, just after the statement #include <Carbon/Carbon.h>:

Example 10-1. Constants Needed for the About Window

#define kMTPOpenAboutWindowCommand 'aBtb'
#define kMTPVersionInfoID 132

Before we write the function, you’ll declare its prototype. It takes a window reference to the About window as a parameter. You can put the following function prototype in the main.c file, along with the other function prototypes you’ve declared so far.

pascal void MTPAboutWindowCommandHandler (WindowRef window);

Now we can add the function. It shows the About window, gets the Get Info string from the InfoPlist.strings file, and displays the string in the About window. Copy the AboutWindowCommandHandler function in Example 10.2 to the main.c file.

Example 10-2. A Function That Shows the About Window

pascal void MTPAboutWindowCommandHandler (WindowRef window)
{  
    CFStringRef                 text;
    CFBundleRef                 appBundle;
    ControlID  versionInfoID = { kMTPApplicationSignature, 
                                kMTPVersionInfoID };
    ControlRef                  versionControl;
    ControlFontStyleRec         controlStyle;
 
    appBundle = CFBundleGetMainBundle ();                           // 1
    text = (CFStringRef) CFBundleGetValueForInfoDictionaryKey (appBundle, 
                                    CFSTR("CFBundleGetInfoString")); // 2
    if ((text == CFSTR(" ") ) || (text== NULL))
           text = CFSTR("Nameless Application.");                   // 3
    GetControlByID( window, &versionInfoID, &versionControl );      // 4
    SetControlData ( versionControl, kControlLabelPart, 
                                kControlStaticTextCFStringTag,
                                sizeof(CFStringRef), &text);        // 5
    controlStyle.flags = kControlUseJustMask;                       // 6
    controlStyle.just = teCenter;                                   // 7
    SetControlFontStyle( versionControl, &controlStyle );           // 8
    ShowWindow (window);                                            // 9
    SelectWindow (window);                              
}

Here’s what the function does:

  1. The Core Foundation Bundle Services function CFBundleGetMainBundle returns the bundle associated with the Moon Travel Planner application. You need to pass the bundle as a parameter to the function in the next statement.

  2. The Core Foundation Bundle Services function CFBundleGetValueForInfoDictionaryKey returns the string associated with the key CFBundleGetInfoString. This is the string you modified in Section 10.1. The function CFBundleGetValueForInfoDictionaryKey takes a CFString object as a parameter, so you must use the function CFSTR to convert the Get Info string to a CFString object.

  3. To catch possible errors, if the string CFBundleGetInfoString doesn’t exist, then set the value of text to “Nameless Application.”

  4. The Control Manager function GetControlByID gets the control handle associated with the text field in which you’ll display the version information.

  5. The Control Manager function SetControlData sets the text field to the value of the string returned by the function CFBundleGetValueForInfoDictionaryKey.

  6. The flag kControlUseJustMask specifies that the justification field of the controlStyle data structure should be applied to the control.

  7. The Text Edit constant teCenter specifies that text in the control should be centered.

  8. The Control Manager function SetControlFontStyle sets the font style for the static text field to the values passed in the controlStyle data structure.

  9. Now that the text you want to display is written to the control, you need to show the window using the Window Manager function ShowWindow. Then, make it active using the SelectWindow function.

So far, nothing in our Moon Travel Planner application calls the MTPAboutWindowCommandHandler function. When the user chooses About Moon Travel Planner from the application menu, the About command is issued, but nothing in our program captures that command. We need to add another case to the switch statement in the main window event handler you wrote in Chapter 6. Recall that handler takes care of the Compute Travel Time and Show Facts commands. We need to add a statement so it also handles the About command. Modify the switch statement in the function MTPMainWindowEventHandler so it now looks like the code shown in Example 10.3.

Example 10-3. The Modified Switch Statement in the Main Window Event Handler

switch (command.commandID)  
                                   
      {
        case kMTPComputeCommand:
              MTPComputeCommandHandler ((WindowRef) userData);     
              result = noErr;
              break;
        case kMTPShowMoonFactsCommand: 
              MTPShowMoonFactsWindow(gMoonFactsWindow);
              result = noErr;
              break;
        case kMTPOpenAboutWindowCommand: 
              MTPAboutWindowCommandHandler(gAboutWindow);
              result = noErr;
              break;
      }

Once the window is open, the Moon Travel Planner application needs to handle any events associated with it. We need to write an event handler for the window next.

Writing an Event Handler for the About Window

You’ve already written two event handlers—one for the main window and another to handle the Facts for the Traveler window—so writing a third should be fairly routine for you.

In this section, you’ll declare an event type specifier associated with the About window event handler, then install the event handler for the About window.

The handler only needs to take care of a window close event. Copy the following to the main function, after the declaration for the Facts for the Travelers window event specifier:

EventTypeSpec aboutSpec = { kEventClassWindow, kEventWindowClose };

Declare the event handler. Copy the following declaration to the main.c file, just after the constants and global variable declarations:

pascal OSStatus MTPAboutWindowEventHandler (
                            EventHandlerCallRef handlerRef,
                            EventRef event, void *userData);

Install the event handler. After the line DisposeNibReference(nibRef), add the following code:

InstallWindowEventHandler (gAboutWindow,
            NewEventHandlerUPP (MTPAboutWindowEventHandler),
            1, &aboutSpec, (void *) gAboutWindow, NULL);

Copy the function in Example 10.4 to the main program, after the function MTPMoonFactsWindowEventHandler.

Example 10-4. The About Window Event Handler

pascal OSStatus MTPAboutWindowEventHandler (EventHandlerCallRef handlerRef, 
                                            EventRef event, void *userData)
{
    OSStatus        result  = eventNotHandledErr; 
    UInt32          eventKind;
    
    eventKind = GetEventKind (event);                              // 1
    if ( eventKind == kEventWindowClose)                           // 2
    {
            HideWindow ( (WindowRef) userData);                    // 3
            result = noErr;
    }
    return result;
}

Here’s what the function does:

  1. The Carbon Event Manager function GetEventKind returns the kind of the event.

  2. If the event is a close window event, then it handles it; otherwise, it returns the result code eventNotHandledErr to indicate the Carbon Event Manger should handle the event.

  3. The Window Manager function HideWindow hides the About window.

Build, run, and test the application

Let’s build and run the application to make sure the About window opens and looks as it should:

  1. Click the Build button in the upper-left corner of the Moon Travel Planner project window.

  2. Click the Run button in the upper-left corner of the project window.

  3. Choose About Moon Travel Planner from the application menu. Does the window open? It should look like the one shown in Figure 10.6.

    The About window for the Moon Travel Planner application

    Figure 10-6. The About window for the Moon Travel Planner application

  4. Click the Close box. Does the About window close?

  5. Click the Quit button.

If everything worked, you’re ready to move on!

Recap

We took a look at the property list and the default properties that Project Builder provides when you create a new project. We also discussed the Standard and Finder keys available to your application and showed how you can add your own custom keys. Finally we created an About window for the Moon Travel Planner application and used the property list as the source of information to display in the About window. In the next chapter, you’ll see how to use Navigation and File services to open and save files.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.221.133