kopia lustrzana https://github.com/jameshball/osci-render
Range of sliders is now controllable
rodzic
bb91460429
commit
72951d3146
|
@ -37,10 +37,6 @@ double Effect::getValue() {
|
|||
return getValue(0);
|
||||
}
|
||||
|
||||
std::vector<EffectDetails> Effect::getDetails() {
|
||||
return details;
|
||||
}
|
||||
|
||||
void Effect::setValue(int index, double value) {
|
||||
details[index].value = value;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ public:
|
|||
void apply();
|
||||
double getValue(int index);
|
||||
double getValue();
|
||||
std::vector<EffectDetails> getDetails();
|
||||
void setValue(int index, double value);
|
||||
void setValue(double value);
|
||||
int getPrecedence();
|
||||
|
@ -22,8 +21,10 @@ public:
|
|||
juce::String getId();
|
||||
juce::String getName();
|
||||
|
||||
private:
|
||||
std::vector<EffectDetails> details;
|
||||
|
||||
private:
|
||||
|
||||
std::vector<double> smoothValues;
|
||||
double frequency = 1.0;
|
||||
int precedence = -1;
|
||||
|
|
|
@ -5,11 +5,25 @@
|
|||
struct EffectDetails {
|
||||
juce::String name;
|
||||
juce::String id;
|
||||
double value = 0.0;
|
||||
double min = 0.0;
|
||||
double max = 1.0;
|
||||
double step = 0.001;
|
||||
bool smoothValueChange = true;
|
||||
std::atomic<double> value = 0.0;
|
||||
std::atomic<double> min = 0.0;
|
||||
std::atomic<double> max = 1.0;
|
||||
std::atomic<double> step = 0.001;
|
||||
std::atomic<bool> smoothValueChange = true;
|
||||
|
||||
EffectDetails(juce::String name, juce::String id, double value, double min, double max, double step, bool smoothValueChange) : name(name), id(id), value(value), min(min), max(max), step(step), smoothValueChange(smoothValueChange) {}
|
||||
|
||||
// COPY CONSTRUCTOR SHOULD ONLY BE USED BEFORE
|
||||
// THE OBJECT IS USED IN MULTIPLE THREADS
|
||||
EffectDetails(const EffectDetails& other) {
|
||||
name = other.name;
|
||||
id = other.id;
|
||||
value.store(other.value.load());
|
||||
min.store(other.min.load());
|
||||
max.store(other.max.load());
|
||||
step.store(other.step.load());
|
||||
smoothValueChange.store(other.smoothValueChange.load());
|
||||
}
|
||||
};
|
||||
|
||||
class EffectApplication {
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
#include "EffectComponent.h"
|
||||
|
||||
EffectComponent::EffectComponent(EffectDetails details) : details(details) {
|
||||
EffectComponent::EffectComponent(Effect& effect, int index) : effect(effect), index(index) {
|
||||
componentSetup();
|
||||
slider.setRange(details.min, details.max, details.step);
|
||||
slider.setValue(details.value, juce::dontSendNotification);
|
||||
}
|
||||
|
||||
EffectComponent::EffectComponent(EffectDetails details, bool checkboxVisible) : EffectComponent(details) {
|
||||
setCheckboxVisible(checkboxVisible);
|
||||
EffectComponent::EffectComponent(Effect& effect, int index, bool checkboxVisible) : EffectComponent(effect, index) {
|
||||
setCheckboxVisible(checkboxVisible);
|
||||
}
|
||||
|
||||
EffectComponent::EffectComponent(Effect& effect) : EffectComponent(effect.getDetails()[0]) {}
|
||||
EffectComponent::EffectComponent(Effect& effect) : EffectComponent(effect, 0) {}
|
||||
|
||||
EffectComponent::EffectComponent(Effect& effect, bool checkboxVisible) : EffectComponent(effect) {
|
||||
setCheckboxVisible(checkboxVisible);
|
||||
|
@ -20,10 +18,32 @@ void EffectComponent::componentSetup() {
|
|||
addAndMakeVisible(slider);
|
||||
addAndMakeVisible(selected);
|
||||
|
||||
EffectDetails details = effect.details[index];
|
||||
|
||||
slider.setRange(details.min, details.max, details.step);
|
||||
slider.setValue(details.value, juce::dontSendNotification);
|
||||
|
||||
slider.setSliderStyle(juce::Slider::LinearHorizontal);
|
||||
slider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 90, slider.getTextBoxHeight());
|
||||
|
||||
selected.setToggleState(false, juce::dontSendNotification);
|
||||
|
||||
min.textBox.setValue(details.min, juce::dontSendNotification);
|
||||
max.textBox.setValue(details.max, juce::dontSendNotification);
|
||||
|
||||
min.textBox.onValueChange = [this]() {
|
||||
effect.details[index].min = min.textBox.getValue();
|
||||
slider.setRange(effect.details[index].min, effect.details[index].max, effect.details[index].step);
|
||||
};
|
||||
|
||||
max.textBox.onValueChange = [this]() {
|
||||
effect.details[index].max = max.textBox.getValue();
|
||||
slider.setRange(effect.details[index].min, effect.details[index].max, effect.details[index].step);
|
||||
};
|
||||
|
||||
popupLabel.setText(details.name + " Settings", juce::dontSendNotification);
|
||||
popupLabel.setJustificationType(juce::Justification::centred);
|
||||
popupLabel.setFont(juce::Font(14.0f, juce::Font::bold));
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,7 +70,19 @@ void EffectComponent::resized() {
|
|||
void EffectComponent::paint(juce::Graphics& g) {
|
||||
g.fillAll(juce::Colours::black);
|
||||
g.setColour(juce::Colours::white);
|
||||
g.drawText(details.name, textBounds, juce::Justification::left);
|
||||
g.drawText(effect.details[index].name, textBounds, juce::Justification::left);
|
||||
}
|
||||
|
||||
void EffectComponent::mouseDown(const juce::MouseEvent& event) {
|
||||
juce::PopupMenu menu;
|
||||
|
||||
menu.addCustomItem(1, popupLabel, 200, 30, false);
|
||||
menu.addCustomItem(2, min, 160, 40, false);
|
||||
menu.addCustomItem(3, max, 160, 40, false);
|
||||
|
||||
menu.showMenuAsync(juce::PopupMenu::Options(), [this](int result) {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
void EffectComponent::setComponent(std::shared_ptr<juce::Component> component) {
|
||||
|
|
|
@ -2,24 +2,27 @@
|
|||
#include <JuceHeader.h>
|
||||
#include "../PluginProcessor.h"
|
||||
#include "../audio/Effect.h"
|
||||
#include "LabelledTextBox.h"
|
||||
|
||||
|
||||
class EffectComponent : public juce::Component {
|
||||
public:
|
||||
EffectComponent(EffectDetails details);
|
||||
EffectComponent(EffectDetails details, bool checkboxVisible);
|
||||
EffectComponent(Effect& effect, int index);
|
||||
EffectComponent(Effect& effect, int index, bool checkboxVisible);
|
||||
EffectComponent(Effect& effect);
|
||||
EffectComponent(Effect& effect, bool checkboxVisible);
|
||||
~EffectComponent();
|
||||
|
||||
void resized() override;
|
||||
void paint(juce::Graphics& g) override;
|
||||
void mouseDown(const juce::MouseEvent& event) override;
|
||||
|
||||
void setCheckboxVisible(bool visible);
|
||||
void setComponent(std::shared_ptr<juce::Component> component);
|
||||
|
||||
juce::Slider slider;
|
||||
EffectDetails details;
|
||||
Effect& effect;
|
||||
int index;
|
||||
juce::ToggleButton selected;
|
||||
|
||||
private:
|
||||
|
@ -28,5 +31,9 @@ private:
|
|||
juce::Rectangle<int> textBounds;
|
||||
std::shared_ptr<juce::Component> component;
|
||||
|
||||
juce::Label popupLabel;
|
||||
LabelledTextBox min{"Min"};
|
||||
LabelledTextBox max{"Max"};
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(EffectComponent)
|
||||
};
|
||||
|
|
|
@ -1,40 +1,40 @@
|
|||
#include "EffectsListComponent.h"
|
||||
|
||||
EffectsListComponent::EffectsListComponent(DraggableListBox& lb, AudioEffectListBoxItemData& data, int rn, std::shared_ptr<Effect> effect) : DraggableListBoxItem(lb, data, rn), effect(effect) {
|
||||
auto details = effect->getDetails();
|
||||
auto details = effect->details;
|
||||
for (int i = 0; i < details.size(); i++) {
|
||||
std::shared_ptr<EffectComponent> effectComponent = std::make_shared<EffectComponent>(details[i], i == 0);
|
||||
std::shared_ptr<EffectComponent> effectComponent = std::make_shared<EffectComponent>(*effect, i, i == 0);
|
||||
// using weak_ptr to avoid circular reference and memory leak
|
||||
std::weak_ptr<EffectComponent> weakEffectComponent = effectComponent;
|
||||
effectComponent->slider.setValue(details[i].value, juce::dontSendNotification);
|
||||
effectComponent->slider.setValue(details[i].value, juce::dontSendNotification);
|
||||
effectComponent->slider.onValueChange = [this, i, weakEffectComponent] {
|
||||
if (auto effectComponent = weakEffectComponent.lock()) {
|
||||
this->effect->setValue(i, effectComponent->slider.getValue());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
if (i == 0) {
|
||||
bool isSelected = false;
|
||||
if (i == 0) {
|
||||
bool isSelected = false;
|
||||
|
||||
{
|
||||
juce::SpinLock::ScopedLockType lock(data.audioProcessor.effectsLock);
|
||||
// check if effect is in audioProcessor enabled effects
|
||||
for (auto processorEffect : data.audioProcessor.enabledEffects) {
|
||||
if (processorEffect->getId() == effect->getId()) {
|
||||
isSelected = true;
|
||||
break;
|
||||
{
|
||||
juce::SpinLock::ScopedLockType lock(data.audioProcessor.effectsLock);
|
||||
// check if effect is in audioProcessor enabled effects
|
||||
for (auto processorEffect : data.audioProcessor.enabledEffects) {
|
||||
if (processorEffect->getId() == effect->getId()) {
|
||||
isSelected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
effectComponent->selected.setToggleState(isSelected, juce::dontSendNotification);
|
||||
effectComponent->selected.setToggleState(isSelected, juce::dontSendNotification);
|
||||
effectComponent->selected.onClick = [this, weakEffectComponent] {
|
||||
if (auto effectComponent = weakEffectComponent.lock()) {
|
||||
auto data = (AudioEffectListBoxItemData&)modelData;
|
||||
juce::SpinLock::ScopedLockType lock(data.audioProcessor.effectsLock);
|
||||
data.setSelected(rowNum, effectComponent->selected.getToggleState());
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
listModel.addComponent(effectComponent);
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ void EffectsListComponent::resized() {
|
|||
|
||||
int EffectsListBoxModel::getRowHeight(int row) {
|
||||
auto data = (AudioEffectListBoxItemData&)modelData;
|
||||
return data.getEffect(row)->getDetails().size() * 30;
|
||||
return data.getEffect(row)->details.size() * 30;
|
||||
}
|
||||
|
||||
bool EffectsListBoxModel::hasVariableHeightRows() const {
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
#include <JuceHeader.h>
|
||||
#include "SliderTextBox.h"
|
||||
|
||||
class LabelledTextBox : public juce::Component {
|
||||
public:
|
||||
LabelledTextBox(juce::String text) {
|
||||
addAndMakeVisible(label);
|
||||
addAndMakeVisible(textBox);
|
||||
label.setText(text, juce::dontSendNotification);
|
||||
label.setJustificationType(juce::Justification::centredLeft);
|
||||
label.setFont(juce::Font(14.0f));
|
||||
}
|
||||
|
||||
~LabelledTextBox() override {}
|
||||
|
||||
void resized() override {
|
||||
auto bounds = getLocalBounds();
|
||||
textBox.setBounds(bounds.removeFromRight(90));
|
||||
label.setBounds(bounds);
|
||||
}
|
||||
|
||||
juce::Label label;
|
||||
SliderTextBox textBox;
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
#include <JuceHeader.h>
|
||||
|
||||
class SliderTextBox : public juce::Slider {
|
||||
public:
|
||||
SliderTextBox() {
|
||||
double RANGE = 999999;
|
||||
double step = 0.01;
|
||||
setRange(-RANGE, RANGE, step);
|
||||
setTextBoxStyle(juce::Slider::TextBoxAbove, false, 90, getTextBoxHeight());
|
||||
setSliderStyle(juce::Slider::SliderStyle::IncDecButtons);
|
||||
setIncDecButtonsMode(juce::Slider::IncDecButtonMode::incDecButtonsDraggable_AutoDirection);
|
||||
setMouseDragSensitivity(2 * RANGE / step);
|
||||
setSliderSnapsToMousePosition(false);
|
||||
setColour(juce::Slider::trackColourId, juce::Colours::transparentBlack);
|
||||
setSize(60, 20);
|
||||
}
|
||||
|
||||
~SliderTextBox() override {}
|
||||
};
|
|
@ -97,10 +97,13 @@
|
|||
file="Source/components/EffectsListComponent.cpp"/>
|
||||
<FILE id="dcLchL" name="EffectsListComponent.h" compile="0" resource="0"
|
||||
file="Source/components/EffectsListComponent.h"/>
|
||||
<FILE id="L9DIT2" name="LabelledTextBox.h" compile="0" resource="0"
|
||||
file="Source/components/LabelledTextBox.h"/>
|
||||
<FILE id="qIxm1z" name="LuaListComponent.cpp" compile="1" resource="0"
|
||||
file="Source/components/LuaListComponent.cpp"/>
|
||||
<FILE id="x0Syav" name="LuaListComponent.h" compile="0" resource="0"
|
||||
file="Source/components/LuaListComponent.h"/>
|
||||
<FILE id="QQzSwh" name="SliderTextBox.h" compile="0" resource="0" file="Source/components/SliderTextBox.h"/>
|
||||
<FILE id="y3UiR0" name="VisualiserComponent.cpp" compile="1" resource="0"
|
||||
file="Source/components/VisualiserComponent.cpp"/>
|
||||
<FILE id="ZueyNl" name="VisualiserComponent.h" compile="0" resource="0"
|
||||
|
|
Ładowanie…
Reference in New Issue