Custom buttonClicked method

I have a class, DrumButton, that derives from TextButton. This class therefore can be ‘listened to’ like any other button that inherits from the Button superclass. I’d like to use the onClicked() method with DrumButton.

I add the MainComponent as a listener to each DrumButton as well as some other initial setup as follows…

	auto count = buttonCollection.myButtons.size();
	for (DrumButton* button : buttonCollection.myButtons)
	{
		addAndMakeVisible(button);
		button->setBounds(window.removeFromLeft(window.getWidth() / count));
		button->addListener(this);
		count--;
	}

Then override the virtual buttonClicked() method of the Listener

void MainComponent::buttonClicked(Button* button)
{
	//I would like to access a property of DrumButton here to assign a vlaue to '???'
	button->onClick = [this]()
	{
		const auto message = generateNoteMessage(???);
		auto timeCode = calculateTimeCode(message.getTimeStamp());
		addMidiMessageToList(message, timeCode);
	};
}

This above works great - but I would like to access some property of DrumButton inside the buttonClicked method, which is not possible because it takes a Button as it’s argument.

Is there anyway to allow buttonClicked to accept a class derived from Button? Or is there another way to accomplish this?

There are two methods, one is dynamic_cast and the other to set custom properties, which is supported by all Components:

  1. auto* drumButton = dynamic_cast<DrumButton*> (button); - but be careful, if the button is not actually a DrumButton, this will return a nullptr.

  2. Add a number to the button using the Component::getProperties():
    In add buttons: button->getProperties().set ("Note", 64);
    In buttonClicked: int num = button->getProperties().getWithDefault ("Note", 0);

Hope that helps…

1 Like

Awesome - exactly what I was looking for :grinning: plus a little extra too.

As always, thank you so much!

Also, you are combing two methods doing the same thing, ie. using a button listener and using the onClick callback. Don’t put an onClick assignment in the buttonClicked method.You want to do one or the other:

for (DrumButton* button : buttonCollection.myButtons)
{
    addAndMakeVisible(button);
    button->setBounds(window.removeFromLeft(window.getWidth() / count));
    button->addListener(this);
              OR
    button->onClick = [this]()
      {
          const auto message = generateNoteMessage(???);
          auto timeCode = calculateTimeCode(message.getTimeStamp());
          addMidiMessageToList(message, timeCode);
      };
    count--;
}
1 Like

Yes you’re right, I did realize this last night :slight_smile: