Suggestion: handling right clicks in buttons

I would propose adding to buttons the ability to handle a right-click.
This would require adding a method to ButtonListener in juce_Button.h:

    /** Called when the button is right clicked. */
	virtual void buttonRightClicked (Button*)				{}

and changing Button::sendClickMessage() at row #377 from:

if (! checker.shouldBailOut()) buttonListeners.callChecked (checker, &ButtonListener::buttonClicked, this);
to:

if (! checker.shouldBailOut()) { if(modifiers.isPopupMenu()) buttonListeners.callChecked (checker, &ButtonListener::buttonRightClicked, this); else buttonListeners.callChecked (checker, &ButtonListener::buttonClicked, this); }

Hello Jules, could you please let me know what you think about this?

There’s already a clicked (const ModifierKeys&) method - doesn’t that have the flag set for a right-click?

But this won’t let me use a ButtonListener. Am I wrong?

Hmm, that’s true.

Can’t explain exactly why, but I really don’t like the idea of reacting to a right button click… It feels wrong. If you really need to do it, you could catch the button state change messages and see which mouse button is down, then use that when the click event arrives.

I do not see why it is so strange to think of opening a context menu by right clicking on a button.

In fact the Juce Demo (in the Widgets/sliders page) uses the Slider::setPopupMenuEnabled() method to do exactly this, and that goes for the sliders of type Slider::IncDecButtons that are indeed buttons.

Frankly I think that my suggestion is compact, efficient and follows your programming style, while yours would complicate the application code for no apparent reason.

By the way, thanks for having implemented the other suggestions!

I agree with Jules here, if you’ve set your mouse to left handed (like me), then the buttonRightClicked make no sense anymore.
What about the other buttons (wheelClick, prevClicked etc…) then ?
What you really meant however is a way to figure out the state of the mouse that generated the click (can be done programmatically too)

Maybe a more elegant change, would be to modify the “buttonClicked” signature to include the mouse event (so when you programmatically trigger the click, then it’s possible to generate a fake mouse move).
Something like:
virtual void buttonClicked(Button * button, const MouseEvent & e) = 0;
or
virtual void buttonClicked(Button * button, const ModifiersKeys & keys) = 0;

You can then do whatever your want in the listener.

I think my main reasons for disliking the idea are more aesthetic than technical.

Generally, a button is something with a big label on it describing what happens when you press it. How would a user know that right-clicking this button would do something else? (To hope that they’ll read your documentation is, in my experience, a bit optimistic!)

But, perhaps what you’re creating is completely unlike a normal button, and does somehow make it obvious that left and right-clicking it will do different things - but in that case, maybe it’d be better to create a custom component for it, rather than trying to bend the existing button class to do what you need?

As Jules has acutely guessed, these are not the usual buttons you would put inside a dialog box, yet most of the time they behave just like them.

I’m using three different variations in my application and I actually already have two of them derived from TextButton to add drag and drop capabilities.

I could certainly extend them further, but I also need a simple way to inform the ButtonListener when a right click occurs. A solution like that proposed by X-Ryl669 would be fine.