Constructing a Video Effects User Interface

This chapter discusses how to construct a user interface that enables users to select an effect, change its parameters, and preview the results.

If your application creates QuickTime movies with video effects, you need to provide the user with a way to choose an effect, adjust its parameters, and preview the results. Although you are free to write your own code for these user interface tasks, you are encouraged to use the APIs that QuickTime provides.

QuickTime provides a standard dialog box (called the standard parameters dialog box) that allows the user to select an effect, choose values for its parameters, and preview the effect. Using this dialog box means that your users see an interface that is standard across applications. In addition, if effects parameters change in the future, your application will not need to be rebuilt to use them.

In most applications, it is appropriate to show the standard parameters dialog box to let users choose and customize effects. QuickTime provides a set of high-level API functions that you can call to do this. Displaying the Effects User Interface Using the High-Level API explains the use of these functions.

In some cases, you might need greater control over the effects user interface than these high-level functions provide. You might, for example, want to add the controls from the standard dialog box to one of your application’s own dialog boxes. QuickTime provides a set of low-level APIs that let you do this. They give you greater control and flexibility than the high-level functions, but they are more complex to use. These low-level functions are discussed in Adding Video Effects Controls to an Existing Dialog Box.

Displaying the Effects User Interface Using the High-Level API

This section describes the set of functions you call to invoke the standard parameters dialog box in your applications.

Getting a List of Effects

Before your application presents the standard parameters dialog box to users, you will probably want to build a list of the effects that are available. QuickTime provides the QTGetEffectsList function to do this for you. This returns a QTAtomContainer structure that contains a list of all the effects currently available.

You can remove effects from the returned list if you want to restrict the set of effects the user can choose from.

If you present the standard parameters dialog box without providing a list of effects, the dialog function gets the list of available effects automatically. This can save you a few lines of code, but your users must wait while QuickTime searches for available effects and generates the list every time you open the dialog box.

Displaying the Standard Parameters Dialog Box

Use the QTCreateStandardParameterDialog function to display the standard parameters dialog box. This allows the user to choose an effect, adjust the settings for that effect, and see a preview of the effect with the selected settings. The use of this function is described below.

When you call the QTCreateStandardParameterDialog function, QuickTime creates a standard parameters dialog box. The contents of the dialog box vary, depending on the list of effects you pass to the function and the set of parameters for the currently chosen effect.

Calling QTCreateStandardParameterDialog does not immediately display the dialog box; it only prepares it for display. The dialog box is shown the first time you call QTIsStandardParameterDialogEvent to process events for the dialog box. Event handling is described in Processing Standard Parameter Dialog Box Events.

The standard parameters dialog box for Apple’s film noise effect is shown in Figure 2-1.

The standard parameters dialog box for Apple's film noise effect

Notice that the dialog box has three main sections. In the upper-left corner is a scrolling list of all the effect components. To the right of this are the parameters of the chosen effect. As you select different items in the list of effects, the parameters change appropriately. There is also an effect preview area below the list of effects. This shows a preview of the chosen effect and parameter settings.

The user interface for setting the value of a parameter may be a slider, as shown in the example above, a set of radio buttons, an editable text field, or any of several other interfaces specified in the parameter description’s kParameterDataBehavior field.

For parameters that are always tweens, the user is presented with a starting and ending value. For parameters that can be tweened optionally, the dialog box presents the user with a single value by default. In order to set such a parameter to a tweened value, the user must hold down the Option key when selecting an effect.

Note that your application does not need to know what effects are available, what their parameters are, or what kind of control to use when setting a parameter. All these details are handled by the standard dialog box function.

The function call to create and display this dialog box is

QTCreateStandardParameterDialog(theEffectList,
                        theEffectParameters,
                        0,
                        &createdDialogID);

The variable theEffectList holds the list of effects returned by the QTGetEffectsList function. You can also pass nil for this value, in which case QTCreateStandardParameterDialog calls QTGetEffectsList to generate the list of all the currently installed effects, then shows these effects. On input, theEffectParameters contains a QTAtomContainer structure that holds the initial values of the effect’s parameters. In most cases, you should pass an empty QTAtomContainer structure as this argument, in which case the default values of each effect are shown.

The third argument specifies how to deal with parameters that can be tweened. Passing in 0 selects the default behavior, which allows the user to set a starting and ending value for parameters that must be tweens, but only allows the user to set a single value for parameters that are optionally tweens.

When the user selects the dialog box’s OK button, the chosen effect’s parameter values are returned in theEffectParameters. The parameter values are returned in a QTAtomContainer structure that you can use as an effect description. You will need to add kEffectSourceName atoms for effects that use one or more sources.

The createdDialog argument returns an ID number that is passed to the other functions that deal with the standard parameters dialog box. This is explained in detail in the next section.

Processing Standard Parameter Dialog Box Events

Once the dialog box has been created, you must process the events sent to it using an event loop. You repeatedly call WaitNextEvent and pass the events returned through the QTIsStandardParameterDialogEvent function.

The QTIsStandardParameterDialogEvent function checks each event to see if it relates to the standard parameters dialog box. You should continue to handle events that are not related to the standard parameters dialog box as usual.

You pass the event record returned from WaitNextEvent to the QTIsStandardParameterDialogEvent function, then check the return value to find out how the events was handled. Common return values are shown in the table below.

Term

Definition

noErr

The event was related to the standard parameters dialog box and was completely processed. Your application should not process this event, instead it should poll WaitNextEvent again.

featureUnsupported

The event was not related to the standard parameters dialog box. Your application should process the event in the normal way.

codecParameterDialogConfirm

