Hello,
I liked the PropertiesDemo example in the Juce Demo, but stuck with the choice made of adding pointers of class DemoSliderPropertyComponent to an array of PropertyComponent*.
Could someone be kind enough to illustrate the way we can get callback from the sliders in this specific example ?
The DemoSliderPropertyComponent
class in the JUCE Demo inherits from SliderPropertyComponent
so you can access its protected
Slider
member and attach a listener to it. You’ll need to inherit from Slider::Listener
and then call slider.addListener (this)
in the constructor. Then implement the listener’s sliderValueChanged()
method, which will be called whenever the Slider
value changes.
This is clear for me. What is less clear is how to get it working in the context of the PropertiesDemo example. I would really need that for a better understanding.
In the example, demoSliderComponents are added to an array of PropertyComponent. When I create a demoSliderComponent, I can’t do slider.addListener with this newly added component.
Let’s say I do the following:
Considering displayLimits is defined like this, in order for being able to be added to the main propertyPanel with the function addSection() :
Array<PropertyComponent*> displayLimits;
Then when I write the following code:
DemoSliderPropertyComponent* s = new DemoSliderPropertyComponent ("Something rich and strange");
displayLimits.add (s);
s->addListener(this);
(‘this’ implementing Slider::Listener),
I get: “No member named addListener in DemoSliderPropertyComponent”
Well no that won’t work as DemoSliderPropertyComponent
isn’t a Slider
, it just contains one as a child component. If you wanted to do something like your example, you’d need to expose its Slider
as a public member or have getter method then you could do:
s->slider.addListener (this);
What are you trying to achieve though? You’ll probably be better off just using a SliderPropertyComponent
to control a Value
object that you can listen to. So you’d have some member variables like this:
OwnedArray<PropertyComponent> propertyComponents;
Value valueToControl;
and then in your constructor:
valueToControl.addListener (this);
...
propertyComponents.add (new SliderPropertyComponent (valueToControl, "SliderProperty", 0.0, 1.0, 0.1));
Now if your parent class inherits from Value::Listener
and implements its valueChanged()
method you will get a callback whenever the user moves the Slider
and changes its underlying Value
.
Thanks, that looks nice. However I tried the following and could not monitor any change from the Slider, could you tell where I got wrong ?:
class SettingsGUI : public Component, public Value::Listener, public Slider::Listener
{
public:
SettingsGUI()
{
PropertyPanel* panel = new PropertyPanel ("Project Settings");
valueToControl.addListener(this);
someSliders.add (new SliderPropertyComponent (valueToControl, "valueOfSomeKind", 0.0, 1.0, 0.1));
panel->addSection("Special", someSliders, true);
}
void valueChanged (Value &value) override
{
DBG(" valchgd: " << value.toString());
}
private:
Array<PropertyComponent*> someSliders;
};
Here is a really minimal working example:
//==============================================================================
class MainContentComponent : public Component,
private Value::Listener
{
public:
//==============================================================================
MainContentComponent()
{
valueToControl.addListener (this);
sliderProps.add (new SliderPropertyComponent (valueToControl, "Slider", 0.0, 1.0, 0.01));
propPanel.addSection ("Sliders", sliderProps);
addAndMakeVisible (propPanel);
setSize (600, 400);
}
~MainContentComponent() {}
void paint (Graphics& g) override
{
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
}
void resized() override
{
propPanel.setBounds (getLocalBounds().reduced (5));
}
private:
void valueChanged (Value& v) override
{
DBG ("Value changed");
}
Value valueToControl;
Array<PropertyComponent*> sliderProps;
PropertyPanel propPanel;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};
Well, thanks and sorry for my last complaint: I don’t why, but my own code was working, in fact.
While we are getting to the core of the question: how do I distinguish in this example, which slider has issued the value (if I add more sliders) ?
The valueChanged()
callback is called with a reference to the Value
that has been modified as its argument, so you can compare this to your Value
members to determine which has changed.
Great, that worked!
I am not used to Values, so did’nt know the easiest way.
Thanks