Skinning the Slider / Replacing knob and slider track with PNGs

Quick and dirty solution:

 

Create a sublass of the original LookAndFeel class. Then, overwrite the following function:



virtual void drawRotarySlider    (   Graphics &     g,
                                     int     x,
                                     int     y,
                                     int     width,
                                     int     height,
                                     float     sliderPosProportional,
                                     float     rotaryStartAngle,
                                     float     rotaryEndAngle,
                                     Slider &     slider );

with something like:

void LookAndFeelCustom::drawRotarySlider    (    Graphics &     g,
                                                 int     x,
                                                 int     y,
                                                 int     width,
                                                 int     height,
                                                 float     sliderPosProportional,
                                                 float     rotaryStartAngle,
                                                 float     rotaryEndAngle,
                                                 Slider &     slider )
{    

    Image myStrip;    

    myStrip = ImageCache::getFromMemory (BinaryData::knobmid_png, BinaryData::knobmid_pngSize);

    
    const double fractRotation = (slider.getValue() - slider.getMinimum()) / (slider.getMaximum() -      slider.getMinimum()); //value between 0 and 1 for current amount of rotation
    const int nFrames = myStrip.getHeight()/myStrip.getWidth(); // number of frames for vertical film strip
    const int frameIdx = (int)ceil(fractRotation * ((double)nFrames-1.0) ); // current index from 0 --> nFrames-1

    const float radius = jmin (width / 2.0f, height / 2.0f) ;
    const float centreX = x + width * 0.5f;
    const float centreY = y + height * 0.5f;
    const float rx = centreX - radius - 1.0f;
    const float ry = centreY - radius /* - 1.0f*/;

    g.drawImage( myStrip, // image    
                 (int)rx, (int)ry, myStrip.getWidth(), myStrip.getWidth(),   // dest
                 0, frameIdx*myStrip.getWidth(), myStrip.getWidth(), myStrip.getWidth()); // source

}

Voila! (this only supports a specific size, you'll have to play around with values, but you probably get the idea)

1 Like