Cusom component Listener


#1

Hi, I have a custom component made of a Slider and a Label, with museListener on the Slider that changes the Label text on mouseEnter.
How can I listen to the Slider in the component from the PluignEditor.cpp?

In the PluginEditor I addAndMakeVisible the custom component like any other component of the plugin.


#2

Here’s how I did that. First, add a Listener class to your custom component. I copy&pasted the Listener from an existing class (like Slider, for example). In the public part of my custom component, I have this:

		struct Listener
	{
		Listener();
		virtual ~Listener();

		virtual void onValueChange( float newValue ) = 0;
	};

	void setListener( Listener* pTheListener ) { pListener = pTheListener; }

Then in the private section I declared a listener pointer. (I only needed one listener, so I don’t have to keep a list of listeners like most classes I’ve seen do. That’s why I have setListener above, instead of addListener.)

		Listener* pListener = NULL;

Then I added my custom component’s Listener as a public parent class for my editor:

                        public MyCustomComponent::Listener,

and overrode its callback there

virtual void onValueChange( float newValue ) override;

In the editor, after creating the custom component, I call setListener(this).

Then in the custom component, when I want to call the callback, I just check if pListener is non-NULL, and if so, then I call its onValueChange() function.

Not sure if there is an easier way for you (such as simply using the Slider sub-component’s Listener instead of making a new Listener in your custom component), but this is working for me.


#3

Oh, and to define the constructor and destructor, which don’t do anything, I just added this to the custom component’s .cpp file:

MyCustomComponent::Listener::Listener() {}
MyCustomComponent::Listener::~Listener() {}

#4

do you even need to provide a constructor? Button::Listener doesn’t…


#5

Assuming you have a structure like this:

struct CustomComponent
{
    Label label;
    Slider slider;
}; 

and you have a class like this:

struct MainComponent : public Component
{
   MainComponent();
   void resized() override;
   void paint(Graphics& g) override;
   CustomComponent customComponent;
};

you can make your MainComponent inherit from Slider::Listener and add your main class as a listener

struct MainComponent : public Component, public Slider::Listener
{
   MainComponent();
   void resized() override;
   void paint(Graphics& g) override;
   void sliderValueChanged (Slider *slider) override; // <- add this 
   CustomComponent customComponent;
}

and in your MainComponent constructor, just add your MainComponent as a listener:

MainComponent::MainComponent()
{
    customComponent.slider.addListener(this);
}

Finally, to see if that slider in your custom component was moved:

void MainComponent::sliderValueChanged (Slider *slider)
{
    if( slider == &customComponent.slider )
    {
        /* it was */
    }
}

#6

Thanks a lot @matkatmusic!
You explained me perfectly!!
I’ll try as I can tonight!


#7

np. you should probably go through the Listener/Broadcaster tutorial and some of the other tutorials for sliders and audio plugins:
https://docs.juce.com/master/tutorial_code_basic_plugin.html


#8

Your solution works great!
Thanks!