I have a row of juce::sliders used as a step sequencer.
Each time the stepper steps forward, I change the color of the current slider.
Problem is, if I am adjusting the value of the slider the ability to adjust gets cut off by the change of property. I’ll be in the middle of setting a value but then the mouse drag stops having an affect the moment the color of the slider is changed.
maybe like this:
instantiate the look and feel class for the slider, add a custom color variable as a property.
change the drawing in the LAF to use the custom color.
now if redraw is triggered in slider self, the color will be used.
class sliderLAFClass : public juce::LookAndFeel_V4
{
public:
Colour myColorToSwitch;
void drawRotarySlider (Graphics& g,
int x, int y, int width, int height,
float sliderPosProportional,
float rotaryStartAngle,
float rotaryEndAngle,
Slider&) override
{
// Use here ColorToSwitch
}
}
class mySliderComponent : public Slider
{
public:
// …
mySliderComponent(){
setLookAndFeel (sliderLAF);
}
~mySliderComponent(){
setLookAndFeel (nullptr);
};
sliderLAFClass sliderLAF;
}
-Set mySliderComponent. sliderLAF.myColorToSwitch to Colour( x, y, z)
-Call mySliderComponent.repaint if needed ( slidervaluechange will trigger repaint() itself)
LookAndFeel is the solution because it provides the draw methods for each slidertype. So it rules the way the slider draws itself.
I presumed the rotaryslider method, you have to lookup the method for your slidertype here: https://docs.juce.com/master/classLookAndFeel__V4.html
you’re interrupting the slider in its doings, using the LAF class will not interrupt the slider, it will change the way the slider represents itself.
I dont know exactly how you are interrupting the slider, but using lookandfeel is the standard method for circumventing such stuff afaik.
I think you can best use drawButtonBackground() in the LAF.
just look up the code for LookAndFeel_V4::drawButtonBackground
copy that funcntion in class sliderLAFClass
add the custom colour usage there
I think what @loveslap would like to know why changing the colour actually tiggers the behaviour.
If you check the inner workings of juce_Slider you’ll see the following.
When the colour property is set the Slider::colourChanged method is called and it its turn it calls lookAndFeelChanged(). In lookAndFeelChanged() quite a few controls are being rebuild and this probably causes the mouse to cancel its dragging behaviour.
I personally think its quite odd that the Slider is being rebuild when just a colour is being changed. But atm that is just how it is.
So what @PaulDriessen is suggestion is to not use Slider::setColour, because that will cause a rebuild but use a custom property (you can add custom properties to any component using component.getProperties().set(“MyColor”, value)) and pick up this custom property in a custom lookAndFeel.
You only have to have one lookAndFeel instance for all your sliders, then override the draw method and pick up the custom property in the draw method.
Don’t forget to to call repaint on your slider after setting the custom property though because otherwise the colour change will not be picked up.
What you gain by this is that you have more control on what happens when you change the color of the slider. But this should never have been needed in the first place because a colour change should not cause a rebuild in my opinion.
Maybe the JUCE team can shed some light here, and maybe even fix the behaviour.
Yes, and if you use Properties as suggested above by @rebbur, you would be able to do that.
You set the Property depending whether you want the slider drawn differently or not.
Then in the draw method drawButtonBackground(), which will be called for all buttons, you examine the button’s Properties and pick up whether to change its color or not.
Properties are really useful for getting a single component of a certain class to do something different from all of its siblings without subclassing it or making a separate LookAndFeel.