Parameters will be presented to the user in some form of interface. Typically on most host systems, this comes in three varieties...
Most systems have an animation sheet and present one of either the paged or the hierarchical layouts.
Because a hierarchy of controls is explicitly set during plugin definition, the case of the animation sheet and hierarchial GUIs are taken care of explicitly.
A paged layout of controls is difficult to standardise, as the size of the page and controls, how the controls are positioned on the page, how many controls appear on a page etc... depend very much upon the host implementation. A paged layout is ideally best described in the .XML resource supplied by the plugin, however a fallback page layout can be specified in OFX via the
kOfxParamTypePage
parameter type.
Several host properties are associated with paged layouts, these are...
kOfxParamHostPropMaxPages
- the maximum number of pages you may use, 0 implies an unpaged layout
kOfxParamHostPropPageRowColumnCount
- the number of rows and columns for parameters in the paged layout.
Each page parameter represents a page of controls. The controls in that page are set by the plugin using the
kOfxParamPropPageChild
multi-dimensional string. For example...
OfxParamHandle page; gHost->paramDefine(plugin, kOfxParamTypePage, "Main", &page); propHost->propSetString(page, kOfxParamPropPageChild, 0, "size"); // add the size parameter to the top left of the page propHost->propSetString(page, kOfxParamPropPageChild, 1, kOfxParamPageSkipRow); // skip a row propHost->propSetString(page, kOfxParamPropPageChild, 2, "centre"); // add the centre parameter propHost->propSetString(page, kOfxParamPropPageChild, 3, kOfxParamPageSkipColumn); // skip a column, we are now at the top of the next column propHost->propSetString(page, kOfxParamPropPageChild, 4, "colour"); // add the colour parameter
The host then places the parameters on that page in the order they were added, starting at the top left and going down columns, then across rows as they fill.
Note that there are two pseudo parameters names used to help control layout, the
kOfxParamPageSkipRow
and
kOfxParamPageSkipColumn
. These will help control how parameters are added to a page, allowing vertical or horizontal slots to be skipped.
A host sets the order of pages by using the instance's
kOfxPluginPropParamPageOrder
property. Note that this property can vary from context to context, so you can exclude pages in contexts they are not useful in. For example...
OfxStatus describeInContext(OfxImageEffectHandle plugin) { ... // order our pages of controls propHost->propSetString(paramSetProp, kOfxPluginPropParamPageOrder, 0, "Main"); propHost->propSetString(paramSetProp, kOfxPluginPropParamPageOrder, 1, "Sampling"); propHost->propSetString(paramSetProp, kOfxPluginPropParamPageOrder, 2, "Colour Correction"); if(isGeneralContext) propHost->propSetString(paramSetProp, kOfxPluginPropParamPageOrder, 3, "Dance! Dance! Dance!"); ... }
Hosts usually retain an undo/redo stack, so users can undo changes they make to a parameter. Often undos and redos are grouped together into an undo/redo block, where multiple parameters are dealt with as a single undo/redo event. Plugins need to be able to deal with this cleanly.
Parameters can be excluded from being undone/redone if they set the
kOfxParamPropCanUndo
property to 0.
If the plugin changes parameters' values by calling the get and set value functions, they will ordinarily be put on the undo stack, one event per parameter that is changed. If the plugin wants to group sets of parameter changes into a single undo block and label that block, it should use the
OfxParameterSuiteV1::paramEditBegin
and
OfxParameterSuiteV1::paramEditEnd
functions.
An example would be a 'preset' choice parameter in a sky simulation whose job is to set other parameters to values that achieve certain looks, eg "Dusk", "Midday", "Stormy", "Night" etc... This parameter has a value change callback which looks for
kOfxParamEventUserEdited
then sets other parameters, sky colour, cloud density, sun position etc.... It also resets itself to the first choice, which says "Example Skys...".
Rather than have many undo events appear on the undo stack for each individual parameter change, the effect groups them via the paramEditBegin/paramEditEnd and gets a single undo event. The 'preset' parameter would also not want to be undoable as it such an event is redunant. Note that as the 'preset' has been changed it will be sent another instance changed action, however it will have a reason of
kOfxChangePluginEdited
, which it ignores and so stops an infinite loop occuring.