Component::setBufferedToImage(true) problem with repaint

I use setBufferedToImage to drastically reduce certain components’ repaint calls successfully. it is a nice little function, but it has a problem unfortunately. you see, i just added an options menu to my plugin where the user can change the colours of certain things. when they press the ok-button the colour is registered in the general appData and i repaint the whole interface with getTopLevelComponent()->repaint();. you can already guess what’s happening, right? the components that are set to buffer will not repaint now, because they have not explicitely been called to repaint, but just try to paint as a side effect of the whole UI being called repaint on. that is ofc not what should happen, when someone wants to refresh the whole UI. So in a quest to solve this issue I thought to myself “ok, easypeasy, I just let a struct derive from component and give it function that repaints and then traverses through all child components that derive from this struct and call this function on all of them” but then i realized in order to do that i’d have to let all my other components derive from this component from now on, which makes not a lot of sense with all components that i just took from juce, but it would also require me to make my own system of keeping track with the hierarchy of those components, which is not hard, but certainly annoying from a code design point of view, considering that juce itself already has a system like that in component itself. so my suggestion is: juce team! please just add a little function to juce::Component that lets us repaint something, including all its child components, in a way that informs the bufferedToImage components that this is not a repaint to ignore.

edit: my alternative would be editing the juce modules directly but i’d like to not having to do that, since i couldn’t update the repository to the latest develop branch anymore then. another alternative would be finding a way to store pointers to all components in a single vector and then just repaint that. i think i’d do that if no solution is offered, but i’d still think it makes sense to have a function like that in juce itself, since it would just nicely complement the setBufferedToImage-functionality

Maybe calling Component::sendLookAndFeelChange(); will do the trick. This will call repaint on the component and call sendLookAndFeelChange on all its children which in turn will also repaint. Its just a matter of traversing over all child components and call their repaint method.

This shouldn’t require modifying the module sources at all - I think it can be done with a free function:

static void forceCompleteRepaint (Component& comp)
{
    comp.repaint();

    for (auto* c : comp.getChildren())
        forceCompleteRepaint (*c);
}
3 Likes

hey i didn’t think of this! thank you. also thanks to rebbur. sounds like that would have solved it as well