The user clicked the OK button in the standard parameters dialog box. Your application should call QTDismissStandardParameterDialog to close the dialog box. The values chosen by the user are put into the atom container you passed in the parameters parameter when you called QTCreateStandardParameterDialog. This atom container now holds an effect description that is ready to insert into an effects track (it may require one or two kEffectSourceName atoms to be complete).

userCanceledErr

The user clicked the Cancel button in the standard parameters dialog box. Your application should call QTDismissStandardParameterDialog to close the dialog box.

The QTIsStandardParameterDialogEvent function may also return error codes, such as memory errors.

Your application should only process the event returned from WaitNextEvent if QTIsStandardParameterDialogEvent returns an error or a featureUnsupported code.

The code in Listing 2-1 is an example event loop showing how QTIsStandardParameterDialogEvent is used.

Listing 2-1  An example event loop showing use of QTIsStandardParameterDialogEvent

while (result == noErr)
{
    EventRecord     theEvent;
    WaitNextEvent(everyEvent, &theEvent, 0, nil);
    result = QTIsStandardParameterDialogEvent(&theEvent,
                                                createdDialogID);
    switch (result)
    {
        case featureUnsupported:
        {
            result = noErr;
            switch (theEvent.what)
            {
                case updateEvt:
                    BeginUpdate((WindowPtr) theEvent.message);
                    EndUpdate((WindowPtr) theEvent.message);
                    break;
            }
            break;
        }
 
        case codecParameterDialogConfirm:
        case userCanceledErr:
                QTDismissStandardParameterDialog(createdDialogID);
                createdDialogID = nil;
                break;
        }
    }
}

Adding Video Effects Controls to an Existing Dialog Box

In most circumstances, it is best to use high-level functions to create a user interface for video effects. However, if you need finer control over the way the interface is presented, QuickTime provides a set of low-level API functions to assist you.

For example, you may want to incorporate the controls from the standard parameters dialog box into an existing dialog box that your application displays, rather than using a completely independent dialog box. This would be necessary if you wanted a single dialog box that allowed users to customize an effect and also specify its duration. To do this, you would create a dialog box with a control for the duration of the effect and then, at runtime, you would add the customization controls from the standard parameters dialog box by calling the ImageCodecCreateStandardParameterDialog function.

Creating Your Application's Dialog Box

First create the dialog box that will incorporate the controls from the standard parameters dialog box. This dialog box must contain a user item that is large enough to hold the controls that will be added. For example, if you are using 12-point Chicago as your dialog box font, the user item should be 250 pixels wide and 300 pixels high. If you are using 9-point Geneva, the user item should be 150 pixels wide and 200 pixels high.

Figure 2-2 shows a dialog box in a running application after a custom effects control has been incorporated.

A dialog box after incorporation of a custom effect control.

Incorporating Controls From the Standard Parameters Dialog Box

Once you have defined the resource for your dialog box, you are ready to add code to your application to create the dialog box and add the effects controls to it. First, call GetNewDialog in the usual way to create an instance of the dialog box. Then call ImageCodecCreateStandardParameterDialog to incorporate the controls from the standard parameter dialog box into the dialog box. You then show the dialog box in the usual way.

The code in Listing 2-2 shows these steps.

Listing 2-2  Creating a dialog box and adding effect controls

movableModalDialog = GetNewDialog(kExtraDialogID, nil, (WindowPtr) -1);
if (movableModalDialog!=nil)
{
    // Add the user interface elements from the standard parameters
    // dialog box to the modal dialog box just created
    ImageCodecCreateStandardParameterDialog(gCompInstance,
                                                 parameterDescription,
                                                 gEffectSample,
                                                 pdOptionsModelDialogBox,
                                                 movableModalDialog,
                                                 kExtraUserItemID,
                                                 &createdDialogID);
    // Now show the dialog box and make it the default port
    ShowWindow(movableModalDialog);
    SelectWindow(movableModalDialog);
    SetPort(movableModalDialog);
}

The call to ImageCodecCreateStandardParameterDialog shows how to pass the existing dialog box (movableModalDialog ) and the item number of the user item (kExtraUserItemID ) that will be replaced with the controls from the standard parameter dialog box.

Once the effect controls have been added, the dialog box is shown, selected, and made the default port.

The rest of the code needed to handle the dialog box is largely the same as dealing with a stand-alone parameters dialog box. You pass every non-null event returned from WaitNextEvent through ImageCodecIsStandardParameterDialogEvent, and continue processing events yourself only if it returns featureUnsupported.

You track MouseDown events sent to the dialog box as usual. When the user clicks the OK button in the dialog box, you need to retrieve the values from the incorporated standard parameters dialog box. To do this, call the function ImageCodecStandardParameterDialogDoAction with the pdActionConfirmDialog action selector. This retrieves an effect description that describes the parameter values the user has chosen. You then call ImageCodecDismissStandardParameterDialog to dispose of the incorporated elements. After this is done, you call DisposeDialog to correctly dispose of the application’s dialog box.

Adding a Preview to Your Dialog Box

You may have noticed that the incorporated control shown in Figure 2-2 does not include a preview, as the standard parameters dialog box does (Figure 2-1).

In order for your dialog box to show a preview of the effect, include another user item in the application’s dialog box to contain the preview movie clip. Then call the ImageCodecStandardParameterDialogDoAction function with the pdActionSetPreviewUserItem action selector, as shown in the following code snippet:

myErr = ImageCodecStandardParameterDialogDoAction(gCompInstance,
                                    gEffectsDialog,
                                    pdActionSetPreviewUserItem,
                                    (void *) kPreviewUserItemID);

This makes the user item whose item number is kPreviewUserItemID (an application-defined constant in this example) the previewer for your dialog box.

You can use the ImageCodecStandardParameterDialogDoAction function to perform a number of similar customizations.