Custom Button best approach (Add Button)

Hello,

I successfully managed to add a custom look and feel to all my TextButtons and customised them in the custom lnf class. Now I want to create a Button with a symbol in it. To be more precise, I want to create a custom Add Button. It should look like my Textbuttons but instead of a text it should have a Big Plus symbol in there. I could just write a plus symbol in there but for a Playbutton that’s not really possible. So I was thinking instead of using an imageButton, which I use at the moment, is it possible to create my own button which inherits from Button or even better TextButton? Then I think if it inherits from Textbutton and I attach the same lnf to it as to the others it should already have the implemented mask so that I just need to paint the plus symbol in the paint method. I already created an addbutton class which inherits from TextButton but I wasn’t able to draw anything in the button. Does somebody see the issue?

/*
  ==============================================================================

    AddButton.h
    Created: 5 Jul 2024 11:31:49am
    Author:  lazlo

  ==============================================================================
*/

#pragma once

#include <JuceHeader.h>

//==============================================================================
/*
*/
class AddButton  : public juce::TextButton
{
public:
    AddButton() {}

    AddButton(const juce::String& name) {}

    ~AddButton() override {}

    void paintButton(juce::Graphics g, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown)
    {
        auto& lf = getLookAndFeel();

        lf.drawButtonBackground(g, *this,
            findColour(getToggleState() ? buttonOnColourId : buttonColourId),
            shouldDrawButtonAsHighlighted, shouldDrawButtonAsDown);

        //lf.drawButtonText(g, *this, shouldDrawButtonAsHighlighted, shouldDrawButtonAsDown);

        //g.drawRect(getLocalBounds().reduced(20, 0), 1);
        g.setColour(juce::Colours::black);
        g.fillRect(getLocalBounds().reduced(20, 0));
    }

    void colourChanged() override { repaint(); }

    enum ColourIds
    {
        buttonColourId = 0x1000100,  /**< The colour used to fill the button shape (when the button is toggled
                                                           'off'). The look-and-feel class might re-interpret this to add
                                                           effects, etc. */
        buttonOnColourId = 0x1000101,  /**< The colour used to fill the button shape (when the button is toggled
                                                           'on'). The look-and-feel class might re-interpret this to add
                                                           effects, etc. */
        textColourOffId = 0x1000102,  /**< The colour to use for the button's text when the button's toggle state is "off". */
        textColourOnId = 0x1000103   /**< The colour to use for the button's text.when the button's toggle state is "on". */
    };
private:
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AddButton)
};

Could this approach worl in general or am I on a wrong path here? I kind of have the feeling the the lnf is blocking the paintButton() function, but I thought actually since I overrite it, it is possible somehow. Maybe somebody can explain that to me.

On the other hand, i thought then, well I could do another custom LnF but I feel like it’s not really DRY since I have to rewrite everything from the other LnF and only change the paint and actually change one line.

Or should I rather go with the image button? I feel like they are not so great if I zoom in or out and just painting these really simple symbols isn’t really complicated.

What approach would you recomment me?

I think you can create a LookAndFeel class and override drawButtonText.

In the overridden implementation, I would make the plus symbol larger with getFont(<insert required plus symbol font size here>)

I would then set an object of that LookAndFeel to your TextButton object.

Sounds pretty quick actually. I’m gonna give that a try!

The only thing I don’t know, is how would you suggest making a preference button with a gear wheel? Like not all my Buttons with symbols have symbols which are similar to an existing char. I thought I could maybe change in that class the paint method and paint a gear wheel or whatever symbol according to the purpose of the button.

My question was more aiming for a general approach to create Buttons with symbols instead of text and that I actually would like to use my existing LnF and only change the text part to a painted symbol.
Do you have an Idea why the changes in the paintButton method is not being visible?

Thank you for your answer :slight_smile:

I may have misunderstood, but you could use an ImageButton and add some bitmaps of your required symbols.

Yes thinking about it, I think it should be an Imagebutton. I tried around a little. So I made the button once with an Imagebutton and then once I painted the images in the button. Painting the content is not easy, especially with more complex figures. So I think the best approach is to use an Imagebutton and adjust my look and feel, that the imagebuttons are getting the same mask as my textbuttons.
In my last questions, I saw it from another point. I think this comes from, that I struggle a bit making use of a custom Look and Feel. I started using the Look And Feel with changing the Look of my Textbuttons, Checkboxes and Sliders. Now I face the first time that I want to change the appearance of other buttons, too - the imagebuttons. My mistake was that I thought I have to rethink the whole button, but now after thinking about it again, it should be much easier to add the look and feel of the textbutton to the look and feel of the imagebutton, by implementing in my custom look and feel the override for the drawImageButton method.

Thanks for repointing me to the imagebutton. Your answer made me think about my approach again and then I realised…