Apple Developer Connection
Member Login Log In | Not a Member? Contact ADC

< Previous PageNext Page > Hide TOC

Providing a Fonts Panel in a Carbon Application

In Mac OS X the Fonts panel is the preferred user interface for users to specify font family, typeface, size, and color settings for text. See “Font User Interface” for a detailed description and screenshot of a Fonts panel. Cocoa applications already use the Fonts panel. With the introduction of the Fonts Panel programming interface, Carbon applications can provide the Fonts panel instead of the Font menu that was used in Mac OS 9. This section shows you how to set up and handle the Carbon events that associated with a Fonts panel.

To support a Fonts panel in a Carbon application, your application must perform the following tasks:

Each of these tasks is described in the sections that follow.

In this section:

Showing and Hiding the Fonts Panel
Handling a Selection Event in the Fonts Panel
Setting a Selection in the Fonts Panel
Handling Change of User Focus


Showing and Hiding the Fonts Panel

It is your application’s responsibility to provide an interface by which the user can activate and deactivate the Fonts panel. Typically users can open the Fonts panel by choosing a Show Fonts menu item from a Format menu. The keyboard equivalent for this item should be command-T. When the Fonts panel is open, your application should change the menu item to Hide Fonts. Your may choose instead to provide a button or other mechanism to activate and deactivate the Fonts panel. What you choose to do depends on the needs of your application.

You can use Interface Builder to provide a Format menu with a Show Fonts menu item. In Interface Builder, you must type the four-character code shfp in the Command text field, as shown in Figure 2-2. The constant kHICommandShowHideFontPanel is defined by the Carbon Event Manager to be the shfp HI command, which is why you must provide this four-character code as the command for the Show Fonts Panel menu item. You can use Project Builder to write code that handles the kHICommandShowHideFontPanel command issued by the Show Fonts Panel menu item.


Figure 2-2  Setting the command for the Show Fonts menu item

Setting the command for the Show Fonts menu item

When the user closes the Fonts panel, either by clicking on its close button or using an application-supplied human interface element (such as a Hide Fonts Panel menu item), the Fonts panel sends a Carbon event of class kEventClassFont and of type kEventFontPanelClosed to the event target your application specified in its most recent call to SetFontInfoForSelection. This allows your application to update any menu items or other controls whose state may need to change because the Fonts panel has closed. Your application must have a Carbon event handler installed to detect this event.

Listing 2-7 shows an application event handler that handles the Carbon events kHICommandShowHideFontPanel and kEventFontPanelClosed. A detailed explanation for each numbered line of code appears following the listing.

Listing 2-7  An function that handles events related to the Fonts panel

pascal OSStatus MyApplicationEventHandler (EventHandlerCallRef myHandler,
                                            EventRef event, void *userData)
{
    OSStatus    status = eventNotHandledErr;
    HICommand   command;
    UInt32  eventClass;
    UInt32  eventKind;
 
    eventClass = GetEventClass(event);// 1
 
    switch (eventClass)
    {
        case kEventClassCommand:// 2
        {
                    GetEventParameter (event, kEventParamDirectObject,
                                            typeHICommand, NULL,
                                            sizeof (HICommand),
                                            NULL, &command);// 3
                    switch (command.commandID)
                    {
                        case kHICommandShowHideFontPanel:// 4
                                status = FPShowHideFontPanel();
                                if (FPIsFontPanelVisible)// 5
                                {
                                    // Your code to set the menu item to Hide Fonts
 
                                }
                                else
                                {
                                    // Your code to set the menu item to Show Fonts
                                }
                        break;
                    }
            break;
            }
 
         case kEventClassFont:// 6
         {
             eventKind  = GetEventKind (event);
             switch (eventKind)
             {
                    case kEventFontPanelClosed:// 7
                        // Your code to set the menu item to Show Fonts
                    break;
                    case kEventFontSelection:// 8
                        status = MyGetFontSelection (event);
                    break;
             }
         }
         break;
    }
    return status;
}

