Thanks mucoder!
@Jules, ofcourse I don't expect anyone to debug my code. the only reason I've published this project is to help newbies like me to see the new AudioParametersValueTreeState usage with hope someone from JUCE/ROLI could chime-in if this is the proper way to initialize it. since the behavior looks a little odd.
The state itself and listeners works really well but I thought that it would "auto-magically" support undo/redo without much code.
Since I guess most people won't have energy to look at the demo project I've made here are the main parts:
PluginProcessor.h has the following objects:
UndoManager undoManager;
AudioProcessorValueTreeState parameters;
Default constructor in PluginProcessor.cpp:
undoManager(30000,30),parameters(*this,&undoManager)
Init within the PluginProcessor.cpp constructor:
auto textValueForDecibel = [](float val) -> String { String rawString = String::formatted("%2.1f",val); rawString.append("dB", 2); return rawString; };
NormalisableRange<float> clipRange = NormalisableRange<float>(-30.0f,0.0f); parameters.createAndAddParameter(PARAM_ID_CLIP, PARAM_NAME_CLIP, PARAM_NAME_CLIP, clipRange, clipRange.snapToLegalValue(0.0f), textValueForDecibel, nullptr);
// set-up ValueTree for saving/loading/undo
parameters.state = ValueTree(String("ValueTreeStateDemo"));
parameters.undoManager->clearUndoHistory();
parameters.undoManager->redo();
(the reason I'm clearing undo history is the it starts dirty I don't undetstand why..)
getStateInformation:
DBG("Store XML");
ScopedPointer<XmlElement> xml(parameters.state.createXml());
copyXmlToBinary (*xml, destData);
setStateInformation:
ScopedPointer<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
parameters.state = ValueTree::fromXml(*xmlState);
parameters.undoManager->clearUndoHistory();
The save/load ofcourse works like a charm and seems very neat as I can also add non-parameters to the valuetree by myself ;)
PluginEditor.h has:
ScopedPointer<Slider> clipSlider;
ScopedPointer<AudioProcessorValueTreeState::SliderAttachment> clipParamAttach
in PluginEditor.cpp constructor:
clipParamAttach = new juce::AudioProcessorValueTreeState::SliderAttachment (processor.parameters, PARAM_ID_CLIP, *clipSlider);
It implements button listeners for TextButtons - Undo/Redo so my listener basically does that:
else if (buttonThatWasClicked == undoBtn)
{
if(processor.parameters.undoManager->canUndo())
{
processor.parameters.undoManager->undo();
}
}
Same applies for redo.
I don't understand the behavior as for example: (the values are examples since my range is different ofcourse...)
1. I click the slider set it from 1.0 to 0.7 then to 0.5 then to 0.3
2. click undo it'll jump to 1.0
---- or
1. I click the slider it set it from 1.0 to 0.5...
2. click undo, works as expected.
3. click redo, does nothing (I'd expect the value to be set to 0.5 again...)