# Restoring GUI state after window is closed

**URL:** https://forum.foleysfinest.com/t/restoring-gui-state-after-window-is-closed/173
**Category:** PluginGuiMagic
**Created:** [12 September 2023 10:46 UTC](https://forum.foleysfinest.com/t/restoring-gui-state-after-window-is-closed/173 "2023-09-12T10:46:33Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![fran](https://forum.foleysfinest.com/letter_avatar_proxy/v4/letter/f/a4c791/32.png) [@fran](https://forum.foleysfinest.com/u/fran)
#### Post date: [12 September 2023 10:46 UTC](https://forum.foleysfinest.com/t/restoring-gui-state-after-window-is-closed/173/1 "2023-09-12T10:46:33Z")

</div>

Hello everyone!

I am using PGM for designing a user interface for a synth, and I am having a problem recovering the GUI state when the GUI is redrawn.

In particular, I have a combobox that fills up at runtime with filenames obtained from a user-selected directory. The ComboBox is defined in the XML. I find it using a pointer to the builder and populate it with file entries.

```auto
   if (auto* item = builder_ptr->findGuiItemWithId(GUI_IDs::models)) 
      {
      std::cout << "Found ComboBox" << std::endl;
      if (auto* combo_box =
              dynamic_cast<juce::ComboBox*>(item->getWrappedComponent())) 
        {
        combo_box->clear(false); // Remove all previous items
        int menu_idx = 1;
        for (std::string menuentry : _guiconfig.modelnames) 
          {
          combo_box->addItem(menuentry, menu_idx);
          menu_idx++;
          }

```

I can keep the list in the valueTree or a Processor-owned vector, but my question is, how can I manage to re-populate it when the plugin GUI is redrawn?

For instance, in REAPER, the plugin is redrawn every time I close and open back the plugin window, or every time I switch between plugins connected on the same track.

I know that `foleys::GuiItem` has an `update()` callback, but I cannot fetch any non-GUI related information from there.

Is there any callback that can be handled to re-populate the combobox using values from the valueTree that are visible to the Processor too?

Thanks so much!  
Fran

---

<div class="post-metadata">

### Author: ![daniel](https://forum.foleysfinest.com/user_avatar/forum.foleysfinest.com/daniel/32/5_2.png) [@daniel](https://forum.foleysfinest.com/u/daniel)
#### Post date: [12 September 2023 15:52 UTC](https://forum.foleysfinest.com/t/restoring-gui-state-after-window-is-closed/173/2 "2023-09-12T15:52:18Z")

</div>

Hi Fran,  
This is a good question. The update() is indeed the wrong place like you mentioned. That is called only when the GUI is rebuilt to set all properties from the ValueTree that declares the whole GUI machinery.

I haven’t designed any dynamic ComboBox content yet, it seems it deserves a built in interface.  
However if you look at FoleysSynth in the examples, it populates a Listbox with preset names, so it could serve as example.

Basically I would create a kind of back-end in the processor that you then publish via

```auto
magicState.createAndAddObject<FileListBackend>("files");

// and retrieve it in your bespoke GuiItem that has a combo box in update()
fileList = magicState.getObjectOfType<FileListBackend>("files");

```

That way you can add a combobox that has access to the backend in the processor.

I hope that gets you further…

---

<div class="post-metadata">

### Author: ![fran](https://forum.foleysfinest.com/letter_avatar_proxy/v4/letter/f/a4c791/32.png) [@fran](https://forum.foleysfinest.com/u/fran)
#### Post date: [15 September 2023 08:48 UTC](https://forum.foleysfinest.com/t/restoring-gui-state-after-window-is-closed/173/3 "2023-09-15T08:48:39Z")

</div>

Hey Daniel,

First of all, thank you so much for your quick response!  
It literally got me there, and it is working now 🙂

The only thing is that I am not sure I pulled it off in an elegant way.  
I have an issue with the `combobox.onChange()` lambda function that I am setting during the `GuiItem::update()` method (the factory for the combobox)

The lamba function loads a patch and needs access to the processor.

This is what I do:

```auto
combobox.onChange = [&] {
    MyProcessor *proc = (MyProcessor*)magicBuilder.getMagicState().getProcessor();
    if(proc)
    {
        const unsigned int selected_entry = combobox.getSelectedId() - 1;
        // Stop Audio Processing Thread
        proc->suspendProcessing(true);
        proc->load_patch(selected_entry);
        proc->suspendProcessing(false);
    }
};

```

Is there any other way to avoid handling the processor pointer in such a way? Should I be using a ComboBoxAttachment or a different approach to store the lamda in the valueTree (if that’s possible) instead of resetting it every single time `update()` is called?

Thank you again!  
Fran

---

<div class="post-metadata">

### Author: ![daniel](https://forum.foleysfinest.com/user_avatar/forum.foleysfinest.com/daniel/32/5_2.png) [@daniel](https://forum.foleysfinest.com/u/daniel)
#### Post date: [15 September 2023 09:14 UTC](https://forum.foleysfinest.com/t/restoring-gui-state-after-window-is-closed/173/4 "2023-09-15T09:14:37Z")

</div>

Awesome, glad you got it working so quickly!

That’s exactly how I would have did it.  
The capture is safe, because the magicBuilder and the comboBox will outlive the lambda.  
And the cast is fine, since there is only one processor type in the project.

Style-wise I would prefer auto and dynamic\_cast, but that is just aesthetics:

```auto
if (auto* proc = dynamic_cast<MyProcessor*>(magicBuilder.getMagicState().getProcessor())
{
    const auto selected_entry = combobox.getSelectedId() - 1;
    // ...
}

```

Note that I would avoid unsigned int, since it can be easier reasoned about the value.  
Imagine getSelectedId() returns 0 (which it does when nothing is selected), then it loads the path no 65535.

Cheers,  
Daniel

---

<div class="post-metadata">

### Author: ![fran](https://forum.foleysfinest.com/letter_avatar_proxy/v4/letter/f/a4c791/32.png) [@fran](https://forum.foleysfinest.com/u/fran)
#### Post date: [16 September 2023 18:47 UTC](https://forum.foleysfinest.com/t/restoring-gui-state-after-window-is-closed/173/5 "2023-09-16T18:47:58Z")

</div>

Hey Daniel,

I have taken your suggestions into account 🙂

I have another question, the GUI state (such as the patch list) persists when the window is redrawn, but the attributes I create with `createAndAddObject`, for instance `magicState.createAndAddObject<FileListBackend>("files");` are lost once I close and open the DAW back.

I noted that the parameters I declare in a `ParameterLayout` at ` createParameterLayout()` persist between even when I close and open back the DAW.

Is there a way to store the items created with `magicState.createAndAddObject()` so that they persist between DAWs runs?

Thanks so much again!

Fran

---

<div class="post-metadata">

### Author: ![daniel](https://forum.foleysfinest.com/user_avatar/forum.foleysfinest.com/daniel/32/5_2.png) [@daniel](https://forum.foleysfinest.com/u/daniel)
#### Post date: [17 September 2023 21:32 UTC](https://forum.foleysfinest.com/t/restoring-gui-state-after-window-is-closed/173/6 "2023-09-17T21:32:55Z")

</div>

The MagicState has a ValueTree that is automatically serialised in the getStateInformation().  
There are three parts:

- the parameters are stored in the schema compatible to the AudioProcessorValueTreeState (in the subclass MagicProcessorState, which is default in the MagicProcessor)
- a sub tree “properties” that can be connected from GUI and from the processor via `getPropertyAsValue("path:value")`
- getValueTree() is the root of the xml, where you can add more children if you need

In addition you find an ApplicationSettingsFile in the MagicState, which will be shared from all plugin instances, e.g. for settings

Hope that helps
