Please, do a true fine mode

Hey guys, I did my best to solve this problem. I’d love if anyone could let me know why this is or isn’t hacky trash. ThanksFine_Slider.txt|attachment (8.5 KB)

@cjameslucas You’re much more likely to get a response if you post your code here within triple backticks (```) rather than a text file.

1 Like

No worries, I thought people might want a GIT patch.
In Slider::pimpl

...
    int fineSensitivityMultiplier = 10;
...
    bool isFineDragging = false;
    bool fineDraggingEnabled = true;
...

In Slider

void Slider::setFineDragMode(bool fineDraggingEnabled) { pimpl->fineDraggingEnabled = fineDraggingEnabled; }
bool Slider::getFineDragMode() const noexcept          { return pimpl->fineDraggingEnabled; }

void Slider::setFineModeParameters(int sensitivityMultiplier,
                                   ModifierKeys::Flags keys)
{
    jassert(sensitivityMultiplier > 0);
    jassert(keys != pimpl->modifierToSwapModes);

    pimpl->fineSensitivityMultiplier = sensitivityMultiplier;
    pimpl->modifierForFineMode = keys;
}

In Slider::pimpl

    bool isFineDragMode(ModifierKeys mods) const
    {
        return mods.testFlags(modifierForFineMode);
    }
    void fineDragReset(const MouseEvent& e)
    {
        if (isFineDragMode(e.mods) && !isFineDragging)
        {
            isFineDragging = true;
            mouseDragStartPos = e.position;
            valueOnMouseDown = valueWhenLastDragged;
        }
        else if (!isFineDragMode(e.mods) && isFineDragging)
        {
            isFineDragging = false;
            mouseDragStartPos = e.position;
            valueOnMouseDown = valueWhenLastDragged;
        }
    }
    void handleAbsoluteDrag (const MouseEvent& e)
    {
        auto mousePos = (isHorizontal() || style == RotaryHorizontalDrag) ? e.position.x : e.position.y;
        double newPos = 0;

        if (fineDraggingEnabled)
            fineDragReset (e);

        auto scaledPixelsForFullExtent = isFineDragging ? pixelsForFullDragExtent * fineSensitivityMultiplier
                                                        : pixelsForFullDragExtent;

        if (style == RotaryHorizontalDrag
            || style == RotaryVerticalDrag
            || style == IncDecButtons
            || ((style == LinearHorizontal || style == LinearVertical || style == LinearBar || style == LinearBarVertical)
                && ! snapsToMousePos))
        {
            auto mouseDiff = (style == RotaryHorizontalDrag
                                || style == LinearHorizontal
                                || style == LinearBar
                                || (style == IncDecButtons && incDecDragDirectionIsHorizontal()))
                              ? e.position.x - mouseDragStartPos.x
                              : mouseDragStartPos.y - e.position.y;

            newPos = owner.valueToProportionOfLength (valueOnMouseDown)
                       + mouseDiff * (1.0 / scaledPixelsForFullExtent);

            if (style == IncDecButtons)
            {
                incButton->setState (mouseDiff < 0 ? Button::buttonNormal : Button::buttonDown);
                decButton->setState (mouseDiff > 0 ? Button::buttonNormal : Button::buttonDown);
            }
        }
        else if (style == RotaryHorizontalVerticalDrag)
        {
            auto mouseDiff = (e.position.x - mouseDragStartPos.x)
                               + (mouseDragStartPos.y - e.position.y);

            newPos = owner.valueToProportionOfLength (valueOnMouseDown)
                       + mouseDiff * (1.0 / scaledPixelsForFullExtent);
        }
        ...


    void fineDragReset(const MouseEvent& e)
    {
        if (isFineDragMode(e.mods) && !isFineDragging)
        {
            isFineDragging = true;
            mouseDragStartPos = e.position;
            valueOnMouseDown = valueWhenLastDragged;
        }
        else if (!isFineDragMode(e.mods) && isFineDragging)
        {
            isFineDragging = false;
            mouseDragStartPos = e.position;
            valueOnMouseDown = valueWhenLastDragged;
        }
    }

The fineDragReset function feels sort of jank to me, but without checking to see if you swapped modifiers it causes the slider to snap if you release or press your modifier mid drag as if you had let go or held the modifier the entire time. I also tried implementing this with a new DragMode but I ended up with the same problem, something is happening asynchronously that I don’t understand I believe. I’m not sure, hopefully someone can guide me if there’s a cleaner way to solve it.

This hasn’t been incorporated into Juce, right? If not, does anybody have any advice for how to do this in a Slider subclass?