Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Logarithmic Model Dragging Behavior #7647

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

regulus79
Copy link
Contributor

@regulus79 regulus79 commented Jan 12, 2025

The Problem

Currently, logarithmic knobs and sliders act very weirdly when dragging them. Instead of visually moving at the same rate as the mouse while internally moving logarithmically, the internal value changes linearly with the mouse movement, while only the visual was displayed logarithmically.

This makes log knobs *literally* pointless, as they don't change the sensitivity for values of different magnitudes. They just display their current value logarithmically. In addition, this also causes the knobs to jump at the start and become sluggish relative to the mouse movement, which feels weird.

Might fix #3871

The Solution

This PR addresses this issue by correctly scaling the mouse movement for all knobs.

Changes

  • Knobs tend to draw their visuals using the inverse scaled value of the model. This means that we need to calculate what internal (scaled) value is needed to move the knob by the same number of "pixels" as the mouse moved. Let's talk through the maths:
    • Imagine a simple inverse scaling curve. LMMS's is super complex, but think of something like a sqrt() curve.
    • The x axis is the internal model value. The y axis is pixels. (well, it's not really pixels, but it's close enough)
    • We need to find how much we need to adjust the internal value to change the output by some number of pixels.
    • Imagine that the current internal value of the model is some number, say 0.5. Say that we need to move 5 pixels. How far left/right does the x value need to move so that the y value goes up by 5 pixels?
    • We can use the inverse of the inverse scaling function! I.e., the normal scaling function.
    • The change in internal value given a desired change in pixels is the difference between the current pixel value and the scaledValue(current pixel value + 5 pixels). Since the current pixel value is just inverseScaledValue(model value), it comes out to be:
    • model()->scaledValue(model()->inverseScaledValue(m_lastModelValue) - valueOffset)
      And adding that on to the current model value, we get m_lastModelValue - model()->scaledValue(model()->inverseScaledValue(m_lastModelValue) - valueOffset);
    • (note: for some reason the offsets are subtracted, not added. Don't ask me why.)

Also, these changes make the knobs more generalizable, since it does not depend on how the knob scaling is implemented, and it does not require any derivatives. If we wanted to add more interesting knob scalings in the future, this would make it easier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Mouse contronl on logarithmic models changes the value in linear scale
2 participants