Slider Thumbs and drawLinearSlider Q


#1

It seems that the original intent of the slider class was to have the thumb be larger than the track that it draws in:


The thumb covers up the track in the above pics.
I’m trying to create a slider like this, where the track surrounds the thumb:

Because of how the slider class is designed, it seems that the correct approach to accomplish this is to override getSliderLayout() and make it return the full bounds of the slider via slider.getLocalBounds() as the slider.sliderBounds.

The following code makes the slider thumb stay within a track like that, but it has the downside of not tracking with the mouse entirely, as I have to scale the original sliderPos value:

class VerticalSliderLF    : public LookAndFeel_V3
{
public:
    Slider::SliderLayout getSliderLayout(Slider& s) override 
    {
        Slider::SliderLayout layout;
        layout.sliderBounds = s.getLocalBounds();
        return layout;
    }
    void drawLinearSlider(  Graphics &g, int x, int y, int width, int height,
                            float sliderPos,  float minSliderPos,  float maxSliderPos, const Slider::SliderStyle,
                            Slider &s) override
    {
        g.setColour(Colours::black);
        Rectangle<int> rint(x,y,width,height);

        Rectangle<float> r = rint.toFloat().reduced(0.5f);
        g.drawRoundedRectangle(r,5,1);

        g.setColour(Colours::green);
        
        float radius = (r.getWidth()-1) / 2.f;
        
        g.drawLine(r.getX() + r.getWidth()/2.f, 
                    r.getY() + radius,
                    r.getX() + r.getWidth()/2.f,
                    r.getHeight()-radius);

        auto l = (r.getHeight()-radius) - (r.getY() + radius);
        float originalPos = sliderPos / (float)height; 
        
        sliderPos = l * originalPos; //scaled to our inner size
        g.setColour(Colours::white);
        
        g.fillEllipse(x + width * 0.5f - radius,
                      sliderPos,
                      radius * 2.f,
                      radius * 2.f);
        
    }
};
//in the ctor()
addAndMakeVisible(volumeSlider = new Slider() );
volumeSlider->setLookAndFeel(&verticalSliderLF);
volumeSlider->setSliderStyle(Slider::SliderStyle::LinearVertical);
volumeSlider->setTextBoxStyle(Slider::TextEntryBoxPosition::NoTextBox, true, 0, 0);
//in the header private section:
    ScopedPointer<Slider> volumeSlider;
    VerticalSliderLF verticalSliderLF;

Any ideas how to go about doing this properly without having to scale the original sliderPos value? I’d like to preserve the mouse interaction that the default slider classes have because they work as expected. this scaled version, which it gets me going in the right direction in terms of the visuals, does not respond as expected when using the mouse.


#2

Try subclassing from Slider and overriding hiTest() to detect when the mouse is over the fader cap image

Rail


#3

I’m not drawing an image, if you look at the code i posted.