Mapping a AudioParameterChoice to a Radio Button Group sensecheck


#1

Hi,
As per the title I’m trying to find a neat / sensible way to map an AudioParameterChoice to a group of radio buttons.

Inspired by the ParameterSlider code in the JuceDemoPlugin project I came up with the code below.
It creates a GroupComponent with ToggleButtoms as required as subcomponents to the group.

I have a couple of questions:

  1. Can I get away without hashing the paramID to make a RadioGroupId? It kinda looked like it was only scoped to the parent Component (e.g. the GroupComponent in this case) but I’m not 100% sure.

  2. C++ isn’t my first language can you spot any lurking howlers? Put another way, is there a better way to do this?

Thanks in advance,
Dave


class MainUI::ParameterButtonGroup : public GroupComponent,
    private Timer, private juce::Button::Listener
{
public:
    ParameterButtonGroup (AudioParameterChoice& apc)
        : GroupComponent (((AudioProcessorParameter&)apc).getName(256), ((AudioProcessorParameter&)apc).getName(16)), param(apc)
    {
        ToggleButton* tb;
        DefaultHashFunctions dhf;

        for (int i = 0; i < apc.choices.size(); i++) 
        {
            toggleButtons.add(tb = new ToggleButton (apc.choices[i]));
            tb->setRadioGroupId(dhf.generateHash(apc.paramID, 65535));
            addAndMakeVisible(tb);
            tb->addListener(this);
        }
        startTimerHz(30);
        updateButtonDisplay();
    }

    void buttonClicked (Button*) override 
    {
        //from the listener, handle updating the host param from the buttons
        for (int i = 0; i < toggleButtons.size(); i++) {
            if (toggleButtons[i]->getToggleState()) {
                param.setValueNotifyingHost((float)i/(toggleButtons.size()));
                lastValue = i;
                return;
            }
        }
    }

    void timerCallback() override { updateButtonDisplay();}

    void updateButtonDisplay()
    {
        const int newValue = param.getIndex();
        if (newValue != lastValue && !isMouseButtonDown())
        {
            toggleButtons[newValue]->setToggleState(true, NotificationType::dontSendNotification);
        }
        lastValue = newValue;
    }


    void resized() override
    {
        // set toggle button positions within group
        Rectangle<int> ctrls = getLocalBounds().reduced(5,5);
        ctrls.removeFromTop(5);
        float heightPerButton = (float)ctrls.getHeight() / toggleButtons.size();
        for (int i = 0; i < toggleButtons.size(); i++) {
            toggleButtons[i]->setBounds(ctrls.removeFromBottom(heightPerButton));
        }
    }

    AudioParameterChoice& param;
    OwnedArray<ToggleButton> toggleButtons;
private:
    int lastValue;
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ParameterButtonGroup)
};