Populate ComboBox from AudioProcessorValueTreeState

This question is from trying to implement my own ProcessorEditor in the excellent Juce Step-by-step tutorial.

Using the juce::GenericAudioProcessorEditor an AudioParameterChoice will present itself in the plugin GUI with the given parameter choices as a ComboBox with this constructor:

AudioProcessor()
	: myValueTreeState(*this, nullptr, juce::Identifier("myParameters"{std::make_unique<juce::AudioParameterChoice>("type", "TYPE", juce::StringArray{"LowP", "HighP", "BandP"}, 2)
{
 typePtr = dynamic_cast<juce::AudioParameterChoice*>(myValueTreeState.getParameter("type"));
}

And it can then be used to make a choice like this:

switch (typePtr->getIndex())
{
     //case stuff
}

This is all from the tutorial.
myValueTreeState is a juce::AudioProcessorValueTreeState.

To learn I tried recreating this functionlity using the default plugin template in Projucer, and it worked nicely with juce::AudioParameterInt, juce::AudioParameterFloat & juce::AudioParameterBool. These are presented as sliders and a tick box, by adding appropriate functionality in the PluginEditor, like this:

in PluginEditor.h:

juce::Label cutOffLabel;
juce::Slider cutOffSlider;
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> cutOffAttachment;

in PluginEditor.cpp - PluginEditor constructor:

addAndMakeVisible (cutOffSlider);
cutOffAttachment.reset (new juce::AudioProcessorValueTreeState::SliderAttachment (valueTreeState, "cutoff", cutOffSlider));

Then I tried something similar with ComboBox but I get an empty box:

in PluginEditor.h:

juce::ComboBox filterChoice;
std::unique_ptr<juce::AudioProcessorValueTreeState::ComboBoxAttachment> filterChoiceAttachment;

in PluginEditor.cpp:

addAndMakeVisible (filterChoice);
filterChoiceAttachment.reset (new juce::AudioProcessorValueTreeState::ComboBoxAttachment (valueTreeState, "type", filterChoice));

So the three choices are not propagated to the ComboBox in the same way as for the other GUI components, where range settings are propagated and bools are interpreted to match a tick box-button. I’ve read the documentation and some threads on this but I don’t get it. I guess mainly because I can’t grasp what this Attachment functionality does behind the scenes. I understand the internal representation is float, but since the GenericAudioProcessorEditor handles this I didn’t think that would present any problems for a manually created and corresponding control.

How can I make the defined choices from the AudioProcessorValueTreeState make it into the Combobox? Where is the chain broken in my code?

Obviously I don’t want to recreate and thereby redefine the parameters for the editor since they are already defined in the Processor constructor. I want to define them in once like for the other controls.

I suggested once to populate this automatically but they wanted to keep existing behaviour.
But it can be solved with an “one-liner”:

auto* parameter = valueTreeState.getParameter ("type");
filterChoice->addItemList (parameter->getAllValueStrings(), 1);

addAndMakeVisible (filterChoice);
// and I prefer make_unique, makes no technical difference though in this case:
filterChoiceAttachment = std::make_unique<juce::AudioProcessorValueTreeState::ComboBoxAttachment> (valueTreeState, "type", filterChoice);

Hope that helps.

Yes, I saw that thread but didn’t know how to extract what I needed from that discussion. But this made it work like intended and I do think I get the general idea. Thanks a lot!

1 Like

I need to add it needs to be done before adding the attachment, otherwise the initial update will fail because the ComboBox has no options yet.
Just in case anybody tries the other way round…