Skip to content

Instantly share code, notes, and snippets.

@ffAudio
Last active June 10, 2019 12:31
Show Gist options
  • Select an option

  • Save ffAudio/89284a26e9833d11e952ec9decc45f76 to your computer and use it in GitHub Desktop.

Select an option

Save ffAudio/89284a26e9833d11e952ec9decc45f76 to your computer and use it in GitHub Desktop.
A Component to synchronise a RadioButtonGroup with an AudioParameterChoice
class ChoiceParameterRadioGroup : public Component,
private Button::Listener,
private AudioProcessorValueTreeState::Listener
{
public:
enum Orientation
{
horizontal,
vertical
};
ChoiceParameterRadioGroup (AudioProcessorValueTreeState& s, const String& pID, Orientation o)
: state (s), orientation (o), parameterID (pID)
{
auto* choices = dynamic_cast<AudioParameterChoice*> (state.getParameter (parameterID));
if (choices == nullptr)
{
// Parameter not found or is not of type AudioParameterChoice
jassertfalse;
return;
}
parameter = choices;
const int numChoices = choices->choices.size();
for (int i = 0; i < numChoices; ++i)
{
int edges = 0;
if (i > 0) edges |= (orientation == horizontal) ? TextButton::ConnectedOnLeft : TextButton::ConnectedOnTop;
if (i < numChoices - 1) edges |= (orientation == horizontal) ? TextButton::ConnectedOnRight : TextButton::ConnectedOnBottom;
auto button = std::make_unique<TextButton>(choices->choices [i]);
button->setClickingTogglesState (true);
button->setRadioGroupId (100);
button->addListener (this);
button->setConnectedEdges (edges);
addAndMakeVisible (button.get());
buttons.push_back (std::move (button));
}
auto index = choices->getIndex();
if (isPositiveAndBelow (index, buttons.size()))
buttons [index]->setToggleState (true, sendNotificationSync);
state.addParameterListener (parameterID, this);
}
~ChoiceParameterRadioGroup()
{
state.removeParameterListener (parameterID, this);
}
void resized() override
{
if (buttons.empty())
return;
auto area = getLocalBounds();
if (orientation == horizontal)
{
auto w = getWidth() / int (buttons.size());
for (auto& button : buttons)
button->setBounds (area.removeFromLeft (w));
}
else
{
auto h = getHeight() / int (buttons.size());
for (auto& button : buttons)
button->setBounds (area.removeFromTop (h));
}
}
void buttonClicked (Button* button) override
{
if (updating || parameter == nullptr)
return;
ScopedValueSetter<bool> u (updating, true);
auto index = std::find_if (buttons.begin(), buttons.end(), [button](const auto& b) {return b.get() == button;} );
if (index != buttons.end())
*parameter = int (std::distance (buttons.begin(), index));
}
void parameterChanged (const String& pID, float newValue) override
{
if (updating || pID != parameterID)
return;
ScopedValueSetter<bool> u (updating, true);
auto index = roundToInt (newValue);
if (isPositiveAndBelow (index, buttons.size()))
buttons [index]->setToggleState (true, sendNotificationSync);
}
private:
AudioProcessorValueTreeState& state;
std::vector<std::unique_ptr<Button>> buttons;
Orientation orientation;
String parameterID;
AudioParameterChoice* parameter = nullptr;
bool updating = false;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChoiceParameterRadioGroup)
};
@matkatmusic
Copy link
Copy Markdown

you should change the gist name to include ".cpp". it'll make it have syntax highlighting.

@ffAudio
Copy link
Copy Markdown
Author

ffAudio commented Jun 10, 2019

Changed. Ta!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment