Hi Sean, I’ve only just started with Juce but maybe can offer a little bit here.
As per the plugin demo, I was using an XML structure in getStateInformation() and setStateInformation(). Having set this up I wanted to add functionality to store and load presets from my plugin GUI and realised that I could do so using the same technique, simply storing the XML as a file. So I defined serialiseStateInformation() which returns an XmlElement and is called by both getStateInformation() and my save presets button. I also defined deSerialiseStateInformation(ScopedPointer xmlState) which reads the state and updates all internal variables. This gets called by both setStateInformation() and my load presets button.
The presets xml file is stored in the userApplicationDataDirectory, using File::getSpecialLocation(). Have only verified this on Win 7 so far.
[code]//-------------------------------------------
// PluginProcessor.cpp
//-------------------------------------------
void HyperdriveAudioProcessor::getStateInformation (MemoryBlock& destData)
{
copyXmlToBinary (serialiseStateInformation(), destData);
}
void HyperdriveAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
// Fix problem with Live storing last preset chosen rather than current state
// see http://www.rawmaterialsoftware.com/viewtopic.php?f=8&t=6138
// or http://www.kvraudio.com/forum/viewtopic.php?p=1096418
setChunkCalled = Time::getMillisecondCounter();
// This getXmlFromBinary() helper function retrieves our XML from the binary blob..
ScopedPointer<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
if (xmlState != 0)
{
deSerialiseStateInformation(xmlState);
}
}
XmlElement HyperdriveAudioProcessor::serialiseStateInformation()
{
// Create an outer XML element…
XmlElement xmlState (“MYPLUGINSETTINGS”);
// add some attributes to it..
xmlState.setAttribute ("uiWidth", lastUIWidth);
xmlState.setAttribute ("uiHeight", lastUIHeight);
XmlElement* xmlChild[numPrograms];
for (int i = 0; i<numPrograms-1; ++i) {
xmlChild[i] = xmlState.createNewChildElement ("ProgramState_" + String(i));
xmlChild[i]->setAttribute ("ProgramName", programName[i]);
xmlChild[i]->setAttribute ("Drive", drive[i]);
xmlChild[i]->setAttribute ("Attack", attack[i]);
xmlChild[i]->setAttribute ("Release", release[i]);
}
return xmlState;
}
//-------------------------------------------
// PluginEditor.cpp
//-------------------------------------------
1 if (buttonThatWasClicked == m_btnSavePresets)
{
//[UserButtonCode_m_btnSavePresets] – add your button handler code here…
String fyleSpec = File::getSpecialLocation(File::userApplicationDataDirectory).getFullPathName() + T("\Hyperdrive\presets.xml");
File fyle(fyleSpec);
fyle.create();
XmlElement xmlState = m_PluginProcessor->serialiseStateInformation();
xmlState.writeToFile(fyle,"");
//[/UserButtonCode_m_btnSavePresets]
}
else if (buttonThatWasClicked == m_btnLoadPresets)
{
//[UserButtonCode_m_btnLoadPresets] – add your button handler code here…
String fyleSpec = File::getSpecialLocation(File::userApplicationDataDirectory).getFullPathName() + T("\Hyperdrive\presets.xml");
File fyle(fyleSpec);
if (fyle.existsAsFile())
{
XmlDocument xmlDoc(fyle);
m_PluginProcessor->deSerialiseStateInformation(xmlDoc.getDocumentElement());
}
//}
}[/code]
Please note that this is still a work in progress. You might notice that when the presets are loaded, I just update the state in the plugin processor and don’t notify the host. I guess I’ll need to dig around in setParameterNotifyingHost() to figure out how to manage that properly.
-Andrew
PS - My aim is to provide basic host independent functionality for editing presets to make it easier for users to restore factory presets or to share presets with other users. It also allows me a convenient method to manage factory presets during development.