Has anyone experienced a snapping issue with a slider who’s range crosses zero?

Slider myslider(Slider::LinearVertical, Slider::NoTextBox);
myslider.setRange (-1.0f, 1.0f, 0.01f);
myslider.setValue (0.0f);

I get -2.23517e-08 as the debug output! Zero should snap to zero as its an integral multiple of my interval from either min or max.

Inspection with the debugger of the snapToLegalValue() function , I notice the interval is 0.0099999997764825821 but that may be normal. Unfortunately, I don’t think the snapToLegalValueFunction is exposed to Slider settings, but I did find a workaround. Just to set the range from 0-2 and then map to and from that range in my code, and set the textFromValueFunction lambda accordingly.

So just wondering if anyone has any thoughts on this. Have I made a mistake? Should I do something different for ranges crossing zero? Or is there an issue in the NormalisableRange class in this case?


I’m having a similar issue, only it doesn’t involve 0.

I noticed that setValue eventually ends up here

    /** Takes a non-normalised value and snaps it based on either the interval property of
    this NormalisableRange or the lambda function supplied to the constructor.
ValueType snapToLegalValue (ValueType v) const noexcept
    if (snapToLegalValueFunction != nullptr)
        return snapToLegalValueFunction (start, end, v);

    if (interval > ValueType())
        v = start + interval * std::floor ((v - start) / interval + static_cast<ValueType> (0.5));

    return (v <= start || end <= start) ? start : (v >= end ? end : v);

Using NormalisableRange works fine. However, I’m trying to use an IncDec slider. When you do setNormalisableRange instead of setRange, the increment and decrement buttons stop functioning.

Also hit this issue.
Appears to be a bug in the implementation of snapToLegalValue and the fact that Slider uses a double range internally so what happens could be something like this if you use floats first

juce::NormalisableRange<float> rangeFloat(-1.0f, 1.0f, 0.01f);
auto lvf = rangeFloat.snapToLegalValue(0.0f); // Fine! lvf == 0.0f

juce::NormalisableRange<double> rangeDouble(rangeFloat.start, rangeFloat.end, rangeFloat.interval);
auto lvd = rangeDouble.snapToLegalValue(0.0); // BAD! lvd == invalid number

snapToLegalValue needs to be fixed