#pragma once #include #include "../PluginProcessor.h" #include "../LookAndFeel.h" #include "../concurrency/BufferConsumer.h" class ThumbRadiusLookAndFeel : public OscirenderLookAndFeel { public: ThumbRadiusLookAndFeel(int thumbRadius) : thumbRadius(thumbRadius) {} int getSliderThumbRadius(juce::Slider& slider) override { return juce::jmin(thumbRadius, slider.isHorizontal() ? slider.getHeight() : slider.getWidth()); } private: int thumbRadius = 12; }; // this is for a vertical slider class ThresholdLookAndFeel : public ThumbRadiusLookAndFeel { public: ThresholdLookAndFeel(int thumbRadius) : ThumbRadiusLookAndFeel(thumbRadius) {} void drawLinearSliderThumb(juce::Graphics& g, int x, int y, int width, int height, float sliderPos, float minSliderPos, float maxSliderPos, const juce::Slider::SliderStyle style, juce::Slider& slider) override { float kx = (float) x + (float) width * 0.5f; float ky = sliderPos; auto outlineThickness = slider.isEnabled() ? 0.8f : 0.3f; auto sliderRadius = (float) getSliderThumbRadius(slider); auto diameter = sliderRadius * 2.0f; auto halfThickness = outlineThickness * 0.5f; auto isDownOrDragging = slider.isEnabled() && (slider.isMouseOverOrDragging() || slider.isMouseButtonDown()); auto knobColour = slider.findColour(juce::Slider::thumbColourId) .withMultipliedSaturation((slider.hasKeyboardFocus (false) || isDownOrDragging) ? 1.3f : 0.9f) .withMultipliedAlpha(slider.isEnabled() ? 1.0f : 0.7f); y = (int) (ky - sliderRadius); // draw triangle that points left juce::Path p; p.addTriangle( x + diameter, y, x + diameter, y + diameter, x, ky ); g.setColour(knobColour); g.fillPath(p); g.setColour(slider.findColour(sliderThumbOutlineColourId)); g.strokePath(p, juce::PathStrokeType(outlineThickness)); } void drawLinearSlider(juce::Graphics& g, int x, int y, int width, int height, float sliderPos, float minSliderPos, float maxSliderPos, const juce::Slider::SliderStyle style, juce::Slider& slider) override { drawLinearSliderThumb(g, x, y, width, height, sliderPos, minSliderPos, maxSliderPos, style, slider); } }; class VolumeComponent : public juce::Component, public juce::Timer, public juce::Thread { public: VolumeComponent(OscirenderAudioProcessor& p); ~VolumeComponent() override; void paint(juce::Graphics&) override; void timerCallback() override; void run() override; void resized() override; private: OscirenderAudioProcessor& audioProcessor; const int DEFAULT_SAMPLE_RATE = 192000; const double BUFFER_DURATION_SECS = 0.02; int sampleRate = DEFAULT_SAMPLE_RATE; std::vector buffer = std::vector(BUFFER_DURATION_SECS * DEFAULT_SAMPLE_RATE); std::atomic leftVolume = 0; std::atomic rightVolume = 0; std::atomic avgLeftVolume = 0; std::atomic avgRightVolume = 0; ThumbRadiusLookAndFeel thumbRadiusLookAndFeel{20}; juce::Slider volumeSlider; ThresholdLookAndFeel thresholdLookAndFeel{7}; juce::Slider thresholdSlider; std::unique_ptr volumeIcon; std::unique_ptr thresholdIcon; std::shared_ptr consumer; void resetBuffer(); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VolumeComponent) };