Saving editor width and height values

Hello,

What is the appropriate approach for storing the size (width and height) parameters of the plugin’s editor so that it may be saved and recovered in the set/get state information methods?

I am implementing a value tree for my automation-accessible parameters “Mod Depth” and “Mod Rate”, but I wouldn’t want the editor’s width and height values to be seen in this list of parameters (and after combing through the forum, I couldn’t quite find a solution).

The code below illustrates how I am implementing the (vanilla) value tree. Any help would be very much appreciated, even if it is a link to a forum topic that explains this in full :slight_smile:

ExampleAudioProcessor::ExampleAudioProcessor()
{
    ...
    // parameter access
    paramModRate = parameters.getRawParameterValue("modRate");
    paramModDepth = parameters.getRawParameterValue("modDepth");
    ...
}

AudioProcessorValueTreeState::ParameterLayout ExampleAudioProcessor::createParameterLayout()
{
    std::vector <std::unique_ptr<RangedAudioParameter>> params;

    auto parameterModRate = std::make_unique<AudioParameterFloat>("modRate", "Mod Rate", NormalisableRange<float>(0.1, 7.0, 0.001, 0.25), 1.3);
    auto parameterModDepth = std::make_unique<AudioParameterFloat>("modDepth", "Mod Depth", NormalisableRange<float>(0.0, 100.0, 0.1, 1.0), 100.0);
    params.push_back(std::move(parameterModRate));
    params.push_back(std::move(parameterModDepth));

    return { params.begin(), params.end() };
}

void ExampleAudioProcessor::getStateInformation (juce::MemoryBlock& destData)
{
    auto state = parameters.copyState();
    std::unique_ptr<XmlElement> xml (state.createXml());
    copyXmlToBinary (*xml, destData);
}

void ExampleAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
    std::unique_ptr<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
    if (xmlState.get() != nullptr)
        if (xmlState->hasTagName (parameters.state.getType()))
            parameters.replaceState (ValueTree::fromXml (*xmlState));
}

I set the last size into the public state ValueTree in the AudioProcessorValueTreeState whenever the AudioProcessorEditor is resized.
In the AudioProcessorEditor constructor I use that size when calling setSize().

// processor
int getEditorWidth()
{
    auto size = state.getOrCreateChildWithName ("lastSize", nullptr);
    return size.getProperty ("width", 640);
}
int getEditorHeight()
{
    auto size = state.getOrCreateChildWithName ("lastSize", nullptr);
    return size.getProperty ("height", 480);
}

void setEditorSize (int width, int height)
{
    auto size = state.getOrCreateChildWithName ("lastSize", nullptr);
    size.setProperty ("width", width, nullptr);
    size.setProperty ("height", height, nullptr);
}

// in editor constructor:
setSize (processor.getEditorWidth(), processor.getEditorHeight());

// in editor resized:
processor.setEditorSize (getWidth(), getHeight());

// and optionally in processor setStateInformation (could be unsafe, if setStateInformation is not on the message thread)
if (auto* editor = getActiveEditor())
{
    editor->setSize (getEditorWidth(), getEditorHeight());
}
2 Likes

Wonderful, thank you! I was able to implement this after brushing up on the ValueTree class and adding one to my AudioProcessor.
(https://docs.juce.com/master/tutorial_value_tree.html)

This works to maintain the size of the editor during the runtime of my DAW (Logic in this case). However, if I close my DAW, I would like the size of the plugin to persist when I re-open the DAW.

I believe I would need to modify the getStateInformation method to place the ValueTree data into destData along with the AudioProcessorValueTreeState “parameters”. What is the best way to go about this?

The state is a public member of the APVTS ValueTree. In your implementation you are already saving the data. If it didn’t work, then maybe because the session was not recognised as dirty and therefore not saved at all. I forgot, you should probably call updateHostDisplay() in our setEditorSize() to tell the host that the state has changed and allow saving.

1 Like

I realized I misunderstood that state was a member of my APVTS ‘parameters’, so I had created a separate ValueTree named ‘state’ :man_facepalming:
Instead, using ‘parameters.state.getOrCreateChildWithName()’ (accessing the state member of my APVTS) has the editor’s size persisting after the DAW has been restarted.
Thank you!

1 Like