Get rid of right-click clicking


#1

Hello,

I want to use right-clicking action only for showing popup menu.
But when I do right-click on a textbutton, it triggers mouse clicking.
How can I get rid of this behavior?

Thank you,


#2

You can check the modifier keys in the buttonClicked() method, and only respond to left click for action, and right click for menu. https://www.juce.com/doc/classModifierKeys


#3

Thank you, I will check it.


#4

Well, that’s only half of the story, because even with code that ignores actions taken with the right mouse button, the Button widget on screen will be animated as if it had been clicked, which is weird for a click that then does nothing.

I have modified slightly my version of JUCE so that the Button only reacts to left mouse clicks (required code changes are described below).

I think it would be a good feature request to have this behavior optionally enabled with a bool option in the base Button class, like setClickableWithLeftMouseButtonOnly().
What does @jules and its team think of this?

Here are the required code changes to only react to left clicks:
(The original parts are those commented out, with their replacement next to them)

Button::ButtonState Button::updateState()
{
    /* return updateState (isMouseOver (true), isMouseButtonDown()); */
    return updateState (isMouseOver (true), isMouseButtonDown() && ModifierKeys::getCurrentModifiers ().isLeftButtonDown ());
}

void Button::mouseDown (const MouseEvent& e)
{
    updateState (true, /*true*/ e.mods.isLeftButtonDown ());

    if (isDown())
    {
        if (autoRepeatDelay >= 0)
            callbackHelper->startTimer (autoRepeatDelay);

        if (triggerOnMouseDown)
            internalClickCallback (e.mods);
    }
}

void Button::mouseDrag (const MouseEvent& e)
{
    const ButtonState oldState = buttonState;
    updateState (isMouseOrTouchOver (e), /*true*/ e.mods.isLeftButtonDown() || e.source.isTouch());

    if (autoRepeatDelay >= 0 && buttonState != oldState && isDown())
        callbackHelper->startTimer (autoRepeatSpeed);
}

#5

We’re always reluctant to clutter a base class like Button with anything that’s not essential, and this doesn’t sound like a particularly useful addition for most people.

Why not just have a subclass which overrides mouseDown/Up/Drag() to only call the superclass method if the left button is down?


#6

It’s a good idea which would allow me to remove one of the places where I customized my copy of JUCE. Will have a go at it and let you know if it’s effective


#7

Thank you.
This works perfectly for my purpose.


#8

How did you do with this? I’m struggling to find a way to do this for all the myriad button types without duplicating code unnecessarily, and I don’t want to get into hacking my local copy of JUCE either.


#9

Hello,

Sorry, I don’t remember this well.

I think I customized my copy of JUCE.

That’s all I can come up with now.


#10

I ended up with this approach :

    class LeftClickOnlyButton : public Button
    {
    public:
        LeftClickOnlyButton(const String& buttonName) : Button(buttonName) {};

        void internalClickCallback(const ModifierKeys& mods) override
        {
            if(mods.isLeftButtonDown())
            {
                Button::internalClickCallback(mods);
            }
        }
    };

    class LeftClickOnlyToggleButton : public ToggleButton
    {
    public:
        LeftClickOnlyToggleButton() : ToggleButton() {};
        LeftClickOnlyToggleButton(const String& buttonText) : ToggleButton(buttonText) {};

        void internalClickCallback(const ModifierKeys& mods) override
        {
            if(mods.isLeftButtonDown())
            {
                ToggleButton::internalClickCallback(mods);
            }
        }
    };

etc etc for the different button types I needed, but can’t help thinking there must be a more efficient way.


#11

here is another thread about it :