Here’s what the code does:

  1. Calls the Carbon Event Manager function GetEventClass to obtain the event class.

  2. Checks to see if the event class is a command event.

  3. Calls the Carbon Event Manager function GetEventParameter to obtain the HI command from the event.

  4. If the HI command is kHICommandShowHideFontPanel, calls the Fonts Panel function FPShowHideFontPanel. Calling the function FPShowHideFontPanel displays the Fonts panel if it is not currently displayed, and hides it if it is currently displayed.

    The result code fontPanelShowErr is returned if, for unknown reasons, the Fonts panel cannot be made visible. Specific result codes, such as memFullErr can also be returned

    The Fonts panel opens with the system’s default settings unless you first set the selection information by calling the Fonts Panel function SetFontInfoForSelection. See “Setting a Selection in the Fonts Panel” for more information.

  5. Calls the Fonts Panel function FPIsFontPanelVisible to determine if the Fonts panel is now visible. Your application should provide code to the menu item (or other user interface element) appropriately.

  6. Checks to see if the event class is a font event.

  7. If the event kind is a close event, you must provide code to set the menu item (or other user interface element) appropriately.

  8. If the event kind is a font selection event, calls your function to handle font selection. Font selection events are discussed in “Handling a Selection Event in the Fonts Panel.”

Handling a Selection Event in the Fonts Panel

As the user selects font settings from the Fonts panel, your application receives a font-selection Carbon event (kEventFontSelection) from the Fonts panel. The settings selected by the user in the Fonts panel are passed as event parameters in the kEventFontSelection event. Your application simply extracts as many of the parameters as it can from the event and applies the font settings appropriately.

The event type kEventFontSelection contains parameters that reflect the current Fonts panel settings. Provided your application has a Carbon event handler installed to detect this event, it can obtain the parameters listed in Table 2-2. Listing 2-7 shows an application event handler that detects the event type kEventFontSelection and calls the function show in Listing 2-8.

Table 2-2  Parameters for the event the kEventFontSelection

Parameter

Type

Description

kEventParamATSUFontID

typeATSUFontID

Specifies the font ID of the selected font.

kEventParamATSUFontSize

typeATSUSize

Specifies the size of the font as a Fixed value.

kEventParamFMFontFamily

typeFMFontFamily

Specifies the font family reference of the font.

kEventParamFMFontStyle

typeFMFontStyle

Specifies the QuickDraw style of the font.

kEventParamFMFontSize

typeFMFontSize

Specifies the size of the font as an integer.

kEventParamFontColor

typeFontColor

Specifies the color of the text as RGBColor.

The function in Listing 2-8 (MyGetFontSelection) obtains the font family, font style, and font size from a selection made by the user in the Fonts panel. You can just as easily extract the ATSUI font and size parameters using the parameters and types shown in Table 2-2. A detailed explanation for each numbered line of code appears following the listing.

Listing 2-8  A function that obtains the current selection in the Fonts panel

OSStatus MyGetFontSelection (EventRef event)
 
{
    OSStatus status = noErr;
    FMFontFamilyInstance    instance;       // 1
    FMFontSize              fontSize;
 
    instance.fontFamily = kInvalidFontFamily;
    instance.fontStyle = normal;
    fontSize = 0;
 
    status = GetEventParameter (event, kEventParamFMFontFamily,
                                    typeFMFontFamily, NULL,
                                    sizeof (instance.fontFamily),
                                    NULL, &(instance.fontFamily));// 2
    check_noerr (status);// 3
 
    status = GetEventParameter (event, kEventParamFMFontStyle,
                                    typeFMFontStyle, NULL,
                                    sizeof (instance.fontStyle),
                                    NULL, &(instance.fontStyle));// 4
    check_noerr (status);
 
    status = GetEventParameter (event, kEventParamFMFontSize,
                                    typeFMFontSize, NULL,
                                    sizeof( fontSize), NULL, &fontSize);// 5
    check_noerr (status);
 
    return status;
}

Here’s what the code does:

  1. Declares and initializes variables used to get font information.

  2. Calls the Carbon Event Manager function GetEventParameter to extract the font family parameter, passing these parameters:

    • the event

    • the event parameter name kEventParamFMFontFamily

    • the event parameter type

    • NULL, to indicate not to return the actual type of the parameter, which is not needed in this case

    • the size of the event parameter value

    • NULL, to indicate not to return the actual size of the parameter, which is not needed in this case

    • on output, points to the font size of the selection

  3. Checks for errors before continuing. This is always something your application should do, even though, for clarity, error-checking code is sometimes omitted from the sample code in this book.

  4. Calls the Carbon Event Manager function GetEventParameter to extract the font style parameter. Similar to the previous call to this function, passes NULL to indicate the actual type and size of the parameter need not be returned.

  5. Calls the Carbon Event Manager function GetEventParameter to extract the font size parameter. Similar to the previous call to this function, passes NULL to indicate the actual type and size of the parameter need not be returned.

Setting a Selection in the Fonts Panel

