No appropriate default constructor available when trying to create a toggleable button

Hey, I’ve been trying to implement my own custom graphics for a buttons / sliders in my plugin. I’ve been trying to write my own bypass button but i keep getting the error "juce::BypassButton": No appropriate default constructor available when i try to use it in my PluginEditor.h file.

Here’s the code inside my StyleSheet.h file for the button.

class BypassButton : public juce::ToggleButton
    {

	public:
		BypassButton(const String& name) : juce::ToggleButton(name)
		{
			setLookAndFeel(&mainButtonLookAndFeel);
		}

		~BypassButton()
		{
			setLookAndFeel(nullptr);
		}

	private:
		class BypassButtonLookAndFeel : public LookAndFeel_V4
		{
		public:
			BypassButtonLookAndFeel()
			{
				image = ImageCache::getFromMemory(BinaryData::Toggle_png, BinaryData::Toggle_pngSize);
                
				// image is vertical strip, each frame is 1/2 of the height
				// 0 = off, 1 = on
			}

			void drawTickBox(Graphics& g, Component& component,
                float x,
                float y,
                float w,
                float h,
                bool ticked,
                bool isEnabled,
                bool isMouseOverButton,
                bool isButtonDown) override
			{
				const auto frames = 2;
				const auto frameId = static_cast<int>(ticked);

				g.drawImage(image,
					x,
					y,
					w,
					h,
					0,
					frameId * image.getHeight() / frames,
					image.getWidth(),
					image.getHeight() / frames);
			}

		private:
			Image image;
            
			JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(BypassButtonLookAndFeel)
		} mainButtonLookAndFeel;

		JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(BypassButton)
	};

Any help would be awesome. Thanks!

In your derrived class you only implemented a constructor taking const String& (mind the missing juce:: namespace… intentional?)
When you use your class, you need to supply a string either as default argument or in the initialiser list of the containing class:

// member:
BypassButton bypassButton {"Bypass"};
1 Like

Thanks for that! I didn’t think i had to do that since my custom sliders just worked!
BTW, is this just a thing for ToggleButtons or will it apply to other things that inherit from the Button class?

(also i have the whole file contained in a namespace juce thingy so I can avoid writing juce:: 100s of times)

I would recommend not to add your symbols to the juce namespace. You are provoking name clashes, which is why the namespace was added in the first place.
If you must you can import the namespace using namespace juce, but even this might one day fall on your feet.

You would get this error because you are trying to create your BypassButton by calling BypassButton() somewhere, but you have only provided a BypassButton(const String& name).

When you ask if this is a ToggleButton issue, I would say no, instead it is a BypassButton issue because of the missing default constructor implementation

If you look at the ToggleButton class, it has 2 constructors. One that takes no arguments, and one that takes a string.

You can mimic that here, if you don’t want to have to provide a string.

This isn’t a button thing, but a c++ thing. You can’t default construct a class without implementing a default constructor (one that takes no arguments).

You could also save space and leave the one constructor you have but make it

BypassButton(const String& name = “”) : juce::ToggleButton(name)

1 Like

Ok, its broke again (not your fault lol), this is the new version with the whole namespace juce thing removed to avoid shooting my foot in the future. I’m now getting the error No instance of constructor "juce::ToggleButton::ToggleButton" matches the argument list which is kinda confusing me.

EDIT: I got it to work! just changed this tiny bit here.

	BypassButton() : juce::ToggleButton
	{
		setLookAndFeel(&mainButtonLookAndFeel);
	}

Changed this to

	BypassButton() : juce::ToggleButton("Bypass")
	{
		setLookAndFeel(&mainButtonLookAndFeel);
	}

This is the older not working code


class BypassButton : public juce::ToggleButton
{

public:
    BypassButton() : juce::ToggleButton
	{
		setLookAndFeel(&mainButtonLookAndFeel);
	}

	~BypassButton()
	{
		setLookAndFeel(nullptr);
	}

private:
	class BypassButtonLookAndFeel : public juce::LookAndFeel_V4
	{
	public:
		BypassButtonLookAndFeel()
		{
			image = ImageCache::getFromMemory(BinaryData::Toggle_png, BinaryData::Toggle_pngSize);
                
			// image is vertical strip, each frame is 1/2 of the height
			// 0 = off, 1 = on
		}

		void drawTickBox(Graphics& g, Component& component,
            float x,
            float y,
            float w,
            float h,
            bool ticked,
            bool isEnabled,
            bool isMouseOverButton,
            bool isButtonDown) override
		{
			const auto frames = 2;
			const auto frameId = static_cast<int>(ticked);

			g.drawImage(image,
				x,
				y,
				w,
				h,
				0,
				frameId * image.getHeight() / frames,
				image.getWidth(),
				image.getHeight() / frames);
		}
        

	private:
		Image image;
            
		JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(BypassButtonLookAndFeel)
	} mainButtonLookAndFeel;

	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(BypassButton)
};

I’m a bit new to C++ so bear with my dumbness and thanks for the help.

This would have worked too

BypassButton() : juce::ToggleButton()

Or leaving it out entirely, as you now have default constructors, no need to explicitly call through to the bases constructor if you don’t need to.

If you don’t want to mess around with the string parameter initialization of the constructor, leave it empty, and then set the name later with setName(name)

In this constructor you are attempting to construct the juce::ToggleButton as well, this means that you need to match one of the constructors found in JUCE: ToggleButton Class Reference

If you are curios about the c++ details, search around for c++ constructors and initializer list. You are usuing an initializer list for BypassButton : juce::ToggleButton() the : is a sign that this is happening

That’s great info, thanks for that. I’ve been reading the docs all day but a lot of it is new to me since im a c++ newbie. Any advice for understanding it better?

I often see people recommending Cherno videos (for C++ topics) from Youtube as well as The Audio Programmer (C++ and audio topics) from Youtube. There are many examples/tutorials on the JUCE website as well.

The more exposure you get the better! Don’t let the struggles get you down, happens to everyone. I think a stronger c++ understanding will help you sort out some of the mysterious error messages quicker

1 Like

As a side note: every button can be turned into a toggle button by calling

setClickingTogglesState (true);

It seems to me you are not going to use that string from ToggleButton in your LookAndFeel anyway, in which case you can inherit juce::Button and implement the abstract functions instead.

1 Like