Setting precise increments for a slider object

Hi, I’m making a plugin that implements linear vertical sliders that currently look like this:
So I can click and drag up and down to change the value.
However I’m running into some dificulty with how the slider steps up to the next value. I’ve been trying to fiddle around with setMouseDragSensitivity() but couldn’t get it to behave how I wanted.
Basically I want the this slider to increment by 0.05 when dragging normally but then increment by 0.001 when alt-dragging. I guess this would be accomplished by calling

setRange(min, max, 0.0001)

but how would I go about calculating the correct sensitivity to put into setMouseDragSensitivity()?
or is there another magic method that does what I want?


Slider implements ctrl-drag as velocity mode, which is not the same as fine mode. This is how I implement fine mode. I don’t change the range interval, because for attached controls it’s set by SliderAttachment as the parameter interval. I use snapValue instead.

class Slider : juce::Slider
    bool fine{};
    // you need some way to set these
    struct { double snap{ 1.0 }; int sensitivity{ 500 }; } mode[2];

    void setFineMode (bool on)
        setMouseDragSensitivity (mode[fine = on].sensitivity);

        // disable velocity mode
        setVelocityModeParameters (1.0, 1, 0.0, false);

    double snapValue (double attemptedValue, DragMode dragMode) override
        if (dragMode == notDragging)
            return attemptedValue;

        return juce::roundToInt (attemptedValue / mode[fine].snap) * mode[fine].snap;

    void mouseDown (const juce::MouseEvent& event) override
        setFineMode (event.mods.isAnyModifierKeyDown());
        juce::Slider::mouseDown (event);

    void mouseDrag (const juce::MouseEvent& event) override
        if (fine != event.mods.isAnyModifierKeyDown())
            setFineMode (!fine);

        juce::Slider::mouseDrag (event);

Unfortunately, setMouseDragSensitivity needs to be modified -otherwise you get jumps every time you switch between modes. I added these lines at the end:

if (pimpl->currentDrag != nullptr)
    pimpl->mouseDragStartPos = pimpl->mousePosWhenLastDragged;
    pimpl->valueWhenLastDragged = (pimpl->sliderBeingDragged == 2 ? pimpl->valueMax
                                : (pimpl->sliderBeingDragged == 1 ? pimpl->valueMin
                                                                  : pimpl->currentValue)).getValue();
    pimpl->valueOnMouseDown = pimpl->valueWhenLastDragged;

Sensitivity is the screen distance for full scale drag, so you may have say 500 pixels for coarse and 1000 for fine. It’s independent from the snap interval, but you may want them to be proportional. For example, if you have an interval of 0.01 in a 0…1 range, you may want a multiple of 100 for sensitivity, so that every step takes the same amount of pixels.

1 Like