Skip to content

Instantly share code, notes, and snippets.

@Xenakios
Created November 4, 2022 14:48
Show Gist options
  • Select an option

  • Save Xenakios/440ba354bf2cea57d7a82779ba08ed82 to your computer and use it in GitHub Desktop.

Select an option

Save Xenakios/440ba354bf2cea57d7a82779ba08ed82 to your computer and use it in GitHub Desktop.
// for plugins without custom GUI
class GenericParameterComponent : public juce::Component
{
public:
GenericParameterComponent(ClapProcessor* proc, clap_id param_id)
: m_proc(proc), m_param_id(param_id)
{
m_slider.setSliderStyle(juce::Slider::SliderStyle::LinearBar);
m_slider.setRange(proc->paramInfo[param_id].min_value,proc->paramInfo[param_id].max_value);
m_slider.setValue(proc->getParameterValue(param_id),juce::dontSendNotification);
m_slider.setNumDecimalPlacesToDisplay(3);
m_slider.onValueChange=[this]()
{
// Clap plugins don't allow fiddling with the parameters directly from the GUI thread
// So, we put the slider value into a thread safe FIFO and the audio thread code
// takes care of passing the value into the plugin correctly
m_proc->m_from_gui_param_events.push({m_param_id,m_slider.getValue()});
};
m_label.setText(m_proc->paramInfo[param_id].name,juce::dontSendNotification);
m_button.setButtonText("...");
m_button.onClick=[this]()
{
juce::PopupMenu menu;
menu.addItem("Assign to active envelope",[](){});
menu.addItem("Randomize",[](){});
menu.addItem("Set to default value",[this]()
{
m_slider.setValue(m_proc->paramInfo[m_param_id].default_value);
});
menu.showMenuAsync(juce::PopupMenu::Options());
};
addAndMakeVisible(m_slider);
addAndMakeVisible(m_label);
addAndMakeVisible(m_button);
}
void updateSlider()
{
double curvalue = m_proc->getParameterValue(m_param_id);
if (m_slider.getValue()!=curvalue) // maybe might want to do something more "fuzzy" here...
{
m_slider.setValue(curvalue,juce::dontSendNotification);
}
}
void paint(juce::Graphics& g) override
{
g.fillAll(juce::Colours::darkgrey);
}
void resized() override
{
auto r = getLocalBounds();
juce::FlexBox flex;
flex.flexDirection = juce::FlexBox::Direction::row;
flex.items.add(juce::FlexItem(m_label).withHeight(getHeight()).withWidth(m_lab_w));
flex.items.add(juce::FlexItem(m_slider).withHeight(getHeight()).withFlex(6));
flex.items.add(
juce::FlexItem(m_button).withHeight(getHeight())
.withWidth(40).withMargin(2).withHeight(20)
.withAlignSelf(juce::FlexItem::AlignSelf::center));
flex.performLayout(r);
}
juce::Label m_label;
float m_lab_w = 0.0f;
private:
ClapProcessor* m_proc = nullptr;
clap_id m_param_id = -1;
juce::Slider m_slider;
juce::TextButton m_button;
};
class GenericClapComponent : public juce::Component, public juce::Timer
{
public:
GenericClapComponent(ClapProcessor* proc) : m_proc(proc)
{
float maxw = 0.0f;
for (auto& pinfo : m_proc->paramInfo)
{
auto comp = std::make_unique<GenericParameterComponent>(m_proc,pinfo.second.id);
addAndMakeVisible(comp.get());
maxw = std::max(
comp->m_label.getFont().getStringWidthFloat(comp->m_label.getText()),maxw);
m_param_comps.push_back(std::move(comp));
}
for (auto& c : m_param_comps)
c->m_lab_w = maxw+2.0f;
setOpaque(true);
startTimer(100);
}
void timerCallback() override
{
for (auto& c : m_param_comps)
c->updateSlider();
}
void paint(juce::Graphics& g) override
{
g.fillAll(juce::Colours::darkgrey.darker());
}
void resized() override
{
auto r = getLocalBounds();
juce::FlexBox flex;
flex.flexDirection = juce::FlexBox::Direction::column;
flex.flexWrap = juce::FlexBox::Wrap::wrap;
for (int i=0;i<m_param_comps.size();++i)
{
flex.items.add(juce::FlexItem(*m_param_comps[i]).withMinHeight(30.0f).withMargin(2.0f).withFlex(1.0));
}
flex.performLayout(r.reduced(10));
}
private:
ClapProcessor* m_proc = nullptr;
std::vector<std::unique_ptr<GenericParameterComponent>> m_param_comps;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment