diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp index af86714488..9c7ceb87b7 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp @@ -217,19 +217,19 @@ AudioProcessorParameterWithID* AudioProcessorValueTreeState::createAndAddParamet void AudioProcessorValueTreeState::addParameterListener (StringRef paramID, Listener* listener) { - if (Parameter* p = Parameter::getParameterForID (processor, paramID)) + if (auto* p = Parameter::getParameterForID (processor, paramID)) p->listeners.add (listener); } void AudioProcessorValueTreeState::removeParameterListener (StringRef paramID, Listener* listener) { - if (Parameter* p = Parameter::getParameterForID (processor, paramID)) + if (auto* p = Parameter::getParameterForID (processor, paramID)) p->listeners.remove (listener); } Value AudioProcessorValueTreeState::getParameterAsValue (StringRef paramID) const { - if (Parameter* p = Parameter::getParameterForID (processor, paramID)) + if (auto* p = Parameter::getParameterForID (processor, paramID)) return p->state.getPropertyAsValue (valuePropertyID, undoManager); return {}; @@ -237,7 +237,7 @@ Value AudioProcessorValueTreeState::getParameterAsValue (StringRef paramID) cons NormalisableRange AudioProcessorValueTreeState::getParameterRange (StringRef paramID) const noexcept { - if (Parameter* p = Parameter::getParameterForID (processor, paramID)) + if (auto* p = Parameter::getParameterForID (processor, paramID)) return p->range; return NormalisableRange(); @@ -250,7 +250,7 @@ AudioProcessorParameterWithID* AudioProcessorValueTreeState::getParameter (Strin float* AudioProcessorValueTreeState::getRawParameterValue (StringRef paramID) const noexcept { - if (Parameter* p = Parameter::getParameterForID (processor, paramID)) + if (auto* p = Parameter::getParameterForID (processor, paramID)) return &(p->value); return nullptr; @@ -382,7 +382,7 @@ struct AttachedControlBase : public AudioProcessorValueTreeState::Listener, void setNewUnnormalisedValue (float newUnnormalisedValue) { - if (AudioProcessorParameter* p = state.getParameter (paramID)) + if (auto* p = state.getParameter (paramID)) { const float newValue = state.getParameterRange (paramID) .convertTo0to1 (newUnnormalisedValue); @@ -394,7 +394,7 @@ struct AttachedControlBase : public AudioProcessorValueTreeState::Listener, void sendInitialUpdate() { - if (float* v = state.getRawParameterValue (paramID)) + if (auto* v = state.getRawParameterValue (paramID)) parameterChanged (paramID, *v); } @@ -415,7 +415,7 @@ struct AttachedControlBase : public AudioProcessorValueTreeState::Listener, void beginParameterChange() { - if (AudioProcessorParameter* p = state.getParameter (paramID)) + if (auto* p = state.getParameter (paramID)) { if (state.undoManager != nullptr) state.undoManager->beginNewTransaction(); @@ -570,21 +570,37 @@ struct AudioProcessorValueTreeState::ComboBoxAttachment::Pimpl : private Attach { const ScopedLock selfCallbackLock (selfCallbackMutex); + if (state.getParameter (paramID) != nullptr) { - ScopedValueSetter svs (ignoreCallbacks, true); - combo.setSelectedItemIndex (roundToInt (newValue), sendNotificationSync); + auto normValue = state.getParameterRange (paramID) + .convertTo0to1 (newValue); + auto index = roundToInt (normValue * (combo.getNumItems() - 1)); + + if (index != combo.getSelectedItemIndex()) + { + ScopedValueSetter svs (ignoreCallbacks, true); + combo.setSelectedItemIndex (index, sendNotificationSync); + } } } - void comboBoxChanged (ComboBox* comboBox) override + void comboBoxChanged (ComboBox*) override { const ScopedLock selfCallbackLock (selfCallbackMutex); if (! ignoreCallbacks) { - beginParameterChange(); - setNewUnnormalisedValue ((float) comboBox->getSelectedId() - 1.0f); - endParameterChange(); + if (auto* p = state.getParameter (paramID)) + { + auto newValue = (float) combo.getSelectedItemIndex() / (combo.getNumItems() - 1); + + if (p->getValue() != newValue) + { + beginParameterChange(); + p->setValueNotifyingHost (newValue); + endParameterChange(); + } + } } } diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h index 509410ac03..ed9557541c 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h @@ -206,6 +206,11 @@ public: /** An object of this class maintains a connection between a ComboBox and a parameter in an AudioProcessorValueTreeState. + Combobox items will be spaced linearly across the range of the parameter. For + example if the range is specified by NormalisableRange (-0.5f, 0.5f, 0.5f) + and you add three items then the first will be mapped to a value of -0.5, the + second to 0, and the third to 0.5. + During the lifetime of this ComboBoxAttachment object, it keeps the two things in sync, making it easy to connect a combo box to a parameter. When this object is deleted, the connection is broken. Make sure that your AudioProcessorValueTreeState