Two-Value rotary slider

Hi all!

I am creating a filter plugin that can automate the cutoff at different rates. I am trying to create a two-value range slider around the cutoff slider as shown in the image below.

Juce forum question

The first approach I tried to take was to create two sliders next to each other with custom look and feel classes so it would give the appearance of one range slider. This would also make saving min and max values to the AudioProcessorValueTreeState really easy. However, I did not get this working since the other slider seemed to block the other slider and it could not be used.

I also tried to create a default two-value slider but I think that can’t be changed to a rotary slider, correct? Also storing the values to the APVTS is difficult since you have to write your own slider attachment for that.

What would be the best approach for creating this kind of slider? I think it would be neat if Juce had a TwoValueRotarySlider or something like that with a SliderAttachment to it. Thank you so much in advance.

Just what-iffing here… perhaps you could use two rotary sliders, one in front of the other (and slightly smaller, as you’ve shown), but both of them within a third, parent component that has just a label or something but is otherwise transparent black (to force it to get paint messages), and trap the mouse messages in that third component, determining the distance of the mouse down from its center, and sending the mouse message to the chosen rotary slider, each of which is hooked up normally to your APVTS?

The reason it doesn’t work without that parent is that mouse clicks are sent to the component whose rectangular bounds contain the mouse click, not the circular visible bounds that you see. But no reason you can’t fake that circular bounds behavior in a parent component, as far as I can see.

Thanks for your answer Howard! That’s actually a pretty good idea. I’ll have to try it out.

if you go for the approach of just overlapping 2 knobs you’ll notice that kinda sucks because the top one will eat the mouse events of the bottom one, since it’s a transparent rectangle even at the places where there is nothing drawn. so i propose that you actually make a slider with a radial hittest centred at the component’s center, so you can make it the exact length of the knob’s radius. then the outter knob can have its own grabable space.

1 Like

My first thought would be to create a parent component that has two sliders, each with some variable to indicate whether they should control the top or bottom of the range. You might be able to do some of the mouse event handling in the two sliders’ parent component by deriving from Slider::Listener and having the sliderValueChanged callback switch which slider should receive mouse clicks based on the cursor position.