UserPresetHandler
The UserPresetHandler
object can be used to customize the data handling of your project. You can attach callbacks to certain events (eg. loading user presets), define a custom data object that will replace the default XML structure of a user preset and add custom automation parameters. In order to use it, create it with Engine.createUserPresetHandler()
and then use one of its methods.
const var UserPresetHandler = Engine.createUserPresetHandler();
It's considered best practice to only have one of these objects around.
Class methods
attachAutomationCallback
Attaches a callback to automation changes. Pass a non-function as updateCallback to remove the callback for the given automation ID.
UserPresetHandler.attachAutomationCallback(String automationId, var updateCallback, var isSynchronous)
This attaches a script callback to an automation parameter that was previously registered using
Userpresethandler.setCustomAutomation()
.
The automationId
argument must match the ID
property of one of the existing automation parameters. The function you pass in as updateFunction
must have a single parameter that will contain the parameter value when the parameter is changed. You can decide whether the execution of the parameter should be done synchronously (in the audio thread) or deferred on the UI thread depenending on your use case.
Unlike the setControlCallback()
function, registering an additional callback will not
override the connections defined with the connections
property so it can be used to perform additional tasks.
Use clearAttachedCallbacks()
in order to remove previously registered functions.
clearAttachedCallbacks
Clears all attached callbacks. Edit on GitHub
UserPresetHandler.clearAttachedCallbacks()
createObjectForAutomationValues
Creates an object containing the values for every automation ID. Edit on GitHub
UserPresetHandler.createObjectForAutomationValues()
createObjectForSaveInPresetComponents
Creates an object containing all values of components with the saveInPreset
flag. Edit on GitHub
UserPresetHandler.createObjectForSaveInPresetComponents()
getAutomationIndex
Returns the automation index. Edit on GitHub
UserPresetHandler.getAutomationIndex(String automationID)
getSecondsSinceLastPresetLoad
Returns the amount of seconds since the last preset has been loaded. Edit on GitHub
UserPresetHandler.getSecondsSinceLastPresetLoad()
isCurrentlyLoadingPreset
Returns true if this is called somewhere inside a preset load. This takes the thread ID into account to avoid false positives when calling this on another thread. Edit on GitHub
UserPresetHandler.isCurrentlyLoadingPreset()
isInternalPresetLoad
Returns true if the user preset that is about to be loaded is a DAW state (or initial state). This function is only useful during the pre / post load callbacks. Edit on GitHub
UserPresetHandler.isInternalPresetLoad()
isOldVersion
Checks if the given version string is a older version than the current project version number. Edit on GitHub
UserPresetHandler.isOldVersion( String version)
resetToDefaultUserPreset
Loads the default user preset (if it's defined in the project). Edit on GitHub
UserPresetHandler.resetToDefaultUserPreset()
runTest
Runs a few tests that catches data persistency issues. Edit on GitHub
UserPresetHandler.runTest()
setAutomationValue
Sends an automation value change for the given index. Edit on GitHub
UserPresetHandler.setAutomationValue(int automationIndex, float newValue)
setCustomAutomation
Enables host / MIDI automation with the custom user preset model.
UserPresetHandler.setCustomAutomation(var automationData)
This method allows to define automation parameters that can be attached / detached to UI elements dynamically. If you use this mode, all MIDI CC automation and macro assignments will operate on the automation data model instead of the actual UI element (so assigning a MIDI CC to a UI element via drop down or learn mode will connect the automation data with the source).
This is useful when you're using an UI element that can be assigned to multiple targets dynamically. In order to use it, just call this method with a JSON object that describes all automatable parameters. Then use the automationID
property of a UI element to assign the control to one of the automation targets. This can be done dynamically.
Be aware that this function only works in combination with a custom user preset model, so you need to call UserPresetHandler.setUseCustomDataModel()
before using this method.
The JSON object you need to pass in here must be an array of objects where each array element describes one automation parameter. The automation object can / must have these properties:
Property | Type | Default | Description |
ID
|
String | - | a unique identifier for the automation parameter |
min
|
double | 0.0 | he minimum value |
max
|
double | 1.0 | the maximum value |
middlePosition
|
double | mid | the middle position |
stepSize
|
double | 0.0 | the step size |
allowMidiAutomation
|
bool | true
|
whether this parameter can be automated using MIDI CC messages |
allowHostAutomation
|
bool | true
|
whether this parameter can be automated using host automation (plugin parameters) |
connections
|
Array | []
|
A list of parameter targets that are changed when the parameter is changed. Each element of this array must be a object with a processorId
and parameterId
property (just like the default UI element connections). |
Example object:
const var automationObject =
[
{
"ID": "First Parameter",
"min": 0.5,
"max": 2.0,
"middlePosition": 1.0,
"stepSize": 0.0,
"allowMidiAutomation": true,
"allowHostAutomation": false,
"connections": [
{
"processorId": "SimpleGain1",
"parameterId": "Gain"
},
{
"processorId": "SimpleGain2",
"parameterId": "Gain"
},
]
}
]
The connections
property is not the only way to add logic to a automation parameter, you can alse use Userpresethandler.attachAutomationCallback()
in order to add a scripted callback (this is equivalent to ScriptComponent.setControlCallback()
vs. using the processorId
/ parameterId
connections).
setEnableUserPresetPreprocessing
Enables a preprocessing of every user preset that is being loaded. Edit on GitHub
UserPresetHandler.setEnableUserPresetPreprocessing(bool processBeforeLoading, bool shouldUnpackComplexData)
setPostCallback
Sets a callback that will be executed after the preset has been loaded. Edit on GitHub
UserPresetHandler.setPostCallback(var presetPostCallback)
setPostSaveCallback
Sets a callback that will be executed after a preset has been saved. Edit on GitHub
UserPresetHandler.setPostSaveCallback(var presetPostSaveCallback)
setPreCallback
Sets a callback that will be executed synchronously before the preset was loaded Edit on GitHub
UserPresetHandler.setPreCallback(var presetPreCallback)
setUseCustomUserPresetModel
Disables the default user preset data model and allows a manual data handling.
UserPresetHandler.setUseCustomUserPresetModel(var loadCallback, var saveCallback, bool usePersistentObject)
This function can be used to bypass the default HISE data model (one value per UI element) and roll your own data model with dedicated callbacks for loading and saving the state of your projects (eg. in user presets, DAW save files, init state, etc).
In order to use this function, you need to supply two methods for loading and saving with these signatures:
const var uph = Engine.createUserPresetHandler();
inline function onPresetLoad(var obj)
{
// do something with `obj`
}
inline function onPresetSave()
{
return { "MyObject": someContent };
}
uph.setUseCustomUserPresetModel(onPresetLoad, onPresetSave, false);
The load function contains a single parameter with a JSON object describing your plugin state. What the content of this object is is defined by your save function, which expects you to return a object that fully describes your plugin state.
Usually this means that you have one big JSON object that you return in your save function and restore in your load function.
During development, the usePersistentObject
flag might be helpful - if this is true, it will call the save function before recompiling and call the load function with the previous object after compiling, so that the values of your data object to not reset each time you compile. However this might overwrite the object you define, so at the beginning, you must use this function at least once without this flag. In the compiled project it won't make much of a difference as the recompilation does not happen after the plugin was instantiated.
Also be aware that if you want to use the custom automation model, you will need to enable this mode too.
setUseUndoForPresetLoading
Enables Engine.undo() to restore the previous user preset (default is disabled). Edit on GitHub
UserPresetHandler.setUseUndoForPresetLoading(bool shouldUseUndoManager)
updateAutomationValues
Updates the given automation values and optionally sends out a message. Edit on GitHub
UserPresetHandler.updateAutomationValues(var data, var sendMessage, bool useUndoManager)
updateConnectedComponentsFromModuleState
Restores the values for all UI elements that are connected to a processor with the processorID
/ parameterId
properties. Edit on GitHub
UserPresetHandler.updateConnectedComponentsFromModuleState()
updateSaveInPresetComponents
Restores all values of components with the saveInPreset
flag. Edit on GitHub
UserPresetHandler.updateSaveInPresetComponents(var obj)