Trying to change Slider LinearBar fill colour(s) with LookAndFeel

When I have a Slider set to LinearBar, I can change the color of the filled part with Slider::trackColourId, and the outline with Slider::textBoxOutlineColourId, but does anything control the color of the non-filled part?

In other words, if you click in the middle, the part to the left will be filled with trackColourId. But what about the part on the right? It seems to be just showing whatever the component’s background color is.

I just encountered this problem and fixed it with 2 lines of code. So, whenever a slider is drawn, the LookAndFeel_V4::drawnLinearSlider() is called. However, the source code went overly simplistic for when LinearBar or anything styled as bar is being used:

void LookAndFeel_V4::drawLinearSlider (Graphics& g, int x, int y, int width, int height,
                                       float sliderPos,
                                       float minSliderPos,
                                       float maxSliderPos,
                                       const Slider::SliderStyle style, Slider& slider)
{
    if (slider.isBar())
    {
        g.setColour (slider.findColour (Slider::trackColourId));
        g.fillRect (slider.isHorizontal() ? Rectangle<float> (static_cast<float> (x), (float) y + 0.5f, sliderPos - (float) x, (float) height - 1.0f)
                                          : Rectangle<float> ((float) x + 0.5f, sliderPos, (float) width - 1.0f, (float) y + ((float) height - sliderPos)));

        drawLinearSliderOutline (g, x, y, width, height, style, slider);
    }
    else
    {
// code
}

What you need is to override and modify that part of the code to make it fill a solid color sized as the slider. I am drawing a rounded rectangle as my linear bar as part on a wip software, so I’m using fillRoundedRectangle. drawRect might work if your bar is stock. This is what I end up with:

if (slider.isBar())
    {
        // These 2 lines below!
g.setColour (slider.findColour (Slider::backgroundColourId));
        g.fillRoundedRectangle (x, y, width, height, 14.0f);
        
        g.setColour (slider.findColour (Slider::trackColourId));
        // Change fillRect to fillRoundedRectangle (my modification)
        g.fillRoundedRectangle (slider.isHorizontal() ? Rectangle<float> (static_cast<float> (x), (float) y + 0.5f, sliderPos - (float) x, (float) height - 1.0f)
                                          : Rectangle<float> ((float) x + 0.5f, sliderPos, (float) width - 1.0f, (float) y + ((float) height - sliderPos)), 14.0f);
    }

and afterwards, changing the backgroundColourId will adjust the non-filled part you mentioned in your question.

~Adi

1 Like