I’m trying to implement a true fine mode for my sliders (which are actually just textboxes). I disabled velocity mode and kept two values of drag sensitivity, one for coarse and one for fine. On mouseDrag, I check the modifier keys and setMouseDragSensitivity accordingly. It works, but with a defect: if the mode is changed during a drag, the value jumps. This happens because the full drag extent has changed but the drag start position hasn’t. The only fix I could think of is calling mouseDown, which has the defect of starting a new gesture and a new undoable action:
I keep undoManager as a pointer because some sliders are not attached. mouseDown sets the initial mode. If it changes while dragging, a flag is raised and Slider::mouseDown is called. If the slider is attached, this begins a new undo transaction (through sliderDragStarted in SliderAttachment::Pimpl). After that, onDragStart is called, which drops the flag and undoes the transaction. This works because
onDragStart is called after all listeners. This is brittle, but I can’t think of other way with all the relevant parts being hidden in pimpls.
Could someone take a cursory look to see if I’m doing something silly and this will explode at the fourth run? Many people asked for a true fine mode in other threads, I guessed someone may have tried something like this before.
Sorry, I wrote before your message. That would be velocity mode. The problem with velocity mode is that it depends on mouse speed. If you move too little, it stalls. Then you move faster and it runs. The use case would be: you want to slide from 0 to 51.4, so you coarse drag to 50, then fine drag to 51.4. Both drags should be absolute, but with different sensitivities. The problem is that absolute drags are computed with respect to the drag start point, which is set is mouseDown. So you have to call mouseDown after changing the sensitivity, but it also triggers a new undo transaction. You end up with many transactions for a single drag, one for every mode change.
And only calling that function when the modifiers, and therefore the sensitivity you want to use, changes. With this you won’t need to manually call Slider::mouseDown in MySlider::mouseDrag. You should also remove the else statement from MySlider::mouseDrag.