[JUCE API] Costomizing the Rotary Slide(2)

SangHoon You·2025년 5월 14일
0

JUCE API

목록 보기
13/17
post-thumbnail

6. Track Background

// 6. Track Background
    const float radiusSquare = boundSquare.getWidth() * 0.5f;
    const float thicknessTrack = radiusSquare * 0.1f;
    const float radiusTrack = radiusSquare - thicknessTrack * 0.5f;
    
    // path's geometry
    path.clear();
    path.addCentredArc(boundSquare.getCentreX(), boundSquare.getCentreY(),
                       radiusTrack, radiusTrack, 0.0f,
                       rotaryStartAngle, rotaryEndAngle,
                       true);
    
    // path's design
    juce::PathStrokeType stroketype (thicknessTrack,
                                     juce::PathStrokeType::JointStyle::curved,
                                     juce::PathStrokeType::EndCapStyle::rounded);
    
    g.setColour(MyColors::RotaryKnob::trackBackground);
    g.strokePath(path, stroketype);
  • The track is a indication of a parameter's amount, so we need a space(thickness) to reveal it.
  • In order to making a geometry of path, we use the addCentredArc(). It needs a center point, radius, start angle and end angle.
  • For creating a design of path, I used juce::PathStroketype class. I decide the thickness of track, design of join&end point.
  • And strokePath() can draw a path with the stroke object.


7. Dial

    // 7. Dial
    const float anglePos = rotaryStartAngle + sliderPosProportional * (rotaryEndAngle - rotaryStartAngle);
    const float RboundInner = boundInner.getWidth() * 0.5f;
    const float Rstart = RboundInner * 0.5f;
    const float Rend = RboundInner * 0.85f;
    
    // Adjustment of Coordinate System
    const float theta = anglePos - juce::MathConstants<float>::halfPi;
    
    // Trigonometry
    const juce::Point<float> startPoint (boundInner.getCentreX() + Rstart * cos(theta),
                                         boundInner.getCentreY() + Rstart * sin(theta));
    const juce::Point<float> endPoint (boundInner.getCentreX() + Rend * cos(theta),
                                         boundInner.getCentreY() + Rend * sin(theta));
    
    path.clear();
    path.startNewSubPath(startPoint);
    path.lineTo(endPoint);
    
    g.setColour(MyColors::RotaryKnob::dial);
    g.strokePath(path, stroketype);
  • AnglePos means the current angle of parameter. But Juce used a different coordinate system than standard mathematics.
  • So I have to minus half of pi to adjusting the anglePos for the standard coodinate system
  • StartPoint and EndPoint : In trigonometry, if you know the distance and angle from a reference point, you can find the exact position of the point.
  • I drew the line of dial by using startNewSubPath() and lineTo() function.


8. Track Value

Some parameters can have negative values, so the starting point might not always be the start angle. Therefore, the value of anglePos should be handled differently depending on the case.

class MyRotaryKnob  : public juce::Slider
{
    public:
        MyRotaryKnob(juce::AudioProcessorValueTreeState& inApvts,
                     const juce::String& inParamId,
                     const bool inStartMiddle = false)
                     {
                         getProperties().set("StartMiddle", inStartMiddle);
                     } 
}

mKnobAmount(mAudioprocessor.getmApvts(),MyParamId::FeedBack::Amount.getParamID(),true)
mKnobGain(mAudioprocessor.getmApvts(), MyParamId::Output::Gain.getParamID(),true)
  • To distinguish the parameter whether it starts from middle or not, I added a flag in RotaryKnob class.
  • Especially, I modify the knob of the Feedback Amount and Gain.

    // 8. track value
    const bool flagStartMiddle = inSlider.getProperties()["StartMiddle"];
    const float startAngle = flagStartMiddle ?
                             (rotaryStartAngle + sliderPosProportional * (rotaryEndAngle - rotaryStartAngle)) :
                             rotaryStartAngle;
     path.clear();
        path.addCentredArc(boundInner.getCentreX(), boundInner.getCentreY(),
                           radiusTrack, radiusTrack, 0.0f, startAngle, anglePos, true);

        g.setColour(MyColors::RotaryKnob::trackActive);
        g.strokePath(path, stroketype);                     
  • I get the each parameter's flag of start at the middle, I apply to the start angle. SliderPosProportional is the current portion between rotaryStartAngle and rotaryEndAngle.
  • And I arrange the scope of the track value from startAngle to anglePos.


9. Final GUI

After getting rid of the all lines, this is final rotary knob's design.

profile
Audio Plugin Developer

0개의 댓글