Overriding Slider::setRotaryParameters

Hi, I’d like to create a rotary slider that spins many times. Very useful for selecting fractional values with 360 degree steps.
This means I need to set the end angle to be large. I can’t do that because ‘setRotaryParameters’ ‘jasserts’ on me with a check for 4xPI maximum for some reason.

I can’t over ride the function because it sets ‘pimpl’ which is private.

Can anyone help me inherit Slider so I can do this please.
Otherwise I’ll have to edit ‘juce_SIider.cpp’ every time I get the Juce code, which is not ideal at all.

OK, is there any way someone from the Juce team can remove the assert for 4PI angle (why 4PI?) limit on the rotary parameters please. It’s hindering functionality of the Slider a little, and it won’t cause a crash or anything dangerous.

Are you sure that multiple rotations is working as you expect it to? The class was not designed to support that, so I wouldn’t be surprised if there were problems converting between and angle and a proportion of the range.

The 4 pi limit is so you can set an initial angle of close to 2 pi, then a final angle close to 4 pi.

Thanks for the reply.
Yes, I’m sure.
Why even set a limit? It seems a little Draconian, for something that doesn’t crash anything.

If you don’t think people would want to do something, doesn’t mean you should make it a law not to. :grin:

Never mind, I’ve decided to write my own rotary slider instead.

The reason why I shy away from rolling my own Sliders is, that I cannot use the LookAndFeel mechanism.
It is unlucky that it is not extendable for custom components.

I.e. for sure I can create my own LookAndFeelMethods, but adding those to the existing getLookAndFeel() lookup and also the findColour() makes it hard to come up with a compatible solution.

Can I not copy this from juce_Silder.cpp?

    void paint (Graphics& g, LookAndFeel& lf)
        if (style != IncDecButtons)
            if (isRotary())
                auto sliderPos = (float) owner.valueToProportionOfLength (lastCurrentValue);
                jassert (sliderPos >= 0 && sliderPos <= 1.0f);

                lf.drawRotarySlider (g,
                                     sliderRect.getX(), sliderRect.getY(),
                                     sliderRect.getWidth(), sliderRect.getHeight(),
                                     sliderPos, rotaryParams.startAngleRadians,
                                     rotaryParams.endAngleRadians, owner);
                lf.drawLinearSlider (g,
                                     sliderRect.getX(), sliderRect.getY(),
                                     sliderRect.getWidth(), sliderRect.getHeight(),
                                     getLinearSliderPos (lastCurrentValue),
                                     getLinearSliderPos (lastValueMin),
                                     getLinearSliderPos (lastValueMax),
                                     style, owner);

            if ((style == LinearBar || style == LinearBarVertical) && valueBox == nullptr)
                g.setColour (owner.findColour (Slider::textBoxOutlineColourId));
                g.drawRect (0, 0, owner.getWidth(), owner.getHeight(), 1);

…with a separate LF

Unfortunately no, because owner is of type Slider&. If you inherit Slider and start from there you can (in which case you don’t need to override in the first place).
But from your description it did rather sound like you do a custom juce::Component, which means you cannot supply yourself as Slider reference.

This gets better and better. So the api is not flexible enough to adjust to my own needs, and I can’t do my own rotary knob.
I can make another component control though, I’ve done it before with Juce, so your statement is a little confusing there.
/Edit/. I didn’t want to call the slider code, just use the same rendering. I just showed that as an example.

I also wanted to do a knob that pauses on set values to make it easier for the user to select a value from a continuous range, like the really useful pan knob in FL Studio, that stops momentarily on centre. And other knob types.
But I can’t use snapValue() for that, because it sets an internal value.

I guess the best way to tackle this would be to use a Slider but override every method where RotaryParameters is referenced and completely ignore them using your own values.

It will most likely be in the mapping from mouse position to value (btw. I assume you use HorizontalVerticalDrag?) and all those related functions.
Probably doable, but I remember a lengthy implementation and lot’s of obstacles of similar kind revolving around absolute and velocity drag mode…

Using a Slider also has the advantage you can use the SliderParameterAttachment…

Thanks for the suggestion. It seems I can’t override the reference functions because they use many other variables that I can’t access. So I have to write my own component just to get around this 4pi thing.