Basic question on changing properties at run-time

Hi. Apologies for the newbie question. I must be missing something completely obvious.
I’m trying to change properties of UI elements based on some interaction at run-time. This should be pretty basic. But for whatever reason, its not happening. The code compiles, but nothing on the interface changes.
The relevant lines of code are;

auto myNode = magicState.getSettings().getChildWithName(IDs::paramSomethingFromUI);
myNode.setProperty("visibility", false, nullptr);

I’ve tried it with changing different properties, and tried it with
magicState.getSettings().getOrCreateChildWithName(IDs::paramSomethingFromUI, nullptr);
instead of the first line, as well as other variations. I’ve also looked through the examples
What am I missing? Is there some trivial example that I should look at to see how its done?


Hi Josh,

Thanks for your question. That is indeed not obvious, given there are two concepts here.
The magicState.getSettings() is a settings machinery for all instances of your plugin. That is not (yet) accessible from the GUI tree.

The properties in the GUI is accessed via getPropertyAsValue(). An example can be seen in EqualizerExample:

Those properties are then accessible in the GUI editor:

I hope that gets you further, let me know if it helped…

1 Like

This got me halfway there. That is, I see how to use getPropertyAsValue and properties in the GUI tree. It works sometimes, but not in all cases. I can’t tell yet if its related or a different problem.
I’m trying to have a view and everything in it iniitially hidden, and then made visible after some user action (user registers the plugin). I can use getPropertyAsValue.setProperty to change the visibility, but it still shows as visible when the plugin is first loaded, no matter what I try.
Here’s the relevant code;

magicState.setGuiValueTree(BinaryData::magic_xml, BinaryData::magic_xmlSize);
DBG("initially, should be locked");
magicState.getPropertyAsValue("Views:Unlocked").setValue(false); //Not working!
magicState.addTrigger("UnlockClicked", [&] { //Working!
  if (locked == 1) {
    DBG("should be unlocked");
    locked = 0;
  } else {
    DBG("should be locked");
    locked = 1;

where Views:Unlocked controls the visibility of a Slider and of the View that contains it.

I also tried setting Visibility to false in PrepareToPlay . Didn’t work.
Any idea why this didn’t work? Is there an example where interface elements are initially invisible and then made visible later?

I tried that evening as well, and there is something weird. I tried the same setup, adding a view as overlay that you should be able to click away. But it keeps on showing.

Weirdly I have no problem with the analyzer curves in the EqualizerExample.
I took pretty much the same route you did, adding a trigger that sets the visibility to false.
I thought maybe setStateInformation breaks the referTo of the GuiItem’s visibility, so I forced the GUI to rebuild after setStateInformation, but that didn’t help either.

There is something wrong, but I had to leave it after that evening, because of an other project.
I won’t be able this weekend either, but I keep looking into it.

Thanks. I’ll be patient :wink:
If there isn’t a direct solution, maybe there’s an alternative. For instance, maybe all the other controls don’t have listeners until the required user action happens, or the audio processing all gets bypassed until after the user action. Doable, but not preferred.

If we get this fixed, I’d be happy to provide a PGM version of the JUCE tutorial JUCE: Tutorial: Unlock your plugins through online registration , which could be useful to the PGM community.

1 Like

Quick related question. Is there a way to add or remove a node’s class at run-time? That way I can use the hidden class from the equaliser example to have components leave the interface, rather than leave a blank space?

That should be possible. The ValueTree is watched, so if you add a node it should update automatically.

The drawback is, that you cannot use the editor. But you could design the popup separately and even store it in a separate xml file.

Let me know how it goes.

I got it working now. Here, the main interface is invisible until someone clicks the Unlock button.

Here’s how it looks for a simple example (showing both the lock and unlock screens).

The “View (root)” 's display is set to “contents”

“TextButton (Lock)” 's onClick is set to “LockClicked”

And “TextButton (Unlock)” 's visibility is set to “Views:Locked”
“TextButton (Unlock)” 's onClick is set to “UnlockClicked”

and the important lines of code in the processor are;

magicState.addTrigger("UnlockClicked", [&] {
magicState.addTrigger("LockClicked", [&] {

I think the problem I had before was just finding the right combination of display, visibility etc.on each interface element, right ordering of things in the value tree with display ‘contents’, and making sure to initialise properties properly.

Now, I need to figure out how to get JUCE’s OnlineUnlockForm to work while using Plugin GUI Magic. I know it will probaably involve adding it as a node into the ValueStateTree somehow. If you’ve got any examples or advice, that would be great.