Using Value Tree in subcomponents

Hi all,
I have built a GUI for a plugin that is based on subcomponents and I want to use the Value Tree inside each subcomponent so I can attach my sliders. I can’t understand how to pass the value tree state to the subcomponents. Can anyone suggest a way?

My guess
Let’s say I have a slider inside a header sucomponent, and this header is in a class:

class HeaderComponent : public Component
{
public:
    
    typedef AudioProcessorValueTreeState::SliderAttachment SliderAttachment;
    
    enum
    {
        paramControlHeight = 40,
        paramLabelWidth    = 80,
        paramSliderWidth   = 350
    };
    
    HeaderComponent (AudioProcessorValueTreeState& valueTreeState)
    {
        
        addAndMakeVisible (globalGainSlider);
        globalGainAttachment.reset (new SliderAttachment (valueTreeState, "global_gain", globalGainSlider));
        
    }

    void paint (Graphics& g) override
    {
        g.fillAll(Colours::lightblue);
        
        Rectangle<int> headerArea (getLocalBounds());
        g.setColour (Colours::greenyellow);
        g.drawRect (headerArea,3.0f);
        
    }
    
    void resized() override
    {
        auto sliderLeft = paramLabelWidth + 10;
        globalGainSlider.setBounds (sliderLeft, 140, getWidth() - sliderLeft - 10, 20);
    
    }
    
private:

    Slider globalGainSlider;
    std::unique_ptr<SliderAttachment> globalGainAttachment;
};

My guess is to pass the value tree state in the constructor of the component: HeaderComponent (AudioProcessorValueTreeState& valueTreeState) . However, I can’t understand how correctly pass it from the PluginEditor.cpp, my (wrong) attempt is:

    #include "PluginProcessor.h"
#include "PluginEditor.h"

//==============================================================================
ProvaEditorSubcomponentsAudioProcessorEditor::ProvaEditorSubcomponentsAudioProcessorEditor (ProvaEditorSubcomponentsAudioProcessor& p, AudioProcessorValueTreeState& vts)
    : AudioProcessorEditor (&p), processor (p), valueTreeState (vts)
{
    
    header = HeaderComponent(vts);
    addAndMakeVisible (header);
    
    setSize (800, 800);
}

ProvaEditorSubcomponentsAudioProcessorEditor::~ProvaEditorSubcomponentsAudioProcessorEditor()
{
}

//==============================================================================
void ProvaEditorSubcomponentsAudioProcessorEditor::paint (Graphics& g)
{

    g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
}

void ProvaEditorSubcomponentsAudioProcessorEditor::resized()
{
    auto area = getLocalBounds();
    auto headerHeight = 300;
    header.setBounds(area.removeFromTop(headerHeight));
}

The file PluginEditor. h is

#pragma once

#include "../JuceLibraryCode/JuceHeader.h"
#include "PluginProcessor.h"
#include "HeaderComponent.h"
#include "Panel1Component.h"




//==============================================================================
class ProvaEditorSubcomponentsAudioProcessorEditor  : public AudioProcessorEditor
{
public:
    
    typedef AudioProcessorValueTreeState::SliderAttachment SliderAttachment;
    
    ProvaEditorSubcomponentsAudioProcessorEditor (ProvaEditorSubcomponentsAudioProcessor& parent, AudioProcessorValueTreeState& vts);
    ~ProvaEditorSubcomponentsAudioProcessorEditor();

    //==============================================================================
    void paint (Graphics&) override;
    void resized() override;

private:

    ProvaEditorSubcomponentsAudioProcessor& processor;
    
    AudioProcessorValueTreeState& valueTreeState;
    
    
    HeaderComponent header;
    Panel1Component panel1;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProvaEditorSubcomponentsAudioProcessorEditor)
};

Maybe try passing a ValueTree into the constructor instead of AudioProcessorValueTreeState?

Hi, it can’t be correct, I need to pass an AudioProcessorValueTreeState since the SliderAttachment requires it (see
https://docs.juce.com/develop/classAudioProcessorValueTreeState_1_1SliderAttachment.html )

I can’t understand the right way to pass it… any idea from the community?

@frodojedi everything looks fine in your code. What is the actual problem? What doesn’t work?

Have you read the JUCE tutorial “Saving and loading your plug-in state”? It explains where to create the AudioProcessorValueTreeState and shows how to pass it to the Editor.

You cannot assign a member like that. This line would call the copy constructor, which is disabled for Components (or should be using the JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR).

You have to supply the vts when the member is constructed. You can even do that in the header nowadays (from C++11 onwards):

class ProvaEditorSubcomponentsAudioProcessorEditor  : public AudioProcessorEditor
{
public:
// ...
private:
    ProvaEditorSubcomponentsAudioProcessor& processor;
    AudioProcessorValueTreeState& valueTreeState;

    HeaderComponent header { valueTreeState };
// ...

Just make sure, the reference is declared before it is used as argument for a member.

Hope that helps

Thanks a lot Daniel! Now it works!