You can programmatically set a selection in the Fonts panel by calling the function SetFontInfoForSelection. You can call this function even when the Fonts panel is not open or visible. When the Fonts panel becomes visible later, the style information specified in the most recent call to SetFontInfoForSelection is selected.

Listing 2-9 shows a function (MySetFontSelection) that passes an ATSUI style object (ATSUStyle) to the function SetFontInfoForSelection to set up a selection in the Fonts panel. A detailed explanation for each numbered line of code appears following the listing.

Listing 2-9  A function that programmatically sets a selection in the Fonts panel

OSStatus MySetFontSelection (WindowRef thisWindow)
{
    OSStatus            status = noErr;
    ATSUStyle           myStyle;// 1
    ATSUAttributeTag    myTags[2];
    ByteCount           mySizes[2];
    ATSUAttributeValuePtr   myValues[2];
    ATSUFontID          theFontID;
    Fixed               theFontSize;
    HIObjectRef     myHIObjectTarget;// 2
 
    status = ATSUCreateStyle (&myStyle);// 3
    verify_noerr (ATSUFindFontFromName ("Times Roman",
                            strlen ("Times Roman"),
                            kFontFullName, kFontNoPlatform,
                            kFontNoScript, kFontNoLanguage,
                            &theFontID) );// 4
 
    myTags[0] = kATSUFontTag;// 5
    mySizes[0] = sizeof (theFontID);
    myValues[0] = &theFontID;
 
    theFontSize = Long2Fix (36);    // 6
    myTags[1] = kATSUSizeTag;
    mySizes[1] = sizeof(theFontSize);
    myValues[1] = &theFontSize;
 
    verify_noerr (ATSUSetAttributes (myStyle, 2,
                            myTags, mySizes, myValues) );// 7
    myHIObjectTarget = (HIObjectRef) GetWindowEventTarget (thisWindow);  // 8
    SetFontInfoForSelection (kFontSelectionATSUIType,
                            1,
                            &myStyle,
                            myHIObjectTarget);// 9
    status = ATSUDisposeStyle (myStyle);// 10
    return status;
}

Here’s what the code does:

  1. Declares variables necessary to set up an ATSUI style for two style attributes. Each attribute in an ATSUI style consists of three values (a triple)—an attribute tag, the value associated with the tag, and the size of the value. See ATSUI Reference for a list of the style attribute tags you can supply.

  2. Declares an HIObjectRef variable. You need to pass a value of this type to the function SetFontInfoForSelection. An HI object (HIObject) is an HI Toolbox data type; it is the base class for a variety of objects that appear in the user interface. An HI object can receive events and can have event handlers installed on it. See the HIObject reference documentation for more information:

    http://developer.apple.com/documentation/Carbon/Reference/HIObjectReference/index.html

  3. Calls the ATSUI function ATSUCreateStyle to create and initialize an ATSUI style object. The newly-created style object contains default values for style attributes, font features, and font variations.

  4. Calls the ATSUI function ATSUFindFontFromName to obtain the font ID for the specified font.

  5. Declares a triple (tag, size, value) for the font ID attribute.

    Note: A triple is a set of three values that consist of an attribute tag, a value for that tag, and the size of the value. In ATSUI, triples are used to specify style, line, and layout attributes.

  6. Declares a triple for the font size attribute. Font size must be specified as a Fixed value, which is why the code calls the macro Long2Fix prior to assigning the font size to the myValues array.

  7. Calls the ATSUI function ATSUSetAttributes to associate the font ID and font size attributes with the ATSUI style object.

  8. Calls the Carbon Event Manager function GetWindowEventTarget to obtain the window that should be associated with the selection event. You’d typically set a selection in the Fonts panel to reflect the style selected in the active document window (or the default setting for a newly-opened document window). You need the resulting value (EventTargetRef), cast as an HIObjectRef, to pass to the function SetFontInfoForSelection in the next step.

  9. Calls the Fonts Panel function SetFontInfoForSelection to set the selection in the Fonts panel with these parameters:

    • kFontSelectionATSUIType specifies the style is an ATSUI style and not a QuickDraw style.

    • the size of the style array.

    • a pointer to the ATSUI style object that contains the attribute information you want to set in the Fonts panel.

    • a reference to the Carbon Event Manager HI object to which subsequent Fonts panel events should be sent. This should be the window or control holding the current user focus, or the application itself. The value can change from one call to another, as the user focus shifts. If this value is NULL, the Fonts panel sends events to the application target as returned by the function GetApplicationEventTarget.

  10. Calls the ATSUI function ATSUDisposeStyle to dispose of the ATSUStyle data structure. If you plan to use the same style again in your application, you don’t need to dispose of the style now. It is more efficient to reuse ATSUStyle data structure than to recreate them.

