DrawableButton Image with Text Label tweak


I found it was nice to be able to have an unscaled image alongside a text label with my DrawableButton. Rather than fiddle with button sizes to try and find the magical combination that would do this, it turns out to be a VERY easy little add…

class JUCE_API  DrawableButton  : public Button
    enum ButtonStyle
        ImageFitted,                /**< The button will just display the images, but will resize and centre them to fit inside it. */
        ImageRaw,                   /**< The button will just display the images in their normal size and position.
                                         This leaves it up to the caller to make sure the images are the correct size and position for the button. */
        ImageAboveTextLabel,        /**< Draws the button as a text label across the bottom with the image resized and scaled to fit above it. */
		ImageRawAboveTextLabel,  /** As above but image is drawn normal size */
        ImageOnButtonBackground     /**< Draws the button as a standard rounded-rectangle button with the image on top. */


void DrawableButton::paintButton (Graphics& g,
bool isMouseOverButton,
bool isButtonDown)
Rectangle imageSpace;

if (style == ImageOnButtonBackground)
    const int insetX = getWidth() / 4;
    const int insetY = getHeight() / 4;

    imageSpace.setBounds (insetX, insetY, getWidth() - insetX * 2, getHeight() - insetY * 2);

    getLookAndFeel().drawButtonBackground (g, *this,
    g.fillAll (getBackgroundColour());

    const int textH = (style == ImageAboveTextLabel || style == ImageRawAboveTextLabel)
                        ? jmin (16, proportionOfHeight (0.25f))
                        : 0;

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

    imageSpace.setBounds (indentX, indentY,
                          getWidth() - indentX * 2,
                          getHeight() - indentY * 2 - textH);

    if (textH > 0)
        g.setFont ((float) textH);

        g.setColour (Colours::black.withAlpha (isEnabled() ? 1.0f : 0.4f));
        g.drawFittedText (getName(),
                          2, getHeight() - textH - 1,
                          getWidth() - 4, textH,
                          Justification::centred, 1);

g.setImageResamplingQuality (Graphics::mediumResamplingQuality);
g.setOpacity (1.0f);

const Drawable* imageToDraw = 0;

if (isEnabled())
    imageToDraw = getCurrentImage();
    imageToDraw = getToggleState() ? disabledImageOn
                                   : disabledImage;

    if (imageToDraw == 0)
        g.setOpacity (0.4f);
        imageToDraw = getNormalImage();

if (imageToDraw != 0)
    if (style == ImageRaw || style == ImageRawAboveTextLabel)
        imageToDraw->draw (g);
        imageToDraw->drawWithin (g,



i am trying to make a modified version of this too that allows positioning of the text to the left/right/top/bottom of the image, as in the REALbasic (and other ) bevelbuttoncontrols.

Only trouble is - as i said in a posting here:


that when i attempt to make a copy of the original juce Drawablebutton code, - even if i just rename the button class and .h, .cpp files there seem to be these errors i just cant fathom the solution for.

once i crack this and have written the code i’ll be glad to submit it to the community here or to jules.


Sounds like you’ve done something odd…Did you inherit your Bevel class from DrawableButton ? Button ?

Looks like you might have inherited from DrawableButton, which you can’t do as paintButton isn’t virtual.

Why not post your .h and .cpp files, I bet its something simple


sure it is


No. I made a copy of the DrawableButton .h and .cpp files - renamed them to BevelButton.h/.cpp

and changed the name DrawableButton to BevelButton in all the places in the copied source wherever found.

Thus i inherit from Button and not DrawableButton


Well, you can’t just take entire files from inside the juce project and put them into your app’s project - the library code puts itself into the juce namespace, and includes special internal headers, so that’s not going to work outside the lib itself. Sure, take a copy of the guts of the class, but obviously you have to edit its headers a bit.


Ok, In your original thread your linker errors refer to both…





the files were renamed BevelButton.h and BevelButton.cpp.

the class inside the files was renamed Bevel_Button ( after trying BevelButton just to ensure it wasnt some strance case issue )

i have initially left these new files in the same place as the originals - so they should just behave exactly as a new JUCE namespace control. i did go through the headers carefully, but i cannot see anything wrong.

i sent you the files i believe. maybe youll see whats wrong,


That’s not how the code is supposed to be used - why on earth would you try to add your class to the juce library rather than just putting it in your own code? Just put it in your own app, in your own namespace, and the problem will go away…