setVisible on pass by reference components very slow

I have a group of linked buttons that control the visibility of two other components called panel components. The group of linked buttons is a child component of a parent which is called a controller component. The group of linked buttons has access to the two panel components as pass by reference via the controller component which has access to the two panels pass-by-reference too.

The problem is that the GUI is very slow ( a couple of seconds) whenever I try to set visibility on the panels from the group of linked buttons using setVisible().

I found a similar post here, however am not sure how this resolved the issue: Help! Button is so sloooooow to react :(

A weird thing is that I have two plugins that use exactly the same presentation code, but only one of them has no issues, yet the other does. All compiler flags are identical. The only difference is that the one that works ironically displays more content in the panels.

I also noticed that my sliders in the one that doesn’t work are also very jumpy (this isn’t a problem in the one that works). I have even set up a new project and this exhibited the same slowness.

One other thing I noticed is that the slowness would be considerably

I have no idea where else to look. Any help is much appreciated - thanks.

After further investigation, I have nailed it down to an component that I have tat contains a custom snap slider component (with it’s own look and feel) and buttons for each value on the slider. I have overrided the constructor to take a value, hopefully, this has not caused issues.

Other than that I can’t see anywhere else that would cause the slowness - I even tried to remove the buttons thinking that there were too many, however this did not reduce the slowness. I am happy to share code here if someone wouldn’t mind having a look. The component is pretty useful and offers a way to create a clickable snap slider.

To me it sounds you have some things triggering each other, wasting time, but that is a shot in the dark without the code.
I don’t know, what you mean by snap slider, but there is the interval in the NormalisableRange, that drives either a RangedAudioParameter (and it’s descendants like e.g. AudioParameterFloat), and a range in the Slider, that is set up from the AudioParameterFloat via the SliderAttachment.

I could imagine, if you now added your own snap behaviour, that this is batteling with the already present snapToValue in the range. That would explain why it appears so slow.

Maybe it’s really time to show the relevant parts of your code…

Thanks @daniel

I should explain what it is a bit more. The code below is the header file for the main component that has a custom RotaryHorizontalVerticalDrag slider component and a series of buttons for each value, represented by the OwnedArray _valueButtons, which is then populated by setValues at instantiation.

class SnapSliderComponent : public Component,
public Button::Listener,
public Slider::Listener
{
public:

    explicit SnapSliderComponent(const int);

    void resized() override;

    SnapSlider& getSlider() { return slider; }

    void setValues(Array<float>);

    Array<float> getValues(){return _values;};

private:

    int _type;

    Array<float> _values;

    SnapSlider slider;

    Label label1, label2;

    OwnedArray<PushButton> _valueButtons;

    void buttonClicked (Button* button) override;

    void sliderValueChanged (Slider * slider) override;

};

The buttons are then created and placed in resized(). The buttons use setValue to change the slider value in buttonClicked(). Additionally, the buttons are looped through to place them in front or behind the pot using the following code:

slider.setValue(button->getName().getDoubleValue());
for (auto* comp : _valueButtons)
{
    if(button == comp)button->toBehind(&slider);
    else comp->toFront(false);
}

In the same way sliderValueChanged is called to reposition the buttons:

for (auto* comp : _valueButtons)
{
    if(String(slider->getValue()) == comp->getName())comp->toBehind(slider);
    else comp->toFront(false);
}

The SnapSlider class extends the Slider class and overrides the snapValue function so that values are snapped when the rotary slider is dragged. The getSlider function in the main component returns the address of the slider component which is then used to attach an APVTS parameter during instantiation. An instantiation looks like:

_gainSlider.getSlider().setKnobScale(0.1f);
_gainSlider.getSlider().setKnobBaseColour(Colours::blue);
_gainSlider.getSlider().setKnobDetail(true);
_gainSlider.getSlider().setTextColour(Colours::white);
_gainSlider.getSlider().setTickColour(Colours::transparentBlack);
_gainSlider.getSlider().setSliderStyle(SnapSlider::SliderStyle::RotaryHorizontalVerticalDrag);
_gainSlider.getSlider().setTextBoxStyle(SnapSlider::NoTextBox, true, 0, 0);
_gainSlider.setValues(controller->getGainValues());
addChildComponent(_gainSlider);
p_gainAttachment.reset (new SliderAttachment (_valueTreeState, "gain_" + String(_channel) + "_" + _band, _gainSlider.getSlider()));
_gainSlider.getSlider().addListener(this);

The PushButton class extends the TextButton class simply to adjust the look and feel.

Hopefully, these snippets shed a bit of light on how this all fits together. I have placed breakpoints all over the place and nothing is triggered whenever setVisible is called by parent GroupComponent that holds these sliders.

Thanks for your help.

Ok, so this is embarrassing @daniel,

It turned out to be the size of my SVG files that was causing the issue. The png generated for a mesh was quite large (~900KB) in one of the files and as a result 18 of these were being drawn each time. I reduced the size considerably now and the display response is fast.

Thank you.

I’m glad it turned out to have a simple cause and solution :slight_smile: