#include "ArcKnob.h" ArcKnob::ArcKnob(juce::RangedAudioParameter& param) : juce::Slider(juce::Slider::RotaryHorizontalVerticalDrag, juce::Slider::NoTextBox), parameter(param) { } void ArcKnob::paint(juce::Graphics& g) { auto bounds = getLocalBounds().toFloat(); float diameter = juce::jmin(bounds.getWidth(), bounds.getHeight()); float radius = diameter * 0.42f; float cx = bounds.getCentreX(); float cy = bounds.getCentreY(); const float startAngle = juce::MathConstants::pi * 1.25f; const float endAngle = juce::MathConstants::pi * 2.75f; const float angleRange = endAngle - startAngle; float rangeMin = static_cast(getMinimum()); float rangeMax = static_cast(getMaximum()); float value = static_cast(getValue()); float normalizedValue = (rangeMax > rangeMin) ? juce::jlimit(0.0f, 1.0f, (value - rangeMin) / (rangeMax - rangeMin)) : 0.0f; float valueAngle = startAngle + normalizedValue * angleRange; // Background arc (dim) juce::Path bgArc; bgArc.addArc(cx - radius, cy - radius, radius * 2.0f, radius * 2.0f, startAngle, endAngle, true); g.setColour(juce::Colour(0xff333340)); g.strokePath(bgArc, juce::PathStrokeType(1.5f)); // Value arc if (normalizedValue > 0.001f) { juce::Path valueArc; valueArc.addArc(cx - radius, cy - radius, radius * 2.0f, radius * 2.0f, startAngle, valueAngle, true); g.setColour(juce::Colour(0xff7ecfcf)); g.strokePath(valueArc, juce::PathStrokeType(1.5f)); } // Center dot g.setColour(juce::Colour(0xff7ecfcf)); g.fillEllipse(cx - 2.0f, cy - 2.0f, 4.0f, 4.0f); }