Handling Change of User Focus

The user focus is the part of your application's user interface toward which keyboard input is directed; it can be a window, a control, or any other user interface element. For the Fonts panel, your application needs to track user focus only for those user interface elements to which you want Fonts panel events sent.

In Figure 2-3 the user focus is in the top window while in Figure 2-4 the user focus is in the window on the right side. Compare the Fonts panel in one figure with the Fonts panel in the other figure. As the user focus changes, so do the selections in the Fonts panel. Your application should behave in a similar manner when the user focus changes.


Figure 2-3  User focus in the top window

User focus in the top window

To handle changes in the user focus, when a Carbon event target (typically a control or window) gains the focus, your application calls the Fonts Panel function SetFontInfoForSelection, providing the Fonts panel with style run information for the currently selected text. If the Fonts panel is visible when this function is called, its contents are updated to reflect the style run information passed to the Fonts panel.


Figure 2-4  User focus in the window on the right side

User focus in the window on the right side

If the Fonts panel is not visible, there is no user-visible effect. However, the information supplied by SetFontInfoForSelection is saved so that when the Fonts panel becomes visible again, the correct settings are displayed. The function SetFontInfoForSelection also lets your application specify the event target to which Fonts panel-related Carbon events should be sent.

When the user focus shifts, the component receiving the focus calls SetFontInfoForSelection to register itself as the new event target (even if iNumStyles is still 0). The component that relinquishes focus should call the function SetFontInfoForSelection, specifying 0 for iNumStyles parameter and NULL for iEventTarget parameter. This tells the Fonts panel that its settings are to be cleared. In the case that there is not another window open to receive focus, you need to set the Fonts panel to its default settings.

For example, if your application supports multiple windows, you can install a Carbon event handler to check for window class events (kEventClassWindow) that are event kinds kEventWindowFocusAcquired and kEventWindowFocusRelinquish. In response to these two event kinds, you call the function SetFontInfoForSelection.

Listing 2-10 shows a function (MyWindowEventHandler) that is installed on every document window to handle user-focus events in an application. A detailed explanation for each numbered line of code appears following the listing.

Listing 2-10  A function that handles user-focus events

pascal OSStatus MyWindowEventHandler (EventHandlerCallRef myHandler,
                                        EventRef event, void * userData)
{
    OSStatus    status = eventNotHandledErr;
    UInt32      eventClass = GetEventClass (event);
    WindowRef   thisWindow = NULL;
 
    switch (eventClass)
    {
        case kEventClassWindow:
        {
            switch (GetEventKind (event))
            {
                case kEventWindowFocusRelinquish:// 1
                {
                    SetFontInfoForSelection (kFontSelectionATSUIType,
                                    0, NULL, NULL);// 2
                }
                break;
                case kEventWindowFocusAcquired: // 3
                {
                    status = GetEventParameter (event,
                                    kEventParamDirectObject,
                                    typeWindowRef, NULL,
                                    sizeof (WindowRef), NULL,
                                    &thisWindow);// 4
                   status = MySetFontSelection (thisWindow);// 5
                }
                break;
            }
            break;
         }
    }
 
    return status;
}

Here’s what the code does:

  1. Checks for a focus-relinquish event. In this example, the settings are cleared. If there is not another window to receive focus, you should set the Fonts panel to its default settings.

  2. Clears the Fonts panel settings. The constant kFontSelectionATSUIType specifies to use an ATSUStyle collection instead of QuickDraw style. When you clear the Fonts panel settings, you need to set the window target (the last parameter to the function SetFontInfoForSelection) to NULL.

  3. Checks for a focus-acquired event.

  4. Calls the Carbon Event Manager function GetEventParameter to obtain a window reference to the window that acquired the focus.

  5. In the case of a focus-acquired event, the code calls a the function MySetFontSelection to set the font family, font style, and font size to values appropriate for the window. The MySetFontSelection function calls SetFontInfoForSelection to set the selection in the Fonts panel and set the window target to the window that acquired the focus.

    Your application would need to supply a function that sets fonts selections appropriately. For example, you may need to retrieve font settings from the document attached to the window that acquires user focus.



< Previous PageNext Page > Hide TOC


Last updated: 2007-12-11




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.
Get information on Apple products.
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Copyright © 2007 Apple Inc.
All rights reserved. | Terms of use | Privacy Notice