2023-07-02 17:47:04 +00:00
|
|
|
#include "EffectComponent.h"
|
|
|
|
|
2023-07-21 10:08:55 +00:00
|
|
|
EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect, int index) : effect(effect), index(index), audioProcessor(p) {
|
2023-07-18 17:28:09 +00:00
|
|
|
addAndMakeVisible(slider);
|
2023-07-21 19:04:10 +00:00
|
|
|
addChildComponent(lfoSlider);
|
2023-07-18 17:28:09 +00:00
|
|
|
addAndMakeVisible(selected);
|
2023-07-20 16:24:34 +00:00
|
|
|
addAndMakeVisible(lfo);
|
|
|
|
|
|
|
|
lfo.addItem("Static", static_cast<int>(LfoType::Static));
|
|
|
|
lfo.addItem("Sine", static_cast<int>(LfoType::Sine));
|
|
|
|
lfo.addItem("Square", static_cast<int>(LfoType::Square));
|
|
|
|
lfo.addItem("Seesaw", static_cast<int>(LfoType::Seesaw));
|
|
|
|
lfo.addItem("Triangle", static_cast<int>(LfoType::Triangle));
|
|
|
|
lfo.addItem("Sawtooth", static_cast<int>(LfoType::Sawtooth));
|
|
|
|
lfo.addItem("Reverse Sawtooth", static_cast<int>(LfoType::ReverseSawtooth));
|
|
|
|
lfo.addItem("Noise", static_cast<int>(LfoType::Noise));
|
|
|
|
|
|
|
|
lfo.setLookAndFeel(&lfoLookAndFeel);
|
|
|
|
|
2023-07-18 17:28:09 +00:00
|
|
|
effect.addListener(index, this);
|
|
|
|
setupComponent();
|
2023-07-04 13:58:36 +00:00
|
|
|
}
|
|
|
|
|
2023-07-21 10:08:55 +00:00
|
|
|
EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect, int index, bool checkboxVisible) : EffectComponent(p, effect, index) {
|
2023-07-17 13:37:36 +00:00
|
|
|
setCheckboxVisible(checkboxVisible);
|
2023-07-04 19:47:54 +00:00
|
|
|
}
|
|
|
|
|
2023-07-21 10:08:55 +00:00
|
|
|
EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect) : EffectComponent(p, effect, 0) {}
|
2023-07-11 17:48:45 +00:00
|
|
|
|
2023-07-21 10:08:55 +00:00
|
|
|
EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect, bool checkboxVisible) : EffectComponent(p, effect) {
|
2023-07-11 17:48:45 +00:00
|
|
|
setCheckboxVisible(checkboxVisible);
|
|
|
|
}
|
|
|
|
|
2023-07-18 17:28:09 +00:00
|
|
|
void EffectComponent::setupComponent() {
|
2023-07-18 18:20:54 +00:00
|
|
|
EffectParameter* parameter = effect.parameters[index];
|
2023-07-17 13:37:36 +00:00
|
|
|
|
2023-07-18 18:20:54 +00:00
|
|
|
slider.setRange(parameter->min, parameter->max, parameter->step);
|
|
|
|
slider.setValue(parameter->getValueUnnormalised(), juce::dontSendNotification);
|
2023-07-17 13:37:36 +00:00
|
|
|
|
2023-07-02 17:47:04 +00:00
|
|
|
slider.setSliderStyle(juce::Slider::LinearHorizontal);
|
2023-07-20 16:24:34 +00:00
|
|
|
slider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 70, slider.getTextBoxHeight());
|
2023-07-02 17:47:04 +00:00
|
|
|
|
2023-07-18 18:20:54 +00:00
|
|
|
bool enabled = effect.enabled == nullptr || effect.enabled->getValue();
|
|
|
|
selected.setToggleState(enabled, juce::dontSendNotification);
|
2023-07-17 13:37:36 +00:00
|
|
|
|
2023-07-21 10:08:55 +00:00
|
|
|
lfoEnabled = parameter->lfo != nullptr && parameter->lfoRate != nullptr;
|
|
|
|
if (lfoEnabled) {
|
|
|
|
lfo.setSelectedId(parameter->lfo->getValueUnnormalised(), juce::dontSendNotification);
|
2023-07-20 16:24:34 +00:00
|
|
|
|
2023-07-21 10:08:55 +00:00
|
|
|
lfo.onChange = [this]() {
|
|
|
|
if (lfo.getSelectedId() != 0) {
|
|
|
|
effect.parameters[index]->lfo->setUnnormalisedValueNotifyingHost(lfo.getSelectedId());
|
2023-07-21 10:41:01 +00:00
|
|
|
|
|
|
|
if (lfo.getSelectedId() == static_cast<int>(LfoType::Static)) {
|
|
|
|
lfoSlider.setVisible(false);
|
|
|
|
slider.setVisible(true);
|
|
|
|
} else {
|
|
|
|
lfoSlider.setVisible(true);
|
|
|
|
slider.setVisible(false);
|
|
|
|
}
|
2023-07-21 10:08:55 +00:00
|
|
|
}
|
|
|
|
};
|
2023-07-21 10:41:01 +00:00
|
|
|
|
|
|
|
lfoSlider.setRange(parameter->lfoRate->min, parameter->lfoRate->max, parameter->lfoRate->step);
|
|
|
|
lfoSlider.setValue(parameter->lfoRate->getValueUnnormalised(), juce::dontSendNotification);
|
|
|
|
|
|
|
|
if (lfo.getSelectedId() == static_cast<int>(LfoType::Static)) {
|
|
|
|
lfoSlider.setVisible(false);
|
|
|
|
slider.setVisible(true);
|
|
|
|
} else {
|
|
|
|
lfoSlider.setVisible(true);
|
|
|
|
slider.setVisible(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
lfoSlider.setSliderStyle(juce::Slider::LinearHorizontal);
|
|
|
|
lfoSlider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 70, lfoSlider.getTextBoxHeight());
|
|
|
|
lfoSlider.setTextValueSuffix("Hz");
|
|
|
|
lfoSlider.setColour(juce::Slider::thumbColourId, juce::Colour(0xff00ff00));
|
|
|
|
|
|
|
|
lfoSlider.onValueChange = [this]() {
|
|
|
|
effect.parameters[index]->lfoRate->setUnnormalisedValueNotifyingHost(lfoSlider.getValue());
|
|
|
|
};
|
2023-07-21 10:08:55 +00:00
|
|
|
}
|
|
|
|
|
2023-07-18 18:20:54 +00:00
|
|
|
min.textBox.setValue(parameter->min, juce::dontSendNotification);
|
|
|
|
max.textBox.setValue(parameter->max, juce::dontSendNotification);
|
2023-07-17 13:37:36 +00:00
|
|
|
|
|
|
|
min.textBox.onValueChange = [this]() {
|
2023-07-17 14:39:21 +00:00
|
|
|
double minValue = min.textBox.getValue();
|
|
|
|
double maxValue = max.textBox.getValue();
|
|
|
|
if (minValue >= maxValue) {
|
2023-07-18 18:20:54 +00:00
|
|
|
minValue = maxValue - effect.parameters[index]->step;
|
2023-07-17 14:39:21 +00:00
|
|
|
min.textBox.setValue(minValue, juce::dontSendNotification);
|
|
|
|
}
|
2023-07-18 18:20:54 +00:00
|
|
|
effect.parameters[index]->min = minValue;
|
|
|
|
slider.setRange(effect.parameters[index]->min, effect.parameters[index]->max, effect.parameters[index]->step);
|
2023-07-17 13:37:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
max.textBox.onValueChange = [this]() {
|
2023-07-17 14:39:21 +00:00
|
|
|
double minValue = min.textBox.getValue();
|
|
|
|
double maxValue = max.textBox.getValue();
|
|
|
|
if (maxValue <= minValue) {
|
2023-07-18 18:20:54 +00:00
|
|
|
maxValue = minValue + effect.parameters[index]->step;
|
2023-07-17 14:39:21 +00:00
|
|
|
max.textBox.setValue(maxValue, juce::dontSendNotification);
|
|
|
|
}
|
2023-07-18 18:20:54 +00:00
|
|
|
effect.parameters[index]->max = maxValue;
|
|
|
|
slider.setRange(effect.parameters[index]->min, effect.parameters[index]->max, effect.parameters[index]->step);
|
2023-07-17 13:37:36 +00:00
|
|
|
};
|
|
|
|
|
2023-07-18 18:20:54 +00:00
|
|
|
popupLabel.setText(parameter->name + " Settings", juce::dontSendNotification);
|
2023-07-17 13:37:36 +00:00
|
|
|
popupLabel.setJustificationType(juce::Justification::centred);
|
|
|
|
popupLabel.setFont(juce::Font(14.0f, juce::Font::bold));
|
2023-07-02 17:47:04 +00:00
|
|
|
}
|
|
|
|
|
2023-07-04 13:58:36 +00:00
|
|
|
|
2023-07-18 17:28:09 +00:00
|
|
|
EffectComponent::~EffectComponent() {
|
|
|
|
effect.removeListener(index, this);
|
|
|
|
}
|
2023-07-02 17:47:04 +00:00
|
|
|
|
2023-07-20 16:24:34 +00:00
|
|
|
void EffectComponent::resized() {
|
2023-07-02 17:47:04 +00:00
|
|
|
auto bounds = getLocalBounds();
|
2023-07-05 17:17:11 +00:00
|
|
|
auto componentBounds = bounds.removeFromRight(25);
|
|
|
|
if (component != nullptr) {
|
|
|
|
component->setBounds(componentBounds);
|
2023-07-05 16:57:41 +00:00
|
|
|
}
|
|
|
|
|
2023-07-21 10:08:55 +00:00
|
|
|
if (lfoEnabled) {
|
|
|
|
lfo.setBounds(bounds.removeFromRight(100).reduced(5));
|
|
|
|
}
|
2023-07-20 16:24:34 +00:00
|
|
|
|
2023-07-22 21:11:02 +00:00
|
|
|
auto checkboxLabel = bounds.removeFromLeft(120);
|
2023-07-20 16:24:34 +00:00
|
|
|
|
2023-07-05 11:02:28 +00:00
|
|
|
if (checkboxVisible) {
|
2023-07-20 16:24:34 +00:00
|
|
|
checkboxLabel.removeFromLeft(2);
|
|
|
|
selected.setBounds(checkboxLabel.removeFromLeft(25));
|
2023-07-05 11:02:28 +00:00
|
|
|
} else {
|
2023-07-20 16:24:34 +00:00
|
|
|
checkboxLabel.removeFromLeft(5);
|
2023-07-02 17:47:04 +00:00
|
|
|
}
|
2023-07-20 16:24:34 +00:00
|
|
|
textBounds = checkboxLabel;
|
|
|
|
slider.setBounds(bounds);
|
2023-07-21 10:41:01 +00:00
|
|
|
lfoSlider.setBounds(bounds);
|
2023-07-02 17:47:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectComponent::paint(juce::Graphics& g) {
|
2023-07-11 21:28:54 +00:00
|
|
|
g.fillAll(juce::Colours::black);
|
|
|
|
g.setColour(juce::Colours::white);
|
2023-07-18 18:20:54 +00:00
|
|
|
g.drawText(effect.parameters[index]->name, textBounds, juce::Justification::left);
|
2023-07-17 13:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectComponent::mouseDown(const juce::MouseEvent& event) {
|
2023-07-17 14:39:21 +00:00
|
|
|
if (event.mods.isPopupMenu()) {
|
|
|
|
juce::PopupMenu menu;
|
2023-07-17 13:37:36 +00:00
|
|
|
|
2023-07-17 14:39:21 +00:00
|
|
|
menu.addCustomItem(1, popupLabel, 200, 30, false);
|
|
|
|
menu.addCustomItem(2, min, 160, 40, false);
|
|
|
|
menu.addCustomItem(3, max, 160, 40, false);
|
2023-07-17 13:37:36 +00:00
|
|
|
|
2023-07-17 14:39:21 +00:00
|
|
|
menu.showMenuAsync(juce::PopupMenu::Options(), [this](int result) {});
|
|
|
|
}
|
2023-07-02 17:47:04 +00:00
|
|
|
}
|
|
|
|
|
2023-07-18 17:28:09 +00:00
|
|
|
void EffectComponent::parameterValueChanged(int parameterIndex, float newValue) {
|
|
|
|
triggerAsyncUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectComponent::parameterGestureChanged(int parameterIndex, bool gestureIsStarting) {}
|
|
|
|
|
|
|
|
void EffectComponent::handleAsyncUpdate() {
|
|
|
|
setupComponent();
|
2023-07-21 10:08:55 +00:00
|
|
|
juce::SpinLock::ScopedLockType lock1(audioProcessor.parsersLock);
|
|
|
|
juce::SpinLock::ScopedLockType lock2(audioProcessor.effectsLock);
|
|
|
|
if (effect.getId().contains("lua")) {
|
|
|
|
effect.apply();
|
|
|
|
}
|
2023-07-18 17:28:09 +00:00
|
|
|
}
|
|
|
|
|
2023-07-05 17:17:11 +00:00
|
|
|
void EffectComponent::setComponent(std::shared_ptr<juce::Component> component) {
|
|
|
|
this->component = component;
|
2023-07-05 16:57:41 +00:00
|
|
|
addAndMakeVisible(component.get());
|
|
|
|
}
|
|
|
|
|
2023-07-05 11:02:28 +00:00
|
|
|
void EffectComponent::setCheckboxVisible(bool visible) {
|
|
|
|
checkboxVisible = visible;
|
2023-07-02 17:47:04 +00:00
|
|
|
}
|