Modifier bug

Hello, I have a slight problem with using a modifier on a slider.
If I hold down shift and move a slider, it works perfectly. But if I keep hold of shift then move another slider. Then let go of shift, the original slider retains the shift held status, so I guess the letting go status is only set for the second slider. It’s easily remedied by hitting shift again, it’s just slightly annoying.

the original slider retains the shift held status

What do you mean by this? The shift modifier is only used in the Slider’s mouse drag callback so doesn’t persist or have any concept of being ‘let go’.

The callback is called with shift down on the first slider. - Perfect.
I keep shift held and move to the second slider and let go of shift - the callback for shift up is only called for the second slider. Leaving the first one set to shift down. And because it won’t get another callback until I hit a modifier again, it remains in that state.
Some code, I think I’m doing this right:

class SnapSlider : public Slider
{
public:
double snapValue(double v, DragMode ) override
{
	if (shiftDown)
	{
		v = floor(v*2.0) / 2.0; // Snap to .5 steps.
	}
	return v;
}

void modifierKeysChanged(const ModifierKeys& modifiers) override
{
	shiftDown = modifiers.isShiftDown();
} 
	private:
		bool shiftDown = false;
};
/** Called when a modifier key is pressed or released.

    Whenever the shift, control, alt or command keys are pressed or released,
    this method will be called on the component that currently has the keyboard focus.
    Remember that a component will only be given the focus if its setWantsKeyboardFocus()
    method has been used to enable this.

    The default implementation of this method actually calls its parent's modifierKeysChanged
    method, so that focused components which aren't interested in this will give their
    parents a chance to act on the event instead.

    @see keyStateChanged, ModifierKeys
*/
virtual void modifierKeysChanged (const ModifierKeys& modifiers);

Note that you can only expect that to get called on the focused component, it doesn’t get called for all components every time a key changes.

…but I should mention that you can read the current modifier key state at any time, or better still, use the one that gets passed into the mouse event callbacks. Keeping your own flag like that is probably a bad idea.

So when something leaves a focus it can still be considered as having an active state? Interesting. It seemed like a great and simple idea having a callback. Oh well. How should I read the shift key status in my slider snap control?

Like I said - if you’re responding to a mouse event, it gives you that info in the event structure.

…or if it is not in a mouse callback directly, there is a static method for that called ModifierKeys::getCurrentModifiers()

if (ModifierKeys::getCurrentModifiers().isShiftDown()) {
    // do stuff

I think you are referring to Slider::snapTo()…

3 Likes

Brilliant. Thanks Daniel. I started out wondering how to grab that value.