A more flexible DrawableButton?


#1

Hello Jules,

I have tried without success to reduce the size of the border that a DrawableButton puts around its Image when using the ImageOnButtonBackground style. Looking at the code in DrawableButton::resized(), I see that the minimum allowed border is 1/4 of the button dimension per side.

I also tried deriving a class, overriding resized(), and apart from the fact that the way to access the various images for each state is quite annoying without some sort of getImage(index) method, this does not work, since DrawableButton::buttonStateChanged() explicitly calls DrawableButton::resized() instead of just resized().

Yes, I could write an almost identical class that does what I need, but would you consider making DrawableButton a little more customizable?

Thanks
 


#2

What would you suggest adding to the class that would do what you need?


#3

A minimal modification that would not break existing code and would consent a derived class to change the layout, would be to eliminate the explicit reference to DrawableButton::resized() inside buttonStateChanged():

void DrawableButton::buttonStateChanged()
{
...

    if (imageToDraw != currentImage)
    {
        removeChildComponent (currentImage);
        currentImage = imageToDraw;

        if (currentImage != nullptr)
        {
            currentImage->setInterceptsMouseClicks (false, false);
            addAndMakeVisible (currentImage);
            /*DrawableButton::*/resized();
        }
    }

...
}

Another nice change that would make the 'edgeIndent' variable more effective would be:

void DrawableButton::resized()
{
...

        else
        {
            Rectangle<int> imageSpace;

            const int indentX = jmin (edgeIndent, proportionOfWidth  (0.3f));
            const int indentY = jmin (edgeIndent, proportionOfHeight (0.3f));
            

           if (style == ImageOnButtonBackground)
            {
        /*
                imageSpace = getLocalBounds().reduced (jmax (getWidth()  / 4, indentX),
                                                       jmax (getHeight() / 4, indentY));
        */
                imageSpace = getLocalBounds().reduced(indentX, indentY);

            }

...

}

Although this would break existing code.


#4

Ok, I've cleaned up the code a bit and added a virtual method getImageBounds() that will probably do the job for you.


#5

I don't' see the commit in git yet. but (if it is not what you've done) i think it would be better to move the resized() and getImageBounds() into the lookandfeel no?


#6

Whoops, forgot to push. Yeah, it could be argued that it belongs in the L+F but TBH this all seems like a lot of fuss to me over such a simple class. If you have a custom button that deviates dramatically from it then it probably belongs in a class of its own.


#7

Thank you Jules.