// async_attach.h // custom attachments for frequency controls // changes are withheld until confirmed #pragma once #include "JuceHeader.h" struct AsyncAttachmentSource : juce::AudioProcessorValueTreeState::Listener { friend struct AsyncAttachment; AsyncAttachmentSource (juce::AudioProcessorValueTreeState& state, const juce::String& id); ~AsyncAttachmentSource() { state_.removeParameterListener (paramID_, this); } auto lastValue() const { return lastValue_; } auto parameter() const { return state_.getParameter (paramID_); } void beginGesture() { if (notifyGesture) notifyGesture (true); } void endGesture() { if (notifyGesture) notifyGesture (false); } void confirmValue (float value, bool setParameter); void confirmGesture (bool starting); std::function notifyValue; std::function notifyGesture; private: void parameterChanged (const juce::String&, float value) override; juce::AudioProcessorValueTreeState& state_; const juce::String paramID_; std::vector attachments_; float lastValue_{}; bool ignoreCallbacks_{}; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncAttachmentSource) }; struct AsyncAttachment { AsyncAttachment (AsyncAttachmentSource& src) : source{ src } { src.attachments_.push_back (this); } virtual ~AsyncAttachment(); virtual void setLastValue() = 0; void valueChanged (float newValue); AsyncAttachmentSource& source; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncAttachment) }; struct AsyncSliderAttachment : juce::Slider::Listener, private AsyncAttachment { AsyncSliderAttachment (AsyncAttachmentSource& src, juce::Slider& slider); ~AsyncSliderAttachment() { slider_.removeListener (this); } private: void sliderDragStarted (juce::Slider*) override { source.beginGesture(); } void sliderDragEnded (juce::Slider*) override { source.endGesture(); } void sliderValueChanged (juce::Slider*) override { valueChanged (float (slider_.getValue())); } void setLastValue() override { slider_.setValue (source.lastValue(), juce::sendNotificationSync); } juce::Slider& slider_; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncSliderAttachment) };