ShapeButton does not reflect toggleState

ShapeButton has 3 colours (normal/over/down), but it currently does not use the down one when down on toggleState. So if it is setClickingToggleState (true), it won’t reflect the current state.

a call to getToggleState() in ShapeButton::paintButton() would fix that :

    g.setColour (isButtonDown || getToggleState() ? downColour
		                                  : isMouseOverButton ? overColour
                                                  : normalColour);
1 Like

Good spot! Added to develop.


This change has broken some UI in my app because not all shape buttons reflect toggle state in the same way.

I purposefully have a lot of code that changes ShapeButton colours when the state is toggled.
For example, I use ShapeButtons to control various panel visibilities in Tracktion. I don’t want the button to look the same when the panel is visible and when the user has the mouse held down on the button. I often use the same colour for the ‘on’ state but change the shape.

To me, the ‘up/over/down’ states are separate from the ‘toggled’ states and you may well want effectively 6 different colours for the toggled variants of the state.

Wouldn’t it be better to add a method to set the toggled state colours? (And then a method to use these instead of the default colours so we could have both behaviours?)

Hmm yeah. How about if ShapeButton had up/over/down colours for the toggled on state which by default are just set to be the same as the normal colours passed to the constructor and then there could be a setToggledColours method which changes the toggled on colours? Then the paintButton method could do something like this:

g.setColour (isButtonDown ? (getToggleState() ? downColourOn : downColour)
                          : isMouseOverButton ? (getToggleState() ? overColourOn : overColour)
                                              : (getToggleState() ? normalColourOn : normalColour));

Yeah, I think there needs to be a separate setToggledColours method.
However, I use the setColours method a lot to update the colours when the LookAndFeel or colour scheme changes. So really you need two modes, one for a single set of colours and one for setting separate colours for toggles.

The difficulty with automatically turning the toggle colours on with the new method is there’s then no way to turn them off. For this reason I would probably still include a method to toggle between the two modes. But I’m not completely sure what the best approach is yet.

Did you guys ever decide on the best plan for this? We’ve got a launch coming up and I’ve got dull but active buttons in my UI…

Hi Dave,

Sorry, this post totally slipped under my radar over the holidays! I’ve added some methods to ShapeButton to allow a different set of normal/over/down colours to be used when its toggled on and pushed the changes to the develop branch. Hopefully it’s what you needed but let me know if not.


Thanks! That seems to have sorted my problem.
I’ve not tried out the new method yet but I’m sure it’s more flexible now.

same issue with DrawableButton : it does not reflect the toggled state with on or down colours.

When you set the Images in DrawableButton::setImages(), you need to set a different version of the image for each state. The default is to use the same Image for all states…

What I usually do, is work with Image::desaturated() or Image::multiplyAllAlphas (0.5) or similar.

A feature request could be to add a blend over colour, if no extra image is given… and there is a typo in the docs at ColourIds of DrawableButton: “A set of colour IDs to use to change the colour of various aspects of the link.”

ah, right, it’s the “normalOn” image that is used for the toggled state. i was expecting the down image for a moment. sorry for the noise then!

It’s still the same, right ? setClickingTogglesState doesn’t do anything …

Ran into the same issue so thought I would share my findings if anyone else comes across this.

You have to set separate on colours using .setOnColours and also make sure you call shouldUseOnColours(true).