Can you verify, that the returned tree is valid? It probably is, but it is safer to write:
auto tree = ValueTree::readFromStream(stream);
if (tree.isValid())
{
VTree = tree;
}
else
{
DBG ("Read invalid value tree");
}
Second, are you using the Attachment classes? Or how are you synchronising the values?
When you wrote that with a Slider::Listener by hand, it is easy to forget to update the slider from a parameter change…
Note that when you use operator=, you don’t specify an undomanger so it can’t possibly record the operation!
ValueTree::operator= isn’t really changing any data, you should think of it more like a smart-pointer assignment. None of the trees themselves change, so there’s nothing to undo/redo.
What you’re really attempting to do is to deep-copy the tree, and now that you come to mention it, that’s a function that’s missing from the class. In Tracktion we have a helper function to do it:
static inline juce::ValueTree copyValueTree (juce::ValueTree& dest, const juce::ValueTree& src, juce::UndoManager* um)
{
if (! dest.getParent().isValid())
{
dest = src.createCopy();
}
else
{
dest.copyPropertiesFrom (src, um);
dest.removeAllChildren (um);
for (int i = 0; i < src.getNumChildren(); ++i)
dest.addChild (src.getChild (i).createCopy(), i, um);
}
return dest;
}
…but TBH I should really move this into ValueTree to make it more widely useable, because there’s often a need to do this kind of thing.
thanks for the quick reply and the code snippet. But that I still have the same problem. The preset loads correct but no um.undo() possible or um.canUndo() = true. Changing a parameter via GUI undo works perfect.
@ Jules: I have implemented your function copyValueTree and call it as follows:
If the preset is loading ok but you can’t undo then probably VTree->state is invalid. As you can see in Jules’ function if the dest-tree is invalid you just copy your source tree without the undomanager knowing what’s going on.
My guess is that you didn’t initialize your AudioProcessorValueTreeState.
Try VTree->state = ValueTree(“STATE”); after you’ve created it.
Yes, I wanted to rule out the option, that the values actually change but you don’t see it, if you would have implemented the updates only one way. But in this case it should be fine.
If you post code, you can use three backticks ``` on a single line before and after the code, then it will be formatted as code and preserve the indent.
The function I quoted was just an example of how you might copy state, and it made the assumption that if the tree you’re copying is just “loose” with no parent, then there’s no point in all the extra work of copying its internal bits over. Obviously if you have different assumptions in your code, then you’d need to do things differently.
BTW I already added a function that probably does what you want: ValueTree::copyPropertiesAndChildrenFrom()