Last active
June 10, 2019 12:31
-
-
Save ffAudio/89284a26e9833d11e952ec9decc45f76 to your computer and use it in GitHub Desktop.
A Component to synchronise a RadioButtonGroup with an AudioParameterChoice
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
you should change the gist name to include ".cpp". it'll make it have syntax highlighting.