Significantly simplify usage of SwitchButtons

pull/249/head
James H Ball 2024-08-13 14:55:30 +01:00 zatwierdzone przez James H Ball
rodzic 87edfe0608
commit 96fb3efbb0
20 zmienionych plików z 135 dodań i 123 usunięć

Wyświetl plik

@ -204,18 +204,6 @@
}
});
window.__JUCE__.backend.addEventListener("intensityChanged", intensity => {
controls.exposureStops = intensity;
});
window.__JUCE__.backend.addEventListener("persistenceChanged", persistence => {
controls.persistence = persistence;
});
window.__JUCE__.backend.addEventListener("hueChanged", hue => {
controls.hue = hue;
});
document.addEventListener("dblclick", function() {
toggleFullscreen();
});

Wyświetl plik

@ -688,6 +688,13 @@ function doScriptProcessor(event) {
xSamples[i] = dataView.getFloat32(i * 4 * 2, true);
ySamples[i] = dataView.getFloat32(i * 4 * 2 + 4, true);
}
const getSettingsFn = Juce.getNativeFunction("getSettings");
getSettingsFn().then(settings => {
controls.exposureStops = settings.intensity;
controls.persistence = settings.persistence;
controls.hue = settings.hue;
});
if (controls.sweepOn) {
var gain = Math.pow(2.0,controls.mainGain);

Wyświetl plik

@ -14,8 +14,6 @@ FrameSettingsComponent::FrameSettingsComponent(OscirenderAudioProcessor& p, Osci
addAndMakeVisible(threshold);
addAndMakeVisible(stride);
animate.setTooltip("Enables animation for files that have multiple frames, such as GIFs or Line Art.");
sync.setTooltip("Synchronises the animation's framerate with the BPM of your DAW.");
offsetLabel.setTooltip("Offsets the animation's start point by a specified number of frames.");
rateLabel.setText("Frames per Second", juce::dontSendNotification);
@ -27,23 +25,13 @@ FrameSettingsComponent::FrameSettingsComponent(OscirenderAudioProcessor& p, Osci
update();
auto updateAnimation = [this]() {
audioProcessor.animateFrames->setValueNotifyingHost(animate.getToggleState());
audioProcessor.animationSyncBPM->setValueNotifyingHost(sync.getToggleState());
audioProcessor.animationRate->setUnnormalisedValueNotifyingHost(rateBox.getValue());
audioProcessor.animationOffset->setUnnormalisedValueNotifyingHost(offsetBox.getValue());
audioProcessor.invertImage->setValueNotifyingHost(invertImage.getToggleState());
};
animate.onClick = updateAnimation;
sync.onClick = updateAnimation;
rateBox.onFocusLost = updateAnimation;
offsetBox.onFocusLost = updateAnimation;
invertImage.onClick = [this]() {
audioProcessor.invertImage->setValue(invertImage.getToggleState());
};
invertImage.setTooltip("Inverts the image so that dark pixels become light, and vice versa.");
threshold.slider.onValueChange = [this]() {
audioProcessor.imageThreshold->setValue(threshold.slider.getValue());
};
@ -52,35 +40,32 @@ FrameSettingsComponent::FrameSettingsComponent(OscirenderAudioProcessor& p, Osci
audioProcessor.imageStride->setValue(stride.slider.getValue());
};
audioProcessor.animateFrames->addListener(this);
audioProcessor.animationSyncBPM->addListener(this);
audioProcessor.animationRate->addListener(this);
audioProcessor.animationOffset->addListener(this);
audioProcessor.invertImage->addListener(this);
}
FrameSettingsComponent::~FrameSettingsComponent() {
audioProcessor.invertImage->removeListener(this);
audioProcessor.animationOffset->removeListener(this);
audioProcessor.animationRate->removeListener(this);
audioProcessor.animationSyncBPM->removeListener(this);
audioProcessor.animateFrames->removeListener(this);
}
void FrameSettingsComponent::resized() {
auto area = getLocalBounds().withTrimmedTop(20).reduced(20);
double rowHeight = 20;
auto toggleBounds = area.removeFromTop(rowHeight);
auto toggleWidth = juce::jmin(area.getWidth() / 3, 150);
if (animated) {
animate.setBounds(toggleBounds.removeFromLeft(toggleWidth));
sync.setBounds(toggleBounds.removeFromLeft(toggleWidth));
double rowSpace = 10;
auto firstColumn = area.removeFromLeft(220);
auto animateBounds = firstColumn.removeFromTop(rowHeight);
animate.setBounds(animateBounds.removeFromLeft(100));
sync.setBounds(animateBounds.removeFromLeft(100));
firstColumn.removeFromTop(rowSpace);
animateBounds = firstColumn.removeFromTop(rowHeight);
auto animateBounds = firstColumn.removeFromTop(rowHeight);
rateLabel.setBounds(animateBounds.removeFromLeft(140));
rateBox.setBounds(animateBounds.removeFromLeft(60));
firstColumn.removeFromTop(rowSpace);
@ -91,9 +76,9 @@ void FrameSettingsComponent::resized() {
}
if (image) {
invertImage.setBounds(toggleBounds.removeFromLeft(toggleWidth));
auto secondColumn = area;
auto invertBounds = secondColumn.removeFromTop(rowHeight);
invertImage.setBounds(invertBounds.removeFromLeft(100));
secondColumn.removeFromTop(5);
rowHeight = 30;
@ -105,9 +90,6 @@ void FrameSettingsComponent::resized() {
void FrameSettingsComponent::update() {
rateBox.setValue(audioProcessor.animationRate->getValueUnnormalised(), false, 2);
offsetBox.setValue(audioProcessor.animationOffset->getValueUnnormalised(), false, 2);
animate.setToggleState(audioProcessor.animateFrames->getValue(), false);
sync.setToggleState(audioProcessor.animationSyncBPM->getValue(), false);
invertImage.setToggleState(audioProcessor.invertImage->getValue(), false);
if (sync.getToggleState()) {
rateLabel.setText("Frames per Beat", juce::dontSendNotification);
rateLabel.setTooltip("Set the animation's speed in frames per beat.");

Wyświetl plik

@ -4,6 +4,7 @@
#include "PluginProcessor.h"
#include "components/DoubleTextBox.h"
#include "components/EffectComponent.h"
#include "components/SwitchButton.h"
class OscirenderAudioProcessorEditor;
class FrameSettingsComponent : public juce::GroupComponent, public juce::AudioProcessorParameter::Listener, juce::AsyncUpdater {
@ -25,14 +26,14 @@ private:
bool animated = true;
bool image = true;
juce::ToggleButton animate{"Animate"};
juce::ToggleButton sync{"BPM Sync"};
jux::SwitchButton animate{audioProcessor.animateFrames};
jux::SwitchButton sync{audioProcessor.animationSyncBPM};
juce::Label rateLabel{ "Framerate","Framerate"};
juce::Label offsetLabel{ "Offset","Offset" };
DoubleTextBox rateBox{ audioProcessor.animationRate->min, audioProcessor.animationRate->max };
DoubleTextBox offsetBox{ audioProcessor.animationOffset->min, audioProcessor.animationRate->max };
juce::ToggleButton invertImage{"Invert Image"};
jux::SwitchButton invertImage{audioProcessor.invertImage};
EffectComponent threshold{ audioProcessor, *audioProcessor.imageThreshold };
EffectComponent stride{ audioProcessor, *audioProcessor.imageStride };

Wyświetl plik

@ -53,7 +53,6 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
inputEnabled.onClick = [this] {
audioProcessor.inputEnabled->setBoolValueNotifyingHost(!audioProcessor.inputEnabled->getBoolValue());
};
inputEnabled.setTooltip("Enable to use input audio, instead of the generated audio.");
addAndMakeVisible(fileLabel);
fileLabel.setJustificationType(juce::Justification::centred);

Wyświetl plik

@ -5,20 +5,10 @@ MidiComponent::MidiComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
setText("MIDI Settings");
addAndMakeVisible(midiToggle);
addAndMakeVisible(midiLabel);
addAndMakeVisible(voicesSlider);
addAndMakeVisible(voicesLabel);
addAndMakeVisible(keyboard);
midiToggle.setToggleState(audioProcessor.midiEnabled->getBoolValue(), juce::dontSendNotification);
midiToggle.setTooltip("Enable MIDI input for the synth. If disabled, the synth will play a constant tone, as controlled by the frequency slider.");
midiToggle.onClick = [this]() {
audioProcessor.midiEnabled->setBoolValueNotifyingHost(midiToggle.getToggleState());
};
audioProcessor.midiEnabled->addListener(this);
voicesSlider.setRange(1, 16, 1);
voicesSlider.setValue(audioProcessor.voices->getValueUnnormalised(), juce::dontSendNotification);
voicesSlider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 50, 20);
@ -69,7 +59,6 @@ MidiComponent::~MidiComponent() {
audioProcessor.releaseTime->removeListener(this);
audioProcessor.releaseShape->removeListener(this);
audioProcessor.midiEnabled->removeListener(this);
audioProcessor.voices->removeListener(this);
}
@ -80,7 +69,6 @@ void MidiComponent::parameterValueChanged(int parameterIndex, float newValue) {
void MidiComponent::parameterGestureChanged(int parameterIndex, bool gestureIsStarting) {}
void MidiComponent::handleAsyncUpdate() {
midiToggle.setToggleState(audioProcessor.midiEnabled->getBoolValue(), juce::dontSendNotification);
voicesSlider.setValue(audioProcessor.voices->getValueUnnormalised(), juce::dontSendNotification);
Env newEnv = Env(
@ -110,9 +98,7 @@ void MidiComponent::handleAsyncUpdate() {
void MidiComponent::resized() {
auto area = getLocalBounds().withTrimmedTop(20).reduced(20);
auto topRow = area.removeFromTop(30);
auto midiToggleBounds = topRow.removeFromLeft(120);
midiToggle.setBounds(midiToggleBounds.removeFromLeft(30).withSizeKeepingCentre(30, 20).translated(0, 1));
midiLabel.setBounds(midiToggleBounds);
midiToggle.setBounds(topRow.removeFromLeft(120).translated(0, 1));
topRow.removeFromLeft(80);
voicesSlider.setBounds(topRow.removeFromLeft(250));
if (midiSettingsButton.isVisible()) {

Wyświetl plik

@ -20,8 +20,7 @@ private:
OscirenderAudioProcessor& audioProcessor;
OscirenderAudioProcessorEditor& pluginEditor;
juce::Label midiLabel{"midiLabel", "MIDI Enabled"};
jux::SwitchButton midiToggle = { "switchButton", false };
jux::SwitchButton midiToggle = jux::SwitchButton(audioProcessor.midiEnabled);
juce::Slider voicesSlider;
juce::Label voicesLabel;
juce::TextButton midiSettingsButton{"Audio/MIDI Settings..."};

Wyświetl plik

@ -67,7 +67,7 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
}
if (juce::JUCEApplicationBase::isStandaloneApp()) {
if (juce::TopLevelWindow::getNumTopLevelWindows() == 1) {
if (juce::TopLevelWindow::getNumTopLevelWindows() > 0) {
juce::TopLevelWindow* w = juce::TopLevelWindow::getTopLevelWindow(0);
juce::DocumentWindow* dw = dynamic_cast<juce::DocumentWindow*>(w);
if (dw != nullptr) {

Wyświetl plik

@ -149,6 +149,9 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
permanentEffects.push_back(thresholdEffect);
permanentEffects.push_back(imageThreshold);
permanentEffects.push_back(imageStride);
permanentEffects.push_back(intensityEffect);
permanentEffects.push_back(persistenceEffect);
permanentEffects.push_back(hueEffect);
for (int i = 0; i < 26; i++) {
addLuaSlider();
@ -157,9 +160,6 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
allEffects = toggleableEffects;
allEffects.insert(allEffects.end(), permanentEffects.begin(), permanentEffects.end());
allEffects.insert(allEffects.end(), luaEffects.begin(), luaEffects.end());
allEffects.push_back(intensityEffect);
allEffects.push_back(persistenceEffect);
allEffects.push_back(hueEffect);
for (auto effect : allEffects) {
for (auto effectParameter : effect->parameters) {

Wyświetl plik

@ -184,8 +184,8 @@ public:
)
);
BooleanParameter* midiEnabled = new BooleanParameter("MIDI Enabled", "midiEnabled", VERSION_HINT, false);
BooleanParameter* inputEnabled = new BooleanParameter("Audio Input Enabled", "inputEnabled", VERSION_HINT, false);
BooleanParameter* midiEnabled = new BooleanParameter("MIDI Enabled", "midiEnabled", VERSION_HINT, false, "Enable MIDI input for the synth. If disabled, the synth will play a constant tone, as controlled by the frequency slider.");
BooleanParameter* inputEnabled = new BooleanParameter("Audio Input Enabled", "inputEnabled", VERSION_HINT, false, "Enable to use input audio, instead of the generated audio.");
std::atomic<float> frequency = 220.0f;
juce::SpinLock parsersLock;
@ -223,12 +223,12 @@ public:
IntParameter* voices = new IntParameter("Voices", "voices", VERSION_HINT, 4, 1, 16);
BooleanParameter* animateFrames = new BooleanParameter("Animate", "animateFrames", VERSION_HINT, true);
BooleanParameter* animationSyncBPM = new BooleanParameter("Sync To BPM", "animationSyncBPM", VERSION_HINT, false);
BooleanParameter* animateFrames = new BooleanParameter("Animate", "animateFrames", VERSION_HINT, true, "Enables animation for files that have multiple frames, such as GIFs or Line Art.");
BooleanParameter* animationSyncBPM = new BooleanParameter("Sync To BPM", "animationSyncBPM", VERSION_HINT, false, "Synchronises the animation's framerate with the BPM of your DAW.");
FloatParameter* animationRate = new FloatParameter("Animation Rate", "animationRate", VERSION_HINT, 30, -1000, 1000, 0.01);
FloatParameter* animationOffset = new FloatParameter("Animation Offset", "animationOffset", VERSION_HINT, 0, -10000, 10000, 0.1);
BooleanParameter* invertImage = new BooleanParameter("Invert Image", "invertImage", VERSION_HINT, false);
BooleanParameter* invertImage = new BooleanParameter("Invert Image", "invertImage", VERSION_HINT, false, "Inverts the image so that dark pixels become light, and vice versa.");
std::shared_ptr<Effect> imageThreshold = std::make_shared<Effect>(
[this](int index, Point input, const std::vector<double>& values, double sampleRate) {
return input;

Wyświetl plik

@ -4,7 +4,7 @@
class BooleanParameter : public juce::AudioProcessorParameterWithID {
public:
BooleanParameter(juce::String name, juce::String id, int versionHint, bool value) : AudioProcessorParameterWithID(juce::ParameterID(id, versionHint), name), value(value) {}
BooleanParameter(juce::String name, juce::String id, int versionHint, bool value, juce::String description) : AudioProcessorParameterWithID(juce::ParameterID(id, versionHint), name), value(value), description(description) {}
juce::String getName(int maximumStringLength) const override {
return name.substring(0, maximumStringLength);
@ -83,7 +83,12 @@ public:
void load(juce::XmlElement* xml) {
setBoolValueNotifyingHost(xml->getBoolAttribute("value", getDefaultValue()));
}
juce::String getDescription() {
return description;
}
private:
std::atomic<bool> value = false;
juce::String description;
};

Wyświetl plik

@ -167,7 +167,7 @@ void Effect::markEnableable(bool enable) {
if (enabled != nullptr) {
enabled->setValue(enable);
} else {
enabled = new BooleanParameter(getName() + " Enabled", getId() + "Enabled", parameters[0]->getVersionHint(), enable);
enabled = new BooleanParameter(getName() + " Enabled", getId() + "Enabled", parameters[0]->getVersionHint(), enable, "Toggles the effect.");
}
}

Wyświetl plik

@ -329,7 +329,7 @@ public:
std::atomic<bool> smoothValueChange = true;
LfoTypeParameter* lfo = new LfoTypeParameter(name + " LFO", paramID + "Lfo", getVersionHint(), 1);
FloatParameter* lfoRate = new FloatParameter(name + " LFO Rate", paramID + "LfoRate", getVersionHint(), 1.0f, 0.0f, 1000.0f, 0.01f, "Hz");
BooleanParameter* sidechain = new BooleanParameter(name + " Sidechain Enabled", paramID + "Sidechain", getVersionHint(), false);
BooleanParameter* sidechain = new BooleanParameter(name + " Sidechain Enabled", paramID + "Sidechain", getVersionHint(), false, "Toggles " + name + " Sidechain.");
std::atomic<float> phase = 0.0f;
juce::String description;

Wyświetl plik

@ -43,7 +43,7 @@ EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect, in
menu.addCustomItem(2, min, 160, 40, false);
menu.addCustomItem(3, max, 160, 40, false);
menu.showMenuAsync(juce::PopupMenu::Options().withParentComponent(audioProcessor.getActiveEditor()), [this](int result) {});
menu.showMenuAsync(juce::PopupMenu::Options(), [this](int result) {});
};
effect.addListener(index, this);

Wyświetl plik

@ -34,6 +34,7 @@ class SvgButton : public juce::DrawableButton, public juce::AudioProcessorParame
if (toggle != nullptr) {
toggle->addListener(this);
setToggleState(toggle->getBoolValue(), juce::NotificationType::dontSendNotification);
setTooltip(toggle->getDescription());
}
}

Wyświetl plik

@ -29,6 +29,7 @@
#pragma once
#include "JuceHeader.h"
#include "../audio/BooleanParameter.h"
namespace jux
{
@ -40,7 +41,7 @@ namespace jux
@see juce::ToggableButton
*/
class SwitchButton : public juce::Button
class SwitchButton : public juce::Button, public juce::AudioProcessorParameter::Listener
{
public:
enum ColourIds
@ -56,6 +57,32 @@ public:
switchCircle.setWantsKeyboardFocus (false);
switchCircle.setInterceptsMouseClicks (false, false);
}
SwitchButton(BooleanParameter* parameter) : SwitchButton(parameter->name, false) {
this->parameter = parameter;
setToggleState(parameter->getBoolValue(), juce::NotificationType::dontSendNotification);
parameter->addListener(this);
onStateChange = [this]() {
this->parameter->setBoolValueNotifyingHost(getToggleState());
};
addAndMakeVisible(label);
label.setTooltip(parameter->getDescription());
label.setText(parameter->name, juce::NotificationType::dontSendNotification);
}
~SwitchButton() {
if (parameter != nullptr) {
parameter->removeListener(this);
}
}
void parameterValueChanged(int parameterIndex, float newValue) override {
juce::MessageManager::callAsync([this]() {
setToggleState(parameter->getBoolValue(), juce::NotificationType::dontSendNotification);
});
}
void parameterGestureChanged(int parameterIndex, bool gestureIsStarting) override {}
void setMillisecondsToSpendMoving (int newValue)
{
@ -98,8 +125,10 @@ public:
{
Button::resized();
auto b = getSwitchBounds();
label.setBounds(getLabelBounds());
juce::Rectangle<float> switchCircleBounds;
if (! isVertical)
if (!isVertical)
switchCircleBounds = { getSwitchState() ? b.getRight() - b.getHeight() : b.getX(), b.getY(), b.getHeight(), b.getHeight() };
else
switchCircleBounds = {
@ -113,6 +142,7 @@ public:
private:
int millisecondsToSpendMoving { 75 };
juce::Label label;
bool getSwitchState() const
{
@ -121,13 +151,16 @@ private:
bool isInverted = false;
bool isVertical = false;
juce::Rectangle<float> getSwitchBounds()
{
auto b = getLocalBounds().toFloat().reduced(4, 4).translated(0, -1);
return b;
juce::Rectangle<float> getSwitchBounds() {
return getLocalBounds().removeFromLeft(30).withSizeKeepingCentre(30, 20).toFloat().reduced(4, 4).translated(0, -1);
}
juce::Rectangle<int> getLabelBounds() {
auto b = getLocalBounds();
b.removeFromLeft(34);
return b.translated(0, -1);
}
juce::String onText, offText;
class SwitchCircle : public Component
{
void paint (juce::Graphics& g) override
@ -139,6 +172,8 @@ private:
juce::ComponentAnimator animator;
bool prevToggleState = false;
BooleanParameter* parameter = nullptr;
};
} // namespace jux

Wyświetl plik

@ -1,12 +1,17 @@
#include "VisualiserComponent.h"
#include "../LookAndFeel.h"
#include "VisualiserSettings.h"
#include "VisualiserComponent.h"
VisualiserComponent::VisualiserComponent(OscirenderAudioProcessor& p, VisualiserComponent* parent, bool useOldVisualiser) : backgroundColour(juce::Colours::black), waveformColour(juce::Colour(0xff00ff00)), audioProcessor(p), oldVisualiser(useOldVisualiser), juce::Thread("VisualiserComponent"), parent(parent) {
resetBuffer();
startTimerHz(60);
startThread();
settingsWindow.setResizable(false, false);
settingsWindow.setUsingNativeTitleBar(true);
settings.setLookAndFeel(&getLookAndFeel());
settings.setSize(550, 130);
settingsWindow.setContentNonOwned(&settings, true);
setMouseCursor(juce::MouseCursor::PointingHandCursor);
setWantsKeyboardFocus(true);
@ -282,29 +287,7 @@ void VisualiserComponent::popoutWindow() {
popOutButton.setVisible(false);
}
void VisualiserComponent::setIntensity(double intensity) {
browser.emitEventIfBrowserIsVisible("intensityChanged", intensity);
}
void VisualiserComponent::setPersistence(double persistence) {
browser.emitEventIfBrowserIsVisible("persistenceChanged", persistence);
}
void VisualiserComponent::setHue(double hue) {
browser.emitEventIfBrowserIsVisible("hueChanged", hue);
}
void VisualiserComponent::openSettings() {
juce::DialogWindow::LaunchOptions options;
VisualiserSettings* settings = new VisualiserSettings(audioProcessor, *this);
settings->setLookAndFeel(&getLookAndFeel());
options.content.setOwned(settings);
options.content->setSize(500, 250);
options.dialogTitle = "Visualiser Settings";
options.dialogBackgroundColour = Colours::dark;
options.escapeKeyTriggersCloseButton = true;
options.useNativeTitleBar = true;
options.resizable = false;
juce::DialogWindow* dw = options.launchAsync();
settingsWindow.setVisible(true);
settingsWindow.toFront(true);
}

Wyświetl plik

@ -2,10 +2,12 @@
#include <algorithm>
#include <JuceHeader.h>
#include "../LookAndFeel.h"
#include "../concurrency/BufferConsumer.h"
#include "../PluginProcessor.h"
#include "LabelledTextBox.h"
#include "SvgButton.h"
#include "VisualiserSettings.h"
enum class FullScreenMode {
TOGGLE,
@ -121,6 +123,9 @@ private:
.withNativeFunction("pause", [this](auto& var, auto complete) {
setPaused(active);
})
.withNativeFunction("getSettings", [this](auto& var, auto complete) {
complete(settings.getSettings());
})
);
std::vector<float> tempBuffer;
@ -129,6 +134,8 @@ private:
std::shared_ptr<BufferConsumer> consumer;
std::function<void(FullScreenMode)> fullScreenCallback;
VisualiserSettings settings = VisualiserSettings(audioProcessor, *this);
SettingsWindow settingsWindow = SettingsWindow("Visualiser Settings");
void resetBuffer();
void popoutWindow();

Wyświetl plik

@ -1,34 +1,38 @@
#include "VisualiserSettings.h"
#include "VisualiserComponent.h"
#include "../PluginEditor.h"
VisualiserSettings::VisualiserSettings(OscirenderAudioProcessor& p, VisualiserComponent& visualiser) : audioProcessor(p), visualiser(visualiser) {
addAndMakeVisible(intensity);
addAndMakeVisible(persistence);
addAndMakeVisible(hue);
intensity.slider.onValueChange = [this] {
double value = intensity.slider.getValue();
intensity.effect.setValue(value);
this->visualiser.setIntensity(value);
};
persistence.slider.onValueChange = [this] {
double value = persistence.slider.getValue();
persistence.effect.setValue(value);
this->visualiser.setPersistence(value);
};
hue.slider.onValueChange = [this] {
double value = hue.slider.getValue();
hue.effect.setValue(value);
this->visualiser.setHue(value);
intensity.setSliderOnValueChange();
persistence.setSliderOnValueChange();
hue.setSliderOnValueChange();
gridToggle.setToggleState(audioProcessor.midiEnabled->getBoolValue(), juce::dontSendNotification);
gridToggle.setTooltip("Enables the oscilloscope graticule.");
gridToggle.onClick = [this]() {
audioProcessor.midiEnabled->setBoolValueNotifyingHost(gridToggle.getToggleState());
};
}
VisualiserSettings::~VisualiserSettings() {}
void VisualiserSettings::resized() {
auto area = getLocalBounds().withTrimmedTop(20).reduced(20);
auto area = getLocalBounds().reduced(20);
double rowHeight = 30;
intensity.setBounds(area.removeFromTop(rowHeight));
persistence.setBounds(area.removeFromTop(rowHeight));
hue.setBounds(area.removeFromTop(rowHeight));
}
juce::var VisualiserSettings::getSettings() {
auto settings = new juce::DynamicObject();
settings->setProperty("intensity", audioProcessor.intensityEffect->getActualValue());
settings->setProperty("persistence", audioProcessor.persistenceEffect->getActualValue());
settings->setProperty("hue", audioProcessor.hueEffect->getActualValue());
return juce::var(settings);
}

Wyświetl plik

@ -1,16 +1,19 @@
#pragma once
#include <JuceHeader.h>
#include "VisualiserComponent.h"
#include "EffectComponent.h"
#include "SvgButton.h"
#include "../LookAndFeel.h"
#include "SwitchButton.h"
class VisualiserComponent;
class VisualiserSettings : public juce::Component {
public:
VisualiserSettings(OscirenderAudioProcessor&, VisualiserComponent&);
~VisualiserSettings();
void resized() override;
juce::var getSettings();
private:
OscirenderAudioProcessor& audioProcessor;
VisualiserComponent& visualiser;
@ -18,6 +21,18 @@ private:
EffectComponent intensity{audioProcessor, *audioProcessor.intensityEffect};
EffectComponent persistence{audioProcessor, *audioProcessor.persistenceEffect};
EffectComponent hue{audioProcessor, *audioProcessor.hueEffect};
jux::SwitchButton gridToggle = { "gridToggle", false };
jux::SwitchButton noiseToggle = { "noiseToggle", false };
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VisualiserSettings)
};
class SettingsWindow : public juce::DocumentWindow {
public:
SettingsWindow(juce::String name) : juce::DocumentWindow(name, Colours::darker, juce::DocumentWindow::TitleBarButtons::closeButton) {}
void closeButtonPressed() override {
setVisible(false);
}
};