ValueTree: How to Refresh All Listeners

Anyone know how to force all listeners of a ValueTree to get a valueTreePropertyChanged() message even when a property has not actually changed?

I have various bits of UI listening to a juce::Colour property in my ValueTree. After registering the UI listeners, I would like to send an initial data refresh to all listeners so they can initialize themselves with the initial ValueTree properties.

Alternatively, I could manually write some code in each Component to go find its ValueTree properties of interest which may be deeper in the tree hierarchy. This would require multiple calls to getChildWithName() depending on how deep in the hierarchy the properties of interest are. So, I would like to find a way to eliminate this per-Component tree parsing and simply refresh all listeners.

Is there any easy way to do this which I am missing?

i feel like there’s some missing information, or i just don’t get it. because the thing is: if the colour in the valueTree really hasn’t changed then what is the desired effect of sending a message to the listeners of that colour? say a component reacts to it by repainting itself. it would repaint itself with the same colour as before, right?

I don’t know any way to do this. The value tree only notifies values that change to the listeners.

I think there is no other way than to read the values from the value tree directly if you create UI components without using the listeners for initializing the values.

1 Like

Here’s a bit more info:

My UI components are registered to listen to the ValueTree only after they are constructed. During each UI component construction, I provide some initial color values for painting. Then later, each UI component is registered as a listener to the ValueTree. Then, after all UI components have been registered to listen to the ValueTree, I would like the listener callback function, valueTreePropertyChanged(), to be called for all those UI components which will set the proper color values and trigger new repaints().

I could always pass in the ValueTree at construction, but I will have the same problem I mention in my original post: I would have to search through the hierarchy for the properties I want. The benefit of setting my colour values via the valueTreePropertyChanged() is that I only need to check if my specific unique property ID (juce::Identifier) changed instead of searching through the whole ValueTree hierarchy.

this is not exactly answering your initial question, but i just tell you how i made my colour-handling-system in case you wanna read alternative solutions:

in one of my latest plugin releases i have implement a menu where you can change the colour sheme for every instance of the plugin. i suppose that’s what you want if you store colours in valueTrees in the first place? In that implementation I have a namespace where an enum class defines different colours by their functions, like for hovering, normal, text, highlighting etc., and whenever a component wants to draw something it reads from an array of colours with this enum. that way you can make sure as long as this array is always having the right colours at all times your components have too (if you repaint them then as well). then i have a function that gives the array default colours which is only being used if no custom colours can be found. used propertiesFile for that btw. it’s better than saving it with the valueTree of the current preset, because that way it works for all instances of the plugin. so basically i load all this at init. now whenever a colour has been changed in the menu i’m using a selfmade event system to send a “ColourChanged” event. my event system then sends this information to every component in the project and the ones that draw something can repaint then. in their paint call they read from that array i was talking before.

1 Like

Yes, you have to choose carefully here :slight_smile:
I would recommend if you want to use Undo / Redo. I normally also save configuration-settings that are the same for all app instances in a propertiesFile without using the value tree.

1 Like

@Mrugalla @kunz Thank you for sharing your approaches, these were helpful to hear.

In my case, I am using ValueTrees to allow colours in the plugin to be modified at runtime with a colour picker component. These Colour values also need to be serialized to/from files, so ValueTree seems to be the best solution for this case.

I do still wish there was some method to send updates to all ValueTree listeners even if properties have not yet changed.

But, I did find a hacky workaround for my case: I just manually set one of the ValueTree colour properties to a wrong value, then set it back to the correct colour value and this triggers the update.

serialization was exactly why i mentioned AppProperties. cause the thing is having a valueTree in the processor is good for saving the state of one instance of a plugin and then you can have another instance with its own settings and everything, but there are also states for the whole plugin regardless of instance sometimes and that’s usually colourshemes and stuff. some developers even have an even higher level for that where they have shared state for every plugin of the same developer or something like that

You can force a callback for a property

ValueTree::sendPropertyChangeMessage (const Identifier & property )

2 Likes

Ah this is exactly what I needed, thank you! I looked the ValueTree docs up and down twice but missed this both times. Thank you again!

1 Like

Another option is if your components hold a ValueTree member, you set it to listen to that, then at the end of the constructor do mTree = mainTree, which will call the ValueTreeRedirected() callback in the listener.

1 Like