# Is there a trick to restoring the Toggle state (TextButton) from the APVTS (my sliders restore fine)?

**URL:** <https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718>\
**Category:** General JUCE discussion\
**Created:** [April 7, 2023, 7:51pm UTC](https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718 "2023-04-07T19:51:45Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![TrustedSteed](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/trustedsteed/32/13862_2.png) [@TrustedSteed](https://forum.juce.com/u/TrustedSteed)\
**Post date:** [April 7, 2023, 7:51pm UTC](https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718/1 "2023-04-07T19:51:46Z")

</div>

I’m having an issue restoring my Toggle Buttons (TextButtons).

In `getStateInformation()` I am getting the APVTS tree and the sliders restore fine to their previous value.  
But my Toggle(TExt) buttons don’t. They seem to all restore to true.  
I did a debug DGB string in `getStateInformation()` and the values all report correctly.

```auto
apvts.replaceState(tree);
mRedToggleButton_value = apvts.getRawParameterValue("redToggleButtonParameterID")->load();
mGreenToggleButton_value = apvts.getRawParameterValue("greenToggleButtonParameterID")->load();
mBlueToggleButton_value = apvts.getRawParameterValue("blueToggleButtonParameterID")->load();

```

```auto
outputstr += (mRedToggleButton_value ? " Red=True" : " Red=False");
outputstr += (mBlueToggleButton_value ? " Blue=True" : " Blue=False");
outputstr += (mGreenToggleButton_value ? " Green=True" : " Green=False");            
DBG(outputstr); //correct values shown

```

i.e. Blue is `true`, the others are `false` reported in the code above DBG string.  
But then I query the values later and they are **all** `true`!

Is there a quirk with restoring toggle states of TextButtons in JUCE that I should know about?

(I notice that if I turn a knob on my plugin UI and close the DAW, it says “Save Yes/No” but if I turn a button on or off, and close the DAW, it doesn’t offer a “Save”.)

**Extra info** … My constructor in PlginProcessor.cpp snippet:  
` mRedToggleButton_value(false), mGreenToggleButton_value(false), mBlueToggleButton_value(false)`  
PluginEditor.cpp constructor snippet:  
`mRedToggleButton_buttonAttachment(audioProcessor.apvts, "redToggleButtonParameterID", mRedToggleButton), //same for blue and green`

---

<div class="post-metadata">

**Author:** ![refusesoftware](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/refusesoftware/32/20561_2.png) [@refusesoftware](https://forum.juce.com/u/refusesoftware)\
**Post date:** [April 8, 2023, 8:27pm UTC](https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718/2 "2023-04-08T20:27:14Z")

</div>

Which OS, plugin format, and DAW is this happening in?

---

<div class="post-metadata">

**Author:** ![TrustedSteed](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/trustedsteed/32/13862_2.png) [@TrustedSteed](https://forum.juce.com/u/TrustedSteed)\
**Post date:** [April 8, 2023, 8:54pm UTC](https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718/3 "2023-04-08T20:54:47Z")

</div>

Windows, vst3, Reaper.

---

<div class="post-metadata">

**Author:** ![TrustedSteed](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/trustedsteed/32/13862_2.png) [@TrustedSteed](https://forum.juce.com/u/TrustedSteed)\
**Post date:** [April 10, 2023, 6:22pm UTC](https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718/4 "2023-04-10T18:22:35Z")

</div>

Does the APVTS store only **float values**? I’ve been assuming that it can store Booleans too…  
`mRedToggleButton_value = apvts.getRawParameterValue("redToggleButtonParameterID")->load();`  
So 1.0f, 0.0f for true, false…?

I am using `mRedToggleButton.setToggleState(true, juce::NotificationType::dontSendNotification);` But I am getting the feeling that its not actually changing the value in the APVTS… is this feeling correct?

I read other suggestions I should use to set the value, e.g. `setValueNotifyingHost` Is this the solution I should be looking at?

---

<div class="post-metadata">

**Author:** ![refusesoftware](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/refusesoftware/32/20561_2.png) [@refusesoftware](https://forum.juce.com/u/refusesoftware)\
**Post date:** [April 10, 2023, 7:17pm UTC](https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718/5 "2023-04-10T19:17:21Z")

</div>

APVTS holds a bunch of RangedAudioParameters, which does use float values under the hood, and the different parameter types are all subclasses of that. (See the inheritance diagram for [RangedAudioParameters](https://docs.juce.com/master/classRangedAudioParameter.html) to see how they relate.) But it shouldn’t be a problem to access that as a bool.

I’m a little unclear about what your code is doing and what you expect it to do. Is `mRedToggleButton_value` just a temporary value that you’re using to generate DBG test strings with, or is it a class member that you’re accessing over time? Is it a `bool` or a `Value` or something else?

> [@TrustedSteed](#):
>
> But then I query the values later and they are **all** `true`!

Later, like when? After toggling the buttons onscreen?

---

<div class="post-metadata">

**Author:** ![refusesoftware](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/refusesoftware/32/20561_2.png) [@refusesoftware](https://forum.juce.com/u/refusesoftware)\
**Post date:** [April 10, 2023, 7:20pm UTC](https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718/6 "2023-04-10T19:20:26Z")

</div>

> [@TrustedSteed](#):
>
> I read other suggestions I should use to set the value, e.g. `setValueNotifyingHost` Is this the solution I should be looking at?

No, the [ButtonAttachment](https://docs.juce.com/master/classAudioProcessorValueTreeState_1_1ButtonAttachment.html) should handle the connection between the APVTS value and the Button component. You don’t need to involve `setValueNotifyingHost`.

---

<div class="post-metadata">

**Author:** ![TrustedSteed](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/trustedsteed/32/13862_2.png) [@TrustedSteed](https://forum.juce.com/u/TrustedSteed)\
**Post date:** [April 10, 2023, 7:42pm UTC](https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718/7 "2023-04-10T19:42:13Z")

</div>

I toggle the buttons on the UI and they toggle fine. I have three buttons, Red, Green, Blue. When I click the Red button the Green and Blue turn off. And the same behavior for Green and Blue when I click them.

When I close the DAW and reload the plugin, all the buttons are turned on (true), and all light up. So somehow the togglestate() of my button is either not being saved to the APVTS, or not being saved out to the plugin APVTS stream on exit. But I doubt the latter because my slider states work.

```auto
void myplugin::buttonClicked(juce::Button* button)
{

    if (button == &mBlueToggleButton)
    {
        mGreenToggleButton.setToggleState(false, juce::NotificationType::dontSendNotification);
        mRedToggleButton.setToggleState(false, juce::NotificationType::dontSendNotification);
        mBlueToggleButton.setToggleState(true, juce::NotificationType::dontSendNotification); 
    }
    else if (button == &mGreenToggleButton)
    {
        mBlueToggleButton.setToggleState(false, juce::NotificationType::dontSendNotification);
        mRedToggleButton.setToggleState(false, juce::NotificationType::dontSendNotification);
        mGreenToggleButton.setToggleState(true, juce::NotificationType::dontSendNotification); 

    }
    else if (button == &mRedToggleButton)
    {
        mBlueToggleButton.setToggleState(false, juce::NotificationType::dontSendNotification);
        mGreenToggleButton.setToggleState(false, juce::NotificationType::dontSendNotification);
        mRedToggleButton.setToggleState(true, juce::NotificationType::dontSendNotification); 
    }

```

(the above works to toggle my buttons on the UI)  
.h

```auto
    juce::TextButton mBlueToggleButton;
    juce::TextButton mGreenToggleButton;
    juce::TextButton mRedToggleButton;

    juce::AudioProcessorValueTreeState::ButtonAttachment mBlueToggleButton_buttonAttachment;
    juce::AudioProcessorValueTreeState::ButtonAttachment mRedToggleButton_buttonAttachment;
    juce::AudioProcessorValueTreeState::ButtonAttachment mGreenToggleButton_buttonAttachment;

```

In my Editor constructor:

```auto
    mRedToggleButton_buttonAttachment(audioProcessor.apvts, "redToggleButtonParameterID", mRedToggleButton),   
    mGreenToggleButton_buttonAttachment(audioProcessor.apvts, "greenToggleButtonParameterID", mGreenToggleButton),   
    mBlueToggleButton_buttonAttachment(audioProcessor.apvts, "blueToggleButtonParameterID", mBlueToggleButton),   

```

Also, a perhaps significant thing is that , if I alter a slider, when I quit, the DAW asks me to save. But when I alter button toggle states the DAW **does not** ask me to save. So, in theory, when I change toggle states on the buttons I don’t think the changes are being effected in the APVTS.

---

<div class="post-metadata">

**Author:** ![cpr2323](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/cpr2323/32/18682_2.png) [@cpr2323](https://forum.juce.com/u/cpr2323)\
**Post date:** [April 10, 2023, 8:32pm UTC](https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718/8 "2023-04-10T20:32:01Z")

</div>

This isn’t part of the answer to your problem, but your if/else pattern, can be reduced to just three lines.

```auto
mGreenToggleButton.setToggleState(button == &mGreenToggleButton, juce::NotificationType::dontSendNotification);
mRedToggleButton.setToggleState(button == &mRedToggleButton, juce::NotificationType::dontSendNotification);
mBlueToggleButton.setToggleState(button == &mBlueToggleButton, juce::NotificationType::dontSendNotification);
```

---

<div class="post-metadata">

**Author:** ![refusesoftware](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/refusesoftware/32/20561_2.png) [@refusesoftware](https://forum.juce.com/u/refusesoftware)\
**Post date:** [April 10, 2023, 11:03pm UTC](https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718/9 "2023-04-10T23:03:43Z")

</div>

Ah, OK, I think I see the problem.

However, first, another bit of advice…

Now that I see you’re trying to do a set of buttons where only one at a time is activated, it makes me wonder if there should really be three different parameters. Is it really just describing three states of a single parameter? If so, better to express that as an AudioParameterChoice (or AudioParameterInt), rather than using 3 different parameters for it.

Not only will that approach result in clearer and more maintainable code, it will also not break once you load this in a DAW and expose its parameters to automation. Because, while it’s possible in your Editor to reinforce this group of 3 buttons having only one at a time in its “true” state, what would happen in a DAW’s automation lanes if the user set two of them to true at the same time?

Also, rather than use that verbose branching code in your `myplugin::buttonClicked` method, consider using [Button::setRadioGroupId](https://docs.juce.com/master/classButton.html#a29adebc6ed27829f75b69c6ba40ef958), which can do the same thing for you just by calling it on each button (using the same group ID).

Anyways… I suspect the issue here is that that JUCE Buttons are not “toggleable” by default. So your attachment class (connecting the button and APVTS) is probably fine, it’s just that when you call e.g. `mGreenToggleButton.setToggleState`, it doesn’t do anything.

So the solution to that would be to call `setToggleable (true)` on each button in the Editor’s ctor. And you may need to call `setClickingTogglesState (true)` as well, if you take my advice to replace your `myplugin::buttonClicked` method with the use of [Button::setRadioGroupId](https://docs.juce.com/master/classButton.html#a29adebc6ed27829f75b69c6ba40ef958).

---

<div class="post-metadata">

**Author:** ![TrustedSteed](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/trustedsteed/32/13862_2.png) [@TrustedSteed](https://forum.juce.com/u/TrustedSteed)\
**Post date:** [April 11, 2023, 1:21pm UTC](https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718/10 "2023-04-11T13:21:24Z")

</div>

–solution below–

---

<div class="post-metadata">

**Author:** ![TrustedSteed](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/trustedsteed/32/13862_2.png) [@TrustedSteed](https://forum.juce.com/u/TrustedSteed)\
**Post date:** [April 11, 2023, 2:00pm UTC](https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718/11 "2023-04-11T14:00:02Z")

</div>

The toggle button issue is solved.

When I implemented `addListener()` and took over the `buttonclicked()` method, this meant I overrode the code that updated the APVTS, so the listener was not updating the APVTS.

So I had to manually update the APVTS, by putting some code in `buttonclicked()` : ` audioProcessor.updateRedBlueGreenToggles(0.0f, 0.0f, 1.0f);`

Then in my audioProcessor, manually update the APVTS:

```auto
void myPluginAudioProcessor::updateRedBlueGreenToggles(float redValue, float greenValue, float blueValue)
{
    apvts.getParameter("redToggleButtonParameterID")->setValueNotifyingHost(redValue);
    apvts.getParameter("greenToggleButtonParameterID")->setValueNotifyingHost(greenValue);
    apvts.getParameter("blueToggleButtonParameterID")->setValueNotifyingHost(blueValue);
}

```

I am assuming `NotifyingHost` is OK. It seems to work - I exit the plugin and come back in and all is restored correctly.  
(I’ll change the 0.0 1.0f to true false later, and may look at the AudioParameterChoice)

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [April 11, 2023, 8:05pm UTC](https://forum.juce.com/t/is-there-a-trick-to-restoring-the-toggle-state-textbutton-from-the-apvts-my-sliders-restore-fine/55718/12 "2023-04-11T20:05:02Z")

</div>

> [@TrustedSteed](#):
>
> When I implemented `addListener()` and took over the `buttonclicked()` method, this meant I overrode the code that updated the APVTS, so the listener was not updating the APVTS.

That’s actually not what happens. The addListener adds to a ListenerList, which will send the event to all listeners in a not guaranteed order. And the ButtonAttachment also listens to that ListenerList.  
Your listener must have had a different adverse side effect.
